blob: 3879074c83c955ed766dcd9a0d05ce919fe82e2f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2021 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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.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
{
ElementLocation elementLocation = (ElementLocation)element.getUserData(ElementLocation.ID);
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;
}
}