src/share/jaxws_classes/com/sun/tools/internal/ws/processor/modeler/wsdl/PseudoSchemaBuilder.java

changeset 0
373ffda63c9a
child 637
9c07ef4934dd
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
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
23 * questions.
24 */
25
26 package com.sun.tools.internal.ws.processor.modeler.wsdl;
27
28 import com.sun.tools.internal.ws.processor.generator.Names;
29 import static com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModelerBase.getExtensionOfType;
30 import com.sun.tools.internal.ws.wscompile.ErrorReceiver;
31 import com.sun.tools.internal.ws.wscompile.WsimportOptions;
32 import com.sun.tools.internal.ws.wscompile.Options;
33 import com.sun.tools.internal.ws.wsdl.document.*;
34 import com.sun.tools.internal.ws.wsdl.document.jaxws.JAXWSBinding;
35 import com.sun.tools.internal.ws.wsdl.document.schema.SchemaKinds;
36 import com.sun.tools.internal.ws.wsdl.document.soap.SOAP12Binding;
37 import com.sun.tools.internal.ws.wsdl.document.soap.SOAPBinding;
38 import org.xml.sax.InputSource;
39
40 import javax.xml.namespace.QName;
41 import java.io.ByteArrayInputStream;
42 import java.io.StringReader;
43 import java.io.StringWriter;
44 import java.nio.charset.StandardCharsets;
45 import java.text.MessageFormat;
46 import java.util.*;
47
48
49 /**
50 * Builds all possible pseudo schemas for async operation ResponseBean to feed to XJC.
51 *
52 * @author Vivek Pandey
53 */
54 public class PseudoSchemaBuilder {
55
56 private final StringWriter buf = new StringWriter();
57 private final WSDLDocument wsdlDocument;
58 private WSDLModeler wsdlModeler;
59 private final List<InputSource> schemas = new ArrayList<InputSource>();
60 private final HashMap<QName, Port> bindingNameToPortMap = new HashMap<QName, Port>();
61 private static final String w3ceprSchemaBinding = "<bindings\n" +
62 " xmlns=\"http://java.sun.com/xml/ns/jaxb\"\n" +
63 " xmlns:wsa=\"http://www.w3.org/2005/08/addressing\"\n" +
64 " xmlns:xjc=\"http://java.sun.com/xml/ns/jaxb/xjc\"\n" +
65 " version=\"2.1\">\n" +
66 " \n" +
67 " <bindings scd=\"x-schema::wsa\" if-exists=\"true\">\n" +
68 //comment the following, otw JAXB won't generate ObjectFactory, classes from wsa schema. See JAX-WS-804
69 // " <schemaBindings map=\"false\" />\n" +
70 " <bindings scd=\"wsa:EndpointReference\">\n" +
71 " <class ref=\"javax.xml.ws.wsaddressing.W3CEndpointReference\" xjc:recursive=\"true\"/>\n" +
72 " </bindings>\n" +
73 " <bindings scd=\"~wsa:EndpointReferenceType\">\n" +
74 " <class ref=\"javax.xml.ws.wsaddressing.W3CEndpointReference\" xjc:recursive=\"true\"/>\n" +
75 " </bindings>\n" +
76 " </bindings>\n" +
77 "</bindings>";
78
79 private static final String memberSubmissionEPR = "<bindings\n" +
80 " xmlns=\"http://java.sun.com/xml/ns/jaxb\"\n" +
81 " xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"\n" +
82 " version=\"2.1\">\n" +
83 " \n" +
84 " <bindings scd=\"x-schema::wsa\" if-exists=\"true\">\n" +
85 //comment the following, otw JAXB won't generate ObjectFactory, classes from wsa schema. See JAX-WS-804
86 // " <schemaBindings map=\"false\" />\n" +
87 " <bindings scd=\"wsa:EndpointReference\">\n" +
88 " <class ref=\"com.sun.xml.internal.ws.developer.MemberSubmissionEndpointReference\"/>\n" +
89 " </bindings>\n" +
90 " <bindings scd=\"~wsa:EndpointReferenceType\">\n" +
91 " <class ref=\"com.sun.xml.internal.ws.developer.MemberSubmissionEndpointReference\"/>\n" +
92 " </bindings>\n" +
93 " </bindings>\n" +
94 "</bindings>";
95
96 private final static String sysId = "http://dummy.pseudo-schema#schema";
97
98 private WsimportOptions options;
99 public static List<InputSource> build(WSDLModeler wsdlModeler, WsimportOptions options, ErrorReceiver errReceiver) {
100 PseudoSchemaBuilder b = new PseudoSchemaBuilder(wsdlModeler.document);
101 b.wsdlModeler = wsdlModeler;
102 b.options = options;
103 b.build();
104 int i;
105 for(i = 0; i < b.schemas.size(); i++){
106 InputSource is = b.schemas.get(i);
107 is.setSystemId(sysId+(i + 1));
108 }
109 //add w3c EPR binding
110 if(!(options.noAddressingBbinding) && options.target.isLaterThan(Options.Target.V2_1)){
111 InputSource is = new InputSource(new ByteArrayInputStream(w3ceprSchemaBinding.getBytes(StandardCharsets.UTF_8)));
112 is.setSystemId(sysId+(++i +1));
113 b.schemas.add(is);
114 }
115
116
117 //TODO: uncomment after JAXB fixes the issue related to passing multiples of such bindings
118 //add member submission EPR binding
119 // InputSource is1 = new InputSource(new ByteArrayInputStream(memberSubmissionEPR.getBytes()));
120 // is1.setSystemId(sysId+(++i + 1));
121 // b.schemas.add(is1);
122
123 return b.schemas;
124 }
125
126
127 private PseudoSchemaBuilder(WSDLDocument _wsdl) {
128 this.wsdlDocument = _wsdl;
129 }
130
131 private void build() {
132 for(Iterator<Service> itr=wsdlDocument.getDefinitions().services(); itr.hasNext(); ) {
133 build(itr.next());
134 }
135 }
136
137 private void build(Service service) {
138 for( Iterator<Port> itr=service.ports(); itr.hasNext(); ) {
139 build(itr.next() );
140 }
141 }
142
143 private void build(Port port) {
144 if(wsdlModeler.isProvider(port))
145 return;
146 Binding binding = port.resolveBinding(wsdlDocument);
147
148 SOAPBinding soapBinding =
149 (SOAPBinding)getExtensionOfType(binding, SOAPBinding.class);
150 //lets try and see if its SOAP 1.2. dont worry about extension flag, its
151 // handled much earlier
152 if (soapBinding == null) {
153 soapBinding =
154 (SOAPBinding)getExtensionOfType(binding, SOAP12Binding.class);
155 }
156 if(soapBinding == null)
157 return;
158 PortType portType = binding.resolvePortType(wsdlDocument);
159
160 QName bindingName = WSDLModelerBase.getQNameOf(binding);
161
162 //we dont want to process the port bound to the binding processed earlier
163 if(bindingNameToPortMap.containsKey(bindingName))
164 return;
165
166 bindingNameToPortMap.put(bindingName, port);
167
168
169 for(Iterator itr=binding.operations(); itr.hasNext();){
170 BindingOperation bindingOperation = (BindingOperation)itr.next();
171
172 // get only the bounded operations
173 Set boundedOps = portType.getOperationsNamed(bindingOperation.getName());
174 if(boundedOps.size() != 1)
175 continue;
176 Operation operation = (Operation)boundedOps.iterator().next();
177
178 // No pseudo schema required for doc/lit
179 if(wsdlModeler.isAsync(portType, operation)){
180 buildAsync(portType, operation, bindingOperation);
181 }
182 }
183 }
184
185 /**
186 * @param portType
187 * @param operation
188 * @param bindingOperation
189 */
190 private void buildAsync(PortType portType, Operation operation, BindingOperation bindingOperation) {
191 String operationName = getCustomizedOperationName(operation);//operation.getName();
192 if(operationName == null)
193 return;
194 Message outputMessage = null;
195 if(operation.getOutput() != null)
196 outputMessage = operation.getOutput().resolveMessage(wsdlDocument);
197 if(outputMessage != null){
198 List<MessagePart> allParts = new ArrayList<MessagePart>(outputMessage.getParts());
199 if(options != null && options.additionalHeaders) {
200 List<MessagePart> addtionalHeaderParts = wsdlModeler.getAdditionHeaderParts(bindingOperation, outputMessage, false);
201 allParts.addAll(addtionalHeaderParts);
202 }
203 if(allParts.size() > 1)
204 build(getOperationName(operationName), allParts);
205 }
206
207 }
208
209 private String getCustomizedOperationName(Operation operation) {
210 JAXWSBinding jaxwsCustomization = (JAXWSBinding)getExtensionOfType(operation, JAXWSBinding.class);
211 String operationName = (jaxwsCustomization != null)?((jaxwsCustomization.getMethodName() != null)?jaxwsCustomization.getMethodName().getName():null):null;
212 if(operationName != null){
213 if(Names.isJavaReservedWord(operationName)){
214 return null;
215 }
216
217 return operationName;
218 }
219 return operation.getName();
220 }
221
222 private void writeImports(QName elementName, List<MessagePart> parts){
223 Set<String> uris = new HashSet<String>();
224 for(MessagePart p:parts){
225 String ns = p.getDescriptor().getNamespaceURI();
226 if(!uris.contains(ns) && !ns.equals("http://www.w3.org/2001/XMLSchema") && !ns.equals(elementName.getNamespaceURI())){
227 print("<xs:import namespace=''{0}''/>", ns);
228 uris.add(ns);
229 }
230 }
231 }
232
233 boolean asyncRespBeanBinding = false;
234 private void build(QName elementName, List<MessagePart> allParts){
235
236 print(
237 "<xs:schema xmlns:xs=''http://www.w3.org/2001/XMLSchema''" +
238 " xmlns:jaxb=''http://java.sun.com/xml/ns/jaxb''" +
239 " xmlns:xjc=''http://java.sun.com/xml/ns/jaxb/xjc''" +
240 " jaxb:extensionBindingPrefixes=''xjc''" +
241 " jaxb:version=''1.0''" +
242 " targetNamespace=''{0}''>",
243 elementName.getNamespaceURI());
244
245 writeImports(elementName, allParts);
246
247 if(!asyncRespBeanBinding){
248 print(
249 "<xs:annotation><xs:appinfo>" +
250 " <jaxb:schemaBindings>" +
251 " <jaxb:package name=''{0}'' />" +
252 " </jaxb:schemaBindings>" +
253 "</xs:appinfo></xs:annotation>",
254 wsdlModeler.getJavaPackage() );
255 asyncRespBeanBinding = true;
256 }
257
258 print("<xs:element name=''{0}''>", elementName.getLocalPart());
259 print("<xs:complexType>");
260 print("<xs:sequence>");
261
262
263 for(MessagePart p:allParts) {
264 //rpclit wsdl:part must reference schema type not element, also it must exclude headers and mime parts
265 if(p.getDescriptorKind() == SchemaKinds.XSD_ELEMENT){
266 print("<xs:element ref=''types:{0}'' xmlns:types=''{1}''/>",p.getDescriptor().getLocalPart(), p.getDescriptor().getNamespaceURI());
267 }else{
268 print("<xs:element name=''{0}'' type=''{1}'' xmlns=''{2}'' />",
269 p.getName(),
270 p.getDescriptor().getLocalPart(),
271 p.getDescriptor().getNamespaceURI() );
272 }
273 }
274
275 print("</xs:sequence>");
276 print("</xs:complexType>");
277 print("</xs:element>");
278 print("</xs:schema>");
279
280 // reset the StringWriter, so that next operation element could be written
281 if(buf.toString().length() > 0){
282 //System.out.println("Response bean Schema for operation========> "+ elementName+"\n\n"+buf);
283 InputSource is = new InputSource(new StringReader(buf.toString()));
284 schemas.add(is);
285 buf.getBuffer().setLength(0);
286 }
287 }
288
289 private QName getOperationName(String operationName){
290 if(operationName == null)
291 return null;
292 // String namespaceURI = wsdlDocument.getDefinitions().getTargetNamespaceURI()+"?"+portType.getName()+"?" + operationName;
293 String namespaceURI = "";
294 return new QName(namespaceURI, operationName+"Response");
295 }
296
297 private void print( String msg ) {
298 print( msg, new Object[0] );
299 }
300 private void print( String msg, Object arg1 ) {
301 print( msg, new Object[]{arg1} );
302 }
303 private void print( String msg, Object arg1, Object arg2 ) {
304 print( msg, new Object[]{arg1, arg2} );
305 }
306 private void print( String msg, Object arg1, Object arg2, Object arg3 ) {
307 print( msg, new Object[]{arg1,arg2,arg3} );
308 }
309 private void print( String msg, Object[] args ) {
310 buf.write(MessageFormat.format(msg,args));
311 buf.write('\n');
312 }
313
314 }

mercurial