1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
54 import com.sun.xml.internal.ws.wsdl.parser.SOAPConstants;
55 import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants;
56 import com.sun.xml.internal.ws.wsdl.writer.document.Binding;
57 import com.sun.xml.internal.ws.wsdl.writer.document.BindingOperationType;
58 import com.sun.xml.internal.ws.wsdl.writer.document.Definitions;
59 import com.sun.xml.internal.ws.wsdl.writer.document.Fault;
60 import com.sun.xml.internal.ws.wsdl.writer.document.FaultType;
61 import com.sun.xml.internal.ws.wsdl.writer.document.Import;
62 import com.sun.xml.internal.ws.wsdl.writer.document.Message;
63 import com.sun.xml.internal.ws.wsdl.writer.document.Operation;
64 import com.sun.xml.internal.ws.wsdl.writer.document.ParamType;
65 import com.sun.xml.internal.ws.wsdl.writer.document.Port;
66 import com.sun.xml.internal.ws.wsdl.writer.document.PortType;
67 import com.sun.xml.internal.ws.wsdl.writer.document.Service;
68 import com.sun.xml.internal.ws.wsdl.writer.document.Types;
69 import com.sun.xml.internal.ws.wsdl.writer.document.soap.Body;
70 import com.sun.xml.internal.ws.wsdl.writer.document.soap.BodyType;
71 import com.sun.xml.internal.ws.wsdl.writer.document.soap.Header;
72 import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPAddress;
73 import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPFault;
74 import com.sun.xml.internal.ws.wsdl.writer.document.xsd.Schema;
75 import com.sun.xml.internal.ws.spi.db.BindingContext;
76 import com.sun.xml.internal.ws.spi.db.BindingHelper;
77 import com.sun.xml.internal.ws.spi.db.TypeInfo;
78 import com.sun.xml.internal.ws.spi.db.WrapperComposite;
79 import com.sun.xml.internal.ws.util.RuntimeVersion;
80 import com.sun.xml.internal.ws.policy.jaxws.PolicyWSDLGeneratorExtension;
81 import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants;
82 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Element;
83 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.ComplexType;
84 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.ExplicitGroup;
85 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.LocalElement;
86
87 import javax.jws.soap.SOAPBinding.Style;
88 import javax.jws.soap.SOAPBinding.Use;
89 import javax.xml.bind.SchemaOutputResolver;
90 import javax.xml.namespace.QName;
91 import javax.xml.transform.Result;
92 import javax.xml.transform.Transformer;
93 import javax.xml.transform.TransformerConfigurationException;
94 import javax.xml.transform.TransformerException;
95 import javax.xml.transform.TransformerFactory;
96 import javax.xml.transform.dom.DOMResult;
97 import javax.xml.transform.dom.DOMSource;
98 import javax.xml.transform.sax.SAXResult;
99 import javax.xml.ws.Holder;
100 import javax.xml.ws.WebServiceException;
101
102 import org.w3c.dom.Document;
103
104 import java.io.IOException;
105 import java.net.URI;
106 import java.net.URISyntaxException;
107 import java.util.ArrayList;
108 import java.util.HashMap;
109 import java.util.HashSet;
110 import java.util.Iterator;
111 import java.util.List;
112 import java.util.Set;
113
114
115 /**
116 * Class used to generate WSDLs from a {@link SEIModel}.
117 *
118 * @author WS Development Team
119 */
120 public class WSDLGenerator {
121 private JAXWSOutputSchemaResolver resolver;
122 private WSDLResolver wsdlResolver = null;
123 private AbstractSEIModelImpl model;
124 private Definitions serviceDefinitions;
125 private Definitions portDefinitions;
126 private Types types;
127 /**
128 * Constant String for ".wsdl"
129 */
130 private static final String DOT_WSDL = ".wsdl";
131 /**
132 * Constant String appended to response message names
133 */
134 private static final String RESPONSE = "Response";
135 /**
136 * constant String used for part name for wrapped request messages
137 */
138 private static final String PARAMETERS = "parameters";
139 /**
140 * the part name for unwrappable response messages
141 */
142 private static final String RESULT = "parameters";
143 /**
144 * the part name for response messages that are not unwrappable
145 */
146 private static final String UNWRAPPABLE_RESULT = "result";
147 /**
148 * The WSDL namespace
149 */
150 private static final String WSDL_NAMESPACE = WSDLConstants.NS_WSDL;
151
152 /**
153 * the XSD namespace
154 */
155 private static final String XSD_NAMESPACE = SOAPNamespaceConstants.XSD;
156 /**
157 * the namespace prefix to use for the XSD namespace
158 */
159 private static final String XSD_PREFIX = "xsd";
160 /**
161 * The SOAP 1.1 namespace
162 */
163 private static final String SOAP11_NAMESPACE = SOAPConstants.NS_WSDL_SOAP;
164 /**
165 * The SOAP 1.2 namespace
166 */
167 private static final String SOAP12_NAMESPACE = SOAPConstants.NS_WSDL_SOAP12;
179 private static final String TNS_PREFIX = "tns";
180
181 /**
182 * Constant String "document" used to specify <code>document</code> style
183 * soapBindings
184 */
185 private static final String DOCUMENT = "document";
186 /**
187 * Constant String "rpc" used to specify <code>rpc</code> style
188 * soapBindings
189 */
190 private static final String RPC = "rpc";
191 /**
192 * Constant String "literal" used to create <code>literal</code> use binddings
193 */
194 private static final String LITERAL = "literal";
195 /**
196 * Constant String to flag the URL to replace at runtime for the endpoint
197 */
198 private static final String REPLACE_WITH_ACTUAL_URL = "REPLACE_WITH_ACTUAL_URL";
199 private Set<QName> processedExceptions = new HashSet<QName>();
200 private WSBinding binding;
201 private String wsdlLocation;
202 private String portWSDLID;
203 private String schemaPrefix;
204 private WSDLGeneratorExtension extension;
205 List<WSDLGeneratorExtension> extensionHandlers;
206
207 private String endpointAddress = REPLACE_WITH_ACTUAL_URL;
208 private Container container;
209 private final Class implType;
210
211 private boolean inlineSchemas; // TODO
212 private final boolean disableXmlSecurity;
213
214 /**
215 * Creates the WSDLGenerator
216 * @param model The {@link AbstractSEIModelImpl} used to generate the WSDL
217 * @param wsdlResolver The {@link WSDLResolver} to use resovle names while generating the WSDL
218 * @param binding specifies which {@link javax.xml.ws.BindingType} to generate
451 */
452 protected void generateTypes() {
453 types = portDefinitions.types();
454 if (model.getBindingContext() != null) {
455 if (inlineSchemas && model.getBindingContext().getClass().getName().indexOf("glassfish") == -1) {
456 resolver.nonGlassfishSchemas = new ArrayList<DOMResult>();
457 }
458 try {
459 model.getBindingContext().generateSchema(resolver);
460 } catch (IOException e) {
461 // TODO locallize and wrap this
462 throw new WebServiceException(e.getMessage());
463 }
464 }
465 if (resolver.nonGlassfishSchemas != null) {
466 TransformerFactory tf = XmlUtil.newTransformerFactory(!disableXmlSecurity);
467 try {
468 Transformer t = tf.newTransformer();
469 for (DOMResult xsd : resolver.nonGlassfishSchemas) {
470 Document doc = (Document) xsd.getNode();
471 SAXResult sax = new SAXResult(new TXWContentHandler(types));
472 t.transform(new DOMSource(doc.getDocumentElement()), sax);
473 }
474 } catch (TransformerConfigurationException e) {
475 throw new WebServiceException(e.getMessage(), e);
476 } catch (TransformerException e) {
477 throw new WebServiceException(e.getMessage(), e);
478 }
479 }
480 generateWrappers();
481 }
482
483 void generateWrappers() {
484 List<WrapperParameter> wrappers = new ArrayList<WrapperParameter>();
485 for (JavaMethodImpl method : model.getJavaMethods()) {
486 if(method.getBinding().isRpcLit()) continue;
487 for (ParameterImpl p : method.getRequestParameters()) {
488 if (p instanceof WrapperParameter) {
489 if (WrapperComposite.class.equals((((WrapperParameter)p).getTypeInfo().type))) {
490 wrappers.add((WrapperParameter)p);
491 }
492 }
493 }
494 for (ParameterImpl p : method.getResponseParameters()) {
495 if (p instanceof WrapperParameter) {
496 if (WrapperComposite.class.equals((((WrapperParameter)p).getTypeInfo().type))) {
497 wrappers.add((WrapperParameter)p);
498 }
499 }
500 }
501 }
502 if (wrappers.isEmpty()) return;
503 HashMap<String, Schema> xsds = new HashMap<String, Schema>();
504 for(WrapperParameter wp : wrappers) {
505 String tns = wp.getName().getNamespaceURI();
506 Schema xsd = xsds.get(tns);
507 if (xsd == null) {
508 xsd = types.schema();
509 xsd.targetNamespace(tns);
510 xsds.put(tns, xsd);
511 }
512 Element e = xsd._element(Element.class);
513 e._attribute("name", wp.getName().getLocalPart());
514 e.type(wp.getName());
515 ComplexType ct = xsd._element(ComplexType.class);
516 ct._attribute("name", wp.getName().getLocalPart());
517 ExplicitGroup sq = ct.sequence();
518 for (ParameterImpl p : wp.getWrapperChildren() ) {
519 if (p.getBinding().isBody()) {
520 LocalElement le = sq.element();
521 le._attribute("name", p.getName().getLocalPart());
522 TypeInfo typeInfo = p.getItemType();
523 boolean repeatedElement = false;
524 if (typeInfo == null) {
525 typeInfo = p.getTypeInfo();
526 } else {
527 repeatedElement = true;
528 }
529 QName type = model.getBindingContext().getTypeName(typeInfo);
530 le.type(type);
531 if (repeatedElement) {
532 le.minOccurs(0);
533 le.maxOccurs("unbounded");
534 }
535 }
536 }
537 }
538 }
539
540 /**
541 * Generates the WSDL messages
542 */
543 protected void generateMessages() {
544 for (JavaMethodImpl method : model.getJavaMethods()) {
545 generateSOAPMessages(method, method.getBinding());
546 }
547 }
548
549 /**
550 * Generates messages for a SOAPBinding
551 * @param method The {@link JavaMethod} to generate messages for
552 * @param binding The {@link com.sun.xml.internal.ws.api.model.soap.SOAPBinding} to add the generated messages to
553 */
554 protected void generateSOAPMessages(JavaMethodImpl method, com.sun.xml.internal.ws.api.model.soap.SOAPBinding binding) {
555 boolean isDoclit = binding.isDocLit();
556 // Message message = portDefinitions.message().name(method.getOperation().getName().getLocalPart());
557 Message message = portDefinitions.message().name(method.getRequestMessageName());
|
1 /*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
54 import com.sun.xml.internal.ws.wsdl.parser.SOAPConstants;
55 import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants;
56 import com.sun.xml.internal.ws.wsdl.writer.document.Binding;
57 import com.sun.xml.internal.ws.wsdl.writer.document.BindingOperationType;
58 import com.sun.xml.internal.ws.wsdl.writer.document.Definitions;
59 import com.sun.xml.internal.ws.wsdl.writer.document.Fault;
60 import com.sun.xml.internal.ws.wsdl.writer.document.FaultType;
61 import com.sun.xml.internal.ws.wsdl.writer.document.Import;
62 import com.sun.xml.internal.ws.wsdl.writer.document.Message;
63 import com.sun.xml.internal.ws.wsdl.writer.document.Operation;
64 import com.sun.xml.internal.ws.wsdl.writer.document.ParamType;
65 import com.sun.xml.internal.ws.wsdl.writer.document.Port;
66 import com.sun.xml.internal.ws.wsdl.writer.document.PortType;
67 import com.sun.xml.internal.ws.wsdl.writer.document.Service;
68 import com.sun.xml.internal.ws.wsdl.writer.document.Types;
69 import com.sun.xml.internal.ws.wsdl.writer.document.soap.Body;
70 import com.sun.xml.internal.ws.wsdl.writer.document.soap.BodyType;
71 import com.sun.xml.internal.ws.wsdl.writer.document.soap.Header;
72 import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPAddress;
73 import com.sun.xml.internal.ws.wsdl.writer.document.soap.SOAPFault;
74 import com.sun.xml.internal.ws.spi.db.BindingContext;
75 import com.sun.xml.internal.ws.spi.db.BindingHelper;
76 import com.sun.xml.internal.ws.util.RuntimeVersion;
77 import com.sun.xml.internal.ws.policy.jaxws.PolicyWSDLGeneratorExtension;
78 import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants;
79
80 import javax.jws.soap.SOAPBinding.Style;
81 import javax.jws.soap.SOAPBinding.Use;
82 import javax.xml.bind.SchemaOutputResolver;
83 import javax.xml.namespace.QName;
84 import javax.xml.transform.Result;
85 import javax.xml.transform.Transformer;
86 import javax.xml.transform.TransformerConfigurationException;
87 import javax.xml.transform.TransformerException;
88 import javax.xml.transform.TransformerFactory;
89 import javax.xml.transform.dom.DOMResult;
90 import javax.xml.transform.dom.DOMSource;
91 import javax.xml.transform.sax.SAXResult;
92 import javax.xml.ws.Holder;
93 import javax.xml.ws.WebServiceException;
94
95 import org.w3c.dom.Document;
96 import org.w3c.dom.NodeList;
97
98 import java.io.IOException;
99 import java.net.URI;
100 import java.net.URISyntaxException;
101 import java.util.ArrayList;
102 import java.util.HashSet;
103 import java.util.Iterator;
104 import java.util.List;
105 import java.util.Set;
106
107
108 /**
109 * Class used to generate WSDLs from a {@link SEIModel}.
110 *
111 * @author WS Development Team
112 */
113 public class WSDLGenerator {
114 private JAXWSOutputSchemaResolver resolver;
115 private WSDLResolver wsdlResolver = null;
116 private AbstractSEIModelImpl model;
117 private Definitions serviceDefinitions;
118 private Definitions portDefinitions;
119 private Types types;
120 /**
121 * Constant String for ".wsdl"
122 */
123 private static final String DOT_WSDL = ".wsdl";
124 /**
125 * The WSDL namespace
126 */
127 private static final String WSDL_NAMESPACE = WSDLConstants.NS_WSDL;
128
129 /**
130 * the XSD namespace
131 */
132 private static final String XSD_NAMESPACE = SOAPNamespaceConstants.XSD;
133 /**
134 * the namespace prefix to use for the XSD namespace
135 */
136 private static final String XSD_PREFIX = "xsd";
137 /**
138 * The SOAP 1.1 namespace
139 */
140 private static final String SOAP11_NAMESPACE = SOAPConstants.NS_WSDL_SOAP;
141 /**
142 * The SOAP 1.2 namespace
143 */
144 private static final String SOAP12_NAMESPACE = SOAPConstants.NS_WSDL_SOAP12;
156 private static final String TNS_PREFIX = "tns";
157
158 /**
159 * Constant String "document" used to specify <code>document</code> style
160 * soapBindings
161 */
162 private static final String DOCUMENT = "document";
163 /**
164 * Constant String "rpc" used to specify <code>rpc</code> style
165 * soapBindings
166 */
167 private static final String RPC = "rpc";
168 /**
169 * Constant String "literal" used to create <code>literal</code> use binddings
170 */
171 private static final String LITERAL = "literal";
172 /**
173 * Constant String to flag the URL to replace at runtime for the endpoint
174 */
175 private static final String REPLACE_WITH_ACTUAL_URL = "REPLACE_WITH_ACTUAL_URL";
176
177 static public final String XsdNs = "http://www.w3.org/2001/XMLSchema";
178
179 private Set<QName> processedExceptions = new HashSet<QName>();
180 private WSBinding binding;
181 private String wsdlLocation;
182 private String portWSDLID;
183 private String schemaPrefix;
184 private WSDLGeneratorExtension extension;
185 List<WSDLGeneratorExtension> extensionHandlers;
186
187 private String endpointAddress = REPLACE_WITH_ACTUAL_URL;
188 private Container container;
189 private final Class implType;
190
191 private boolean inlineSchemas; // TODO
192 private final boolean disableXmlSecurity;
193
194 /**
195 * Creates the WSDLGenerator
196 * @param model The {@link AbstractSEIModelImpl} used to generate the WSDL
197 * @param wsdlResolver The {@link WSDLResolver} to use resovle names while generating the WSDL
198 * @param binding specifies which {@link javax.xml.ws.BindingType} to generate
431 */
432 protected void generateTypes() {
433 types = portDefinitions.types();
434 if (model.getBindingContext() != null) {
435 if (inlineSchemas && model.getBindingContext().getClass().getName().indexOf("glassfish") == -1) {
436 resolver.nonGlassfishSchemas = new ArrayList<DOMResult>();
437 }
438 try {
439 model.getBindingContext().generateSchema(resolver);
440 } catch (IOException e) {
441 // TODO locallize and wrap this
442 throw new WebServiceException(e.getMessage());
443 }
444 }
445 if (resolver.nonGlassfishSchemas != null) {
446 TransformerFactory tf = XmlUtil.newTransformerFactory(!disableXmlSecurity);
447 try {
448 Transformer t = tf.newTransformer();
449 for (DOMResult xsd : resolver.nonGlassfishSchemas) {
450 Document doc = (Document) xsd.getNode();
451 if (inlineSchemas) {
452 NodeList importList = doc.getDocumentElement().getElementsByTagNameNS("http://www.w3.org/2001/XMLSchema", "import");
453 for(int i = 0; i < importList.getLength(); i++) {
454 org.w3c.dom.Element impElem = (org.w3c.dom.Element)importList.item(i);
455 impElem.removeAttribute("schemaLocation");
456 }
457 }
458 SAXResult sax = new SAXResult(new TXWContentHandler(types));
459 t.transform(new DOMSource(doc.getDocumentElement()), sax);
460 }
461 } catch (TransformerConfigurationException e) {
462 throw new WebServiceException(e.getMessage(), e);
463 } catch (TransformerException e) {
464 throw new WebServiceException(e.getMessage(), e);
465 }
466 }
467 }
468
469 /**
470 * Generates the WSDL messages
471 */
472 protected void generateMessages() {
473 for (JavaMethodImpl method : model.getJavaMethods()) {
474 generateSOAPMessages(method, method.getBinding());
475 }
476 }
477
478 /**
479 * Generates messages for a SOAPBinding
480 * @param method The {@link JavaMethod} to generate messages for
481 * @param binding The {@link com.sun.xml.internal.ws.api.model.soap.SOAPBinding} to add the generated messages to
482 */
483 protected void generateSOAPMessages(JavaMethodImpl method, com.sun.xml.internal.ws.api.model.soap.SOAPBinding binding) {
484 boolean isDoclit = binding.isDocLit();
485 // Message message = portDefinitions.message().name(method.getOperation().getName().getLocalPart());
486 Message message = portDefinitions.message().name(method.getRequestMessageName());
|