/* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.internal.ws.wsdl.parser; import com.sun.tools.internal.ws.api.wsdl.TWSDLExtensible; import com.sun.tools.internal.ws.api.wsdl.TWSDLExtensionHandler; import com.sun.tools.internal.ws.resources.WsdlMessages; import com.sun.tools.internal.ws.util.xml.XmlUtil; import com.sun.tools.internal.ws.wscompile.ErrorReceiverFilter; import com.sun.tools.internal.ws.wscompile.WsimportOptions; import com.sun.tools.internal.ws.wsdl.document.Binding; import com.sun.tools.internal.ws.wsdl.document.BindingFault; import com.sun.tools.internal.ws.wsdl.document.BindingInput; import com.sun.tools.internal.ws.wsdl.document.BindingOperation; import com.sun.tools.internal.ws.wsdl.document.BindingOutput; import com.sun.tools.internal.ws.wsdl.document.Definitions; import com.sun.tools.internal.ws.wsdl.document.Documentation; import com.sun.tools.internal.ws.wsdl.document.Fault; import com.sun.tools.internal.ws.wsdl.document.Import; import com.sun.tools.internal.ws.wsdl.document.Input; import com.sun.tools.internal.ws.wsdl.document.Message; import com.sun.tools.internal.ws.wsdl.document.MessagePart; import com.sun.tools.internal.ws.wsdl.document.Operation; import com.sun.tools.internal.ws.wsdl.document.OperationStyle; import com.sun.tools.internal.ws.wsdl.document.Output; import com.sun.tools.internal.ws.wsdl.document.Port; import com.sun.tools.internal.ws.wsdl.document.PortType; import com.sun.tools.internal.ws.wsdl.document.Service; import com.sun.tools.internal.ws.wsdl.document.WSDLConstants; import com.sun.tools.internal.ws.wsdl.document.WSDLDocument; import com.sun.tools.internal.ws.wsdl.document.jaxws.JAXWSBindingsConstants; import com.sun.tools.internal.ws.wsdl.document.schema.SchemaConstants; import com.sun.tools.internal.ws.wsdl.document.schema.SchemaKinds; import com.sun.tools.internal.ws.wsdl.framework.Entity; import com.sun.tools.internal.ws.wsdl.framework.ParserListener; import com.sun.tools.internal.ws.wsdl.framework.TWSDLParserContextImpl; import com.sun.xml.internal.ws.util.ServiceFinder; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.w3c.dom.Node; /** * A parser for WSDL documents. This parser is used only at the tool time. * Extensions should extend TWSDLExtensionHandler, so that it will be called during * parsing wsdl to handle wsdl extenisbility elements. Generally these extensions * will effect the artifacts generated during WSDL processing. * * @see com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser which will be used for WSDL parsing * at runtime. * * @author WS Development Team */ public class WSDLParser { private final ErrorReceiverFilter errReceiver; private WsimportOptions options; //wsdl extension handlers private final Map extensionHandlers; private MetadataFinder forest; private ArrayList<ParserListener> listeners; public WSDLParser(WsimportOptions options, ErrorReceiverFilter errReceiver, MetadataFinder forest) { this.extensionHandlers = new HashMap(); this.options = options; this.errReceiver = errReceiver; if (forest == null) { forest = new MetadataFinder(new WSDLInternalizationLogic(), options, errReceiver); forest.parseWSDL(); if (forest.isMexMetadata) { errReceiver.reset(); } } this.forest = forest; // register handlers for default extensions register(new SOAPExtensionHandler(extensionHandlers)); register(new HTTPExtensionHandler(extensionHandlers)); register(new MIMEExtensionHandler(extensionHandlers)); register(new JAXWSBindingExtensionHandler(extensionHandlers)); register(new SOAP12ExtensionHandler(extensionHandlers)); // MemberSubmission Addressing not supported by WsImport anymore see JAX_WS-1040 for details //register(new MemberSubmissionAddressingExtensionHandler(extensionHandlers, errReceiver, options.isExtensionMode())); register(new W3CAddressingExtensionHandler(extensionHandlers, errReceiver)); register(new W3CAddressingMetadataExtensionHandler(extensionHandlers, errReceiver)); register(new Policy12ExtensionHandler()); register(new Policy15ExtensionHandler()); for (TWSDLExtensionHandler te : ServiceFinder.find(TWSDLExtensionHandler.class)) { register(te); } } //TODO RK remove this after tests are fixed. WSDLParser(WsimportOptions options, ErrorReceiverFilter errReceiver) { this(options,errReceiver,null); } private void register(TWSDLExtensionHandler h) { extensionHandlers.put(h.getNamespaceURI(), h); } public void addParserListener(ParserListener l) { if (listeners == null) { listeners = new ArrayList<ParserListener>(); } listeners.add(l); } public WSDLDocument parse() throws SAXException, IOException { // parse external binding files for (InputSource value : options.getWSDLBindings()) { errReceiver.pollAbort(); Document root = forest.parse(value, false); if(root==null) continue; // error must have been reported Element binding = root.getDocumentElement(); if (!Internalizer.fixNull(binding.getNamespaceURI()).equals(JAXWSBindingsConstants.NS_JAXWS_BINDINGS) || !binding.getLocalName().equals("bindings")){ errReceiver.error(forest.locatorTable.getStartLocation(binding), WsdlMessages.PARSER_NOT_A_BINDING_FILE( binding.getNamespaceURI(), binding.getLocalName())); continue; } NodeList nl = binding.getElementsByTagNameNS( "http://java.sun.com/xml/ns/javaee", "handler-chains"); for(int i = 0; i < nl.getLength(); i++){ options.addHandlerChainConfiguration((Element) nl.item(i)); } } return buildWSDLDocument(); } public MetadataFinder getDOMForest() { return forest; } private WSDLDocument buildWSDLDocument(){ /** * Currently we are working off first WSDL document * TODO: add support of creating WSDLDocument from fromjava.collection of WSDL documents */ String location = forest.getRootWSDL(); //It means that WSDL is not found, an error might have been reported, lets try to recover if(location == null) return null; Document root = forest.get(location); if(root == null) return null; WSDLDocument document = new WSDLDocument(forest, errReceiver); document.setSystemId(location); TWSDLParserContextImpl context = new TWSDLParserContextImpl(forest, document, listeners, errReceiver); Definitions definitions = parseDefinitions(context, root); document.setDefinitions(definitions); return document; } private Definitions parseDefinitions(TWSDLParserContextImpl context, Document root) { context.pushWSDLLocation(); context.setWSDLLocation(context.getDocument().getSystemId()); new Internalizer(forest, options, errReceiver).transform(); Definitions definitions = parseDefinitionsNoImport(context, root); if(definitions == null){ Locator locator = forest.locatorTable.getStartLocation(root.getDocumentElement()); errReceiver.error(locator, WsdlMessages.PARSING_NOT_AWSDL(locator.getSystemId())); } processImports(context); context.popWSDLLocation(); return definitions; } private void processImports(TWSDLParserContextImpl context) { for(String location : forest.getExternalReferences()){ if (!context.getDocument().isImportedDocument(location)){ Document doc = forest.get(location); if(doc == null) continue; Definitions importedDefinitions = parseDefinitionsNoImport(context, doc); if(importedDefinitions == null) continue; context.getDocument().addImportedEntity(importedDefinitions); context.getDocument().addImportedDocument(location); } } } private Definitions parseDefinitionsNoImport( TWSDLParserContextImpl context, Document doc) { Element e = doc.getDocumentElement(); //at this poinjt we expect a wsdl or schema document to be fully qualified if(e.getNamespaceURI() == null || (!e.getNamespaceURI().equals(WSDLConstants.NS_WSDL) || !e.getLocalName().equals("definitions"))){ return null; } context.push(); context.registerNamespaces(e); Definitions definitions = new Definitions(context.getDocument(), forest.locatorTable.getStartLocation(e)); String name = XmlUtil.getAttributeOrNull(e, Constants.ATTR_NAME); definitions.setName(name); String targetNamespaceURI = XmlUtil.getAttributeOrNull(e, Constants.ATTR_TARGET_NAMESPACE); definitions.setTargetNamespaceURI(targetNamespaceURI); boolean gotDocumentation = false; boolean gotTypes = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); return null; } gotDocumentation = true; if(definitions.getDocumentation() == null) definitions.setDocumentation(getDocumentationFor(e2)); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_TYPES)) { if (gotTypes && !options.isExtensionMode()) { errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_ONLY_ONE_TYPES_ALLOWED(Constants.TAG_DEFINITIONS)); return null; } gotTypes = true; //add all the wsdl:type elements to latter make a list of all the schema elements // that will be needed to create jaxb model if(!options.isExtensionMode()) validateSchemaImports(e2); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_MESSAGE)) { Message message = parseMessage(context, definitions, e2); definitions.add(message); } else if ( XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_PORT_TYPE)) { PortType portType = parsePortType(context, definitions, e2); definitions.add(portType); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_BINDING)) { Binding binding = parseBinding(context, definitions, e2); definitions.add(binding); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_SERVICE)) { Service service = parseService(context, definitions, e2); definitions.add(service); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_IMPORT)) { definitions.add(parseImport(context, definitions, e2)); } else if (XmlUtil.matchesTagNS(e2, SchemaConstants.QNAME_IMPORT)) { errReceiver.warning(forest.locatorTable.getStartLocation(e2), WsdlMessages.WARNING_WSI_R_2003()); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e2); if (!handleExtension(context, definitions, e2)) { checkNotWsdlRequired(e2); } } } context.pop(); context.fireDoneParsingEntity( WSDLConstants.QNAME_DEFINITIONS, definitions); return definitions; } private Message parseMessage( TWSDLParserContextImpl context, Definitions definitions, Element e) { context.push(); context.registerNamespaces(e); Message message = new Message(definitions, forest.locatorTable.getStartLocation(e), errReceiver); String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME); message.setName(name); boolean gotDocumentation = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { Util.fail( "parsing.onlyOneDocumentationAllowed", e.getLocalName()); } gotDocumentation = true; message.setDocumentation(getDocumentationFor(e2)); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_PART)) { MessagePart part = parseMessagePart(context, e2); message.add(part); } else { //Ignore any extensibility elements, WS-I BP 1.1 Profiled WSDL 1.1 schema allows extension elements here. /*Util.fail( "parsing.invalidElement", e2.getTagName(), e2.getNamespaceURI()); */ } } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_MESSAGE, message); return message; } private MessagePart parseMessagePart(TWSDLParserContextImpl context, Element e) { context.push(); context.registerNamespaces(e); MessagePart part = new MessagePart(forest.locatorTable.getStartLocation(e)); String partName = Util.getRequiredAttribute(e, Constants.ATTR_NAME); part.setName(partName); String elementAttr = XmlUtil.getAttributeOrNull(e, Constants.ATTR_ELEMENT); String typeAttr = XmlUtil.getAttributeOrNull(e, Constants.ATTR_TYPE); if (elementAttr != null) { if (typeAttr != null) { errReceiver.error(context.getLocation(e), WsdlMessages.PARSING_ONLY_ONE_OF_ELEMENT_OR_TYPE_REQUIRED(partName)); } part.setDescriptor(context.translateQualifiedName(context.getLocation(e), elementAttr)); part.setDescriptorKind(SchemaKinds.XSD_ELEMENT); } else if (typeAttr != null) { part.setDescriptor(context.translateQualifiedName(context.getLocation(e), typeAttr)); part.setDescriptorKind(SchemaKinds.XSD_TYPE); } else { // XXX-NOTE - this is wrong; for extensibility purposes, // any attribute can be specified on a <part> element, so // we need to put an extensibility hook here errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ELEMENT_OR_TYPE_REQUIRED(partName)); } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_PART, part); return part; } private PortType parsePortType( TWSDLParserContextImpl context, Definitions definitions, Element e) { context.push(); context.registerNamespaces(e); PortType portType = new PortType(definitions, forest.locatorTable.getStartLocation(e), errReceiver); String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME); portType.setName(name); boolean gotDocumentation = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation = true; if(portType.getDocumentation() == null) portType.setDocumentation(getDocumentationFor(e2)); } else if ( XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OPERATION)) { Operation op = parsePortTypeOperation(context, e2); op.setParent(portType); portType.add(op); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e2); if (!handleExtension(context, portType, e2)) { checkNotWsdlRequired(e2); } }/*else { Util.fail( "parsing.invalidElement", e2.getTagName(), e2.getNamespaceURI()); }*/ } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_PORT_TYPE, portType); return portType; } private Operation parsePortTypeOperation( TWSDLParserContextImpl context, Element e) { context.push(); context.registerNamespaces(e); Operation operation = new Operation(forest.locatorTable.getStartLocation(e)); String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME); operation.setName(name); String parameterOrderAttr = XmlUtil.getAttributeOrNull(e, Constants.ATTR_PARAMETER_ORDER); operation.setParameterOrder(parameterOrderAttr); boolean gotDocumentation = false; boolean gotInput = false; boolean gotOutput = false; boolean gotFault = false; boolean inputBeforeOutput = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e2.getLocalName())); } gotDocumentation = true; if(operation.getDocumentation() == null) operation.setDocumentation(getDocumentationFor(e2)); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_INPUT)) { if (gotInput) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT, Constants.TAG_OPERATION, name)); } context.push(); context.registerNamespaces(e2); Input input = new Input(forest.locatorTable.getStartLocation(e2), errReceiver); input.setParent(operation); String messageAttr = Util.getRequiredAttribute(e2, Constants.ATTR_MESSAGE); input.setMessage(context.translateQualifiedName(context.getLocation(e2), messageAttr)); String nameAttr = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME); input.setName(nameAttr); operation.setInput(input); gotInput = true; if (gotOutput) { inputBeforeOutput = false; } // check for extensiblity attributes for (Iterator iter2 = XmlUtil.getAllAttributes(e2); iter2.hasNext(); ) { Attr e3 = (Attr)iter2.next(); if (e3.getLocalName().equals(Constants.ATTR_MESSAGE) || e3.getLocalName().equals(Constants.ATTR_NAME)) continue; // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlAttribute(e3); handleExtension(context, input, e3, e2); } // verify that there is at most one child element and it is a documentation element boolean gotDocumentation2 = false; for (Iterator iter2 = XmlUtil.getAllChildren(e2); iter2.hasNext(); ) { Element e3 = Util.nextElement(iter2); if (e3 == null) break; if (XmlUtil .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation2) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation2 = true; input.setDocumentation(getDocumentationFor(e3)); } else { errReceiver.error(forest.locatorTable.getStartLocation(e3), WsdlMessages.PARSING_INVALID_ELEMENT(e3.getTagName(), e3.getNamespaceURI())); } } context.pop(); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OUTPUT)) { if (gotOutput) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT, Constants.TAG_OPERATION, name)); } context.push(); context.registerNamespaces(e2); Output output = new Output(forest.locatorTable.getStartLocation(e2), errReceiver); output.setParent(operation); String messageAttr = Util.getRequiredAttribute(e2, Constants.ATTR_MESSAGE); output.setMessage(context.translateQualifiedName(context.getLocation(e2), messageAttr)); String nameAttr = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME); output.setName(nameAttr); operation.setOutput(output); gotOutput = true; if (gotInput) { inputBeforeOutput = true; } // check for extensiblity attributes for (Iterator iter2 = XmlUtil.getAllAttributes(e2); iter2.hasNext(); ) { Attr e3 = (Attr)iter2.next(); if (e3.getLocalName().equals(Constants.ATTR_MESSAGE) || e3.getLocalName().equals(Constants.ATTR_NAME)) continue; // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlAttribute(e3); handleExtension(context, output, e3, e2); } // verify that there is at most one child element and it is a documentation element boolean gotDocumentation2 = false; for (Iterator iter2 = XmlUtil.getAllChildren(e2); iter2.hasNext(); ) { Element e3 = Util.nextElement(iter2); if (e3 == null) break; if (XmlUtil .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation2) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation2 = true; output.setDocumentation(getDocumentationFor(e3)); } else { errReceiver.error(forest.locatorTable.getStartLocation(e3), WsdlMessages.PARSING_INVALID_ELEMENT(e3.getTagName(), e3.getNamespaceURI())); } } context.pop(); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_FAULT)) { context.push(); context.registerNamespaces(e2); Fault fault = new Fault(forest.locatorTable.getStartLocation(e2)); fault.setParent(operation); String messageAttr = Util.getRequiredAttribute(e2, Constants.ATTR_MESSAGE); fault.setMessage(context.translateQualifiedName(context.getLocation(e2), messageAttr)); String nameAttr = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME); fault.setName(nameAttr); operation.addFault(fault); gotFault = true; // check for extensiblity attributes for (Iterator iter2 = XmlUtil.getAllAttributes(e2); iter2.hasNext(); ) { Attr e3 = (Attr)iter2.next(); if (e3.getLocalName().equals(Constants.ATTR_MESSAGE) || e3.getLocalName().equals(Constants.ATTR_NAME)) continue; // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlAttribute(e3); handleExtension(context, fault, e3, e2); } // verify that there is at most one child element and it is a documentation element boolean gotDocumentation2 = false; for (Iterator iter2 = XmlUtil.getAllChildren(e2); iter2.hasNext(); ) { Element e3 = Util.nextElement(iter2); if (e3 == null) break; if (XmlUtil .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation2) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation2 = true; if(fault.getDocumentation() == null) fault.setDocumentation(getDocumentationFor(e3)); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e3); if (!handleExtension(context, fault, e3)) { checkNotWsdlRequired(e3); } }/*else { Util.fail( "parsing.invalidElement", e3.getTagName(), e3.getNamespaceURI()); }*/ } context.pop(); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e2); if (!handleExtension(context, operation, e2)) { checkNotWsdlRequired(e2); } }/*else { Util.fail( "parsing.invalidElement", e2.getTagName(), e2.getNamespaceURI()); }*/ } if (gotInput && !gotOutput && !gotFault) { operation.setStyle(OperationStyle.ONE_WAY); } else if (gotInput && gotOutput && inputBeforeOutput) { operation.setStyle(OperationStyle.REQUEST_RESPONSE); } else if (gotInput && gotOutput && !inputBeforeOutput) { operation.setStyle(OperationStyle.SOLICIT_RESPONSE); } else if (gotOutput && !gotInput && !gotFault) { operation.setStyle(OperationStyle.NOTIFICATION); } else { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_INVALID_OPERATION_STYLE(name)); } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_OPERATION, operation); return operation; } private Binding parseBinding( TWSDLParserContextImpl context, Definitions definitions, Element e) { context.push(); context.registerNamespaces(e); Binding binding = new Binding(definitions, forest.locatorTable.getStartLocation(e), errReceiver); String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME); binding.setName(name); String typeAttr = Util.getRequiredAttribute(e, Constants.ATTR_TYPE); binding.setPortType(context.translateQualifiedName(context.getLocation(e), typeAttr)); boolean gotDocumentation = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation = true; binding.setDocumentation(getDocumentationFor(e2)); } else if ( XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OPERATION)) { BindingOperation op = parseBindingOperation(context, e2); binding.add(op); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e2); if (!handleExtension(context, binding, e2)) { checkNotWsdlRequired(e2); } } } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_BINDING, binding); return binding; } private BindingOperation parseBindingOperation( TWSDLParserContextImpl context, Element e) { context.push(); context.registerNamespaces(e); BindingOperation operation = new BindingOperation(forest.locatorTable.getStartLocation(e)); String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME); operation.setName(name); boolean gotDocumentation = false; boolean gotInput = false; boolean gotOutput = false; boolean gotFault = false; boolean inputBeforeOutput = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation = true; operation.setDocumentation(getDocumentationFor(e2)); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_INPUT)) { if (gotInput) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT, Constants.TAG_OPERATION, name)); } /* Here we check for the use scenario */ context.push(); context.registerNamespaces(e2); BindingInput input = new BindingInput(forest.locatorTable.getStartLocation(e2)); String nameAttr = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME); input.setName(nameAttr); operation.setInput(input); gotInput = true; if (gotOutput) { inputBeforeOutput = false; } // verify that there is at most one child element and it is a documentation element boolean gotDocumentation2 = false; for (Iterator iter2 = XmlUtil.getAllChildren(e2); iter2.hasNext(); ) { Element e3 = Util.nextElement(iter2); if (e3 == null) break; if (XmlUtil .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation2) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation2 = true; input.setDocumentation(getDocumentationFor(e3)); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e3); if (!handleExtension(context, input, e3)) { checkNotWsdlRequired(e3); } } } context.pop(); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_OUTPUT)) { if (gotOutput) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_TOO_MANY_ELEMENTS(Constants.TAG_INPUT, Constants.TAG_OPERATION, name)); } context.push(); context.registerNamespaces(e2); BindingOutput output = new BindingOutput(forest.locatorTable.getStartLocation(e2)); String nameAttr = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAME); output.setName(nameAttr); operation.setOutput(output); gotOutput = true; if (gotInput) { inputBeforeOutput = true; } // verify that there is at most one child element and it is a documentation element boolean gotDocumentation2 = false; for (Iterator iter2 = XmlUtil.getAllChildren(e2); iter2.hasNext(); ) { Element e3 = Util.nextElement(iter2); if (e3 == null) break; if (XmlUtil .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation2) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation2 = true; output.setDocumentation(getDocumentationFor(e3)); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e3); if (!handleExtension(context, output, e3)) { checkNotWsdlRequired(e3); } } } context.pop(); } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_FAULT)) { context.push(); context.registerNamespaces(e2); BindingFault fault = new BindingFault(forest.locatorTable.getStartLocation(e2)); String nameAttr = Util.getRequiredAttribute(e2, Constants.ATTR_NAME); fault.setName(nameAttr); operation.addFault(fault); gotFault = true; // verify that there is at most one child element and it is a documentation element boolean gotDocumentation2 = false; for (Iterator iter2 = XmlUtil.getAllChildren(e2); iter2.hasNext(); ) { Element e3 = Util.nextElement(iter2); if (e3 == null) break; if (XmlUtil .matchesTagNS(e3, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation2) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation2 = true; if(fault.getDocumentation() == null) fault.setDocumentation(getDocumentationFor(e3)); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e3); if (!handleExtension(context, fault, e3)) { checkNotWsdlRequired(e3); } } } context.pop(); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e2); if (!handleExtension(context, operation, e2)) { checkNotWsdlRequired(e2); } } } if (gotInput && !gotOutput && !gotFault) { operation.setStyle(OperationStyle.ONE_WAY); } else if (gotInput && gotOutput && inputBeforeOutput) { operation.setStyle(OperationStyle.REQUEST_RESPONSE); } else if (gotInput && gotOutput && !inputBeforeOutput) { operation.setStyle(OperationStyle.SOLICIT_RESPONSE); } else if (gotOutput && !gotInput && !gotFault) { operation.setStyle(OperationStyle.NOTIFICATION); } else { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_INVALID_OPERATION_STYLE(name)); } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_OPERATION, operation); return operation; } private Import parseImport( TWSDLParserContextImpl context, Definitions definitions, Element e) { context.push(); context.registerNamespaces(e); Import anImport = new Import(forest.locatorTable.getStartLocation(e)); String namespace = Util.getRequiredAttribute(e, Constants.ATTR_NAMESPACE); anImport.setNamespace(namespace); String location = Util.getRequiredAttribute(e, Constants.ATTR_LOCATION); anImport.setLocation(location); // according to the schema in the WSDL 1.1 spec, an import can have a documentation element boolean gotDocumentation = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation = true; anImport.setDocumentation(getDocumentationFor(e2)); } else { errReceiver.error(forest.locatorTable.getStartLocation(e2), WsdlMessages.PARSING_INVALID_ELEMENT(e2.getTagName(), e2.getNamespaceURI())); } } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_IMPORT, anImport); return anImport; } private Service parseService( TWSDLParserContextImpl context, Definitions definitions, Element e) { context.push(); context.registerNamespaces(e); Service service = new Service(definitions, forest.locatorTable.getStartLocation(e), errReceiver); String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME); service.setName(name); boolean gotDocumentation = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) break; if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation = true; if (service.getDocumentation() == null) { service.setDocumentation(getDocumentationFor(e2)); } } else if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_PORT)) { Port port = parsePort(context, definitions, e2); service.add(port); } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e2); if (!handleExtension(context, service, e2)) { checkNotWsdlRequired(e2); } } } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_SERVICE, service); return service; } private Port parsePort( TWSDLParserContextImpl context, Definitions definitions, Element e) { context.push(); context.registerNamespaces(e); Port port = new Port(definitions, forest.locatorTable.getStartLocation(e), errReceiver); String name = Util.getRequiredAttribute(e, Constants.ATTR_NAME); port.setName(name); String bindingAttr = Util.getRequiredAttribute(e, Constants.ATTR_BINDING); port.setBinding(context.translateQualifiedName(context.getLocation(e), bindingAttr)); boolean gotDocumentation = false; for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) { Element e2 = Util.nextElement(iter); if (e2 == null) { break; } if (XmlUtil.matchesTagNS(e2, WSDLConstants.QNAME_DOCUMENTATION)) { if (gotDocumentation) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_ONLY_ONE_DOCUMENTATION_ALLOWED(e.getLocalName())); } gotDocumentation = true; if (port.getDocumentation() == null) { port.setDocumentation(getDocumentationFor(e2)); } } else { // possible extensibility element -- must live outside the WSDL namespace checkNotWsdlElement(e2); if (!handleExtension(context, port, e2)) { checkNotWsdlRequired(e2); } } } context.pop(); context.fireDoneParsingEntity(WSDLConstants.QNAME_PORT, port); return port; } private void validateSchemaImports(Element typesElement){ for (Iterator iter = XmlUtil.getAllChildren(typesElement); iter.hasNext();) { Element e = Util.nextElement(iter); if (e == null) { break; } if (XmlUtil.matchesTagNS(e, SchemaConstants.QNAME_IMPORT)) { errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.WARNING_WSI_R_2003()); }else{ checkNotWsdlElement(e); // if (XmlUtil.matchesTagNS(e, SchemaConstants.QNAME_SCHEMA)) { // forest.getInlinedSchemaElement().add(e); // } } } } private boolean handleExtension( TWSDLParserContextImpl context, TWSDLExtensible entity, Element e) { TWSDLExtensionHandler h = (TWSDLExtensionHandler) extensionHandlers.get(e.getNamespaceURI()); if (h == null) { context.fireIgnoringExtension(e, (Entity) entity); errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_UNKNOWN_EXTENSIBILITY_ELEMENT_OR_ATTRIBUTE(e.getLocalName(), e.getNamespaceURI())); return false; } else { return h.doHandleExtension(context, entity, e); } } private boolean handleExtension( TWSDLParserContextImpl context, TWSDLExtensible entity, Node n, Element e) { TWSDLExtensionHandler h = (TWSDLExtensionHandler) extensionHandlers.get(n.getNamespaceURI()); if (h == null) { context.fireIgnoringExtension(e, (Entity) entity); errReceiver.warning(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_UNKNOWN_EXTENSIBILITY_ELEMENT_OR_ATTRIBUTE(n.getLocalName(), n.getNamespaceURI())); return false; } else { return h.doHandleExtension(context, entity, e); } } private void checkNotWsdlElement(Element e) { // possible extensibility element -- must live outside the WSDL namespace if (e.getNamespaceURI() != null && e.getNamespaceURI().equals(Constants.NS_WSDL)) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_INVALID_WSDL_ELEMENT(e.getTagName())); } } private void checkNotWsdlAttribute(Attr a) { // possible extensibility element -- must live outside the WSDL namespace if (Constants.NS_WSDL.equals(a.getNamespaceURI())) { errReceiver.error(forest.locatorTable.getStartLocation(a.getOwnerElement()), WsdlMessages.PARSING_INVALID_WSDL_ELEMENT(a.getLocalName())); } } private void checkNotWsdlRequired(Element e) { // check the wsdl:required attribute, fail if set to "true" String required = XmlUtil.getAttributeNSOrNull( e, Constants.ATTR_REQUIRED, Constants.NS_WSDL); if (required != null && required.equals(Constants.TRUE) && !options.isExtensionMode()) { errReceiver.error(forest.locatorTable.getStartLocation(e), WsdlMessages.PARSING_REQUIRED_EXTENSIBILITY_ELEMENT(e.getTagName(), e.getNamespaceURI())); } } private Documentation getDocumentationFor(Element e) { String s = XmlUtil.getTextForNode(e); if (s == null) { return null; } else { return new Documentation(s); } } }