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

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

mercurial