blob: 898938169ecdbdfc51a2ef9fb85601c8ef85f9c2 [file] [log] [blame]
/*
* 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);
}
}
}