src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/WSDLParser.java

changeset 0
373ffda63c9a
child 637
9c07ef4934dd
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
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
23 * questions.
24 */
25
26 package com.sun.tools.internal.ws.wsdl.parser;
27
28 import com.sun.tools.internal.ws.api.wsdl.TWSDLExtensible;
29 import com.sun.tools.internal.ws.api.wsdl.TWSDLExtensionHandler;
30 import com.sun.tools.internal.ws.resources.WsdlMessages;
31 import com.sun.tools.internal.ws.util.xml.XmlUtil;
32 import com.sun.tools.internal.ws.wscompile.ErrorReceiverFilter;
33 import com.sun.tools.internal.ws.wscompile.WsimportOptions;
34 import com.sun.tools.internal.ws.wsdl.document.Binding;
35 import com.sun.tools.internal.ws.wsdl.document.BindingFault;
36 import com.sun.tools.internal.ws.wsdl.document.BindingInput;
37 import com.sun.tools.internal.ws.wsdl.document.BindingOperation;
38 import com.sun.tools.internal.ws.wsdl.document.BindingOutput;
39 import com.sun.tools.internal.ws.wsdl.document.Definitions;
40 import com.sun.tools.internal.ws.wsdl.document.Documentation;
41 import com.sun.tools.internal.ws.wsdl.document.Fault;
42 import com.sun.tools.internal.ws.wsdl.document.Import;
43 import com.sun.tools.internal.ws.wsdl.document.Input;
44 import com.sun.tools.internal.ws.wsdl.document.Message;
45 import com.sun.tools.internal.ws.wsdl.document.MessagePart;
46 import com.sun.tools.internal.ws.wsdl.document.Operation;
47 import com.sun.tools.internal.ws.wsdl.document.OperationStyle;
48 import com.sun.tools.internal.ws.wsdl.document.Output;
49 import com.sun.tools.internal.ws.wsdl.document.Port;
50 import com.sun.tools.internal.ws.wsdl.document.PortType;
51 import com.sun.tools.internal.ws.wsdl.document.Service;
52 import com.sun.tools.internal.ws.wsdl.document.WSDLConstants;
53 import com.sun.tools.internal.ws.wsdl.document.WSDLDocument;
54 import com.sun.tools.internal.ws.wsdl.document.jaxws.JAXWSBindingsConstants;
55 import com.sun.tools.internal.ws.wsdl.document.schema.SchemaConstants;
56 import com.sun.tools.internal.ws.wsdl.document.schema.SchemaKinds;
57 import com.sun.tools.internal.ws.wsdl.framework.Entity;
58 import com.sun.tools.internal.ws.wsdl.framework.ParserListener;
59 import com.sun.tools.internal.ws.wsdl.framework.TWSDLParserContextImpl;
60 import com.sun.xml.internal.ws.util.ServiceFinder;
61 import org.w3c.dom.Attr;
62 import org.w3c.dom.Document;
63 import org.w3c.dom.Element;
64 import org.w3c.dom.NodeList;
65 import org.xml.sax.InputSource;
66 import org.xml.sax.Locator;
67 import org.xml.sax.SAXException;
68
69 import java.io.IOException;
70 import java.util.ArrayList;
71 import java.util.HashMap;
72 import java.util.Iterator;
73 import java.util.Map;
74 import org.w3c.dom.Node;
75
76 /**
77 * A parser for WSDL documents. This parser is used only at the tool time.
78 * Extensions should extend TWSDLExtensionHandler, so that it will be called during
79 * parsing wsdl to handle wsdl extenisbility elements. Generally these extensions
80 * will effect the artifacts generated during WSDL processing.
81 *
82 * @see com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser which will be used for WSDL parsing
83 * at runtime.
84 *
85 * @author WS Development Team
86 */
87 public class WSDLParser {
88 private final ErrorReceiverFilter errReceiver;
89 private WsimportOptions options;
90
91 //wsdl extension handlers
92 private final Map extensionHandlers;
93 private MetadataFinder forest;
94 private ArrayList<ParserListener> listeners;
95
96 public WSDLParser(WsimportOptions options, ErrorReceiverFilter errReceiver, MetadataFinder forest) {
97 this.extensionHandlers = new HashMap();
98 this.options = options;
99 this.errReceiver = errReceiver;
100 if (forest == null) {
101 forest = new MetadataFinder(new WSDLInternalizationLogic(), options, errReceiver);
102 forest.parseWSDL();
103 if (forest.isMexMetadata) {
104 errReceiver.reset();
105 }
106 }
107 this.forest = forest;
108 // register handlers for default extensions
109 register(new SOAPExtensionHandler(extensionHandlers));
110 register(new HTTPExtensionHandler(extensionHandlers));
111 register(new MIMEExtensionHandler(extensionHandlers));
112 register(new JAXWSBindingExtensionHandler(extensionHandlers));
113 register(new SOAP12ExtensionHandler(extensionHandlers));
114
115 // MemberSubmission Addressing not supported by WsImport anymore see JAX_WS-1040 for details
116 //register(new MemberSubmissionAddressingExtensionHandler(extensionHandlers, errReceiver, options.isExtensionMode()));
117
118 register(new W3CAddressingExtensionHandler(extensionHandlers, errReceiver));
119 register(new W3CAddressingMetadataExtensionHandler(extensionHandlers, errReceiver));
120 register(new Policy12ExtensionHandler());
121 register(new Policy15ExtensionHandler());
122 for (TWSDLExtensionHandler te : ServiceFinder.find(TWSDLExtensionHandler.class)) {
123 register(te);
124 }
125
126 }
127
128 //TODO RK remove this after tests are fixed.
129 WSDLParser(WsimportOptions options, ErrorReceiverFilter errReceiver) {
130 this(options,errReceiver,null);
131 }
132 private void register(TWSDLExtensionHandler h) {
133 extensionHandlers.put(h.getNamespaceURI(), h);
134 }
135
136 public void addParserListener(ParserListener l) {
137 if (listeners == null) {
138 listeners = new ArrayList<ParserListener>();
139 }
140 listeners.add(l);
141 }
142
143 public WSDLDocument parse() throws SAXException, IOException {
144 // parse external binding files
145 for (InputSource value : options.getWSDLBindings()) {
146 errReceiver.pollAbort();
147 Document root = forest.parse(value, false);
148 if(root==null) continue; // error must have been reported
149 Element binding = root.getDocumentElement();
150 if (!Internalizer.fixNull(binding.getNamespaceURI()).equals(JAXWSBindingsConstants.NS_JAXWS_BINDINGS)
151 || !binding.getLocalName().equals("bindings")){
152 errReceiver.error(forest.locatorTable.getStartLocation(binding), WsdlMessages.PARSER_NOT_A_BINDING_FILE(
153 binding.getNamespaceURI(),
154 binding.getLocalName()));
155 continue;
156 }
157
158 NodeList nl = binding.getElementsByTagNameNS(
159 "http://java.sun.com/xml/ns/javaee", "handler-chains");
160 for(int i = 0; i < nl.getLength(); i++){
161 options.addHandlerChainConfiguration((Element) nl.item(i));
162 }
163
164 }
165 return buildWSDLDocument();
166 }
167
168 public MetadataFinder getDOMForest() {
169 return forest;
170 }
171
172 private WSDLDocument buildWSDLDocument(){
173 /**
174 * Currently we are working off first WSDL document
175 * TODO: add support of creating WSDLDocument from fromjava.collection of WSDL documents
176 */
177
178 String location = forest.getRootWSDL();
179
180 //It means that WSDL is not found, an error might have been reported, lets try to recover
181 if(location == null)
182 return null;
183
184 Document root = forest.get(location);
185
186 if(root == null)
187 return null;
188
189 WSDLDocument document = new WSDLDocument(forest, errReceiver);
190 document.setSystemId(location);
191 TWSDLParserContextImpl context = new TWSDLParserContextImpl(forest, document, listeners, errReceiver);
192
193 Definitions definitions = parseDefinitions(context, root);
194 document.setDefinitions(definitions);
195 return document;
196 }
197
198 private Definitions parseDefinitions(TWSDLParserContextImpl context, Document root) {
199 context.pushWSDLLocation();
200 context.setWSDLLocation(context.getDocument().getSystemId());
201
202 new Internalizer(forest, options, errReceiver).transform();
203
204 Definitions definitions = parseDefinitionsNoImport(context, root);
205 if(definitions == null){
206 Locator locator = forest.locatorTable.getStartLocation(root.getDocumentElement());
207 errReceiver.error(locator, WsdlMessages.PARSING_NOT_AWSDL(locator.getSystemId()));
208
209 }
210 processImports(context);
211 context.popWSDLLocation();
212 return definitions;
213 }
214
215 private void processImports(TWSDLParserContextImpl context) {
216 for(String location : forest.getExternalReferences()){
217 if (!context.getDocument().isImportedDocument(location)){
218 Document doc = forest.get(location);
219 if(doc == null)
220 continue;
221 Definitions importedDefinitions = parseDefinitionsNoImport(context, doc);
222 if(importedDefinitions == null)
223 continue;
224 context.getDocument().addImportedEntity(importedDefinitions);
225 context.getDocument().addImportedDocument(location);
226 }
227 }
228 }
229
230 private Definitions parseDefinitionsNoImport(
231 TWSDLParserContextImpl context,
232 Document doc) {
233 Element e = doc.getDocumentElement();
234 //at this poinjt we expect a wsdl or schema document to be fully qualified
235 if(e.getNamespaceURI() == null || (!e.getNamespaceURI().equals(WSDLConstants.NS_WSDL) || !e.getLocalName().equals("definitions"))){
236 return null;
237 }
238 context.push();
239 context.registerNamespaces(e);
240
241 Definitions definitions = new Definitions(context.getDocument(), forest.locatorTable.getStartLocation(e));
242 String name = XmlUtil.getAttributeOrNull(e, Constants.ATTR_NAME);
243 definitions.setName(name);
244
245 String targetNamespaceURI =
246 XmlUtil.getAttributeOrNull(e, Constants.ATTR_TARGET_NAMESPACE);
247
248 definitions.setTargetNamespaceURI(targetNamespaceURI);
249
250 boolean gotDocumentation = false;
251 boolean gotTypes = false;
252
253 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
254 Element e2 = Util.nextElement(iter);
255 if (e2 == null)
256 break;
257
258 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
259 if (gotDocumentation) {
260 errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
261 return null;
262 }
263 gotDocumentation = true;
264 if(definitions.getDocumentation() == null)
265 definitions.setDocumentation(getDocumentationFor(e2));
266 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_TYPES)) {
267 if (gotTypes && !options.isExtensionMode()) {
268 errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_ONLY_ONE_TYPES_ALLOWED(Constants.TAG_DEFINITIONS));
269 return null;
270 }
271 gotTypes = true;
272 //add all the wsdl:type elements to latter make a list of all the schema elements
273 // that will be needed to create jaxb model
274 if(!options.isExtensionMode())
275 validateSchemaImports(e2);
276 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_MESSAGE)) {
277 Message message = parseMessage(context, definitions, e2);
278 definitions.add(message);
279 } else if (
280 XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_PORT_TYPE)) {
281 PortType portType = parsePortType(context, definitions, e2);
282 definitions.add(portType);
283 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_BINDING)) {
284 Binding binding = parseBinding(context, definitions, e2);
285 definitions.add(binding);
286 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_SERVICE)) {
287 Service service = parseService(context, definitions, e2);
288 definitions.add(service);
289 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_IMPORT)) {
290 definitions.add(parseImport(context, definitions, e2));
291 } else if (XmlUtil.matchesTagNS(e2, SchemaConstants.QNAME_IMPORT)) {
292 errReceiver.warning(forest.locatorTable.getStartLocation(e2), WsdlMessages.WARNING_WSI_R_2003());
293 } else {
294 // possible extensibility element -- must live outside the WSDL namespace
295 checkNotWsdlElement(e2);
296 if (!handleExtension(context, definitions, e2)) {
297 checkNotWsdlRequired(e2);
298 }
299 }
300 }
301
302 context.pop();
303 context.fireDoneParsingEntity(
304 WSDLConstants.QNAME_DEFINITIONS,
305 definitions);
306 return definitions;
307 }
308
309 private Message parseMessage(
310 TWSDLParserContextImpl context,
311 Definitions definitions,
312 Element e) {
313 context.push();
314 context.registerNamespaces(e);
315 Message message = new Message(definitions, forest.locatorTable.getStartLocation(e), errReceiver);
316 String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
317 message.setName(name);
318
319 boolean gotDocumentation = false;
320
321 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
322 Element e2 = Util.nextElement(iter);
323 if (e2 == null)
324 break;
325
326 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
327 if (gotDocumentation) {
328 Util.fail(
329 "parsing.onlyOneDocumentationAllowed",
330 e.getLocalName());
331 }
332 gotDocumentation = true;
333 message.setDocumentation(getDocumentationFor(e2));
334 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_PART)) {
335 MessagePart part = parseMessagePart(context, e2);
336 message.add(part);
337 } else {
338 //Ignore any extensibility elements, WS-I BP 1.1 Profiled WSDL 1.1 schema allows extension elements here.
339 /*Util.fail(
340 "parsing.invalidElement",
341 e2.getTagName(),
342 e2.getNamespaceURI());
343 */
344 }
345 }
346
347 context.pop();
348 context.fireDoneParsingEntity(WSDLConstants.QNAME_MESSAGE, message);
349 return message;
350 }
351
352 private MessagePart parseMessagePart(TWSDLParserContextImpl context, Element e) {
353 context.push();
354 context.registerNamespaces(e);
355 MessagePart part = new MessagePart(forest.locatorTable.getStartLocation(e));
356 String partName = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
357 part.setName(partName);
358
359 String elementAttr =
360 XmlUtil.getAttributeOrNull(e, Constants.ATTR_ELEMENT);
361 String typeAttr = XmlUtil.getAttributeOrNull(e, Constants.ATTR_TYPE);
362
363 if (elementAttr != null) {
364 if (typeAttr != null) {
365 errReceiver.error(context.getLocation(e), WsdlMessages.PARSING_ONLY_ONE_OF_ELEMENT_OR_TYPE_REQUIRED(partName));
366
367 }
368
369 part.setDescriptor(context.translateQualifiedName(context.getLocation(e), elementAttr));
370 part.setDescriptorKind(SchemaKinds.XSD_ELEMENT);
371 } else if (typeAttr != null) {
372 part.setDescriptor(context.translateQualifiedName(context.getLocation(e), typeAttr));
373 part.setDescriptorKind(SchemaKinds.XSD_TYPE);
374 } else {
375 // XXX-NOTE - this is wrong; for extensibility purposes,
376 // any attribute can be specified on a <part> element, so
377 // we need to put an extensibility hook here
378 errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ELEMENT_OR_TYPE_REQUIRED(partName));
379 }
380
381 context.pop();
382 context.fireDoneParsingEntity(WSDLConstants.QNAME_PART, part);
383 return part;
384 }
385
386 private PortType parsePortType(
387 TWSDLParserContextImpl context,
388 Definitions definitions,
389 Element e) {
390 context.push();
391 context.registerNamespaces(e);
392 PortType portType = new PortType(definitions, forest.locatorTable.getStartLocation(e), errReceiver);
393 String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
394 portType.setName(name);
395
396 boolean gotDocumentation = false;
397
398 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
399 Element e2 = Util.nextElement(iter);
400 if (e2 == null)
401 break;
402
403 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
404 if (gotDocumentation) {
405 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
406 }
407 gotDocumentation = true;
408 if(portType.getDocumentation() == null)
409 portType.setDocumentation(getDocumentationFor(e2));
410 } else if (
411 XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OPERATION)) {
412 Operation op = parsePortTypeOperation(context, e2);
413 op.setParent(portType);
414 portType.add(op);
415 } else {
416 // possible extensibility element -- must live outside the WSDL namespace
417 checkNotWsdlElement(e2);
418 if (!handleExtension(context, portType, e2)) {
419 checkNotWsdlRequired(e2);
420 }
421 }/*else {
422 Util.fail(
423 "parsing.invalidElement",
424 e2.getTagName(),
425 e2.getNamespaceURI());
426 }*/
427 }
428
429 context.pop();
430 context.fireDoneParsingEntity(WSDLConstants.QNAME_PORT_TYPE, portType);
431 return portType;
432 }
433
434 private Operation parsePortTypeOperation(
435 TWSDLParserContextImpl context,
436 Element e) {
437 context.push();
438 context.registerNamespaces(e);
439
440 Operation operation = new Operation(forest.locatorTable.getStartLocation(e));
441 String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
442 operation.setName(name);
443 String parameterOrderAttr =
444 XmlUtil.getAttributeOrNull(e, Constants.ATTR_PARAMETER_ORDER);
445 operation.setParameterOrder(parameterOrderAttr);
446
447 boolean gotDocumentation = false;
448
449 boolean gotInput = false;
450 boolean gotOutput = false;
451 boolean gotFault = false;
452 boolean inputBeforeOutput = false;
453
454 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
455 Element e2 = Util.nextElement(iter);
456 if (e2 == null)
457 break;
458
459 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
460 if (gotDocumentation) {
461 errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e2.getLocalName()));
462 }
463 gotDocumentation = true;
464 if(operation.getDocumentation() == null)
465 operation.setDocumentation(getDocumentationFor(e2));
466 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_INPUT)) {
467 if (gotInput) {
468 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT,
469 Constants.TAG_OPERATION,
470 name));
471 }
472
473 context.push();
474 context.registerNamespaces(e2);
475 Input input = new Input(forest.locatorTable.getStartLocation(e2), errReceiver);
476 input.setParent(operation);
477 String messageAttr =
478 Util.getRequiredAttribute(e2, Constants.ATTR_MESSAGE);
479 input.setMessage(context.translateQualifiedName(context.getLocation(e2), messageAttr));
480 String nameAttr =
481 XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME);
482 input.setName(nameAttr);
483 operation.setInput(input);
484 gotInput = true;
485 if (gotOutput) {
486 inputBeforeOutput = false;
487 }
488
489 // check for extensiblity attributes
490 for (Iterator iter2 = XmlUtil.getAllAttributes(e2);
491 iter2.hasNext();
492 ) {
493 Attr e3 = (Attr)iter2.next();
494 if (e3.getLocalName().equals(Constants.ATTR_MESSAGE) ||
495 e3.getLocalName().equals(Constants.ATTR_NAME))
496 continue;
497
498 // possible extensibility element -- must live outside the WSDL namespace
499 checkNotWsdlAttribute(e3);
500 handleExtension(context, input, e3, e2);
501 }
502
503 // verify that there is at most one child element and it is a documentation element
504 boolean gotDocumentation2 = false;
505 for (Iterator iter2 = XmlUtil.getAllChildren(e2);
506 iter2.hasNext();
507 ) {
508 Element e3 = Util.nextElement(iter2);
509 if (e3 == null)
510 break;
511
512 if (XmlUtil
513 .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) {
514 if (gotDocumentation2) {
515 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
516 }
517 gotDocumentation2 = true;
518 input.setDocumentation(getDocumentationFor(e3));
519 } else {
520 errReceiver.error(forest.locatorTable.getStartLocation(e3), WsdlMessages.PARSING_INVALID_ELEMENT(e3.getTagName(),
521 e3.getNamespaceURI()));
522 }
523 }
524 context.pop();
525 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OUTPUT)) {
526 if (gotOutput) {
527 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT,
528 Constants.TAG_OPERATION,
529 name));
530 }
531
532 context.push();
533 context.registerNamespaces(e2);
534 Output output = new Output(forest.locatorTable.getStartLocation(e2), errReceiver);
535 output.setParent(operation);
536 String messageAttr =
537 Util.getRequiredAttribute(e2, Constants.ATTR_MESSAGE);
538 output.setMessage(context.translateQualifiedName(context.getLocation(e2), messageAttr));
539 String nameAttr =
540 XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME);
541 output.setName(nameAttr);
542 operation.setOutput(output);
543 gotOutput = true;
544 if (gotInput) {
545 inputBeforeOutput = true;
546 }
547
548 // check for extensiblity attributes
549 for (Iterator iter2 = XmlUtil.getAllAttributes(e2);
550 iter2.hasNext();
551 ) {
552 Attr e3 = (Attr)iter2.next();
553 if (e3.getLocalName().equals(Constants.ATTR_MESSAGE) ||
554 e3.getLocalName().equals(Constants.ATTR_NAME))
555 continue;
556
557 // possible extensibility element -- must live outside the WSDL namespace
558 checkNotWsdlAttribute(e3);
559 handleExtension(context, output, e3, e2);
560 }
561
562 // verify that there is at most one child element and it is a documentation element
563 boolean gotDocumentation2 = false;
564 for (Iterator iter2 = XmlUtil.getAllChildren(e2);
565 iter2.hasNext();
566 ) {
567 Element e3 = Util.nextElement(iter2);
568 if (e3 == null)
569 break;
570
571 if (XmlUtil
572 .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) {
573 if (gotDocumentation2) {
574 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
575 }
576 gotDocumentation2 = true;
577 output.setDocumentation(getDocumentationFor(e3));
578 } else {
579 errReceiver.error(forest.locatorTable.getStartLocation(e3), WsdlMessages.PARSING_INVALID_ELEMENT(e3.getTagName(),
580 e3.getNamespaceURI()));
581 }
582 }
583 context.pop();
584 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_FAULT)) {
585 context.push();
586 context.registerNamespaces(e2);
587 Fault fault = new Fault(forest.locatorTable.getStartLocation(e2));
588 fault.setParent(operation);
589 String messageAttr =
590 Util.getRequiredAttribute(e2, Constants.ATTR_MESSAGE);
591 fault.setMessage(context.translateQualifiedName(context.getLocation(e2), messageAttr));
592 String nameAttr =
593 XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME);
594 fault.setName(nameAttr);
595 operation.addFault(fault);
596 gotFault = true;
597
598 // check for extensiblity attributes
599 for (Iterator iter2 = XmlUtil.getAllAttributes(e2);
600 iter2.hasNext();
601 ) {
602 Attr e3 = (Attr)iter2.next();
603 if (e3.getLocalName().equals(Constants.ATTR_MESSAGE) ||
604 e3.getLocalName().equals(Constants.ATTR_NAME))
605 continue;
606
607 // possible extensibility element -- must live outside the WSDL namespace
608 checkNotWsdlAttribute(e3);
609 handleExtension(context, fault, e3, e2);
610 }
611
612 // verify that there is at most one child element and it is a documentation element
613 boolean gotDocumentation2 = false;
614 for (Iterator iter2 = XmlUtil.getAllChildren(e2);
615 iter2.hasNext();
616 ) {
617 Element e3 = Util.nextElement(iter2);
618 if (e3 == null)
619 break;
620
621 if (XmlUtil
622 .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) {
623 if (gotDocumentation2) {
624 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
625 }
626 gotDocumentation2 = true;
627 if(fault.getDocumentation() == null)
628 fault.setDocumentation(getDocumentationFor(e3));
629 } else {
630 // possible extensibility element -- must live outside the WSDL namespace
631 checkNotWsdlElement(e3);
632 if (!handleExtension(context, fault, e3)) {
633 checkNotWsdlRequired(e3);
634 }
635 }/*else {
636 Util.fail(
637 "parsing.invalidElement",
638 e3.getTagName(),
639 e3.getNamespaceURI());
640 }*/
641 }
642 context.pop();
643 } else {
644 // possible extensibility element -- must live outside the WSDL namespace
645 checkNotWsdlElement(e2);
646 if (!handleExtension(context, operation, e2)) {
647 checkNotWsdlRequired(e2);
648 }
649 }/*else {
650 Util.fail(
651 "parsing.invalidElement",
652 e2.getTagName(),
653 e2.getNamespaceURI());
654 }*/
655 }
656
657 if (gotInput && !gotOutput && !gotFault) {
658 operation.setStyle(OperationStyle.ONE_WAY);
659 } else if (gotInput && gotOutput && inputBeforeOutput) {
660 operation.setStyle(OperationStyle.REQUEST_RESPONSE);
661 } else if (gotInput && gotOutput && !inputBeforeOutput) {
662 operation.setStyle(OperationStyle.SOLICIT_RESPONSE);
663 } else if (gotOutput && !gotInput && !gotFault) {
664 operation.setStyle(OperationStyle.NOTIFICATION);
665 } else {
666 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_INVALID_OPERATION_STYLE(name));
667 }
668
669 context.pop();
670 context.fireDoneParsingEntity(WSDLConstants.QNAME_OPERATION, operation);
671 return operation;
672 }
673
674 private Binding parseBinding(
675 TWSDLParserContextImpl context,
676 Definitions definitions,
677 Element e) {
678 context.push();
679 context.registerNamespaces(e);
680 Binding binding = new Binding(definitions, forest.locatorTable.getStartLocation(e), errReceiver);
681 String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
682 binding.setName(name);
683 String typeAttr = Util.getRequiredAttribute(e, Constants.ATTR_TYPE);
684 binding.setPortType(context.translateQualifiedName(context.getLocation(e), typeAttr));
685
686 boolean gotDocumentation = false;
687
688 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
689 Element e2 = Util.nextElement(iter);
690 if (e2 == null)
691 break;
692
693 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
694 if (gotDocumentation) {
695 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
696 }
697 gotDocumentation = true;
698 binding.setDocumentation(getDocumentationFor(e2));
699 } else if (
700 XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OPERATION)) {
701 BindingOperation op = parseBindingOperation(context, e2);
702 binding.add(op);
703 } else {
704 // possible extensibility element -- must live outside the WSDL namespace
705 checkNotWsdlElement(e2);
706 if (!handleExtension(context, binding, e2)) {
707 checkNotWsdlRequired(e2);
708 }
709 }
710 }
711
712 context.pop();
713 context.fireDoneParsingEntity(WSDLConstants.QNAME_BINDING, binding);
714 return binding;
715 }
716
717 private BindingOperation parseBindingOperation(
718 TWSDLParserContextImpl context,
719 Element e) {
720 context.push();
721 context.registerNamespaces(e);
722 BindingOperation operation = new BindingOperation(forest.locatorTable.getStartLocation(e));
723 String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
724 operation.setName(name);
725
726 boolean gotDocumentation = false;
727
728 boolean gotInput = false;
729 boolean gotOutput = false;
730 boolean gotFault = false;
731 boolean inputBeforeOutput = false;
732
733 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
734 Element e2 = Util.nextElement(iter);
735 if (e2 == null)
736 break;
737 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
738 if (gotDocumentation) {
739 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
740 }
741 gotDocumentation = true;
742 operation.setDocumentation(getDocumentationFor(e2));
743 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_INPUT)) {
744 if (gotInput) {
745 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT,
746 Constants.TAG_OPERATION,
747 name));
748 }
749
750 /* Here we check for the use scenario */
751 context.push();
752 context.registerNamespaces(e2);
753 BindingInput input = new BindingInput(forest.locatorTable.getStartLocation(e2));
754 String nameAttr =
755 XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME);
756 input.setName(nameAttr);
757 operation.setInput(input);
758 gotInput = true;
759 if (gotOutput) {
760 inputBeforeOutput = false;
761 }
762
763 // verify that there is at most one child element and it is a documentation element
764 boolean gotDocumentation2 = false;
765 for (Iterator iter2 = XmlUtil.getAllChildren(e2);
766 iter2.hasNext();
767 ) {
768 Element e3 = Util.nextElement(iter2);
769 if (e3 == null)
770 break;
771
772 if (XmlUtil
773 .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) {
774 if (gotDocumentation2) {
775 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
776 }
777 gotDocumentation2 = true;
778 input.setDocumentation(getDocumentationFor(e3));
779 } else {
780 // possible extensibility element -- must live outside the WSDL namespace
781 checkNotWsdlElement(e3);
782 if (!handleExtension(context, input, e3)) {
783 checkNotWsdlRequired(e3);
784 }
785 }
786 }
787 context.pop();
788 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OUTPUT)) {
789 if (gotOutput) {
790 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT,
791 Constants.TAG_OPERATION,
792 name));
793 }
794
795 context.push();
796 context.registerNamespaces(e2);
797 BindingOutput output = new BindingOutput(forest.locatorTable.getStartLocation(e2));
798 String nameAttr =
799 XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME);
800 output.setName(nameAttr);
801 operation.setOutput(output);
802 gotOutput = true;
803 if (gotInput) {
804 inputBeforeOutput = true;
805 }
806
807 // verify that there is at most one child element and it is a documentation element
808 boolean gotDocumentation2 = false;
809 for (Iterator iter2 = XmlUtil.getAllChildren(e2);
810 iter2.hasNext();
811 ) {
812
813 Element e3 = Util.nextElement(iter2);
814 if (e3 == null)
815 break;
816
817 if (XmlUtil
818 .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) {
819 if (gotDocumentation2) {
820 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
821 }
822 gotDocumentation2 = true;
823 output.setDocumentation(getDocumentationFor(e3));
824 } else {
825 // possible extensibility element -- must live outside the WSDL namespace
826 checkNotWsdlElement(e3);
827 if (!handleExtension(context, output, e3)) {
828 checkNotWsdlRequired(e3);
829 }
830 }
831 }
832 context.pop();
833 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_FAULT)) {
834 context.push();
835 context.registerNamespaces(e2);
836 BindingFault fault = new BindingFault(forest.locatorTable.getStartLocation(e2));
837 String nameAttr =
838 Util.getRequiredAttribute(e2, Constants.ATTR_NAME);
839 fault.setName(nameAttr);
840 operation.addFault(fault);
841 gotFault = true;
842
843 // verify that there is at most one child element and it is a documentation element
844 boolean gotDocumentation2 = false;
845 for (Iterator iter2 = XmlUtil.getAllChildren(e2);
846 iter2.hasNext();
847 ) {
848 Element e3 = Util.nextElement(iter2);
849 if (e3 == null)
850 break;
851
852 if (XmlUtil
853 .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) {
854 if (gotDocumentation2) {
855 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
856 }
857 gotDocumentation2 = true;
858 if(fault.getDocumentation() == null)
859 fault.setDocumentation(getDocumentationFor(e3));
860 } else {
861 // possible extensibility element -- must live outside the WSDL namespace
862 checkNotWsdlElement(e3);
863 if (!handleExtension(context, fault, e3)) {
864 checkNotWsdlRequired(e3);
865 }
866 }
867 }
868 context.pop();
869 } else {
870 // possible extensibility element -- must live outside the WSDL namespace
871 checkNotWsdlElement(e2);
872 if (!handleExtension(context, operation, e2)) {
873 checkNotWsdlRequired(e2);
874 }
875 }
876 }
877
878 if (gotInput && !gotOutput && !gotFault) {
879 operation.setStyle(OperationStyle.ONE_WAY);
880 } else if (gotInput && gotOutput && inputBeforeOutput) {
881 operation.setStyle(OperationStyle.REQUEST_RESPONSE);
882 } else if (gotInput && gotOutput && !inputBeforeOutput) {
883 operation.setStyle(OperationStyle.SOLICIT_RESPONSE);
884 } else if (gotOutput && !gotInput && !gotFault) {
885 operation.setStyle(OperationStyle.NOTIFICATION);
886 } else {
887 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_INVALID_OPERATION_STYLE(name));
888 }
889
890 context.pop();
891 context.fireDoneParsingEntity(WSDLConstants.QNAME_OPERATION, operation);
892 return operation;
893 }
894
895 private Import parseImport(
896 TWSDLParserContextImpl context,
897 Definitions definitions,
898 Element e) {
899 context.push();
900 context.registerNamespaces(e);
901 Import anImport = new Import(forest.locatorTable.getStartLocation(e));
902 String namespace =
903 Util.getRequiredAttribute(e, Constants.ATTR_NAMESPACE);
904 anImport.setNamespace(namespace);
905 String location = Util.getRequiredAttribute(e, Constants.ATTR_LOCATION);
906 anImport.setLocation(location);
907
908 // according to the schema in the WSDL 1.1 spec, an import can have a documentation element
909 boolean gotDocumentation = false;
910
911 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
912 Element e2 = Util.nextElement(iter);
913 if (e2 == null)
914 break;
915
916 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
917 if (gotDocumentation) {
918 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
919 }
920 gotDocumentation = true;
921 anImport.setDocumentation(getDocumentationFor(e2));
922 } else {
923 errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_INVALID_ELEMENT(e2.getTagName(),
924 e2.getNamespaceURI()));
925 }
926 }
927 context.pop();
928 context.fireDoneParsingEntity(WSDLConstants.QNAME_IMPORT, anImport);
929 return anImport;
930 }
931
932 private Service parseService(
933 TWSDLParserContextImpl context,
934 Definitions definitions,
935 Element e) {
936 context.push();
937 context.registerNamespaces(e);
938 Service service = new Service(definitions, forest.locatorTable.getStartLocation(e), errReceiver);
939 String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
940 service.setName(name);
941
942 boolean gotDocumentation = false;
943
944 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
945 Element e2 = Util.nextElement(iter);
946 if (e2 == null)
947 break;
948
949 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
950 if (gotDocumentation) {
951 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
952 }
953 gotDocumentation = true;
954 if (service.getDocumentation() == null) {
955 service.setDocumentation(getDocumentationFor(e2));
956 }
957 } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_PORT)) {
958 Port port = parsePort(context, definitions, e2);
959 service.add(port);
960 } else {
961 // possible extensibility element -- must live outside the WSDL namespace
962 checkNotWsdlElement(e2);
963 if (!handleExtension(context, service, e2)) {
964 checkNotWsdlRequired(e2);
965 }
966 }
967 }
968
969 context.pop();
970 context.fireDoneParsingEntity(WSDLConstants.QNAME_SERVICE, service);
971 return service;
972 }
973
974 private Port parsePort(
975 TWSDLParserContextImpl context,
976 Definitions definitions,
977 Element e) {
978 context.push();
979 context.registerNamespaces(e);
980
981 Port port = new Port(definitions, forest.locatorTable.getStartLocation(e), errReceiver);
982 String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME);
983 port.setName(name);
984
985 String bindingAttr =
986 Util.getRequiredAttribute(e, Constants.ATTR_BINDING);
987 port.setBinding(context.translateQualifiedName(context.getLocation(e), bindingAttr));
988
989 boolean gotDocumentation = false;
990
991 for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
992 Element e2 = Util.nextElement(iter);
993 if (e2 == null) {
994 break;
995 }
996
997 if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) {
998 if (gotDocumentation) {
999 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName()));
1000 }
1001 gotDocumentation = true;
1002 if (port.getDocumentation() == null) {
1003 port.setDocumentation(getDocumentationFor(e2));
1004 }
1005 } else {
1006 // possible extensibility element -- must live outside the WSDL namespace
1007 checkNotWsdlElement(e2);
1008 if (!handleExtension(context, port, e2)) {
1009 checkNotWsdlRequired(e2);
1010 }
1011 }
1012 }
1013
1014 context.pop();
1015 context.fireDoneParsingEntity(WSDLConstants.QNAME_PORT, port);
1016 return port;
1017 }
1018
1019 private void validateSchemaImports(Element typesElement){
1020 for (Iterator iter = XmlUtil.getAllChildren(typesElement); iter.hasNext();) {
1021 Element e = Util.nextElement(iter);
1022 if (e == null) {
1023 break;
1024 }
1025 if (XmlUtil.matchesTagNS(e, SchemaConstants.QNAME_IMPORT)) {
1026 errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.WARNING_WSI_R_2003());
1027 }else{
1028 checkNotWsdlElement(e);
1029 // if (XmlUtil.matchesTagNS(e, SchemaConstants.QNAME_SCHEMA)) {
1030 // forest.getInlinedSchemaElement().add(e);
1031 // }
1032
1033 }
1034 }
1035 }
1036
1037
1038 private boolean handleExtension(
1039 TWSDLParserContextImpl context,
1040 TWSDLExtensible entity,
1041 Element e) {
1042 TWSDLExtensionHandler h =
1043 (TWSDLExtensionHandler) extensionHandlers.get(e.getNamespaceURI());
1044 if (h == null) {
1045 context.fireIgnoringExtension(e, (Entity) entity);
1046 errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_UNKNOWN_EXTENSIBILITY_ELEMENT_OR_ATTRIBUTE(e.getLocalName(), e.getNamespaceURI()));
1047 return false;
1048 } else {
1049 return h.doHandleExtension(context, entity, e);
1050 }
1051 }
1052
1053 private boolean handleExtension(
1054 TWSDLParserContextImpl context,
1055 TWSDLExtensible entity,
1056 Node n,
1057 Element e) {
1058 TWSDLExtensionHandler h =
1059 (TWSDLExtensionHandler) extensionHandlers.get(n.getNamespaceURI());
1060 if (h == null) {
1061 context.fireIgnoringExtension(e, (Entity) entity);
1062 errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_UNKNOWN_EXTENSIBILITY_ELEMENT_OR_ATTRIBUTE(n.getLocalName(), n.getNamespaceURI()));
1063 return false;
1064 } else {
1065 return h.doHandleExtension(context, entity, e);
1066 }
1067 }
1068
1069 private void checkNotWsdlElement(Element e) {
1070 // possible extensibility element -- must live outside the WSDL namespace
1071 if (e.getNamespaceURI() != null && e.getNamespaceURI().equals(Constants.NS_WSDL)) {
1072 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_INVALID_WSDL_ELEMENT(e.getTagName()));
1073 }
1074 }
1075
1076 private void checkNotWsdlAttribute(Attr a) {
1077 // possible extensibility element -- must live outside the WSDL namespace
1078 if (Constants.NS_WSDL.equals(a.getNamespaceURI())) {
1079 errReceiver.error(forest.locatorTable.getStartLocation(a.getOwnerElement()), WsdlMessages.PARSING_INVALID_WSDL_ELEMENT(a.getLocalName()));
1080 }
1081 }
1082
1083 private void checkNotWsdlRequired(Element e) {
1084 // check the wsdl:required attribute, fail if set to "true"
1085 String required =
1086 XmlUtil.getAttributeNSOrNull(
1087 e,
1088 Constants.ATTR_REQUIRED,
1089 Constants.NS_WSDL);
1090 if (required != null && required.equals(Constants.TRUE) && !options.isExtensionMode()) {
1091 errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_REQUIRED_EXTENSIBILITY_ELEMENT(e.getTagName(),
1092 e.getNamespaceURI()));
1093 }
1094 }
1095
1096 private Documentation getDocumentationFor(Element e) {
1097 String s = XmlUtil.getTextForNode(e);
1098 if (s == null) {
1099 return null;
1100 } else {
1101 return new Documentation(s);
1102 }
1103 }
1104 }

mercurial