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 }