/*
 * 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.
Author:WS Development Team
See Also:
  • which will be used for WSDL parsing at runtime.
/** * 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); } } }