| /******************************************************************************* |
| * Copyright (c) 2001, 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.wst.wsdl.validation.internal.wsdl11; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeSet; |
| import java.util.Vector; |
| |
| import javax.wsdl.Binding; |
| import javax.wsdl.BindingFault; |
| import javax.wsdl.BindingInput; |
| import javax.wsdl.BindingOperation; |
| import javax.wsdl.BindingOutput; |
| import javax.wsdl.Definition; |
| import javax.wsdl.Fault; |
| import javax.wsdl.Input; |
| import javax.wsdl.Message; |
| import javax.wsdl.Operation; |
| import javax.wsdl.OperationType; |
| import javax.wsdl.Output; |
| import javax.wsdl.Part; |
| import javax.wsdl.Port; |
| import javax.wsdl.PortType; |
| import javax.wsdl.Service; |
| import javax.wsdl.Types; |
| import javax.wsdl.WSDLException; |
| import javax.wsdl.extensions.ExtensibilityElement; |
| import javax.wsdl.extensions.ExtensionDeserializer; |
| import javax.wsdl.extensions.ExtensionRegistry; |
| import javax.wsdl.extensions.UnknownExtensibilityElement; |
| import javax.wsdl.extensions.schema.Schema; |
| import javax.wsdl.factory.WSDLFactory; |
| import javax.xml.namespace.QName; |
| |
| import org.apache.xerces.dom.ElementImpl; |
| import org.apache.xerces.dom.ElementNSImpl; |
| import org.apache.xerces.xs.XSModel; |
| import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator; |
| import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.InlineSchemaValidator; |
| import org.eclipse.wst.wsdl.validation.internal.xml.ElementLocation; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| import com.ibm.wsdl.Constants; |
| import com.ibm.wsdl.util.StringUtils; |
| import com.ibm.wsdl.util.xml.DOMUtils; |
| import com.ibm.wsdl.util.xml.QNameUtils; |
| import com.ibm.wsdl.util.xml.XPathUtils; |
| |
| /** |
| * A WSDL document that knows how to parse itself. |
| */ |
| public class WSDLDocument |
| { |
| private static final List STYLE_ONE_WAY = Arrays.asList(new String[] { Constants.ELEM_INPUT }); |
| private static final List STYLE_REQUEST_RESPONSE = |
| Arrays.asList(new String[] { Constants.ELEM_INPUT, Constants.ELEM_OUTPUT }); |
| private static final List STYLE_SOLICIT_RESPONSE = |
| Arrays.asList(new String[] { Constants.ELEM_OUTPUT, Constants.ELEM_INPUT }); |
| private static final List STYLE_NOTIFICATION = Arrays.asList(new String[] { Constants.ELEM_OUTPUT }); |
| |
| private static final String _ERROR_MULTIPLE_TYPES_DEFINED = "_ERROR_MULTIPLE_TYPES_DEFINED"; |
| private static final String _UNABLE_TO_IMPORT_NO_LOCATION = "_UNABLE_TO_IMPORT_NO_LOCATION"; |
| |
| protected ExtensionRegistry extReg = null; |
| protected String factoryImplName = null; |
| |
| // store the element locations within the file - line and column numbers |
| // the location info is stored as an int array of length 2 {linenumber, colnumber} |
| protected Hashtable elementLocations = new Hashtable(); |
| |
| // hold the reader errors |
| protected List readerErrors = new ArrayList(); |
| protected List readerWarnings = new ArrayList(); |
| protected MessageGenerator messagegenerator; |
| |
| private Definition def = null; |
| private Set importedDefs = new TreeSet(); |
| private Element typesEl = null; |
| private List messages = new ArrayList(); |
| private List porttypes = new ArrayList(); |
| private List bindings = new ArrayList(); |
| private List services = new ArrayList(); |
| private List extelements = new ArrayList(); |
| private int depth; |
| // Hold the schemas that are imported or declared inline in this wsdl document. |
| private List schemas = new ArrayList(); |
| private IWSDL11ValidationInfo valinfo; |
| |
| /** |
| * Constructor. Performs a preparse of the document and handles imports and types. |
| * |
| * @param documentBaseURI The URI of this WSDL document. |
| * @param defEl The definitions element. |
| * @param depth The depth of this document in a document tree. |
| * @param messagegenerator A messagegenerator used for retrieving strings. |
| * @param valinfo A WSDL11ValidationInfo object for reporting messages. |
| * @throws WSDLException |
| */ |
| public WSDLDocument(String documentBaseURI, Element defEl, int depth, MessageGenerator messagegenerator, IWSDL11ValidationInfo valinfo) throws WSDLException |
| { |
| this.messagegenerator = messagegenerator; |
| this.valinfo = valinfo; |
| this.depth = depth; |
| |
| checkElementName(defEl, Constants.Q_ELEM_DEFINITIONS); |
| |
| WSDLFactory factory = |
| (factoryImplName != null) ? WSDLFactory.newInstance(factoryImplName) : WSDLFactory.newInstance(); |
| def = factory.newDefinition(); |
| // Fix for WSDL4J adding default WSDL namespace when no default |
| // namespace has been declared. |
| // TODO: Remove this fix once fixed in WSDL4J. |
| if(def.getNamespace("") != null) |
| def.getNamespaces().remove(""); |
| |
| if (extReg != null) |
| { |
| def.setExtensionRegistry(extReg); |
| } |
| |
| String name = DOMUtils.getAttribute(defEl, Constants.ATTR_NAME); |
| String targetNamespace = DOMUtils.getAttribute(defEl, Constants.ATTR_TARGET_NAMESPACE); |
| NamedNodeMap attrs = defEl.getAttributes(); |
| |
| if (documentBaseURI != null) |
| { |
| def.setDocumentBaseURI(documentBaseURI); |
| } |
| |
| if (name != null) |
| { |
| def.setQName(new QName(targetNamespace, name)); |
| } |
| |
| if (targetNamespace != null) |
| { |
| def.setTargetNamespace(targetNamespace); |
| } |
| |
| int size = attrs.getLength(); |
| |
| for (int i = 0; i < size; i++) |
| { |
| Attr attr = (Attr)attrs.item(i); |
| String namespaceURI = attr.getNamespaceURI(); |
| String localPart = attr.getLocalName(); |
| String value = attr.getValue(); |
| |
| if (namespaceURI != null && namespaceURI.equals(Constants.NS_URI_XMLNS)) |
| { |
| if (localPart != null && !localPart.equals(Constants.ATTR_XMLNS)) |
| { |
| def.addNamespace(localPart, value); |
| } |
| else |
| { |
| def.addNamespace(null, value); |
| } |
| } |
| } |
| |
| // There are problems when the model is created and the order of elements is not |
| // Import - Types - Message - PortType - Binding - Service so we need to read them |
| // into the model in that order |
| // Performance wise this should be modified as we have to make 5 extra loops through |
| // all of the elements as a result |
| |
| // take care of Imports, Types, Documentation and extensibleelements together - saves a pass for Documentation |
| // later and Docs don't effect anything else - Imports and Types are essentially the same thing |
| // no preconceived ideas about extensible elements |
| Element tempEl = DOMUtils.getFirstChildElement(defEl); |
| |
| while (tempEl != null) |
| { |
| |
| if (QNameUtils.matches(Constants.Q_ELEM_IMPORT, tempEl)) |
| { |
| String namespaceURI = DOMUtils.getAttribute(tempEl, Constants.ATTR_NAMESPACE); |
| String locationURI = DOMUtils.getAttribute(tempEl, Constants.ATTR_LOCATION); |
| if(locationURI == null || locationURI.equals("")) |
| { |
| addReaderError(def, tempEl, messagegenerator.getString(_UNABLE_TO_IMPORT_NO_LOCATION)); |
| } |
| else |
| { |
| ImportHolder ih = new ImportHolder(namespaceURI, locationURI, def.getDocumentBaseURI(), this, depth+1, tempEl, messagegenerator, valinfo); |
| // Only add the import to the list if it is not an import for this document. |
| if(!documentBaseURI.equals(ih.getLocation())) |
| { |
| importedDefs.add(ih); |
| } |
| } |
| setLocation(tempEl, tempEl); |
| // if (importedDefs == null) |
| // { |
| // importedDefs = new Hashtable(); |
| // } |
| // if (documentBaseURI != null) |
| // { |
| // importedDefs.put(documentBaseURI, def); |
| // } |
| // def.addImport(parseImport(tempEl, def, importedDefs)); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| def.setDocumentationElement(tempEl); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_TYPES, tempEl)) |
| { |
| if(typesEl != null) |
| { |
| setLocation(tempEl, tempEl); |
| addReaderError(def, tempEl, messagegenerator.getString(_ERROR_MULTIPLE_TYPES_DEFINED)); |
| } |
| else |
| { |
| typesEl = tempEl; |
| parseTypes(); |
| } |
| // def.setTypes(parseTypes(tempEl, def)); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_MESSAGE, tempEl)) |
| { |
| messages.add(tempEl); |
| //def.addMessage(parseMessage(tempEl, def)); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_PORT_TYPE, tempEl)) |
| { |
| porttypes.add(tempEl); |
| // PortType pt = parsePortType(tempEl, def); |
| // if(pt != null) |
| // { |
| // def.addPortType(pt); |
| // } |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_BINDING, tempEl)) |
| { |
| bindings.add(tempEl); |
| //def.addBinding(parseBinding(tempEl, def)); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_SERVICE, tempEl)) |
| { |
| services.add(tempEl); |
| //def.addService(parseService(tempEl, def)); |
| } |
| else |
| { |
| extelements.add(tempEl); |
| // def.addExtensibilityElement( |
| // parseExtensibilityElement(Definition.class, tempEl, def)); |
| } |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| } |
| |
| /** |
| * Get the definitions element for this document. |
| * |
| * @return The definitions element for this document. |
| */ |
| public Definition getDefinition() |
| { |
| return def; |
| } |
| |
| /** |
| * Get a set of the imports in this document. |
| * |
| * @return A set of the imports in this document. |
| */ |
| public Set getImports() |
| { |
| return importedDefs; |
| } |
| |
| /** |
| * |
| * @param def |
| * @param doc |
| * @param namespace |
| * @param location |
| */ |
| // public void setImport(Definition def, Element doc, String namespace, String location) |
| // { |
| // if(location == null || location.equals("")) |
| // { |
| // valinfo.addError()_UNABLE_TO_IMPORT_NO_LOCATION |
| // } |
| // Import imp = def.createImport(); |
| // imp.setDefinition(def); |
| // imp.setDocumentationElement(doc); |
| // imp.setNamespaceURI(namespace); |
| // imp.setLocationURI(location); |
| // def.addImport(imp); |
| // } |
| |
| /** |
| * Parse the types in the WSDL document. Handles documentation, import and schema |
| * elements. |
| */ |
| public void parseTypes() |
| { |
| Types types = def.createTypes(); |
| |
| Element tempEl = DOMUtils.getFirstChildElement(typesEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| types.setDocumentationElement(tempEl); |
| } |
| else if (tempEl.getLocalName().equalsIgnoreCase("import")) |
| //else if (QNameUtils.matches(Constants.Q_ELEM_IMPORT, tempEl)) |
| { |
| // this shouldn't really be used here but a little hack will make |
| // life easier |
| //parseImport(tempEl, def, (Map)new Hashtable()); |
| String namespaceURI = DOMUtils.getAttribute(tempEl, Constants.ATTR_NAMESPACE); |
| String locationURI = DOMUtils.getAttribute(tempEl, "schemaLocation"); |
| importedDefs.add(new ImportHolder(namespaceURI, locationURI, def.getDocumentBaseURI(), this, depth+1, tempEl, messagegenerator, valinfo)); |
| try |
| { |
| types.addExtensibilityElement(parseExtensibilityElement(Types.class, tempEl, def)); |
| } |
| catch(WSDLException e) |
| { |
| |
| } |
| } |
| else |
| { |
| try |
| { |
| ExtensibilityElement extElem = parseExtensibilityElement(Types.class, tempEl, def); |
| types.addExtensibilityElement(extElem); |
| } |
| catch(WSDLException e) |
| { |
| |
| } |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| def.setTypes(types); |
| |
| valinfo.setElementLocations(elementLocations); |
| List typesElems = types.getExtensibilityElements(); |
| if(typesElems != null) |
| { |
| Iterator typesElemsIter = typesElems.iterator(); |
| while(typesElemsIter.hasNext()) |
| { |
| ExtensibilityElement typeElement = (ExtensibilityElement)typesElemsIter.next(); |
| |
| InlineSchemaValidator xsdVal = new InlineSchemaValidator(); |
| xsdVal.setMessageGenerator(messagegenerator); |
| |
| List parents = new ArrayList(); |
| parents.add(def); |
| parents.add(0,types); |
| xsdVal.validate(typeElement, parents,valinfo); |
| XSModel[] typesSchemas = valinfo.getSchemas(); |
| List typesSchemaList = new ArrayList(); |
| for(int i = 0; i < typesSchemas.length; i++) |
| { |
| typesSchemaList.add(typesSchemas[i]); |
| } |
| schemas.addAll(typesSchemaList); |
| valinfo.clearSchemas(); |
| } |
| } |
| valinfo.setElementLocations(null); |
| } |
| |
| /** |
| * Parse the messages in this document. |
| */ |
| public void parseMessages() |
| { |
| for (int i = 0; i < messages.size(); i++) |
| { |
| try |
| { |
| def.addMessage(parseMessage((Element)messages.get(i), def)); |
| } |
| catch(WSDLException e) |
| {} |
| } |
| } |
| |
| /** |
| * Parse the portTypes in this document. |
| */ |
| public void parsePorttypes() |
| { |
| for (int i = 0; i < porttypes.size(); i++) |
| { |
| try |
| { |
| PortType pt = parsePortType((Element)porttypes.get(i), def); |
| if (pt != null) |
| { |
| def.addPortType(pt); |
| } |
| } |
| catch(WSDLException e) |
| {} |
| } |
| } |
| |
| /** |
| * Parse the bindings in this document. |
| */ |
| public void parseBindings() |
| { |
| for (int i = 0; i < bindings.size(); i++) |
| { |
| try |
| { |
| def.addBinding(parseBinding((Element)bindings.get(i), def)); |
| } |
| catch(WSDLException e) |
| {} |
| } |
| } |
| |
| /** |
| * Parse the services in this document. |
| */ |
| public void parseServices() |
| { |
| for (int i = 0; i < services.size(); i++) |
| { |
| try |
| { |
| def.addService(parseService((Element)services.get(i), def)); |
| } |
| catch(WSDLException e) |
| {} |
| } |
| } |
| |
| /** |
| * Parse the extensibility elements in this document. |
| */ |
| public void parseExtensibilityElements() |
| { |
| for (int i = 0; i < extelements.size(); i++) |
| { |
| try |
| { |
| def.addExtensibilityElement(parseExtensibilityElement(Definition.class, (Element)extelements.get(i), def)); |
| } |
| catch(WSDLException e) |
| {} |
| } |
| } |
| |
| /** |
| * Add the given list of schemas to the schemas for this document. |
| * |
| * @param schemas The list of schemas to add to this document's schemas. |
| */ |
| public void addSchemas(List schemas) |
| { |
| this.schemas.addAll(schemas); |
| } |
| |
| /** |
| * Get the schemas associated with this document. |
| * |
| * @return The schemas associated with this document. |
| */ |
| public List getSchemas() |
| { |
| return schemas; |
| } |
| |
| /** |
| * Parse the specified binding. |
| * |
| * @param bindingEl The binding element. |
| * @param def The definitions element. |
| * @return A WSDL binding element. |
| * @throws WSDLException |
| */ |
| protected Binding parseBinding(Element bindingEl, Definition def) throws WSDLException |
| { |
| Binding binding = null; |
| String name = DOMUtils.getAttribute(bindingEl, Constants.ATTR_NAME); |
| QName portTypeName; |
| try |
| { |
| portTypeName = DOMUtils.getQualifiedAttributeValue(bindingEl, Constants.ATTR_TYPE, Constants.ELEM_BINDING, false, def); |
| } |
| catch (Exception e) |
| { |
| //the call above fails if there is no qualified namespace for the message name |
| portTypeName = new QName(null, DOMUtils.getAttribute(bindingEl, "type")); |
| } |
| |
| PortType portType = null; |
| |
| if (name != null) |
| { |
| QName bindingName = new QName(def.getTargetNamespace(), name); |
| |
| binding = def.getBinding(bindingName); |
| |
| if (binding == null) |
| { |
| binding = def.createBinding(); |
| binding.setQName(bindingName); |
| } |
| // report an error if a binding with this name has already been defined |
| else if (!binding.isUndefined()) |
| { |
| //addReaderError(def,bindingEl, "_BINDING_NAME_ALREADY_DEFINED"); |
| addReaderError( |
| def, |
| bindingEl, |
| messagegenerator.getString("_BINDING_NAME_ALREADY_DEFINED", "'" + binding.getQName().getLocalPart() + "'")); |
| } |
| } |
| else |
| { |
| binding = def.createBinding(); |
| } |
| |
| // Whether it was retrieved or created, the definition has been found. |
| binding.setUndefined(false); |
| |
| if (portTypeName != null) |
| { |
| portType = def.getPortType(portTypeName); |
| |
| if (portType == null) |
| { |
| portType = def.createPortType(); |
| portType.setQName(portTypeName); |
| def.addPortType(portType); |
| } |
| |
| binding.setPortType(portType); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(bindingEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| binding.setDocumentationElement(tempEl); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_OPERATION, tempEl)) |
| { |
| binding.addBindingOperation(parseBindingOperation(tempEl, portType, def)); |
| } |
| else |
| { |
| binding.addExtensibilityElement(parseExtensibilityElement(Binding.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(binding, bindingEl); |
| |
| return binding; |
| } |
| |
| /** |
| * Parse a specific binding operation. |
| * |
| * @param bindingOperationEl The binding operation element. |
| * @param portType The portType the binding references. |
| * @param def The definitions element. |
| * @return A WSDL binding operation element. |
| * @throws WSDLException |
| */ |
| protected BindingOperation parseBindingOperation(Element bindingOperationEl, PortType portType, Definition def) |
| throws WSDLException |
| { |
| BindingOperation bindingOperation = def.createBindingOperation(); |
| String name = DOMUtils.getAttribute(bindingOperationEl, Constants.ATTR_NAME); |
| |
| if (name != null) |
| { |
| bindingOperation.setName(name); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(bindingOperationEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| bindingOperation.setDocumentationElement(tempEl); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_INPUT, tempEl)) |
| { |
| bindingOperation.setBindingInput(parseBindingInput(tempEl, def)); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_OUTPUT, tempEl)) |
| { |
| bindingOperation.setBindingOutput(parseBindingOutput(tempEl, def)); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_FAULT, tempEl)) |
| { |
| bindingOperation.addBindingFault(parseBindingFault(tempEl, def)); |
| } |
| else |
| { |
| bindingOperation.addExtensibilityElement(parseExtensibilityElement(BindingOperation.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| if (portType != null) |
| { |
| BindingInput bindingInput = bindingOperation.getBindingInput(); |
| BindingOutput bindingOutput = bindingOperation.getBindingOutput(); |
| //String inputName = (bindingInput != null ? bindingInput.getName() : null); |
| //String outputName = (bindingOutput != null ? bindingOutput.getName() : null); |
| |
| // hack code to get at operations that are defined with the same name but different |
| // inputs and outputs |
| Operation op = null; |
| List operations = portType.getOperations(); |
| // get a list of all operations with matching names |
| List matchingOperations = new Vector(); |
| Iterator iOperations = operations.iterator(); |
| while (iOperations.hasNext()) |
| { |
| Operation oper = (Operation)iOperations.next(); |
| if (oper.getName().equalsIgnoreCase(bindingOperation.getName())) |
| { |
| matchingOperations.add(oper); |
| } |
| } |
| |
| if (matchingOperations != null) |
| { |
| // If there's only one matching operation this is what we're referring to. |
| // Only matching if binding operation input name and output name are |
| // both null or the same as the portType operation input and output names. |
| // the portType operation name |
| if (matchingOperations.size() == 1) |
| { |
| // only say the single operation is the one we're looking for if the names |
| // of the binding input and output are not specified |
| Operation tempOp = (Operation)matchingOperations.get(0); |
| boolean inputOK = false; |
| boolean outputOK = false; |
| Input tempInput = tempOp.getInput(); |
| Output tempOutput = tempOp.getOutput(); |
| |
| // order is important in these conditions. condition 2 must fail for 3 to work |
| // check the input |
| if (tempInput == null && bindingInput == null) |
| { |
| inputOK = true; |
| } |
| else if (bindingInput == null || bindingInput.getName() == null) |
| { |
| inputOK = true; |
| } |
| else if (tempInput != null && bindingInput.getName().equals(tempInput.getName())) |
| { |
| inputOK = true; |
| } |
| // check the output |
| if (tempOutput == null && bindingOutput == null) |
| { |
| outputOK = true; |
| } |
| else if (bindingOutput == null || bindingOutput.getName() == null) |
| { |
| outputOK = true; |
| } |
| else if (tempOutput != null && bindingOutput.getName().equals(tempOutput.getName())) |
| { |
| outputOK = true; |
| } |
| if (inputOK && outputOK) |
| { |
| op = tempOp; |
| } |
| // op = (Operation) matchingOperations.get(0); |
| } |
| // otherwise find the operation with the same name, inputname, outputname signature |
| if (matchingOperations != null && op == null) |
| { |
| Iterator iMatchingOperations = matchingOperations.iterator(); |
| while (iMatchingOperations.hasNext()) |
| { |
| |
| boolean inputNamesEqual = false; |
| boolean outputNamesEqual = false; |
| Operation oper = (Operation)iMatchingOperations.next(); |
| // if (oper.getName().equalsIgnoreCase(bindingOperation.getName())) |
| // { |
| Input opInput = oper.getInput(); |
| if (opInput != null && bindingInput != null) |
| { |
| String opInputName = opInput.getName(); |
| String bindingInputName = bindingInput.getName(); |
| if (opInputName != null && opInputName.equalsIgnoreCase(bindingInputName)) |
| { |
| inputNamesEqual = true; |
| } |
| else if (opInputName == null && bindingInputName == null) |
| { |
| inputNamesEqual = true; |
| } |
| } |
| else if (opInput == null && bindingInput == null) |
| { |
| inputNamesEqual = true; |
| } |
| Output opOutput = oper.getOutput(); |
| if (opOutput != null && bindingOutput != null) |
| { |
| String opOutputName = opOutput.getName(); |
| String bindingOutputName = bindingOutput.getName(); |
| if (opOutputName != null && opOutputName.equalsIgnoreCase(bindingOutputName)) |
| { |
| outputNamesEqual = true; |
| } |
| else if (opOutputName == null && bindingOutputName == null) |
| { |
| outputNamesEqual = true; |
| } |
| } |
| else if (opOutput == null && bindingOutput == null) |
| { |
| outputNamesEqual = true; |
| } |
| if (inputNamesEqual && outputNamesEqual) |
| { |
| op = oper; |
| break; |
| } |
| //} |
| } |
| } |
| } |
| //Operation op = portType.getOperation(name, inputName, outputName); |
| |
| if (op == null) |
| { |
| op = def.createOperation(); |
| op.setName(name); |
| portType.addOperation(op); |
| } |
| |
| bindingOperation.setOperation(op); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(bindingOperation, bindingOperationEl); |
| |
| return bindingOperation; |
| } |
| |
| /** |
| * Parse a specific binding input element. |
| * |
| * @param bindingInputEl The binding input element. |
| * @param def The definitions element. |
| * @return A WSDL binding input element. |
| * @throws WSDLException |
| */ |
| protected BindingInput parseBindingInput(Element bindingInputEl, Definition def) throws WSDLException |
| { |
| BindingInput bindingInput = def.createBindingInput(); |
| String name = DOMUtils.getAttribute(bindingInputEl, Constants.ATTR_NAME); |
| |
| if (name != null) |
| { |
| bindingInput.setName(name); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(bindingInputEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| bindingInput.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| bindingInput.addExtensibilityElement(parseExtensibilityElement(BindingInput.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(bindingInput, bindingInputEl); |
| |
| return bindingInput; |
| } |
| |
| /** |
| * Parse a specific binding output element. |
| * |
| * @param bindingOutputEl The binding output element. |
| * @param def The definitions element. |
| * @return A WSDL binding output element. |
| * @throws WSDLException |
| */ |
| protected BindingOutput parseBindingOutput(Element bindingOutputEl, Definition def) throws WSDLException |
| { |
| BindingOutput bindingOutput = def.createBindingOutput(); |
| String name = DOMUtils.getAttribute(bindingOutputEl, Constants.ATTR_NAME); |
| |
| if (name != null) |
| { |
| bindingOutput.setName(name); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(bindingOutputEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| bindingOutput.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| bindingOutput.addExtensibilityElement(parseExtensibilityElement(BindingOutput.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(bindingOutput, bindingOutputEl); |
| |
| return bindingOutput; |
| } |
| |
| /** |
| * Parse a specific binding fault element. |
| * |
| * @param bindingFaultEl The binding fault element. |
| * @param def The definitions element. |
| * @return A WSDL binding fault element. |
| * @throws WSDLException |
| */ |
| protected BindingFault parseBindingFault(Element bindingFaultEl, Definition def) throws WSDLException |
| { |
| BindingFault bindingFault = def.createBindingFault(); |
| String name = DOMUtils.getAttribute(bindingFaultEl, Constants.ATTR_NAME); |
| |
| if (name != null) |
| { |
| bindingFault.setName(name); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(bindingFaultEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| bindingFault.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| bindingFault.addExtensibilityElement(parseExtensibilityElement(BindingFault.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(bindingFault, bindingFaultEl); |
| |
| return bindingFault; |
| } |
| |
| /** |
| * Parse a specific message element. |
| * |
| * @param msgEl The message element. |
| * @param def The definitions element. |
| * @return A WSDL message element. |
| * @throws WSDLException |
| */ |
| protected Message parseMessage(Element msgEl, Definition def) throws WSDLException |
| { |
| Message msg = null; |
| String name = DOMUtils.getAttribute(msgEl, Constants.ATTR_NAME); |
| |
| if (name != null) |
| { |
| QName messageName = new QName(def.getTargetNamespace(), name); |
| |
| msg = def.getMessage(messageName); |
| |
| if (msg == null) |
| { |
| msg = def.createMessage(); |
| msg.setQName(messageName); |
| } |
| else if (!msg.isUndefined()) |
| { |
| // produce an error message as a message with this name has already been defined |
| addReaderError( |
| def, |
| msgEl, |
| messagegenerator.getString("_MESSAGE_NAME_ALREADY_DEFINED", "'" + msg.getQName().getLocalPart() + "'")); |
| } |
| } |
| else |
| { |
| msg = def.createMessage(); |
| } |
| |
| // Whether it was retrieved or created, the definition has been found. |
| msg.setUndefined(false); |
| |
| Element tempEl = DOMUtils.getFirstChildElement(msgEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| msg.setDocumentationElement(tempEl); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_PART, tempEl)) |
| { |
| msg.addPart(parsePart(tempEl, def)); |
| } |
| else |
| { |
| // message allows extensibility elements |
| msg.addExtensibilityElement(parseExtensibilityElement(Message.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(msg, msgEl); |
| |
| return msg; |
| } |
| |
| /** |
| * Parse a specific part element. |
| * |
| * @param partEl The part element. |
| * @param def The definitions element. |
| * @return A WSDL part element. |
| * @throws WSDLException |
| */ |
| protected Part parsePart(Element partEl, Definition def) throws WSDLException |
| { |
| Part part = def.createPart(); |
| String name = DOMUtils.getAttribute(partEl, Constants.ATTR_NAME); |
| |
| QName elementName; |
| try |
| { |
| elementName = DOMUtils.getQualifiedAttributeValue(partEl, Constants.ATTR_ELEMENT, Constants.ELEM_MESSAGE, false, def); |
| } |
| catch (Exception e) |
| { |
| //the call above fails if there is no qualified namespace for the element name |
| elementName = new QName(null, DOMUtils.getAttribute(partEl, Constants.ATTR_ELEMENT)); |
| } |
| |
| QName typeName; |
| try |
| { |
| typeName = DOMUtils.getQualifiedAttributeValue(partEl, Constants.ATTR_TYPE, |
| // Corrected - was ATTR_ELEMENT |
| Constants.ELEM_MESSAGE, false, def); |
| } |
| catch (Exception e) |
| { |
| //the call above fails if there is no qualified namespace for the element attribute |
| typeName = new QName(null, DOMUtils.getAttribute(partEl, Constants.ATTR_TYPE)); |
| } |
| |
| if (name != null) |
| { |
| part.setName(name); |
| } |
| |
| if (elementName != null) |
| { |
| part.setElementName(elementName); |
| } |
| |
| if (typeName != null) |
| { |
| part.setTypeName(typeName); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(partEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| part.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| // XML Validation will catch this |
| DOMUtils.throwWSDLException(tempEl); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| Map extensionAttributes = part.getExtensionAttributes(); |
| |
| extensionAttributes.putAll(getPartAttributes(partEl, def)); |
| |
| // Need to do something here to locate part definition. |
| |
| // add the location of this element to elementLocations |
| setLocation(part, partEl); |
| |
| return part; |
| } |
| |
| /** |
| * Get a map of the part attributes. |
| * |
| * @param el The part attributes element. |
| * @param def The defintions element. |
| * @return A map containing the part attributes. |
| * @throws WSDLException |
| */ |
| protected Map getPartAttributes(Element el, Definition def) throws WSDLException |
| { |
| Map attributes = new HashMap(); |
| NamedNodeMap nodeMap = el.getAttributes(); |
| int atts = nodeMap.getLength(); |
| |
| for (int a = 0; a < atts; a++) |
| { |
| Attr attribute = (Attr)nodeMap.item(a); |
| String lName = attribute.getLocalName(); |
| String nSpace = attribute.getNamespaceURI(); |
| String prefix = attribute.getPrefix(); |
| QName name = new QName(nSpace, lName); |
| |
| if (nSpace != null && !nSpace.equals(Constants.NS_URI_WSDL)) |
| { |
| if (!nSpace.equals(Constants.NS_URI_XMLNS)) |
| { |
| String strValue = attribute.getValue(); |
| QName qValue = null; |
| |
| try |
| { |
| qValue = DOMUtils.getQName(strValue, el, def); |
| } |
| catch (WSDLException e) |
| { |
| qValue = new QName(strValue); |
| } |
| |
| attributes.put(name, qValue); |
| |
| String tempNSUri = def.getNamespace(prefix); |
| |
| while (tempNSUri != null && !tempNSUri.equals(nSpace)) |
| { |
| prefix += "_"; |
| tempNSUri = def.getNamespace(prefix); |
| } |
| |
| def.addNamespace(prefix, nSpace); |
| } |
| } |
| else if ( |
| !lName.equals(Constants.ATTR_NAME) |
| && !lName.equals(Constants.ATTR_ELEMENT) |
| && !lName.equals(Constants.ATTR_TYPE)) |
| { |
| WSDLException wsdlExc = |
| new WSDLException( |
| WSDLException.INVALID_WSDL, |
| "Encountered illegal " |
| + "part extension " |
| + "attribute '" |
| + name |
| + "'. Extension " |
| + "attributes must be in " |
| + "a namespace other than " |
| + "WSDL's."); |
| |
| wsdlExc.setLocation(XPathUtils.getXPathExprFromNode(el)); |
| //throw wsdlExc; |
| } |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(attributes, el); |
| |
| return attributes; |
| } |
| |
| /** |
| * Parse a specific portType element. |
| * |
| * @param portTypeEl The portType element. |
| * @param def The defintions element. |
| * @return A WSDL portType element. |
| * @throws WSDLException |
| */ |
| protected PortType parsePortType(Element portTypeEl, Definition def) throws WSDLException |
| { |
| |
| PortType portType = null; |
| String name = DOMUtils.getAttribute(portTypeEl, Constants.ATTR_NAME); |
| |
| if (name != null) |
| { |
| QName portTypeName = new QName(def.getTargetNamespace(), name); |
| |
| portType = def.getPortType(portTypeName); |
| |
| if (portType == null) |
| { |
| portType = def.createPortType(); |
| portType.setQName(portTypeName); |
| } |
| else if (!portType.isUndefined()) |
| { |
| // if the PortType has already been defined produce an error and return null |
| addReaderError( |
| def, |
| portTypeEl, |
| messagegenerator.getString("_PORTTYPE_NAME_ALREADY_DEFINED", "'" + portType.getQName().getLocalPart() + "'")); |
| return null; |
| } |
| } |
| else |
| { |
| portType = def.createPortType(); |
| } |
| |
| // Whether it was retrieved or created, the definition has been found. |
| portType.setUndefined(false); |
| |
| Element tempEl = DOMUtils.getFirstChildElement(portTypeEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| portType.setDocumentationElement(tempEl); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_OPERATION, tempEl)) |
| { |
| // modified so duplicate operations will not be added to porttype |
| Operation op = parseOperation(tempEl, portType, def); |
| if (op != null) |
| { |
| portType.addOperation(op); |
| } |
| //portType.addOperation(parseOperation(tempEl, portType, def)); |
| } |
| else |
| { |
| // something else that shouldn't be here |
| // NEED TO ADD TO ERROR LIST |
| //DOMUtils.throwWSDLException(tempEl); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(portType, portTypeEl); |
| |
| return portType; |
| } |
| |
| /** |
| * Parse a specific operation element. |
| * |
| * @param opEl The operation element. |
| * @param portType The portType element. |
| * @param def The definitions element. |
| * @return A WSDL operation element. |
| * @throws WSDLException |
| */ |
| protected Operation parseOperation(Element opEl, PortType portType, Definition def) throws WSDLException |
| { |
| Operation op = null; |
| String name = DOMUtils.getAttribute(opEl, Constants.ATTR_NAME); |
| String parameterOrderStr = DOMUtils.getAttribute(opEl, Constants.ATTR_PARAMETER_ORDER); |
| Element tempEl = DOMUtils.getFirstChildElement(opEl); |
| List messageOrder = new Vector(); |
| Element docEl = null; |
| Input input = null; |
| Output output = null; |
| List faults = new Vector(); |
| List extElements = new ArrayList(); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| docEl = tempEl; |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_INPUT, tempEl)) |
| { |
| input = parseInput(tempEl, def); |
| messageOrder.add(Constants.ELEM_INPUT); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_OUTPUT, tempEl)) |
| { |
| output = parseOutput(tempEl, def); |
| messageOrder.add(Constants.ELEM_OUTPUT); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_FAULT, tempEl)) |
| { |
| faults.add(parseFault(tempEl, def)); |
| } |
| else |
| { |
| // operation allows extensibility elements |
| extElements.add(parseExtensibilityElement(Operation.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| if (name != null) |
| { |
| String inputName = (input != null ? input.getName() : null); |
| String outputName = (output != null ? output.getName() : null); |
| |
| boolean opDefined = false; |
| |
| try |
| { |
| |
| //op = portType.getOperation(name, inputName, outputName); |
| |
| //Operation op = null; |
| List operations = portType.getOperations(); |
| if (operations != null) |
| { |
| |
| Iterator iOperations = operations.iterator(); |
| while (iOperations.hasNext()) |
| { |
| boolean inputNamesEqual = false; |
| boolean outputNamesEqual = false; |
| Operation oper = (Operation)iOperations.next(); |
| if (oper.getName().equals(name)) |
| { |
| Input opInput = oper.getInput(); |
| if (opInput != null && input != null) |
| { |
| String opInputName = opInput.getName(); |
| if (opInputName != null && inputName != null && opInputName.equals(inputName)) |
| { |
| inputNamesEqual = true; |
| } |
| else if (opInputName == null && inputName == null) |
| { |
| inputNamesEqual = true; |
| } |
| } |
| else if (opInput == null && input == null) |
| { |
| inputNamesEqual = true; |
| } |
| Output opOutput = oper.getOutput(); |
| if (opOutput != null && output != null) |
| { |
| String opOutputName = opOutput.getName(); |
| if (opOutputName != null && outputName != null && opOutputName.equals(outputName)) |
| { |
| outputNamesEqual = true; |
| } |
| else if (opOutputName == null && outputName == null) |
| { |
| outputNamesEqual = true; |
| } |
| } |
| else if (opOutput == null && output == null) |
| { |
| outputNamesEqual = true; |
| } |
| if (inputNamesEqual && outputNamesEqual) |
| { |
| op = oper; |
| break; |
| } |
| } |
| } |
| } |
| } |
| catch (Exception e) |
| { |
| opDefined = true; |
| } |
| |
| if (op != null /*&& !op.isUndefined()*/ |
| ) |
| { |
| //op = null; |
| opDefined = true; |
| |
| } |
| |
| if (op != null && !opDefined) |
| { |
| if (inputName == null) |
| { |
| Input tempIn = op.getInput(); |
| |
| if (tempIn != null) |
| { |
| if (tempIn.getName() != null) |
| { |
| //op = null; |
| opDefined = true; |
| } |
| } |
| } |
| } |
| |
| if (op != null && !opDefined) |
| { |
| if (outputName == null) |
| { |
| Output tempOut = op.getOutput(); |
| |
| if (tempOut != null) |
| { |
| if (tempOut.getName() != null) |
| { |
| //op = null; |
| opDefined = true; |
| } |
| } |
| } |
| } |
| |
| if (opDefined) |
| { |
| // instead of creating a new one with the same name we're going to return null. |
| // According to the WSDL 1.2 working draft operation overloading is no longer allowed. |
| // Going to use that here to save a lot of work |
| setLocation(op, opEl); |
| addReaderError( |
| portType, |
| op, |
| messagegenerator.getString( |
| "_DUPLICATE_OPERATION_FOR_PORTTYPE", |
| "'" + op.getName() + "'", |
| "'" + portType.getQName().getLocalPart() + "'")); |
| return null; |
| } |
| if (op == null) |
| { |
| op = def.createOperation(); |
| op.setName(name); |
| |
| } |
| } |
| else |
| { |
| op = def.createOperation(); |
| } |
| |
| // Whether it was retrieved or created, the definition has been found. |
| op.setUndefined(false); |
| |
| if (parameterOrderStr != null) |
| { |
| op.setParameterOrdering(StringUtils.parseNMTokens(parameterOrderStr)); |
| } |
| |
| if (docEl != null) |
| { |
| op.setDocumentationElement(docEl); |
| } |
| |
| if (input != null) |
| { |
| op.setInput(input); |
| } |
| |
| if (output != null) |
| { |
| op.setOutput(output); |
| } |
| |
| if (faults.size() > 0) |
| { |
| Iterator faultIterator = faults.iterator(); |
| |
| while (faultIterator.hasNext()) |
| { |
| Fault f = (Fault)faultIterator.next(); |
| // if the fault isn't defined yet |
| if (op.getFault(f.getName()) == null) |
| { |
| op.addFault(f); |
| } |
| else |
| { |
| addReaderError( |
| op, |
| f, |
| messagegenerator.getString("_DUPLICATE_FAULT_NAME", "'" + f.getName() + "'", "'" + op.getName() + "'")); |
| //faultErrors.add(new Object[]{f,"Duplicate Name",op}); |
| } |
| } |
| } |
| |
| if (extElements.size() > 0) |
| { |
| Iterator extElementsIterator = extElements.iterator(); |
| while (extElementsIterator.hasNext()) |
| { |
| op.addExtensibilityElement((ExtensibilityElement)extElementsIterator.next()); |
| } |
| } |
| |
| OperationType style = null; |
| |
| if (messageOrder.equals(STYLE_ONE_WAY)) |
| { |
| style = OperationType.ONE_WAY; |
| } |
| else if (messageOrder.equals(STYLE_REQUEST_RESPONSE)) |
| { |
| style = OperationType.REQUEST_RESPONSE; |
| } |
| else if (messageOrder.equals(STYLE_SOLICIT_RESPONSE)) |
| { |
| style = OperationType.SOLICIT_RESPONSE; |
| } |
| else if (messageOrder.equals(STYLE_NOTIFICATION)) |
| { |
| style = OperationType.NOTIFICATION; |
| } |
| |
| if (style != null) |
| { |
| op.setStyle(style); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(op, opEl); |
| |
| // modified to remove duplicate operations |
| // if(opDefined) |
| // { |
| // addReaderError(portType,op,ValidateWSDLPlugin.getInstance().getString("_DUPLICATE_OPERATION_FOR_PORTTYPE","'"+op.getName()+"'","'"+portType.getQName().getLocalPart()+"'")); |
| // return null; |
| // } |
| return op; |
| } |
| |
| /** |
| * Parse a specific service element. |
| * |
| * @param serviceEl The service element. |
| * @param def The defintions element. |
| * @return A WSDL service element. |
| * @throws WSDLException |
| */ |
| protected Service parseService(Element serviceEl, Definition def) throws WSDLException |
| { |
| Service service = def.createService(); |
| String name = DOMUtils.getAttribute(serviceEl, Constants.ATTR_NAME); |
| |
| if (name != null) |
| { |
| service.setQName(new QName(def.getTargetNamespace(), name)); |
| } |
| Service s; |
| // a service with this name has already been defined |
| if ((s = def.getService(service.getQName())) != null) |
| { |
| addReaderError( |
| def, |
| serviceEl, |
| messagegenerator.getString("_SERVICE_NAME_ALREADY_DEFINED", "'" + s.getQName().getLocalPart() + "'")); |
| return s; |
| } |
| Element tempEl = DOMUtils.getFirstChildElement(serviceEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| service.setDocumentationElement(tempEl); |
| } |
| else if (QNameUtils.matches(Constants.Q_ELEM_PORT, tempEl)) |
| { |
| service.addPort(parsePort(tempEl, def)); |
| } |
| else |
| { |
| service.addExtensibilityElement(parseExtensibilityElement(Service.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(service, serviceEl); |
| |
| return service; |
| } |
| |
| /** |
| * Parse a specific port element. |
| * |
| * @param portEl The port element. |
| * @param def The definitions element. |
| * @return A WSDL port element. |
| * @throws WSDLException |
| */ |
| protected Port parsePort(Element portEl, Definition def) throws WSDLException |
| { |
| Port port = def.createPort(); |
| String name = DOMUtils.getAttribute(portEl, Constants.ATTR_NAME); |
| QName bindingStr; |
| try |
| { |
| bindingStr = DOMUtils.getQualifiedAttributeValue(portEl, Constants.ATTR_BINDING, Constants.ELEM_PORT, false, def); |
| } |
| catch (Exception e) |
| { |
| //the call above fails if there is no qualified namespace for the message name |
| bindingStr = new QName(null, DOMUtils.getAttribute(portEl, "binding")); |
| } |
| |
| if (name != null) |
| { |
| port.setName(name); |
| } |
| |
| if (bindingStr != null) |
| { |
| Binding binding = def.getBinding(bindingStr); |
| |
| if (binding == null) |
| { |
| binding = def.createBinding(); |
| binding.setQName(bindingStr); |
| def.addBinding(binding); |
| } |
| |
| port.setBinding(binding); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(portEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| port.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| port.addExtensibilityElement(parseExtensibilityElement(Port.class, tempEl, def)); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(port, portEl); |
| |
| return port; |
| } |
| |
| /** |
| * Parse a specific extensibility element. |
| * |
| * @param parentType The parent type of the extensibility element. |
| * @param el The extensibility element. |
| * @param def The definitions element. |
| * @return A WSDL extensibility element. |
| * @throws WSDLException |
| */ |
| protected ExtensibilityElement parseExtensibilityElement(Class parentType, Element el, Definition def) |
| throws WSDLException |
| { |
| QName elementType = QNameUtils.newQName(el); |
| |
| try |
| { |
| ExtensionRegistry extReg = def.getExtensionRegistry(); |
| |
| if (extReg == null) |
| { |
| throw new WSDLException( |
| WSDLException.CONFIGURATION_ERROR, |
| "No ExtensionRegistry set for this " |
| + "Definition, so unable to deserialize " |
| + "a '" |
| + elementType |
| + "' element in the " |
| + "context of a '" |
| + parentType.getName() |
| + "'."); |
| } |
| |
| ExtensionDeserializer extDS = extReg.queryDeserializer(parentType, elementType); |
| |
| // asign the ExtensibilityElement to a var so we can add it to the locations |
| ExtensibilityElement extElem = extDS.unmarshall(parentType, elementType, el, def, extReg); |
| // add the location of this element to elementLocations |
| // this might not work properly |
| setLocation(extElem, el); |
| |
| // register all of the child Elements so we can find them later |
| // used for inline schema validation |
| registerChildElements(extElem); |
| |
| return extElem; |
| } |
| catch (WSDLException e) |
| { |
| if (e.getLocation() == null) |
| { |
| e.setLocation(XPathUtils.getXPathExprFromNode(el)); |
| } |
| throw e; |
| } |
| } |
| |
| /** |
| * Parse a specific input element. |
| * |
| * @param inputEl The input element. |
| * @param def The defintions element. |
| * @return A WSDL input element. |
| * @throws WSDLException |
| */ |
| protected Input parseInput(Element inputEl, Definition def) throws WSDLException |
| { |
| |
| Input input = def.createInput(); |
| String name = DOMUtils.getAttribute(inputEl, Constants.ATTR_NAME); |
| QName messageName = null; |
| try |
| { |
| messageName = DOMUtils.getQualifiedAttributeValue(inputEl, Constants.ATTR_MESSAGE, Constants.ELEM_INPUT, false, def); |
| } |
| catch (Exception e) |
| { |
| //the call above fails if there is no qualified namespace for the message name |
| messageName = new QName(null, DOMUtils.getAttribute(inputEl, "message")); |
| } |
| |
| if (name != null) |
| { |
| input.setName(name); |
| } |
| |
| if (messageName != null) |
| { |
| Message message = def.getMessage(messageName); |
| |
| if (message == null) |
| { |
| message = def.createMessage(); |
| message.setQName(messageName); |
| def.addMessage(message); |
| } |
| |
| input.setMessage(message); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(inputEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| input.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| // XML Validation will catch this |
| DOMUtils.throwWSDLException(tempEl); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(input, inputEl); |
| |
| return input; |
| } |
| |
| /** |
| * Parse a specific output element. |
| * |
| * @param outputEl The output element. |
| * @param def The defintions element. |
| * @return A WSDL output element. |
| * @throws WSDLException |
| */ |
| protected Output parseOutput(Element outputEl, Definition def) throws WSDLException |
| { |
| Output output = def.createOutput(); |
| String name = DOMUtils.getAttribute(outputEl, Constants.ATTR_NAME); |
| QName messageName = null; |
| try |
| { |
| messageName = DOMUtils.getQualifiedAttributeValue(outputEl, Constants.ATTR_MESSAGE, Constants.ELEM_OUTPUT, false, def); |
| } |
| catch (Exception e) |
| { |
| //the call above fails if there is no qualified namespace for the message name |
| messageName = new QName(null, DOMUtils.getAttribute(outputEl, "message")); |
| } |
| |
| if (name != null) |
| { |
| output.setName(name); |
| } |
| |
| if (messageName != null) |
| { |
| Message message = def.getMessage(messageName); |
| |
| if (message == null) |
| { |
| message = def.createMessage(); |
| message.setQName(messageName); |
| def.addMessage(message); |
| } |
| |
| output.setMessage(message); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(outputEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| output.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| // XML Validation will catch this |
| DOMUtils.throwWSDLException(tempEl); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(output, outputEl); |
| |
| return output; |
| } |
| |
| /** |
| * Parse a specific fault element. |
| * |
| * @param faultEl The fault element to parse. |
| * @param def The definitions element. |
| * @return A WSDL fault element. |
| * @throws WSDLException |
| */ |
| protected Fault parseFault(Element faultEl, Definition def) throws WSDLException |
| { |
| Fault fault = def.createFault(); |
| String name = DOMUtils.getAttribute(faultEl, Constants.ATTR_NAME); |
| QName messageName = null; |
| try |
| { |
| messageName = DOMUtils.getQualifiedAttributeValue(faultEl, Constants.ATTR_MESSAGE, Constants.ELEM_INPUT, false, def); |
| } |
| catch (Exception e) |
| { |
| //the call above fails if there is no qualified namespace for the message name |
| messageName = new QName(null, DOMUtils.getAttribute(faultEl, "message")); |
| } |
| |
| if (name != null) |
| { |
| fault.setName(name); |
| } |
| |
| if (messageName != null) |
| { |
| Message message = def.getMessage(messageName); |
| |
| if (message == null) |
| { |
| message = def.createMessage(); |
| message.setQName(messageName); |
| def.addMessage(message); |
| } |
| |
| fault.setMessage(message); |
| } |
| |
| Element tempEl = DOMUtils.getFirstChildElement(faultEl); |
| |
| while (tempEl != null) |
| { |
| if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl)) |
| { |
| fault.setDocumentationElement(tempEl); |
| } |
| else |
| { |
| // XML Validation will catch this |
| DOMUtils.throwWSDLException(tempEl); |
| } |
| |
| tempEl = DOMUtils.getNextSiblingElement(tempEl); |
| } |
| |
| // add the location of this element to elementLocations |
| setLocation(fault, faultEl); |
| |
| return fault; |
| } |
| |
| /** |
| * Set the messagegenerator for the reader. |
| * |
| * @param mg The message generator to set. |
| */ |
| public void setMessageGenerator(MessageGenerator mg) |
| { |
| messagegenerator = mg; |
| } |
| |
| /** |
| * Add the refObject to the elementLocation hashtable with the location defined in element. |
| * |
| * @param refObject The object to add. |
| * @param element The element that contains the location information. |
| */ |
| protected void setLocation(Object refObject, Element element) |
| { |
| try |
| { |
| ElementImpl elementImpl = (ElementImpl)element; |
| ElementLocation elementLocation = (ElementLocation)elementImpl.getUserData(); |
| if (elementLocation != null) |
| { |
| |
| elementLocations.put( |
| refObject, |
| new LocationHolder(elementLocation.getLineNumber(), elementLocation.getColumnNumber(), def.getDocumentBaseURI())); |
| } |
| } |
| catch (ClassCastException e) |
| { |
| } |
| } |
| /** |
| * Add a reader error to the list. |
| * |
| * @param parentobject The parent object of the object with the error. |
| * @param object The object with the error. |
| * @param error The error message. |
| */ |
| protected void addReaderError(Object parentobject, Object object, String error) |
| { |
| readerErrors.add(new ReaderError(parentobject, object, error)); |
| } |
| |
| /** |
| * Add a reader warning to the list. |
| * |
| * @param parentobject The parent object of the object with the error. |
| * @param object The object with the error. |
| * @param warning The warning message. |
| */ |
| protected void addReaderWarning(Object parentobject, Object object, String warning) |
| { |
| readerWarnings.add(new ReaderError(parentobject, object, warning)); |
| } |
| |
| /** |
| * Register all of the locations of the child elements of the extensibility |
| * element given. |
| * |
| * @param extElem The extensibility element whose child elements will be registered. |
| */ |
| |
| protected void registerChildElements(ExtensibilityElement extElem) |
| { |
| // only add those that are of type unknown. if they're known they |
| // will take care of themselves |
| if (extElem instanceof UnknownExtensibilityElement) |
| { |
| Element elem = ((UnknownExtensibilityElement)extElem).getElement(); |
| registerChildElementsRecursively(elem); |
| } else if (extElem instanceof Schema) |
| { |
| Element elem = ((Schema)extElem).getElement(); |
| registerChildElementsRecursively(elem); |
| } |
| } |
| |
| /** |
| * Register the location of all of the child elements of elem. |
| * |
| * @param elem The element whose child elements will be registered. |
| */ |
| protected void registerChildElementsRecursively(Element elem) |
| { |
| if (elem instanceof ElementNSImpl) |
| { |
| setLocation(elem, elem); |
| |
| // call the method recursively for each child element |
| NodeList childNodes = elem.getChildNodes(); |
| |
| for (int i = 0; i < childNodes.getLength() || i < 5; i++) |
| { |
| Node n = childNodes.item(i); |
| // we only want nodes that are Elements |
| if (n instanceof Element) |
| { |
| Element child = (Element)n; |
| registerChildElementsRecursively(child); |
| } |
| } |
| } |
| } |
| /** |
| * Check that an element name matches the expected name. |
| * |
| * @param el The element with the name to check. |
| * @param qname The name to check against. |
| * @throws WSDLException |
| */ |
| private static void checkElementName(Element el, QName qname) throws WSDLException |
| { |
| if (!QNameUtils.matches(qname, el)) |
| { |
| WSDLException wsdlExc = new WSDLException(WSDLException.INVALID_WSDL, "Expected element '" + qname + "'."); |
| |
| wsdlExc.setLocation(XPathUtils.getXPathExprFromNode(el)); |
| |
| throw wsdlExc; |
| } |
| } |
| |
| /** |
| * Get the element locations hashtable. |
| * |
| * @return The element locations hashtable. |
| */ |
| public Hashtable getElementLocations() |
| { |
| return elementLocations; |
| } |
| |
| /** |
| * Get the reader errors. |
| * |
| * @return The reader errors. |
| */ |
| public List getReaderErrors() |
| { |
| return readerErrors; |
| } |
| |
| /** |
| * Get reader warnings. |
| * |
| * @return The reader warnings. |
| */ |
| public List getReaderWarnings() |
| { |
| return readerWarnings; |
| } |
| } |