Skip to main content

This CGIT instance is deprecated, and repositories have been moved to Gitlab or Github. See the repository descriptions for specific locations.

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlmandel2005-11-07 07:29:37 +0000
committerlmandel2005-11-07 07:29:37 +0000
commitd702c81d0ff6daf1bd3ccfb9760a83331106008e (patch)
treed09e5ca6da53b201ca75ca3b1cc8e9d1210cfd00 /bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11
parent451e5d5e7454e9c4befcd395dace52aae74d46cc (diff)
downloadwebtools.webservices-d702c81d0ff6daf1bd3ccfb9760a83331106008e.tar.gz
webtools.webservices-d702c81d0ff6daf1bd3ccfb9760a83331106008e.tar.xz
webtools.webservices-d702c81d0ff6daf1bd3ccfb9760a83331106008e.zip
[99731] Separated WSDL validation core and ui.
Diffstat (limited to 'bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11')
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11ValidationInfo.java114
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11Validator.java38
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ImportHolder.java602
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/LocationHolder.java66
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ReaderError.java66
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ValidatorRegistry.java103
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11BasicValidator.java691
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidationInfoImpl.java169
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorController.java420
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorDelegate.java98
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLDocument.java2000
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLReaderImpl.java427
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/http/HTTPValidator.java334
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/mime/MIMEValidator.java47
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/soap/SOAPValidator.java603
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/DOMError.java26
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/FileEntityResolver.java58
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaGenerator.java667
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaValidator.java300
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineXSDResolver.java139
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/SchemaAttributeTable.java104
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/ValidateErrorHandler.java87
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XMLEntityResolverChain.java73
-rw-r--r--bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XSDValidator.java206
24 files changed, 7438 insertions, 0 deletions
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11ValidationInfo.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11ValidationInfo.java
new file mode 100644
index 000000000..0c1bc4ff1
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11ValidationInfo.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.Hashtable;
+
+import org.apache.xerces.xs.XSModel;
+import org.eclipse.wst.wsdl.validation.internal.resolver.URIResolver;
+
+/**
+ * An interface for WSDL 1.1 validation information. Uses an existing
+ * validation info object and provides methods to set and retrieve
+ * schemas and convenience methods for setting errors with objects.
+ */
+public interface IWSDL11ValidationInfo
+{
+ /**
+ * Returns the URI of the file being validated.
+ *
+ * @return The URI of the file being validated.
+ */
+ public String getFileURI();
+
+ /**
+ * Add a schema to the list of schemas available for this WSDL document.
+ *
+ * @param xsModel The schema to add to the list.
+ */
+ public void addSchema(XSModel xsModel);
+
+ /**
+ * Get an array of all the schemas available for this WSDL document.
+ *
+ * @return An array of all the schemas available for this WSDL document.
+ */
+ public XSModel[] getSchemas();
+
+ /**
+ * Clear all the stored schemas.
+ */
+ public void clearSchemas();
+
+ /**
+ * Set the element locations hashtable.
+ *
+ * @param elementLocations The hashtable to set with the element locations.
+ */
+ public void setElementLocations(Hashtable elementLocations);
+
+ /**
+ * Convenience method for extensibly validators to add error messages.
+ *
+ * @param message The error to add.
+ * @param element The object to add the error for.
+ */
+ public void addError(String message, Object element);
+
+ /**
+ * Convenience method for extensibly validators to add error messages.
+ *
+ * @param message The error to add.
+ * @param element The object to add the error for.
+ * @param errorKey The error key for this message
+ * @param messageArguments The strings used to create the message.
+ */
+ public void addError(String message, Object element, String errorKey, Object[] messageArguments);
+
+ /**
+ * Add an error message at the given line and column.
+ *
+ * @param message The error to add.
+ * @param line The line location of the error.
+ * @param column The column location of the error.
+ * @param uri The uri of the file containing the error.
+ */
+ public void addError(String message, int line, int column, String uri);
+
+ /**
+ * Convenience method for extensibly validators to add warning messages.
+ *
+ * @param message The warning to add.
+ * @param element The object to add the warning for.
+ */
+ public void addWarning(String message, Object element);
+
+ /**
+ * Add a warning message at the given line and column.
+ *
+ * @param message The warning to add.
+ * @param line The line location of the warning.
+ * @param column The column location of the warning.
+ * @param uri The uri of the file containing the warning.
+ */
+ public void addWarning(String message, int line, int column, String uri);
+
+ /**
+ * Get the URI resolver in use for this validation. The URI resolver
+ * returned is actually a URI resolver handler that will
+ * iterate through all of the registered URI resolvers.
+ *
+ * @return The URI resolver handler.
+ */
+ public URIResolver getURIResolver();
+}
+
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11Validator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11Validator.java
new file mode 100644
index 000000000..a6bd2e23d
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/IWSDL11Validator.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.List;
+import java.util.ResourceBundle;
+
+/**
+ * Interface for a validator plugged into the WSDL 1.1 validator.
+ */
+public interface IWSDL11Validator
+{
+ /**
+ * Validate the given element.
+ *
+ * @param element The element to validate.
+ * @param parents A list of parents of this element.
+ * @param valInfo The current validation information.
+ */
+ public void validate(Object element, List parents, IWSDL11ValidationInfo valInfo);
+
+ /**
+ * Set the resource bundle of the validator.
+ *
+ * @param rb The resource bundle to set.
+ */
+ public void setResourceBundle(ResourceBundle rb);
+
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ImportHolder.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ImportHolder.java
new file mode 100644
index 000000000..205bc9b79
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ImportHolder.java
@@ -0,0 +1,602 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Import;
+import javax.wsdl.WSDLException;
+
+import org.apache.xerces.xs.XSModel;
+import org.eclipse.wst.wsdl.validation.internal.IValidationMessage;
+import org.eclipse.wst.wsdl.validation.internal.resolver.IURIResolutionResult;
+import org.eclipse.wst.wsdl.validation.internal.util.ErrorMessage;
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.XSDValidator;
+import org.eclipse.wst.wsdl.validation.internal.xml.AbstractXMLConformanceFactory;
+import org.eclipse.wst.wsdl.validation.internal.xml.IXMLValidator;
+import org.eclipse.wst.wsdl.validation.internal.xml.XMLCatalogResolver;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+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;
+
+/**
+ * A class to hold and parse an import element.
+ */
+public class ImportHolder implements Comparable
+{
+ private MessageGenerator messagegenerator;
+
+ private WSDLDocument importingWSDLDoc = null;
+ private WSDLDocument wsdlDocument = null;
+ private Definition importingDef = null;
+ private Element importingDocImportElement = null;
+ private String namespace = null;
+ private String location = null;
+ private String classpathURI = null;
+ private String contextURI = null;
+ private int depth;
+ private Element element = null;
+ private List schemas = new ArrayList();
+ private boolean isWSDLFileImport = true;
+ private boolean importInvalid = false;
+ private Import importDef = null;
+ private IWSDL11ValidationInfo valinfo;
+
+ /**
+ * Constructor.
+ *
+ * @param namespace The namespace of the import.
+ * @param location The location of the import.
+ * @param contextURI The context URI for resolving the import location.
+ * @param wsdlDoc The WSDLDocument that contains the import.
+ * @param depth The depth of the import.
+ * @param importingDocImportElement The element representing the import in the encapsulating WSDLDocument.
+ * @param messagegenerator A messagegenerator for obtaining strings.
+ * @param valinfo The WSDL11ValidationInfo for reporting messages.
+ */
+ public ImportHolder(String namespace, String location, String contextURI, WSDLDocument importingWSDLDoc, int depth, Element importingDocImportElement, MessageGenerator messagegenerator, IWSDL11ValidationInfo valinfo)
+ {
+ this.messagegenerator = messagegenerator;
+ this.valinfo = valinfo;
+ this.importingWSDLDoc = importingWSDLDoc;
+ if(importingWSDLDoc != null)
+ {
+ this.importingDef = importingWSDLDoc.getDefinition();
+ }
+ this.importingDocImportElement = importingDocImportElement;
+ this.depth = depth;
+ this.namespace = namespace;
+ this.location = location;
+
+ // Allow WSDL imports to have no location attribute even though it is required.
+ // Schema will normally catch the problem but this allows users to override the
+ // schema and have the validator run.
+ if (this.location == null)
+ {
+ this.location = namespace;
+ }
+ this.contextURI = contextURI;
+
+ this.location = this.location.replace('\\','/');
+ IURIResolutionResult classpathURI = valinfo.getURIResolver().resolve(this.contextURI, this.namespace, this.location);
+ if(classpathURI.getLogicalLocation() != null)
+ {
+ this.location = classpathURI.getLogicalLocation();
+ }
+ if(classpathURI.getPhysicalLocation() != null)
+ {
+ this.classpathURI = classpathURI.getPhysicalLocation();
+ this.contextURI = null;
+ }
+ }
+
+ public void initialize()
+ {
+ Element documentElement = null;
+ try
+ {
+ documentElement = getElement();
+ }
+ catch(WSDLException e)
+ {
+ }
+ if(documentElement != null)
+ {
+ // Handle WSDL imports.
+ if (QNameUtils.matches(Constants.Q_ELEM_DEFINITIONS, documentElement))
+ {
+ if(isXMLValid(this.classpathURI))
+ {
+ try
+ {
+ wsdlDocument = new WSDLDocument(this.location, documentElement, this.depth, this.messagegenerator, this.valinfo);
+ createWSDLImport(wsdlDocument);
+ }
+ catch(WSDLException e)
+ {
+ valinfo.addError(messagegenerator.getString("_UNABLE_TO_IMPORT_BAD_LOCATION", "'" + importDef.getLocationURI() + "'"), importingDocImportElement);
+ }
+ }
+ }
+ // Handle schema imports.
+ else if (QNameUtils.matches(Constants.Q_ELEM_XSD_2001, documentElement))
+ {
+ createXSDImport();
+ }
+ }
+ }
+
+ protected boolean isXMLValid(String uri)
+ {
+ IXMLValidator xmlValidator = AbstractXMLConformanceFactory.getInstance().getXMLValidator();
+ xmlValidator.setFile(uri);
+ //xmlValidator.setValidationInfo(valInfo);
+ xmlValidator.run();
+ // if there are no xml conformance problems go on to check the wsdl stuff
+ if (xmlValidator.hasErrors())
+ {
+ // temp handling of XML errors until validator is updated.
+ List errors = xmlValidator.getErrors();
+ Iterator errorsIter = errors.iterator();
+ while (errorsIter.hasNext())
+ {
+ IValidationMessage valMes = (IValidationMessage)errorsIter.next();
+ valinfo.addError(valMes.getMessage(), valMes.getLine(), valMes.getColumn(), valMes.getURI());
+ }
+ importInvalid = true;
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Get the importing WSDLDocument.
+ *
+ * @return The importing WSDLDocument.
+ */
+ public WSDLDocument getImportingDocument()
+ {
+ return importingWSDLDoc;
+ }
+
+ /**
+ * Get the WSDL document this import represents.
+ *
+ * @return The WSDL document this import represents.
+ */
+ public WSDLDocument getWSDLDocument()
+ {
+ return wsdlDocument;
+ }
+
+ /**
+ * Get the namespace.
+ *
+ * @return The namespace.
+ */
+ public String getNamespace()
+ {
+ return namespace;
+ }
+
+ /**
+ * Get the location.
+ *
+ * @return The location.
+ */
+ public String getLocation()
+ {
+ return location;
+ }
+
+ /**
+ * Get the context URI.
+ *
+ * @return The context URI.
+ */
+ public String getContextURI()
+ {
+ return contextURI;
+ }
+
+ /**
+ * Get the depth in the WSDL tree.
+ *
+ * @return The depth in the WSDL tree.
+ */
+ public int getDepth()
+ {
+ return depth;
+ }
+
+ /**
+ * Get the containing defintions element.
+ *
+ * @return The containing definitions element.
+ */
+ public Definition getImportingDefinition()
+ {
+ return importingDef;
+ }
+
+ /**
+ * Get the element for this import.
+ *
+ * @return The element for this import.
+ * @throws WSDLException
+ */
+ public Element getElement() throws WSDLException
+ {
+ if(element != null)
+ {
+ return element;
+ }
+
+ String locationURI = location;
+ String namespaceURI = namespace;
+ //Import importDef = importingDef.createImport();
+
+ // Allow locating WSDL documents using any registered URI resolver.
+ //String classpathURI = URIResolver.getInstance().resolve(contextURI, namespaceURI, locationURI);
+// if (!classpathURI.equals(locationURI))
+// {
+// locationURI = classpathURI;
+// contextURI = null;
+// }
+ Reader reader = null;
+ if (locationURI != null)
+ {
+ try
+ {
+ //String contextURI = def.getDocumentBaseURI();
+ //Definition importedDef = null;
+
+ InputSource inputSource = null;
+ URL url = null;
+
+
+ URL contextURL = (contextURI != null) ? StringUtils.getURL(null, contextURI) : null;
+
+ url = StringUtils.getURL(contextURL, locationURI);
+
+ // Handle file:// urls. The correct format should be file:/// or file:/.
+ String urlAuthority = url.getAuthority();
+ String urlProtocol = url.getProtocol();
+ if(urlAuthority !=null && urlProtocol.equalsIgnoreCase("file") && !urlAuthority.equals(""))
+ {
+ url = new URL(urlProtocol,"","/" + urlAuthority + url.getFile());
+ }
+
+ String urlString = url.toString();
+ // Test for case sensitivity on local files.
+ if(urlString.startsWith("file:"))
+ {
+ File testfile = new File(url.getFile());
+ String testfileString = testfile.getAbsolutePath();
+ String canonicalfileString = testfile.getCanonicalPath();
+
+ if (!testfileString.equals(canonicalfileString))
+ {
+ if (!String.valueOf(testfileString.charAt(0)).equalsIgnoreCase
+ (String.valueOf(canonicalfileString.charAt(0)))
+ || !testfileString.substring(1,testfileString.length()).equals
+ (canonicalfileString.substring(1,canonicalfileString.length())))
+ {
+ urlString = "";
+ url = null;
+ }
+ }
+ }
+ if(url != null)
+ {
+ try
+ {
+ reader = StringUtils.getContentAsReader(url);
+ }
+ catch(IOException e)
+ {
+ // No need to do anything here. The error will be handled below.
+ }
+ }
+ if (reader != null)
+ {
+ inputSource = new InputSource(reader);
+ if(classpathURI != null && !classpathURI.equals(location))
+ {
+ inputSource.setByteStream(new URL(classpathURI).openStream());
+ }
+ }
+
+ if (inputSource == null)
+ {
+ // Get the actual location from the element.
+ String actualLocation = DOMUtils.getAttribute(importingDocImportElement, Constants.ATTR_LOCATION);
+ if(actualLocation == null)
+ {
+ actualLocation = DOMUtils.getAttribute(importingDocImportElement, "schemaLocation");
+ }
+ if(actualLocation == null)
+ {
+ actualLocation = namespace;
+ }
+ importingWSDLDoc.addReaderWarning(
+ importingDef,
+ importingDocImportElement,
+ messagegenerator.getString("_UNABLE_TO_IMPORT_BAD_LOCATION", "'" + actualLocation + "'"));
+ importInvalid = true;
+
+ // TODO: modify the reader error to show in all the correct locations.
+ throw new WSDLException(
+ WSDLException.OTHER_ERROR,
+ "Unable to locate imported document "
+ + "at '"
+ + locationURI
+ + "'"
+ + (contextURI == null ? "." : ", relative to '" + contextURI + "'."));
+ }
+ Document doc = null;
+ try
+ {
+ doc = WSDLReaderImpl.getDocument(inputSource, locationURI);
+ }
+ catch(WSDLException e)
+ {
+ // The File is invalid and cannot be read.
+ // Perform XML validation.
+ isXMLValid(locationURI);
+// importingWSDLDoc.addReaderError(
+// importingDef,
+// importingDocImportElement,
+// messagegenerator.getString("_UNABLE_TO_IMPORT_INVALID", "'" + location + "'"));
+ throw e;
+ }
+ element = doc.getDocumentElement();
+ if(!QNameUtils.matches(Constants.Q_ELEM_DEFINITIONS, element))
+ {
+ isWSDLFileImport = false;
+ }
+ // Ensure that the imported document has the same namespace as the import element states.
+ String importTargetNS = element.getAttribute(Constants.ATTR_TARGET_NAMESPACE);
+ if(!importTargetNS.equals(namespace))
+ {
+ importingWSDLDoc.addReaderWarning(
+ importingDef,
+ importingDocImportElement,
+ messagegenerator.getString("_WARN_WRONG_NS_ON_IMPORT", "'" + namespace + "'", "'" + importTargetNS + "'"));
+ element = null;
+ importInvalid = true;
+ }
+ }
+
+ catch(Exception e)
+ {
+ }
+ finally
+ {
+ if(reader != null)
+ {
+ try
+ {
+ reader.close();
+ }
+ catch(IOException e)
+ {}
+ }
+ }
+
+ }
+ return element;
+ }
+
+ /**
+ * Create an import element for a WSDL import of a WSDL document.
+ *
+ * @param wsdlDocument The document of the import.
+ * @return The newly created import element.
+ */
+ public Import createWSDLImport(WSDLDocument wsdlDocument)
+ {
+ if(importDef != null)
+ {
+ return importDef;
+ }
+ importDef = getNewImport();
+
+ if (importDef != null)
+ {
+ importDef.setDefinition(wsdlDocument.getDefinition());
+ schemas.addAll(wsdlDocument.getSchemas());
+ importingWSDLDoc.addSchemas(schemas);
+ }
+
+ return importDef;
+ }
+
+ /**
+ * Create an import element for a WSDL import of a schema import of a schema document.
+ *
+ * @return The newly created import element.
+ */
+ public Import createXSDImport()
+ {
+ if(importDef != null)
+ {
+ return importDef;
+ }
+ importDef = getNewImport();
+ XSDValidator xsdvalidator = new XSDValidator();
+
+ xsdvalidator.validate(location, XMLCatalogResolver.getInstance());
+ if (xsdvalidator.isValid())
+ {
+ XSModel schema = xsdvalidator.getXSModel();
+ if (schema != null)
+ {
+ schemas.add(schema);
+ }
+ }
+ else
+ {
+ // addReaderWarning(
+// def,
+// importDef,
+// messagegenerator.getString("_UNABLE_TO_IMPORT_INVALID", "'" + importDef.getLocationURI() + "'"));
+ Iterator errors = xsdvalidator.getErrors().iterator();
+ while (errors.hasNext())
+ {
+ ErrorMessage err = (ErrorMessage) errors.next();
+ String uri = err.getURI();
+ int line = err.getErrorLine();
+ String errmess = err.getErrorMessage();
+ valinfo.addError(errmess, line, err.getErrorColumn(), uri);
+ }
+ }
+ importingWSDLDoc.addSchemas(schemas);
+ return importDef;
+ }
+
+ /**
+ * Get the import element if it has been created.
+ *
+ * @return The import element if it has been created or null.
+ */
+ public Import getImport()
+ {
+ return importDef;
+ }
+
+ /**
+ * Get a new import element.
+ *
+ * @return A new import element.
+ */
+ private Import getNewImport()
+ {
+ if(importInvalid)
+ {
+ return null;
+ }
+ Import importDef = importingDef.createImport();
+
+ if (namespace != null)
+ {
+ importDef.setNamespaceURI(namespace);
+ }
+
+ if (location != null)
+ {
+ importDef.setLocationURI(location);
+ }
+
+ if(element != null)
+ {
+ Element tempEl = DOMUtils.getFirstChildElement(element);
+
+ while (tempEl != null)
+ {
+ if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl))
+ {
+ importDef.setDocumentationElement(tempEl);
+ }
+
+ tempEl = DOMUtils.getNextSiblingElement(tempEl);
+ }
+ }
+
+ return importDef;
+ }
+
+ /**
+ * Get the schemas corresponding to this import.
+ *
+ * @return The schemas corresponding to this import.
+ */
+ public List getSchemas()
+ {
+ return schemas;
+ }
+
+ /**
+ * Returns true if this import imports a WSDL document, false otherwise.
+ *
+ * @return True if this import imports a WSDL document, false otherwise.
+ */
+ public boolean isWSDLFileImport()
+ {
+ return isWSDLFileImport;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj)
+ {
+ if(obj.getClass() == ImportHolder.class)
+ {
+ ImportHolder otherImport = (ImportHolder)obj;
+
+ if(getNamespace().equals(otherImport.getNamespace()) && getLocation().equals(otherImport.getLocation()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Object obj)
+ {
+ if(obj == null)
+ {
+ throw new NullPointerException();
+ }
+
+ ImportHolder otherImport = (ImportHolder)obj;
+
+ return (getNamespace()+getLocation()).compareTo((otherImport.getNamespace()+otherImport.getLocation()));
+ }
+
+ /**
+ * Set the messagegenerator for the import holder.
+ *
+ * @param mg The message generator to set.
+ */
+ public void setMessageGenerator(MessageGenerator mg)
+ {
+ messagegenerator = mg;
+ }
+
+ /**
+ * Return true if the import is invalid, false otherwise.
+ *
+ * @return True if the import is invalid, false otherwise.
+ */
+ public boolean isImportInvalid()
+ {
+ return importInvalid;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/LocationHolder.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/LocationHolder.java
new file mode 100644
index 000000000..1def333f9
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/LocationHolder.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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;
+
+/**
+ * Holds the location information for an element in a document.
+ */
+public class LocationHolder
+{
+ private int line;
+ private int column;
+ private String uri;
+
+ /**
+ * Constructor.
+ *
+ * @param line The line number.
+ * @param column The column number.
+ * @param uri The URI of the document.
+ */
+ public LocationHolder(int line, int column, String uri)
+ {
+ this.line = line;
+ this.column = column;
+ this.uri = uri;
+ }
+
+ /**
+ * Get the line number.
+ *
+ * @return The line number.
+ */
+ public int getLine()
+ {
+ return line;
+ }
+
+ /**
+ * Get the column number.
+ *
+ * @return The column number.
+ */
+ public int getColumn()
+ {
+ return column;
+ }
+
+ /**
+ * Get the file URI.
+ *
+ * @return The file URI.
+ */
+ public String getURI()
+ {
+ return uri;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ReaderError.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ReaderError.java
new file mode 100644
index 000000000..36b4e44dc
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ReaderError.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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;
+
+/**
+ * Holds an error created when reading a WSDL document.
+ */
+public class ReaderError
+{
+ protected Object parentObject; // the object of the parent of the object with the error
+ protected Object object; // the object the error is associated with
+ protected String error; // the error associated with the object
+
+ /**
+ * Constructor.
+ *
+ * @param parentObject the parent object of the object with the error
+ * @param object the object with the error
+ * @param error the error
+ */
+ public ReaderError(Object parentObject, Object object, String error)
+ {
+ this.parentObject = parentObject;
+ this.object = object;
+ this.error = error;
+ }
+
+ /**
+ * Returns the parent object of the object with the error.
+ *
+ * @return the parent object of the object with the error
+ */
+ public Object getParentObject()
+ {
+ return parentObject;
+ }
+
+ /**
+ * Returns the object with the error.
+ *
+ * @return the object with the error
+ */
+ public Object getObject()
+ {
+ return object;
+ }
+
+ /**
+ * Returns the error message.
+ *
+ * @return the error message
+ */
+ public String getError()
+ {
+ return error;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ValidatorRegistry.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ValidatorRegistry.java
new file mode 100644
index 000000000..90564f483
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/ValidatorRegistry.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.Hashtable;
+import java.util.Map;
+
+
+/**
+ * A registry to hold all the WSDL 1.1 validators.
+ */
+public class ValidatorRegistry
+{
+
+ protected static ValidatorRegistry verInstance;
+
+ protected Map validatorReg = new Hashtable();
+
+ /**
+ * Constructor.
+ */
+ protected ValidatorRegistry()
+ {
+ }
+
+ /**
+ * Returns the instance of this registry.
+ *
+ * @return The instance of this registry.
+ */
+ public static ValidatorRegistry getInstance()
+ {
+ if (verInstance == null)
+ {
+ verInstance = new ValidatorRegistry();
+ }
+ return verInstance;
+ }
+
+ /**
+ * Register this validator delegate with the given namespace.
+ *
+ * @param namespace The namespace the validator is associated with.
+ * @param valDelegate The validator delegate to register.
+ */
+ public void registerValidator(String namespace, WSDL11ValidatorDelegate valDelegate)
+ {
+ // allow the null namespace but make it the empty string
+ if (namespace == null)
+ {
+ namespace = "";
+ }
+
+ // add the validator to the hashtable
+ validatorReg.put(namespace, valDelegate);
+ }
+
+ /**
+ * Ask for the validator associated with this namespace. If none is found
+ * return null.
+ *
+ * @param namespace The namespace of the validator.
+ * @return The WSDL 1.1 validator for the given namespace.
+ */
+ public IWSDL11Validator queryValidatorRegistry(String namespace)
+ {
+ // if the namespace is null allow it and treat it as the empty string
+ if (namespace == null)
+ {
+ namespace = "";
+ }
+ WSDL11ValidatorDelegate delegate = (WSDL11ValidatorDelegate)validatorReg.get(namespace);
+ if(delegate != null)
+ {
+ return delegate.getValidator();
+ }
+ return null;
+ }
+
+ /**
+ * Convenience method that tells whether a validator for a given namespace is registered.
+ *
+ * @param namespace The namespace to check.
+ * @return True if there is a validator registered, false otherwise.
+ */
+ public boolean hasRegisteredValidator(String namespace)
+ {
+ if (queryValidatorRegistry(namespace) != null)
+ {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11BasicValidator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11BasicValidator.java
new file mode 100644
index 000000000..4d7b0c238
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11BasicValidator.java
@@ -0,0 +1,691 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+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.Output;
+import javax.wsdl.Part;
+import javax.wsdl.Port;
+import javax.wsdl.PortType;
+import javax.wsdl.Service;
+import javax.wsdl.Types;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.xml.namespace.QName;
+
+import org.apache.xerces.xs.XSModel;
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.SchemaAttributeTable;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.XSDValidator;
+
+import com.ibm.wsdl.Constants;
+/**
+ * Validate the elements defined in a WSDL 1.1 Document.
+ */
+public class WSDL11BasicValidator implements IWSDL11Validator
+{
+ protected final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
+ protected final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
+ protected final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
+ protected final String SCHEMA_FULL_CHECKING_FEATURE_ID =
+ "http://apache.org/xml/features/validation/schema-full-checking";
+ protected final String CONTINUE_AFTER_FATAL_ERROR_ID = "http://apache.org/xml/features/continue-after-fatal-error";
+ protected final String SOAP_ENCODING_URI = "http://schemas.xmlsoap.org/soap/encoding/";
+
+ // Error and Warning Keys
+ private final String _PORT_NAME_NOT_UNIQUE = "_PORT_NAME_NOT_UNIQUE";
+ private final String _NO_BINDING_FOR_PORT = "_NO_BINDING_FOR_PORT";
+ private final String _NO_ADDRESS_PORT = "_NO_ADDRESS_PORT";
+ private final String _MORE_THEN_ONE_ADDRESS_PORT = "_MORE_THEN_ONE_ADDRESS_PORT"; //TODO should be _MORE_THAN_ONE_ADDRESS_PORT, not THEN
+ private final String _PORTTYPE_UNDEFINED_FOR_BINDING = "_PORTTYPE_UNDEFINED_FOR_BINDING";
+ private final String _OPERATION_UNDEFINED_FOR_PORTTYPE = "_OPERATION_UNDEFINED_FOR_PORTTYPE";
+ private final String _OPERATION_NO_INPUT_OR_OUTPUT = "_OPERATION_NO_INPUT_OR_OUTPUT";
+ private final String _INPUT_NAME_NOT_UNIQUE = "_INPUT_NAME_NOT_UNIQUE";
+ private final String _MESSAGE_UNDEFINED_FOR_INPUT = "_MESSAGE_UNDEFINED_FOR_INPUT";
+ private final String _OUTPUT_NAME_NOT_UNIQUE = "_OUTPUT_NAME_NOT_UNIQUE";
+ private final String _MESSAGE_UNDEFINED_FOR_OUTPUT = "_MESSAGE_UNDEFINED_FOR_OUTPUT";
+ private final String _MESSAGE_UNDEFINED_FOR_FAULT = "_MESSAGE_UNDEFINED_FOR_FAULT";
+ private final String _PART_NO_ELEMENT_OR_TYPE = "_PART_NO_ELEMENT_OR_TYPE";
+ private final String _PART_BOTH_ELEMENT_AND_TYPE = "_PART_BOTH_ELEMENT_AND_TYPE";
+ private final String _PART_INVALID_ELEMENT = "_PART_INVALID_ELEMENT";
+ private final String _PART_INVALID_TYPE = "_PART_INVALID_TYPE";
+ private final String _WARN_SOAPENC_IMPORTED_PART = "_WARN_SOAPENC_IMPORTED_PART";
+
+ private final int ELEMENT = 0;
+ private final int TYPE = 1;
+
+ private final String REQUEST = "Request";
+ private final String RESPONSE = "Response";
+ private final String QUOTE = "'";
+ private final String EMPTY_STRING = "";
+
+
+ //protected WSDL11ValidatorController validatorcontroller;
+ protected MessageGenerator messagegenerator;
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator#validate(java.lang.Object, java.util.List, org.eclipse.wsdl.validate.wsdl11.IWSDL11ValidationInfo)
+ */
+ public void validate(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ //this.validatorcontroller = validatorcontroller;
+ //setDefaultResourceBundleIfNeeded(validatorcontroller);
+ Definition wsdlDefinition = (Definition)element;
+ //validateTypes(wsdlDefinition, valInfo);
+ validateServices(wsdlDefinition, valInfo);
+ validateBindings(wsdlDefinition, valInfo);
+ validatePortTypes(wsdlDefinition, valInfo);
+ validateMessages(wsdlDefinition, valInfo);
+
+ }
+
+ /**
+ * Takes a list of ExtensibilityElements and checks if there's a validator
+ * associated with each element and if so calls the validator.
+ *
+ * @param parents The list of parents of the elements.
+ * @param extensibilityElements The list of elements to validate.
+ * @param validatorcontroller The validator controller.
+ * @param wsdlDefinition The defnintions element for this document.
+ */
+ protected void validateExtensibilityElementList(
+ List parents,
+ List extensibilityElements,
+ IWSDL11ValidationInfo valInfo)
+ {
+ ValidatorRegistry ver = ValidatorRegistry.getInstance();
+ Iterator extElems = extensibilityElements.iterator();
+ while (extElems.hasNext())
+ {
+ ExtensibilityElement element = (ExtensibilityElement)extElems.next();
+ String namespace = element.getElementType().getNamespaceURI();
+ IWSDL11Validator val = ver.queryValidatorRegistry(namespace);
+ if (val != null)
+ {
+ val.validate(element, parents, valInfo);
+ }
+// else
+// {
+// valInfo.addNamespaceWithNoValidator(namespace);
+// }
+ }
+ }
+
+ /**
+ * If the resourcebundle hasn't been set, set it to the one registered with the ValidatorController.
+ *
+ * @param validatorcontroller The validator controller to get the resource bundle from.
+ */
+ // protected void setDefaultResourceBundleIfNeeded(WSDL11ValidatorController validatorcontroller)
+ // {
+ // if (messagegenerator == null)
+ // {
+ // setResourceBundle(validatorcontroller.getResourceBundle());
+ // }
+ // }
+
+ /**
+ * Set the resourcebundle to the one specified.
+ *
+ * @param rb The resource bundle to set.
+ */
+ public void setResourceBundle(ResourceBundle rb)
+ {
+ messagegenerator = new MessageGenerator(rb);
+ }
+
+ /**
+ * Ensure that the Types element is correct.
+ *
+ * @param wsdlDefinition The definitions element from the current document.
+ */
+
+ protected void validateTypes(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
+ {
+ Types types = wsdlDefinition.getTypes();
+ // ensure that types is defined
+ if (types != null)
+ {
+ List parents = new Vector();
+ parents.add(wsdlDefinition);
+ Object extensibleElements[] = types.getExtensibilityElements().toArray();
+ parents.add(0, types);
+ validateExtensibilityElementList(parents, types.getExtensibilityElements(), valInfo);
+ parents.remove(0);
+ }
+ }
+
+ /**
+ * Validates all of the declared services for the definition.
+ *
+ * @param wsdlDefinition The WSDL definitions element.
+ */
+ protected void validateServices(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
+ {
+ if (wsdlDefinition.getServices() == null)
+ return;
+ Object services[] = wsdlDefinition.getServices().values().toArray();
+ List parents = new Vector();
+ parents.add(wsdlDefinition);
+ Hashtable allPorts = new Hashtable();
+
+ //TODO: check that ports in other imported files don't conflict with ports in this one
+ // // register all of the imported ports
+ // Iterator imports = wsdlDefinition.getImports().values().iterator();
+ // while(imports.hasNext())
+ // {
+ // Iterator impservices = ((Import)imports.next()).getDefinition().getServices().values().iterator();
+ // while(impservices.hasNext())
+ // {
+ // Iterator impports = ((Service)impservices.next()).getPorts().values().iterator();
+ // while(impports.hasNext())
+ // {
+ // Port tempP = (Port)impports.next();
+ // allPorts.put(tempP.getName(),tempP);
+ // }
+ // }
+ // }
+ for (int i = 0; i < services.length; i++)
+ {
+ Service s = (Service)services[i];
+ parents.add(0, s);
+ Object ports[] = s.getPorts().values().toArray();
+ HashSet portInputs = new HashSet();
+ HashSet portOutputs = new HashSet();
+ for (int j = 0; j < ports.length; j++)
+ {
+ Port p = (Port)ports[j];
+ parents.add(0, p);
+ // a Port name must be unique within the entire WDSL document
+ if (allPorts.contains(p.getName()))
+ { String[] args = {p.getName()};
+
+ valInfo.addError(messagegenerator.getString(_PORT_NAME_NOT_UNIQUE, QUOTE + args[0] + QUOTE),
+ p, _PORT_NAME_NOT_UNIQUE, args);
+ }
+ else
+ {
+ allPorts.put(p.getName(), p);
+
+ // get the binding for this port and see if the PortType for the binding
+ // is defined
+ if (p.getBinding() == null || p.getBinding().isUndefined())
+ {
+ String bindingName = EMPTY_STRING;
+ if (p.getBinding() != null)
+ {
+ bindingName = p.getBinding().getQName().getLocalPart();
+ }
+ String args[] = {p.getName()};
+ valInfo.addError(
+ messagegenerator.getString(_NO_BINDING_FOR_PORT, QUOTE + args[0] + QUOTE, QUOTE + bindingName + QUOTE),
+ p, _NO_BINDING_FOR_PORT, args);
+ }
+ else
+ {
+ // TODO: Check that the output of one port isn't the input of another and vice versa
+ // extensibility elements the port
+ // there can only be one and must be one extensibility element defined for a port
+ List extelems = p.getExtensibilityElements();
+ if (extelems.size() < 1)
+ { String args[]= {p.getName()};
+ valInfo.addError(messagegenerator.getString(_NO_ADDRESS_PORT, QUOTE + args[0] + QUOTE),
+ p, _NO_ADDRESS_PORT, args);
+ }
+ else if (extelems.size() > 1)
+ {
+ for (int k = 1; k < extelems.size(); k++)
+ {
+ String[] args = {p.getName()};
+ valInfo.addError(
+ messagegenerator.getString(_MORE_THEN_ONE_ADDRESS_PORT, QUOTE + args[0] + QUOTE),
+ extelems.get(k), _MORE_THEN_ONE_ADDRESS_PORT, args);
+ }
+ }
+ validateExtensibilityElementList(parents, p.getExtensibilityElements(), valInfo);
+ }
+ }
+
+ parents.remove(0);
+ }
+ // extensibility elements for the service
+ validateExtensibilityElementList(parents, s.getExtensibilityElements(), valInfo);
+ parents.remove(0);
+ }
+ }
+
+ /**
+ * Checks that the bindings refer to valid PortTypes and all of the operations
+ // in a given binding refer to a defined operation within the corresponding
+ // PortType.
+ *
+ * @param wsdlDefinition The WSDL definitions element.
+ */
+ protected void validateBindings(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
+ {
+ if (wsdlDefinition.getBindings() == null)
+ return;
+ Object bindings[] = wsdlDefinition.getBindings().values().toArray();
+ List parents = new Vector();
+ parents.add(wsdlDefinition);
+ for (int i = 0; i < bindings.length; i++)
+ {
+ Binding b = (Binding)bindings[i];
+ parents.add(0, b);
+ PortType portType = b.getPortType();
+
+ if (portType == null)
+ {
+ continue;
+ }
+ // the PortType is not defined so don't bother checking the operations
+ if (portType.isUndefined())
+ { String[] args = {portType.getQName().getLocalPart(), b.getQName().getLocalPart()};
+ valInfo.addError(
+ messagegenerator.getString(
+ _PORTTYPE_UNDEFINED_FOR_BINDING,
+ QUOTE + args[0] + QUOTE,
+ QUOTE + args[1] + QUOTE),
+ b, _PORTTYPE_UNDEFINED_FOR_BINDING, args);
+ }
+ else
+ {
+ // the PortType is defined so now we have to check that the operations are defined
+ Object bindingOperations[] = b.getBindingOperations().toArray();
+
+ // check if the operation is defined for each BindingOperation
+ for (int k = 0; k < bindingOperations.length; k++)
+ {
+ BindingOperation bo = (BindingOperation)bindingOperations[k];
+ parents.add(0, bo);
+ if (bo.getOperation() == null || bo.getOperation().isUndefined())
+ {
+ String[] args = {b.getQName().getLocalPart(), portType.getQName().getLocalPart()};
+ valInfo.addError(
+ messagegenerator.getString(
+ _OPERATION_UNDEFINED_FOR_PORTTYPE,
+ QUOTE + args[0] + QUOTE,
+ QUOTE + args[1] + QUOTE),
+ bo, _OPERATION_UNDEFINED_FOR_PORTTYPE, args);
+ // nice idea to add suggestions to other elements to fix the error
+ // but it doesn't work with multipe files like this
+ //addValidationMessage(warningList,portType,portType.getQName().getLocalPart() + "Define an operation here to correspond with the operation in: " + bo.getName());
+ }
+ // take care of all the extensibility elements in the binding operation, binding inputs, outputs and faults
+ else
+ {
+ BindingInput binput = bo.getBindingInput();
+ if (binput != null)
+ {
+ parents.add(0, binput);
+ // extensibility elements for binding operation input
+ validateExtensibilityElementList(
+ parents,
+ bo.getBindingInput().getExtensibilityElements(),
+ valInfo);
+ parents.remove(0);
+ }
+ BindingOutput boutput = bo.getBindingOutput();
+ if (boutput != null)
+ {
+ parents.add(0, boutput);
+ // extensibility elements for binding operation output
+ validateExtensibilityElementList(
+ parents,
+ bo.getBindingOutput().getExtensibilityElements(),
+ valInfo);
+ parents.remove(0);
+ }
+ // no input or output has been defined for the operation
+ if (binput == null && boutput == null)
+ { String[] args = { bo.getName() };
+ valInfo.addError(
+ messagegenerator.getString(_OPERATION_NO_INPUT_OR_OUTPUT, QUOTE + args[0] + QUOTE),
+ bo, _OPERATION_NO_INPUT_OR_OUTPUT, args);
+ }
+ // extensibility elements for each binding operation fault
+ Iterator faults = bo.getBindingFaults().values().iterator();
+ while (faults.hasNext())
+ {
+ BindingFault bf = (BindingFault)faults.next();
+ parents.add(0, bf);
+ validateExtensibilityElementList(parents, bf.getExtensibilityElements(), valInfo);
+ parents.remove(0);
+ }
+ }
+ // extensibility elements for binding operation
+ validateExtensibilityElementList(parents, bo.getExtensibilityElements(), valInfo);
+ parents.remove(0);
+ }
+ }
+ // extensibility elements for the binding
+ validateExtensibilityElementList(parents, b.getExtensibilityElements(), valInfo);
+ parents.remove(0);
+ }
+
+ }
+
+ /**
+ * Check that all of the PortTypes have valid messages associated with their
+ // operation input, output and fault types.
+ *
+ * @param wsdlDefinition The WSDL definitions element.
+ */
+ protected void validatePortTypes(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
+ {
+ if (wsdlDefinition.getPortTypes() == null)
+ return;
+ Object porttypes[] = wsdlDefinition.getPortTypes().values().toArray();
+
+ for (int i = 0; i < porttypes.length; i++)
+ {
+ PortType p = (PortType)porttypes[i];
+ Object operations[] = p.getOperations().toArray();
+ List inAndOutNames = new Vector();
+ for (int j = 0; j < operations.length; j++)
+ {
+ Operation o = (Operation)operations[j];
+ if (o == null || o.isUndefined())
+ {
+ continue;
+ }
+
+ // check that the messages are defined for the input, output and faults
+ Message m;
+ Input input = o.getInput();
+ if (input != null)
+ {
+ String inputName = input.getName();
+ // if the name isn't defined it defaults to this
+ if (inputName == null)
+ {
+ inputName = o.getName() + REQUEST;
+ }
+ if (inAndOutNames.contains(inputName))
+ { String[] args = {inputName, p.getQName().getLocalPart() };
+ valInfo.addError(
+ messagegenerator.getString(
+ _INPUT_NAME_NOT_UNIQUE,
+ QUOTE + args[0] + QUOTE,
+ QUOTE + args[1] + QUOTE),
+ input, _INPUT_NAME_NOT_UNIQUE, args);
+ }
+ else
+ {
+ inAndOutNames.add(inputName);
+ }
+
+ m = input.getMessage();
+ if (m != null && m.isUndefined())
+ {
+ String messName = EMPTY_STRING;
+ QName messQName = m.getQName();
+ if (messQName != null)
+ {
+ messName = messQName.getLocalPart();
+ }
+ String[] args = {messName};
+ valInfo.addError(messagegenerator.getString(_MESSAGE_UNDEFINED_FOR_INPUT, QUOTE + args[0] + QUOTE),
+ input, _MESSAGE_UNDEFINED_FOR_INPUT, args);
+ }
+ }
+ Output output = o.getOutput();
+ if (output != null)
+ {
+ String outputName = output.getName();
+ // if the name isn't defined it defaults to this
+ if (outputName == null)
+ {
+ outputName = o.getName() + RESPONSE;
+ }
+
+ if (inAndOutNames.contains(outputName))
+ {
+ String[] args = {outputName, p.getQName().getLocalPart()};
+
+ valInfo.addError(
+ messagegenerator.getString(
+ _OUTPUT_NAME_NOT_UNIQUE,
+ QUOTE + args[0] + QUOTE,
+ QUOTE + args[1] + QUOTE),
+ output, _OUTPUT_NAME_NOT_UNIQUE, args);
+ }
+ else
+ {
+ inAndOutNames.add(outputName);
+ }
+
+ m = output.getMessage();
+ if (m != null && m.isUndefined())
+ {
+ String messName = EMPTY_STRING;
+ QName messQName = m.getQName();
+ if (messQName != null)
+ {
+ messName = messQName.getLocalPart();
+ }
+ String[] args = {messName};
+ valInfo.addError(messagegenerator.getString(_MESSAGE_UNDEFINED_FOR_OUTPUT, QUOTE + args[0] + QUOTE),
+ output, _MESSAGE_UNDEFINED_FOR_OUTPUT, args);
+ }
+ }
+
+ Object faults[] = o.getFaults().values().toArray();
+
+ //List faultNames = new Vector();
+ for (int k = 0; k < faults.length; k++)
+ {
+ Fault f = (Fault)faults[k];
+ m = f.getMessage();
+ if (m != null && m.isUndefined())
+ {
+ String messName = EMPTY_STRING;
+ QName messQName = m.getQName();
+ if (messQName != null)
+ {
+ messName = messQName.getLocalPart();
+ }
+ String args[] = {messName};
+ valInfo.addError(messagegenerator.getString(_MESSAGE_UNDEFINED_FOR_FAULT, QUOTE + args[0] + QUOTE),
+ f, _MESSAGE_UNDEFINED_FOR_FAULT, args);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Check that all the messages defined in the WSDL document are valid.
+ *
+ * @param wsdlDefinition The WSDL definitions element.
+ */
+ protected void validateMessages(Definition wsdlDefinition, IWSDL11ValidationInfo valInfo)
+ {
+ if (wsdlDefinition.getMessages() == null)
+ return;
+ Iterator messages = wsdlDefinition.getMessages().values().iterator();
+
+ while (messages.hasNext())
+ {
+ Message m = (Message)messages.next();
+ if (!m.isUndefined())
+ {
+ // if the message has a part (and it doesn't have to)
+ // ensure each message part has either an element or a type
+ if (!m.getParts().isEmpty())
+ {
+ Iterator parts = m.getParts().values().iterator();
+ while (parts.hasNext())
+ {
+ Part p = (Part)parts.next();
+ QName elementName = p.getElementName();
+ QName typeName = p.getTypeName();
+ Map extAtts = p.getExtensionAttributes();
+ // TODO:This will have to be extended as parts can have extensibility elements
+ //ensure the part has a type or an element defined
+ if (elementName == null && typeName == null && (extAtts == null || extAtts.isEmpty()))
+ { String[] args = { p.getName()};
+ valInfo.addError(messagegenerator.getString(_PART_NO_ELEMENT_OR_TYPE, QUOTE + args[0] + QUOTE),
+ p, _PART_NO_ELEMENT_OR_TYPE, args);
+ }
+ //here the part has both the element and type defined and it can only have one defined
+ else if (elementName != null && typeName != null)
+ { String[] args = {p.getName()};
+ valInfo.addError(messagegenerator.getString(_PART_BOTH_ELEMENT_AND_TYPE, QUOTE + args[0] + QUOTE),
+ p, _PART_BOTH_ELEMENT_AND_TYPE, args);
+ }
+ else if (elementName != null)
+ {
+ if (!checkPartConstituent(elementName.getNamespaceURI(),
+ elementName.getLocalPart(),
+ ELEMENT,
+ p,
+ valInfo))
+ { String[] args = {p.getName(), elementName.getLocalPart()};
+ valInfo.addError(
+ messagegenerator.getString(
+ _PART_INVALID_ELEMENT,
+ QUOTE + args[0] + QUOTE,
+ QUOTE + args[1] + QUOTE),
+ p, _PART_INVALID_ELEMENT, args);
+ }
+ }
+ else if (typeName != null)
+ {
+ // check that the type itself is defined properly
+ if (!checkPartConstituent(typeName.getNamespaceURI(), typeName.getLocalPart(), TYPE, p, valInfo))
+ { String[] args = {p.getName(), typeName.getLocalPart() };
+ valInfo.addError(
+ messagegenerator.getString(
+ _PART_INVALID_TYPE,
+ QUOTE + args[0] + QUOTE,
+ QUOTE + args[1] + QUOTE),
+ p, _PART_INVALID_TYPE, args);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks whether the given name is defined in the namespace for the part. A part is an
+ * ELEMENT or a TYPE.
+ *
+ * @param namespace The namespace to check.
+ * @param name The name to check.
+ * @param part The part to check, either ELEMENT or TYPE.
+ * @param partObject The object representing the given part.
+ * @return True if the part element of type is defined, false otherwise.
+ */
+ protected boolean checkPartConstituent(
+ String namespace,
+ String name,
+ int part,
+ Part partObject,
+ IWSDL11ValidationInfo valInfo)
+ {
+
+ boolean partvalid = false;
+ // First take care of the situation where it's from the schema namespace.
+ // The 1999, 2000 and 2001 schema namespaces are all accepted.
+ if (namespace.equals(Constants.NS_URI_XSD_2001)
+ || namespace.equals(Constants.NS_URI_XSD_1999)
+ || namespace.equals(Constants.NS_URI_XSD_2000))
+ {
+ SchemaAttributeTable xsdTable = new SchemaAttributeTable();
+ if (xsdTable.containsSymbol(name))
+ {
+ partvalid = true;
+ }
+ }
+ // check inline and imported schema
+ else
+ {
+ XSModel[] schemas = valInfo.getSchemas();
+ int numSchemas = schemas.length;
+ //Iterator schemasIter = schemas.iterator();
+ for (int i = 0; i < numSchemas; i++)
+ {
+ XSModel schema = schemas[i];
+ if (schema != null)
+ {
+ if (part == ELEMENT && schema.getElementDeclaration(name, namespace) != null)
+ {
+ partvalid = true;
+ break;
+ }
+ else if (part == TYPE && schema.getTypeDefinition(name, namespace) != null)
+ {
+ partvalid = true;
+ break;
+ }
+ }
+ }
+ }
+ // If the SOAP encoding namespace hasn't been explicitly imported do so
+ // now.
+ // Allow the SOAP encoding namespace to be automatically imported but mark
+ // it as a warning.
+ if (!partvalid && namespace.equals(SOAP_ENCODING_URI))
+ {
+ try
+ {
+ XSDValidator xsdVal = new XSDValidator();
+ String soapEnc = valInfo.getURIResolver().resolve(null, SOAP_ENCODING_URI, null).getPhysicalLocation();
+ if(soapEnc != null)
+ {
+ xsdVal.validate(soapEnc, null);
+ // sanity check in case something goes wrong
+ if (xsdVal.isValid())
+ {
+ XSModel xsModel = xsdVal.getXSModel();
+
+ if (part == ELEMENT && xsModel.getElementDeclaration(name, namespace) != null)
+ {
+ partvalid = true;
+ }
+ else if (part == TYPE && xsModel.getTypeDefinition(name, namespace) != null)
+ {
+ partvalid = true;
+ }
+ valInfo.addWarning(messagegenerator.getString(_WARN_SOAPENC_IMPORTED_PART, QUOTE + name + QUOTE), partObject);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ //TODO: log the error message
+ //System.out.println(e);
+ }
+ }
+ return partvalid;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidationInfoImpl.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidationInfoImpl.java
new file mode 100644
index 000000000..4b30f0953
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidationInfoImpl.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.xerces.xs.XSModel;
+import org.eclipse.wst.wsdl.validation.internal.IValidationInfo;
+import org.eclipse.wst.wsdl.validation.internal.ValidationInfoImpl;
+import org.eclipse.wst.wsdl.validation.internal.resolver.URIResolver;
+
+/**
+ * An implemenation of WSDL11ValidationInfo.
+ */
+public class WSDL11ValidationInfoImpl implements IWSDL11ValidationInfo
+{
+ private IValidationInfo valinfo = null;
+ private Hashtable elementlocations = null;
+ private List schemas = new Vector();
+
+ public WSDL11ValidationInfoImpl(IValidationInfo valinfo)
+ {
+ this.valinfo = valinfo;
+ }
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#getFileURI()
+ */
+ public String getFileURI()
+ {
+ return valinfo.getFileURI();
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#addSchema(org.apache.xerces.xs.XSModel)
+ */
+ public void addSchema(XSModel xsModel)
+ {
+ if (xsModel != null)
+ {
+ schemas.add(xsModel);
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#getSchemas()
+ */
+ public XSModel[] getSchemas()
+ {
+ return (XSModel[])schemas.toArray(new XSModel[schemas.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.wsdl.validate.wsdl11.WSDL11ValidationInfo#cleardSchemas()
+ */
+ public void clearSchemas()
+ {
+ schemas.clear();
+ }
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#setElementLocations(java.util.Hashtable)
+ */
+ public void setElementLocations(Hashtable elementLocations)
+ {
+ this.elementlocations = elementLocations;
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#addError(java.lang.String, java.lang.Object)
+ */
+ public void addError(String message, Object element)
+ {
+ addError(message, element, null, null);
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#addError(java.lang.String, java.lang.Object, java.lang.String, java.lang.Object[])
+ */
+ public void addError(String message, Object element, String errorKey, Object[] messageArguments)
+ {
+ LocationHolder location;
+ if (elementlocations.containsKey(element))
+ {
+ location = (LocationHolder)elementlocations.get(element);
+ addError(message, location.getLine(), location.getColumn(), location.getURI(), errorKey, messageArguments);
+ }
+ // if we give it an element that hasn't been defined we'll set the location
+ // at (0,0) so the error shows up but no line marker in the editor
+ else
+ {
+ addError(message, 0, 1, getFileURI());
+ }
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#addWarning(java.lang.String, java.lang.Object)
+ */
+ public void addWarning(String message, Object element)
+ {
+ LocationHolder location;
+ if (elementlocations.containsKey(element))
+ {
+ location = (LocationHolder)elementlocations.get(element);
+ addWarning(message, location.getLine(), location.getColumn(), location.getURI());
+ }
+ // if we give it an element that hasn't been defined we'll set the location
+ // at (0,0) so the error shows up but no line marker in the editor
+ else
+ {
+ addWarning(message, 0, 1, getFileURI());
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.wsdl.validate.wsdl11.WSDL11ValidationInfo#addNamespaceWithNoValidator(java.lang.String)
+ */
+// public void addNamespaceWithNoValidator(String namespace)
+// {
+// valinfo.addNamespaceWithNoValidator(namespace);
+//
+// }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#addError(java.lang.String, int, int)
+ */
+ public void addError(String message, int line, int column, String uri)
+ {
+ addError(message, line, column, uri, null, null);
+ }
+
+ public void addError(String message, int line, int column, String uri, String errorKey, Object[] messageArguments)
+ {
+ try
+ { ((ValidationInfoImpl)valinfo).addError(message, line, column, uri, errorKey, messageArguments);
+ }
+ catch (ClassCastException e)
+ { System.err.println(e);
+ valinfo.addError(message, line, column, uri);
+ }
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo#addWarning(java.lang.String, int, int)
+ */
+ public void addWarning(String message, int line, int column, String uri)
+ {
+ valinfo.addWarning(message, line, column, uri);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.wsdl.validate.wsdl11.WSDL11ValidationInfo#getURIResolver()
+ */
+ public URIResolver getURIResolver()
+ {
+ return valinfo.getURIResolver();
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorController.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorController.java
new file mode 100644
index 000000000..aa46e81bb
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorController.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+import javax.wsdl.Definition;
+import javax.wsdl.WSDLException;
+
+import org.apache.xerces.xs.XSModel;
+import org.eclipse.wst.wsdl.validation.internal.IWSDLValidator;
+import org.eclipse.wst.wsdl.validation.internal.IValidationInfo;
+import org.eclipse.wst.wsdl.validation.internal.exception.ValidateWSDLException;
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.w3c.dom.Document;
+
+import com.ibm.wsdl.Constants;
+
+/**
+ * The validator controller is the head of validation.
+ */
+public class WSDL11ValidatorController implements IWSDLValidator
+{
+ protected final String _WARN_NO_VALDIATOR = "_WARN_NO_VALDIATOR";
+// protected final int ERROR_MESSAGE = 0;
+// protected final int WARNING_MESSAGE = 1;
+// protected String fileURI;
+// protected List schemas = new Vector();
+// protected Definition wsdlDefinition;
+ protected MessageGenerator messagegenerator = null;
+ //protected ValidationController validationController;
+ protected ValidatorRegistry ver = ValidatorRegistry.getInstance();
+
+ /**
+ * Constructor.
+ */
+ public WSDL11ValidatorController()
+ {
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.wsdl.validate.IWSDLValidator#validate(org.w3c.dom.Document, org.eclipse.wsdl.validate.ValidationInfo)
+ */
+ public void validate(Document domModel, IValidationInfo valInfo) throws ValidateWSDLException
+ {
+ // reset the variables
+// reset();
+// fileURI = valInfo.getFileURI();
+ //this.validationController = validationcontroller;
+
+ IWSDL11ValidationInfo wsdlvalinfo = new WSDL11ValidationInfoImpl(valInfo);
+ WSDLDocument[] wsdlDocs = readWSDLDocument(domModel, valInfo.getFileURI(), getMessageGenerator(), wsdlvalinfo);
+ // Don't validate an null definitions element. Either the file is emtpy and valid or
+ // had an error when reading.
+ if(wsdlDocs != null)
+ {
+ int numWSDLDocs = wsdlDocs.length;
+ for(int i = 0; i < numWSDLDocs; i++)
+ {
+ WSDLDocument tempDoc = wsdlDocs[i];
+ Definition wsdlDefinition = tempDoc.getDefinition();
+ // Register the schemas.
+ List xsdList = tempDoc.getSchemas();
+ Iterator xsdIter = xsdList.iterator();
+ while (xsdIter.hasNext())
+ {
+ wsdlvalinfo.addSchema((XSModel)xsdIter.next());
+ }
+ // Set the element locations table.
+ wsdlvalinfo.setElementLocations(tempDoc.getElementLocations());
+ // Set any reader errors. This needs to be done after the element locations table is set.
+ List readerErrors = tempDoc.getReaderErrors();
+ if (readerErrors != null)
+ {
+ Iterator readerErrorsI = readerErrors.iterator();
+ while (readerErrorsI.hasNext())
+ {
+ ReaderError re = (ReaderError)readerErrorsI.next();
+ wsdlvalinfo.addError(re.getError(), re.getObject());
+ }
+ }
+ List readerWarnings = tempDoc.getReaderWarnings();
+ if (readerWarnings != null)
+ {
+ Iterator readerWarningsI = readerWarnings.iterator();
+ while (readerWarningsI.hasNext())
+ {
+ ReaderError re = (ReaderError)readerWarningsI.next();
+ wsdlvalinfo.addWarning(re.getError(), re.getObject());
+ }
+ }
+ validateWSDLElement(Constants.NS_URI_WSDL, wsdlDefinition, new Vector(), wsdlvalinfo);
+ wsdlvalinfo.clearSchemas();
+ }
+ }
+
+ }
+
+ /**
+ * Validate an imported WSDL document. Allows the calling class to have access to the internal
+ * components of the validation.
+ *
+ * @param wsdlvalinfo The WSDL 1.1 validation info object to use.
+ * @return The definitions element for the import.
+ * @throws ValidateWSDLException
+ */
+// protected Definition validateImport(WSDL11ValidationInfo wsdlvalinfo)
+// {
+// WSDLDocument[] wsdlDocs = null;
+// try
+// {
+// wsdlDocs = readWSDLDocument(null, wsdlvalinfo.getFileURI(), getMessageGenerator(), wsdlvalinfo);
+// }
+// catch(ValidateWSDLException e)
+// {
+// // supress any validation issues with imported documents
+// }
+// // Don't validate an null definitions element. Either the file is emtpy and valid or
+// // had an error when reading.
+// if(wsdlDocs != null)
+// {
+// validateWSDLElement(Constants.NS_URI_WSDL, wsdlDefinition, new Vector(), wsdlvalinfo);
+// }
+// return wsdlDefinition;
+// }
+
+ /**
+ * Read in the WSDL document and set the model and imported schemas.
+ *
+ * @param domModel A DOM model of the document to be read.
+ * @param file The file to read.
+ * @param messagegenerator The messagegenerator the reader should use for any messages produced.
+ * @param wsdlvalinfo The validation information for the current validation.
+ * @return The definitions element for the WSDL document.
+ * @throws ValidateWSDLException
+ */
+ protected WSDLDocument[] readWSDLDocument(Document domModel, String file, MessageGenerator messagegenerator, IWSDL11ValidationInfo wsdlvalinfo) throws ValidateWSDLException
+ {
+ WSDLDocument[] wsdlDocs = null;
+ try
+ {
+
+ WSDLReaderImpl wsdlReader = new WSDLReaderImpl(wsdlvalinfo);
+ wsdlReader.setMessageGenerator(messagegenerator);
+ if(domModel != null)
+ {
+ wsdlDocs = wsdlReader.readWSDL(file, domModel);
+ }
+ else
+ {
+ wsdlDocs = wsdlReader.readWSDL(file);
+ }
+ //wsdlvalinfo.setElementLocations(wsdlReader.getElementLocationsHashtable());
+// List readerErrors = wsdlReader.getReaderErrors();
+// if (readerErrors != null)
+// {
+// Iterator readerErrorsI = readerErrors.iterator();
+// while (readerErrorsI.hasNext())
+// {
+// ReaderError re = (ReaderError)readerErrorsI.next();
+// wsdlvalinfo.addError(re.getError(), re.getObject());
+// }
+// }
+// if (wsdlReader.hasImportSchemas())
+// {
+// List xsdList = wsdlReader.getImportSchemas();
+// Iterator xsdIter = xsdList.iterator();
+// while (xsdIter.hasNext())
+// {
+// wsdlvalinfo.addSchema((XSModel)xsdIter.next());
+// }
+//
+// }
+
+ }
+ catch (WSDLException e)
+ {
+ throw new ValidateWSDLException(e.getMessage() + " " + e.getFaultCode());
+ }
+
+ catch (Exception e)
+ {
+ throw new ValidateWSDLException("unable to read file" + e.getMessage() + " " + e.toString());
+ }
+ return wsdlDocs;
+ }
+
+ /**
+ * Given a WSDL element, call ValidateElement for it.
+ *
+ * @param namespace The namespace of the element to validate.
+ * @param element The element to validate.
+ * @param parents The list of parents for this element.
+ */
+ public void validateWSDLElement(String namespace, Object element, List parents, IWSDL11ValidationInfo wsdlvalinfo)
+ {
+ IWSDL11Validator val = ver.queryValidatorRegistry(namespace);
+ if (val != null)
+ {
+ val.validate(element, parents, wsdlvalinfo);
+ }
+ else
+ {
+ //TODO: Add this as a preference.
+ //wsdlvalinfo.addWarning(messagegenerator.getString(_WARN_NO_VALDIATOR, namespace), element);
+ }
+ }
+
+ /**
+ * Add a schema to the list of schemas.
+ *
+ * @param xsModel The schema to add.
+ */
+// public void addSchema(XSModel xsModel)
+// {
+// if (xsModel != null)
+// {
+// schemas.add(xsModel);
+// }
+// }
+
+ /**
+ * Return the list containing the schemas.
+ *
+ * @return The list of schemas.
+ */
+// public List getSchemas()
+// {
+// return schemas;
+// }
+
+ /**
+ * Get the ResourceBundle for this ValidatorManager.
+ *
+ * @return The resource bundle registered for this controller.
+ * @see #setResourceBundle
+ */
+// public ResourceBundle getResourceBundle()
+// {
+// return resourcebundle;
+// }
+
+ /**
+ * Set the ResourceBundle for this ValidatorManager.
+ *
+ * @param rb The resource bundle to set.
+ * @see #getResourceBundle
+ */
+ public void setResourceBundle(ResourceBundle rb)
+ {
+ if (messagegenerator == null)
+ {
+ messagegenerator = new MessageGenerator(rb);
+ }
+
+ }
+
+ /**
+ * Set the message generator for this controller.
+ *
+ * @param mesgen The message generator to set for this controller.
+ */
+ public void setMessageGenerator(MessageGenerator mesgen)
+ {
+ messagegenerator = mesgen;
+ }
+
+ /**
+ * Get the message generator registered for this controller.
+ *
+ * @return The message generator registered for this controller.
+ */
+ public MessageGenerator getMessageGenerator()
+ {
+ return messagegenerator;
+ }
+
+ /**
+ * Return the filename for the file currently being validated. Some validators require this.
+ *
+ * @return The filename for the file being validated.
+ */
+// public String getFilename()
+// {
+// return fileURI;
+// }
+
+ /**
+ * Convenience method for extensibly validators to add error messages.
+ *
+ * @param object The object to add the error for.
+ * @param error The error to add.
+ */
+// public void addErrorMessage(Object object, String error)
+// {
+// addValidationMessage(ERROR_MESSAGE, object, error);
+// errors = true;
+// }
+
+ /**
+ * Method for extensibly validators to add error messages when they know
+ * line and column numbers.
+ *
+ * @param line The line where the error message is located.
+ * @param column The column where the error message is located.
+ * @param error The error message.
+ */
+// public void addErrorMessage(int line, int column, String error)
+// {
+// addValidationMessage(ERROR_MESSAGE, line, column, error);
+// errors = true;
+// }
+
+ /**
+ * Convenience method for extensibly validators to add warning messages.
+ *
+ * @param object The object to add the warning message.
+ * @param warning The warning message.
+ */
+// public void addWarningMessage(Object object, String warning)
+// {
+// addValidationMessage(WARNING_MESSAGE, object, warning);
+// }
+
+ /**
+ * Method for extensibly validators to add warning messages when they know
+ * line and column numbers.
+ *
+ * @param line The line where the error message is located.
+ * @param column The column where the error message is located.
+ * @param warning The warning message.
+ */
+// public void addWarningMessage(int line, int column, String warning)
+// {
+// addValidationMessage(WARNING_MESSAGE, line, column, warning);
+// }
+
+ /**
+ * If you have an object read in by the reader for this
+ * validatorcontroller the object can be passed in here and the line and column
+ * information will be abstracted from it.
+ *
+ * @param type The type of message to add.
+ * @param o The object that has the error (used to get the location).
+ * @param message The message to add.
+ */
+// protected void addValidationMessage(int type, Object o, String message)
+// {
+// int[] location;
+// if (elementLocations.containsKey(o))
+// {
+// location = (int[])elementLocations.get(o);
+// }
+// // if we give it an element that hasn't been defined we'll set the location
+// // at (0,0) so the error shows up but no line marker in the editor
+// else
+// {
+// location = new int[] { 0, 0 };
+// }
+// addValidationMessage(type, location[0], location[1], message);
+// }
+
+ /**
+ * Creates a validation message of the specified type.
+ *
+ * @param type The type of validation message to add.
+ * @param line The line where the error message is located.
+ * @param column The line where the column message is located.
+ * @param message The message to add.
+ */
+// protected void addValidationMessage(int type, int line, int column, String message)
+// {
+// if (message != null)
+// {
+// if (type == ERROR_MESSAGE)
+// {
+// validationController.addErrorMessage(line, column, message);
+// }
+// else if (type == WARNING_MESSAGE)
+// {
+// validationController.addWarningMessage(line, column, message);
+// }
+// }
+// }
+
+ /**
+ * @see org.eclipse.wsdl.validate.controller.IWSDLValidator#isValid()
+ */
+// public boolean isValid()
+// {
+// return !errors;
+// }
+
+ /**
+ * Reset the validator controller.
+ */
+// protected void reset()
+// {
+// schemas = new Vector();
+// fileURI = "";
+// wsdlDefinition = null;
+// elementLocations = null;
+// resourcebundle = null;
+// //validationController = null;
+// errors = false;
+// }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorDelegate.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorDelegate.java
new file mode 100644
index 000000000..e627a7812
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDL11ValidatorDelegate.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.Locale;
+import java.util.ResourceBundle;
+
+
+/**
+ * The WSDL 1.1 validator delegate holds a reference to a validator to be instantiated at
+ * a later point.
+ */
+public class WSDL11ValidatorDelegate
+{
+ private String validatorClassname = null;
+ private String resourceBundle = null;
+ private ClassLoader classLoader = null;
+ private IWSDL11Validator validator = null;
+
+ /**
+ * Create a delegate for a validator by its class name and resource bundle name.
+ *
+ * @param validatorClassname The name of the validator class.
+ * @param resourceBundle The name of the validator base resource bundle.
+ */
+ public WSDL11ValidatorDelegate(String validatorClassname, String resourceBundle)
+ {
+ this.validatorClassname = validatorClassname;
+ this.resourceBundle = resourceBundle;
+ }
+
+ /**
+ * Create a delegate for a validator by its class name, resource bundle name and
+ * a class loader to load the validator and bundle.
+ *
+ * @param validatorClassname The name of the validator class.
+ * @param resourceBundle The name of the validator base resource bundle.
+ * @param classLoader The class loader to use to load the validator and bundle.
+ */
+ public WSDL11ValidatorDelegate(String validatorClassname, String resourceBundle, ClassLoader classLoader)
+ {
+ this(validatorClassname, resourceBundle);
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Get the validator specified in this delegate.
+ *
+ * @return The WSDL 1.1 validator specified by this delegate.
+ */
+ public IWSDL11Validator getValidator()
+ {
+ if (validator == null)
+ {
+ if(classLoader == null)
+ {
+ classLoader = getClass().getClassLoader();
+ }
+ try
+ {
+ Class validatorClass =
+ classLoader != null ? classLoader.loadClass(validatorClassname) : Class.forName(validatorClassname);
+
+ validator = (IWSDL11Validator)validatorClass.newInstance();
+ if (resourceBundle != null)
+ {
+ ResourceBundle validatorBundle = ResourceBundle.getBundle(resourceBundle, Locale.getDefault(), classLoader);
+ validator.setResourceBundle(validatorBundle);
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ // TODO: add logging
+ System.err.println(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ // TODO: add logging
+ System.err.println(e);
+ }
+ catch (InstantiationException e)
+ {
+ // TODO: add logging
+ System.err.println(e);
+ }
+ }
+ return validator;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLDocument.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLDocument.java
new file mode 100644
index 000000000..ebb113182
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLDocument.java
@@ -0,0 +1,2000 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.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();
+
+ 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);
+ 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);
+ }
+ 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
+ {
+ // XML Validation will catch this
+ DOMUtils.throwWSDLException(tempEl);
+ }
+
+ 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);
+ }
+ catch (Exception e)
+ {
+ //the call above fails if there is no qualified namespace for the element name
+ elementName = new QName(null, DOMUtils.getAttribute(partEl, "element"));
+ }
+
+ QName typeName;
+ try
+ {
+ typeName = DOMUtils.getQualifiedAttributeValue(partEl, Constants.ATTR_TYPE,
+ // Corrected - was ATTR_ELEMENT
+ Constants.ELEM_MESSAGE, false);
+ }
+ catch (Exception e)
+ {
+ //the call above fails if there is no qualified namespace for the element attribute
+ typeName = new QName(null, DOMUtils.getAttribute(partEl, "name"));
+ }
+
+ 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);
+ }
+ 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();
+
+ 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
+ {
+ // invalid element in the operation
+ // XML check will catch this
+ DOMUtils.throwWSDLException(tempEl);
+ }
+
+ 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().equalsIgnoreCase(name))
+ {
+ Input opInput = oper.getInput();
+ if (opInput != null && input != null)
+ {
+ String opInputName = opInput.getName();
+ if (opInputName != null && inputName != null && opInputName.equalsIgnoreCase(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.equalsIgnoreCase(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});
+ }
+ }
+ }
+
+ 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);
+ }
+ 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);
+ }
+ 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);
+ }
+ 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);
+ }
+ 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);
+ }
+ }
+
+ /**
+ * 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;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLReaderImpl.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLReaderImpl.java
new file mode 100644
index 000000000..4e6ecd6a9
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/WSDLReaderImpl.java
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.wsdl.Import;
+import javax.wsdl.WSDLException;
+
+import org.apache.xerces.impl.XMLErrorReporter;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.parsers.StandardParserConfiguration;
+import org.apache.xerces.xni.XNIException;
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.eclipse.wst.wsdl.validation.internal.xml.LineNumberDOMParser;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import com.ibm.wsdl.DefinitionImpl;
+import com.ibm.wsdl.util.StringUtils;
+
+/**
+ * A WSDL reader that supports cyclic WSDL imports, schema imports and inline schemas.
+ * This reader is based on the WSDLReaderImpl from WSDL4J.
+ */
+public class WSDLReaderImpl
+{
+ protected MessageGenerator messagegenerator;
+ protected IWSDL11ValidationInfo wsdlvalinfo;
+
+ /**
+ * Constructor.
+ *
+ * @param wsdlvalinfo The WSDL 1.1 validation info object to use.
+ */
+ public WSDLReaderImpl(IWSDL11ValidationInfo wsdlvalinfo)
+ {
+ this.wsdlvalinfo = wsdlvalinfo;
+ }
+
+ /**
+ * Parse the root document. This method will find all imports and parse them as
+ * well creating a WSDLDocument for each unique WSDL file. This method supports
+ * cyclic WSDL import statements such that file A can import file B and file B
+ * can import file A.
+ *
+ * @param documentBaseURI The base URI of the root document.
+ * @param defEl The definition element of the root document.
+ * @return An array of WSDLDocuments containing all of the unique files in the description.
+ * @throws WSDLException
+ */
+ protected WSDLDocument[] parseDocument(String documentBaseURI, Element defEl) throws WSDLException
+ {
+ int initialImportArraySize = 20;
+ List[] filesAtDepth = new ArrayList[initialImportArraySize];
+ Map filesImporting = new Hashtable();
+ SortedSet parsedImports = new TreeSet();
+ SortedSet importsToParse = new TreeSet();
+ int maxdepth = 0;
+
+ WSDLDocument rootdoc = new WSDLDocument(documentBaseURI, defEl, 0, messagegenerator, wsdlvalinfo);
+ String targetNamespace = rootdoc.getDefinition().getTargetNamespace();
+ ImportHolder rootImport = new ImportHolder(targetNamespace, documentBaseURI, documentBaseURI, rootdoc, 0, null, messagegenerator, wsdlvalinfo);
+ rootImport.createWSDLImport(rootdoc);
+ parsedImports.add(rootImport);
+ List rootList = new ArrayList();
+ filesImporting.put(rootImport.getLocation(), new ArrayList());
+ rootList.add(rootdoc);
+ filesAtDepth[0] = rootList;
+ importsToParse.addAll(rootdoc.getImports());
+ Set imps = rootdoc.getImports();
+ Iterator impIter = imps.iterator();
+ while(impIter.hasNext())
+ {
+ ImportHolder imp = (ImportHolder)impIter.next();
+ List tempList = new ArrayList();
+ tempList.add(imp.getImportingDocument());
+ filesImporting.put(imp.getLocation(), tempList);
+ }
+
+ while(!importsToParse.isEmpty())
+ {
+ ImportHolder imp = (ImportHolder)importsToParse.first();
+ // It's important to initialize the import here so each import
+ // is only created once. In the case of reciprical imports this
+ // avoids an infinite loop.
+ imp.initialize();
+ WSDLDocument impDoc = imp.getWSDLDocument();
+
+ importsToParse.remove(imp);
+
+ parsedImports.add(imp);
+
+ // Add new imports to the list of imports to parse.
+ // Remove all the imports that have already been parsed.
+ if(impDoc != null)
+ {
+ // Increate import array if necessary.
+ if(imp.getDepth() >= initialImportArraySize)
+ {
+ List[] tempArray = new List[filesAtDepth.length + initialImportArraySize];
+ System.arraycopy(filesAtDepth, 0, tempArray, 0, filesAtDepth.length);
+ filesAtDepth = tempArray;
+ }
+ // Create the list for the depth if necessary.
+ int impDepth = imp.getDepth();
+ if(filesAtDepth[impDepth] == null)
+ {
+ if(maxdepth < impDepth)
+ {
+ maxdepth = impDepth;
+ }
+ filesAtDepth[impDepth] = new ArrayList();
+ }
+ filesAtDepth[imp.getDepth()].add(impDoc);
+
+ Set imports = impDoc.getImports();
+ ImportHolder[] importsArray = (ImportHolder[])imports.toArray(new ImportHolder[imports.size()]);
+ for(int i = 0; i < importsArray.length; i++)
+ {
+ ImportHolder ih = importsArray[i];
+ // If already parsed, add the definition importing this file to the list.
+ if(filesImporting.containsKey(ih.getLocation()))
+ {
+ ((List)filesImporting.get(ih.getLocation())).add(ih.getImportingDocument());
+ }
+ // Otherwise add it to the list to parse.
+ else
+ {
+ // Add this import to the list of files importing list.
+ List tempList = new ArrayList();
+ tempList.add(ih.getImportingDocument());
+ filesImporting.put(ih.getLocation(), tempList);
+ importsToParse.add(ih);
+ }
+ }
+ }
+ }
+
+ // Add all of the imports to the respective documents.
+ Iterator importElementsIter = parsedImports.iterator();
+ while(importElementsIter.hasNext())
+ {
+ ImportHolder imp = (ImportHolder)importElementsIter.next();
+ List files = (List)filesImporting.get(imp.getLocation());
+ Iterator filesIter = files.iterator();
+ while(filesIter.hasNext())
+ {
+ WSDLDocument doc = (WSDLDocument)filesIter.next();
+
+ DefinitionImpl def = (DefinitionImpl)doc.getDefinition();
+ Import impElem = imp.getImport();
+ if(impElem != null)
+ {
+ def.addImport(impElem);
+ if(!imp.isWSDLFileImport())
+ {
+ doc.addSchemas(imp.getSchemas());
+ }
+ }
+
+ }
+ }
+
+ // Parse the WSDL documents.
+ // Parse the Messages.
+ for(int i = maxdepth; i >=0; i--)
+ {
+ List docs = filesAtDepth[i];
+ Iterator docsIter = docs.iterator();
+ while(docsIter.hasNext())
+ {
+ WSDLDocument doc = (WSDLDocument)docsIter.next();
+ doc.parseMessages();
+ }
+ }
+ // Parse the Porttypes.
+ for(int i = maxdepth; i >=0; i--)
+ {
+ List docs = filesAtDepth[i];
+ Iterator docsIter = docs.iterator();
+ while(docsIter.hasNext())
+ {
+ WSDLDocument doc = (WSDLDocument)docsIter.next();
+ doc.parsePorttypes();
+ }
+ }
+ // Parse the Bindings.
+ for(int i = maxdepth; i >=0; i--)
+ {
+ List docs = filesAtDepth[i];
+ Iterator docsIter = docs.iterator();
+ while(docsIter.hasNext())
+ {
+ WSDLDocument doc = (WSDLDocument)docsIter.next();
+ doc.parseBindings();
+ }
+ }
+ // Parse the Services.
+ for(int i = maxdepth; i >=0; i--)
+ {
+ List docs = filesAtDepth[i];
+ Iterator docsIter = docs.iterator();
+ while(docsIter.hasNext())
+ {
+ WSDLDocument doc = (WSDLDocument)docsIter.next();
+ doc.parseServices();
+ }
+ }
+ // Parse the Extensibility Elements.
+ for(int i = maxdepth; i >=0; i--)
+ {
+ List docs = filesAtDepth[i];
+ Iterator docsIter = docs.iterator();
+ while(docsIter.hasNext())
+ {
+ WSDLDocument doc = (WSDLDocument)docsIter.next();
+ doc.parseExtensibilityElements();
+ }
+ }
+
+ List wsdlDocs = new ArrayList();
+ for(int i = maxdepth; i >=0; i--)
+ {
+ List docs = filesAtDepth[i];
+ Iterator docsIter = docs.iterator();
+ while(docsIter.hasNext())
+ {
+ WSDLDocument doc = (WSDLDocument)docsIter.next();
+ wsdlDocs.add(doc);
+ }
+ }
+
+ return (WSDLDocument[])wsdlDocs.toArray(new WSDLDocument[wsdlDocs.size()]);
+ }
+
+ /**
+ * Get the WSDL document.
+ *
+ * @param inputSource The source of the document being retrieved.
+ * @param desc The description of the document being retrieved.
+ * @return The WSDL document.
+ * @throws WSDLException
+ */
+ public static Document getDocument(InputSource inputSource, String desc) throws WSDLException
+ {
+ try
+ {
+ StandardParserConfiguration configuration = new StandardParserConfiguration()
+ {
+ protected XMLErrorReporter createErrorReporter()
+ {
+ return new XMLErrorReporter()
+ {
+ public void reportError(String domain, String key, Object[] arguments, short severity) throws XNIException
+ {
+ boolean reportError = true;
+ if (key.equals("PrematureEOF"))
+ {
+ reportError = false;
+ }
+
+ if (reportError)
+ {
+ super.reportError(domain, key, arguments, severity);
+ }
+ }
+ };
+ }
+ };
+
+ ErrorHandler errorHandler = new ErrorHandler()
+ {
+ /* (non-Javadoc)
+ * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+ */
+ public void error(SAXParseException exception) throws SAXException
+ {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
+ */
+ public void fatalError(SAXParseException exception) throws SAXException
+ {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+ */
+ public void warning(SAXParseException exception) throws SAXException
+ {
+ // TODO Auto-generated method stub
+
+ }
+ };
+
+ DOMParser builder = new LineNumberDOMParser(configuration);
+ builder.setErrorHandler(errorHandler);
+ builder.parse(inputSource);
+ Document doc = builder.getDocument();
+
+ return doc;
+ }
+ catch (Throwable t)
+ {
+ throw new WSDLException(WSDLException.PARSER_ERROR, "Problem parsing '" + desc + "'.", t);
+ }
+ }
+
+ /**
+ * Read a WSDL document using a context URI and file URI.
+ *
+ * @param contextURI The context URI to use.
+ * @param wsdlURI The WSDL URI to use.
+ * @return An array of WSDLDocuments.
+ * @throws WSDLException
+ */
+ public WSDLDocument[] readWSDL(String contextURI, String wsdlURI) throws WSDLException
+ {
+ try
+ {
+ URL contextURL = (contextURI != null) ? StringUtils.getURL(null, contextURI) : null;
+ URL url = StringUtils.getURL(contextURL, wsdlURI);
+ Reader reader = StringUtils.getContentAsReader(url);
+ InputSource inputSource = new InputSource(reader);
+ Document doc = getDocument(inputSource, wsdlURI);
+ reader.close();
+ WSDLDocument[] wsdlDocs = null;
+ // only parse the document if it isn't empty
+ if(doc.getDocumentElement() != null)
+ {
+ wsdlDocs = readWSDL(url.toString(), doc);
+ }
+ return wsdlDocs;
+ }
+ catch (WSDLException e)
+ {
+ throw e;
+ }
+ catch (Throwable t)
+ {
+ throw new WSDLException(
+ WSDLException.OTHER_ERROR,
+ "Unable to resolve imported document at '" + wsdlURI + "'.",
+ t);
+ }
+ }
+
+ /**
+ * Set the messagegenerator for the reader.
+ *
+ * @param mg The message generator to set.
+ */
+ public void setMessageGenerator(MessageGenerator mg)
+ {
+ messagegenerator = mg;
+ }
+
+ /**
+ * Read the WSDL document accessible via the specified
+ * URI into a WSDL definition.
+ *
+ * @param wsdlURI A URI pointing to a WSDL file.
+ * @return An array of WSDLDocuments.
+ */
+ public WSDLDocument[] readWSDL(String wsdlURI) throws WSDLException
+ {
+ return readWSDL(null, wsdlURI);
+ }
+
+ /**
+ * Read the WSDL document described by a URI and its definitions element.
+ *
+ * @param documentBaseURI The URI of the WSDL document.
+ * @param definitionsElement The definitions element for the WSDL document.
+ * @return An array of WSDLDocuments.
+ * @throws WSDLException
+ */
+ protected WSDLDocument[] readWSDL(String documentBaseURI,
+ Element definitionsElement)
+ throws WSDLException
+ {
+ return parseDocument(documentBaseURI, definitionsElement);
+ }
+
+ /**
+ * Read the specified WSDL document.
+ *
+ * @param documentBaseURI The document base URI.
+ * @param wsdlDocument The WSDL document.
+ * @return An array of WSDLDocuments.
+ */
+ public WSDLDocument[] readWSDL(String documentBaseURI, Document wsdlDocument)
+ throws WSDLException
+ {
+ return readWSDL(documentBaseURI, wsdlDocument.getDocumentElement());
+ }
+
+
+
+}
+
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/http/HTTPValidator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/http/HTTPValidator.java
new file mode 100644
index 000000000..6780e48e2
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/http/HTTPValidator.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.http;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import javax.wsdl.Binding;
+import javax.wsdl.BindingInput;
+import javax.wsdl.BindingOperation;
+import javax.wsdl.Port;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.http.HTTPOperation;
+
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo;
+
+import com.ibm.wsdl.BindingImpl;
+import com.ibm.wsdl.BindingInputImpl;
+import com.ibm.wsdl.BindingOperationImpl;
+import com.ibm.wsdl.PortImpl;
+import com.ibm.wsdl.extensions.http.HTTPAddressImpl;
+import com.ibm.wsdl.extensions.http.HTTPBindingImpl;
+import com.ibm.wsdl.extensions.http.HTTPOperationImpl;
+import com.ibm.wsdl.extensions.http.HTTPUrlEncodedImpl;
+import com.ibm.wsdl.extensions.http.HTTPUrlReplacementImpl;
+
+/**
+ * The HTTP validator is an extension WSDL validator that validates all elements in the HTTP
+ * namespace.
+ */
+public class HTTPValidator implements IWSDL11Validator
+{
+ private final String _ERROR_INVALID_PORT_ELEMENT = "_ERROR_INVALID_PORT_ELEMENT";
+ private final String _ERROR_INVALID_BINDING_ELEMENT = "_ERROR_INVALID_BINDING_ELEMENT";
+ private final String _ERROR_INVALID_BINDING_OPERATION_ELEMENT = "_ERROR_INVALID_BINDING_OPERATION_ELEMENT";
+ private final String _ERROR_INVALID_BINDING_INPUT_ELEMENT = "_ERROR_INVALID_BINDING_INPUT_ELEMENT";
+ private final String _ERROR_INVALID_HTTP_ELEMENT_FOR_LOCATION = "_ERROR_INVALID_HTTP_ELEMENT_FOR_LOCATION";
+ private final String _ERROR_NO_LOCATION_FOR_ADDRESS = "_ERROR_NO_LOCATION_FOR_ADDRESS";
+ private final String _ERROR_NO_HTTPBINDING_FOR_ADDRESS = "_ERROR_NO_HTTPBINDING_FOR_ADDRESS";
+ private final String _ERROR_INVALID_BINDING_VERB = "_ERROR_INVALID_BINDING_VERB";
+ private final String _ERROR_INVALID_LOCATION_URI = "_ERROR_INVALID_LOCATION_URI";
+ private final String _ERROR_NO_HTTPBINDING_FOR_OPERATION = "_ERROR_NO_HTTPBINDING_FOR_OPERATION";
+ private final String _ERROR_NOT_ONLY_ELEMENT_DEFINED = "_ERROR_NOT_ONLY_ELEMENT_DEFINED";
+ private final String _ERROR_NO_HTTPOPERATION_FOR_URL = "_ERROR_NO_HTTPOPERATION_FOR_URL";
+
+ private final String GET = "GET";
+ private final String POST = "POST";
+
+ private final String QUOTE = "'";
+ private final String EMPTY_STRING = "";
+
+ private MessageGenerator messagegenerator;
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator#validate(java.lang.Object, java.util.List, org.eclipse.wsdl.validate.wsdl11.IWSDL11ValidationInfo)
+ */
+ public void validate(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ // Port HTTP definition
+ // make sure every port has only one address element defined
+ // if it is an address element, validate it
+ if (parents.get(0).getClass() == PortImpl.class)
+ {
+ if (element.getClass() == HTTPAddressImpl.class)
+ {
+ validateAddress(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_PORT_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE),
+ element);
+ }
+ }
+
+ // Binding HTTP definition
+ // A HTTP Binding must have a verb of GET or POST
+ else if (parents.get(0).getClass() == BindingImpl.class)
+ {
+ if (element.getClass() == HTTPBindingImpl.class)
+ {
+ validateBinding(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BINDING_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE),
+ element);
+ }
+ }
+ // Binding Operation HTTP definition
+ // A HTTP Operation has a location uri defined
+ else if (parents.get(0).getClass() == BindingOperationImpl.class)
+ {
+ if (element.getClass() == HTTPOperationImpl.class)
+ {
+ validateOperation(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_INVALID_BINDING_OPERATION_ELEMENT,
+ QUOTE + e.getElementType().getLocalPart() + QUOTE),
+ element);
+ }
+
+ }
+ else if (parents.get(0).getClass() == BindingInputImpl.class)
+ {
+ // validate the HTTP urlEncoded and urlReplacement
+ if (element.getClass() == HTTPUrlEncodedImpl.class || element.getClass() == HTTPUrlReplacementImpl.class)
+ {
+ validateHttpUrl(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BINDING_INPUT_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE),
+ element);
+ }
+ }
+
+ // in this case there has been a HTTP element defined that is not defined for this point in the HTTP namespace
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_INVALID_HTTP_ELEMENT_FOR_LOCATION,
+ QUOTE + e.getElementType().getLocalPart() + QUOTE),
+ element);
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.validator.IWSDL11Validator#setResourceBundle(java.util.ResourceBundle)
+ */
+ public void setResourceBundle(ResourceBundle rb)
+ {
+ if (messagegenerator == null)
+ {
+ messagegenerator = new MessageGenerator(rb);
+ }
+ }
+
+ /**
+ * Ensure that the HTTP address has a value specified for it's uri and that there is a HTTP Binding defined
+ * for the Binding specified in the port.
+ *
+ * @param element The HTTP address element.
+ * @param parents The list of parents of the HTTP address element.
+ * @param validatorcontroller The validator controller in charge of validation.
+ */
+ protected void validateAddress(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ HTTPAddressImpl ha = (HTTPAddressImpl)element;
+
+ String uri = ha.getLocationURI();
+ if (uri == null || uri.equalsIgnoreCase(EMPTY_STRING))
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_NO_LOCATION_FOR_ADDRESS), ha);
+ }
+
+ Port port = (Port)parents.get(0);
+
+ Binding binding = port.getBinding();
+
+ if (!hasHttpBinding(binding))
+ {
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_NO_HTTPBINDING_FOR_ADDRESS,
+ QUOTE + binding.getQName().getLocalPart() + QUOTE,
+ QUOTE + port.getName() + QUOTE),
+ ha);
+ }
+ }
+
+ /**
+ * Ensure the HTTP Binding defined is valid. A HTTP Binding must have a verb of GET or POST.
+ *
+ * @param element The HTTP binding element.
+ * @param parents The list of parents of the HTTP binding element.
+ * @param validatorcontroller The validator controller in charge of validation.
+ */
+ protected void validateBinding(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ HTTPBindingImpl hb = (HTTPBindingImpl)element;
+
+ String verb = hb.getVerb();
+
+ if (verb != null && !verb.equals(GET) && !verb.equals(POST))
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_INVALID_BINDING_VERB, QUOTE + verb + QUOTE), element);
+ }
+ }
+
+ /**
+ * An operation must have a location defined. A HTTP Binding must be specified to use an operation.
+ *
+ * @param element The HTTP operation element.
+ * @param parents The list of parents of the HTTP operation element.
+ * @param validatorcontroller The validator controller in charge of validation.
+ */
+ protected void validateOperation(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ HTTPOperation ho = (HTTPOperation)element;
+
+ String locationURI = ho.getLocationURI();
+
+ if (locationURI != null && locationURI.equalsIgnoreCase(EMPTY_STRING))
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_INVALID_LOCATION_URI), element);
+ }
+
+ Binding binding = (Binding)parents.get(1);
+ if (!hasHttpBinding(binding))
+ {
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_NO_HTTPBINDING_FOR_OPERATION, QUOTE + binding.getQName().getLocalPart() + QUOTE),
+ ho);
+ }
+ }
+
+ /**
+ * Validate the HTTP urlReplacement or urlEncoded. Ensure the HTTP operation has been defined.
+ * Ensure that either element is the only element specified.
+ *
+ * @param element The HTTP binding operation element.
+ * @param parents The list of parents of the HTTP binding operation element.
+ * @param validatorcontroller The validator controller in charge of validation.
+ */
+ protected void validateHttpUrl(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ BindingOperation operation = (BindingOperation)parents.get(1);
+
+ String elementName;
+ if (element.getClass() == HTTPUrlEncodedImpl.class)
+ {
+ elementName = "urlEncoded";
+ }
+ else if (element.getClass() == HTTPUrlReplacementImpl.class)
+ {
+ elementName = "urlReplacement";
+ }
+ else
+ {
+ elementName = EMPTY_STRING;
+ }
+
+ BindingInput input = (BindingInput)parents.get(0);
+ if (input.getExtensibilityElements().size() != 1)
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_NOT_ONLY_ELEMENT_DEFINED, elementName), element);
+ }
+
+ if (!hasHttpOperation(operation))
+ {
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_NO_HTTPOPERATION_FOR_URL, QUOTE + operation.getName() + QUOTE, elementName),
+ element);
+ }
+ }
+
+ /**
+ * Given a BindingOperation tells whether it has a HTTP operation defined for it.
+ *
+ * @param binding The HTTP binding operation element.
+ * @return True if there is an HTTP operation defined, false otherwise.
+ */
+ protected boolean hasHttpOperation(BindingOperation operation)
+ {
+ if (operation != null)
+ {
+ List extelems = operation.getExtensibilityElements();
+ if (extelems != null)
+ {
+ Iterator iextelems = extelems.iterator();
+ while (iextelems.hasNext())
+ {
+ if (iextelems.next().getClass() == HTTPOperationImpl.class)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Given a binding returns true if it has a HTTP binding defined.
+ *
+ * @param binding The binding to check.
+ * @return True if there is an HTTP binding defined.
+ */
+ protected boolean hasHttpBinding(Binding binding)
+ {
+ if (binding != null)
+ {
+ List extelems = binding.getExtensibilityElements();
+ if (extelems != null)
+ {
+ Iterator iextelems = extelems.iterator();
+ while (iextelems.hasNext())
+ {
+ if (iextelems.next().getClass() == HTTPBindingImpl.class)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/mime/MIMEValidator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/mime/MIMEValidator.java
new file mode 100644
index 000000000..54fcea8f2
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/mime/MIMEValidator.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.mime;
+
+import java.util.List;
+import java.util.ResourceBundle;
+
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo;
+
+/**
+ * The MIME validator plugs into the WSDL validator to provide
+ * validation for all elements in a WSDL document within the MIME namespace.
+ */
+public class MIMEValidator implements IWSDL11Validator
+{
+ protected MessageGenerator messagegenerator;
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator#validate(java.lang.Object, java.util.List, org.eclipse.wsdl.validate.wsdl11.IWSDL11ValidationInfo)
+ */
+ public void validate(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.validator.IWSDL11Validator#setResourceBundle(java.util.ResourceBundle)
+ */
+ public void setResourceBundle(ResourceBundle rb)
+ {
+ if (messagegenerator == null)
+ {
+ messagegenerator = new MessageGenerator(rb);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/soap/SOAPValidator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/soap/SOAPValidator.java
new file mode 100644
index 000000000..b3a95493e
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/soap/SOAPValidator.java
@@ -0,0 +1,603 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.soap;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import javax.wsdl.Binding;
+import javax.wsdl.BindingFault;
+import javax.wsdl.BindingOperation;
+import javax.wsdl.Definition;
+import javax.wsdl.Input;
+import javax.wsdl.Message;
+import javax.wsdl.Operation;
+import javax.wsdl.Output;
+import javax.wsdl.Part;
+import javax.wsdl.Port;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.soap.SOAPOperation;
+import javax.xml.namespace.QName;
+
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo;
+
+import com.ibm.wsdl.BindingFaultImpl;
+import com.ibm.wsdl.BindingImpl;
+import com.ibm.wsdl.BindingInputImpl;
+import com.ibm.wsdl.BindingOperationImpl;
+import com.ibm.wsdl.BindingOutputImpl;
+import com.ibm.wsdl.PortImpl;
+import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
+import com.ibm.wsdl.extensions.soap.SOAPBindingImpl;
+import com.ibm.wsdl.extensions.soap.SOAPBodyImpl;
+import com.ibm.wsdl.extensions.soap.SOAPFaultImpl;
+import com.ibm.wsdl.extensions.soap.SOAPHeaderFaultImpl;
+import com.ibm.wsdl.extensions.soap.SOAPHeaderImpl;
+import com.ibm.wsdl.extensions.soap.SOAPOperationImpl;
+
+/**
+ * The SOAP validator plugs into the WSDL validator to provide
+ * validation for all elements in a WSDL document within the SOAP namespace.
+ *
+ */
+public class SOAPValidator implements IWSDL11Validator
+{
+ private final String _ERROR_INVALID_PORT_ELEMENT = "_ERROR_INVALID_PORT_ELEMENT";
+ private final String _ERROR_INVALID_BINDING_ELEMENT = "_ERROR_INVALID_BINDING_ELEMENT";
+ private final String _ERROR_INVALID_BINDING_OPERATION_ELEMENT = "_ERROR_INVALID_BINDING_OPERATION_ELEMENT";
+ private final String _ERROR_INVALID_HEADER_BODY_ELEMENT = "_ERROR_INVALID_HEADER_BODY_ELEMENT";
+ private final String _ERROR_INVALID_FAULT_ELEMENT = "_ERROR_INVALID_FAULT_ELEMENT";
+ private final String _ERROR_INVALID_SOAP_ELEMENT_FOR_LOCATION = "_ERROR_INVALID_SOAP_ELEMENT_FOR_LOCATION";
+ private final String _ERROR_NO_LOCATION_FOR_ADDRESS = "_ERROR_NO_LOCATION_FOR_ADDRESS";
+ private final String _ERROR_NO_SOAPBINDING_FOR_ADDRESS = "_ERROR_NO_SOAPBINDING_FOR_ADDRESS";
+ private final String _ERROR_INVALID_BINDING_STYLE = "_ERROR_INVALID_BINDING_STYLE";
+ private final String _ERROR_INVALID_BINDING_URI = "_ERROR_INVALID_BINDING_URI";
+ private final String _ERROR_INVALID_OPERATION_STYLE = "_ERROR_INVALID_OPERATION_STYLE";
+ private final String _ERROR_NO_SOAPBINDING_FOR_OPERATION = "_ERROR_NO_SOAPBINDING_FOR_OPERATION";
+ private final String _ERROR_INVALID_BODY_ENCODING_STYLE = "_ERROR_INVALID_BODY_ENCODING_STYLE";
+ private final String _ERROR_INVALID_BODY_NAMESPACE_FOR_ENCODED = "_ERROR_INVALID_BODY_NAMESPACE_FOR_ENCODED";
+ private final String _ERROR_INVALID_BODY_USE = "_ERROR_INVALID_BODY_USE";
+ private final String _ERROR_INVALID_BODY_PART_NOT_TYPE = "_ERROR_INVALID_BODY_PART_NOT_TYPE";
+ private final String _ERROR_INVALID_BODY_PART_UNDEFINED = "_ERROR_INVALID_BODY_PART_UNDEFINED";
+ private final String _ERROR_NO_SOAPBINDING_FOR_BODY = "_ERROR_NO_SOAPBINDING_FOR_BODY";
+ private final String _ERROR_HEADER_MESSAGE_UNDEFINED = "_ERROR_HEADER_MESSAGE_UNDEFINED";
+ private final String _ERROR_HEADER_PART_UNDEFINED = "_ERROR_HEADER_PART_UNDEFINED";
+ private final String _ERROR_HEADER_USE_UNDEFINED = "_ERROR_HEADER_USE_UNDEFINED";
+ private final String _ERROR_HEADER_ENCODINGSTYLE_UNDEFINED = "_ERROR_HEADER_ENCODINGSTYLE_UNDEFINED";
+ private final String _ERROR_HEADER_NAMESPACE_UNDEFINED = "_ERROR_HEADER_NAMESPACE_UNDEFINED";
+ private final String _ERROR_NO_SOAPBINDING_FOR_HEADER = "_ERROR_NO_SOAPBINDING_FOR_HEADER";
+ private final String _ERROR_HEADERFAULT_MESSAGE_UNDEFINED = "_ERROR_HEADERFAULT_MESSAGE_UNDEFINED";
+ private final String _ERROR_HEADERFAULT_PART_UNDEFINED = "_ERROR_HEADERFAULT_PART_UNDEFINED";
+ private final String _ERROR_HEADERFAULT_USE_UNDEFINED = "_ERROR_HEADERFAULT_USE_UNDEFINED";
+ private final String _ERROR_HEADERFAULT_ENCODINGSTYLE_UNDEFINED = "_ERROR_HEADERFAULT_ENCODINGSTYLE_UNDEFINED";
+ private final String _ERROR_HEADERFAULT_NAMESPACE_UNDEFINED = "_ERROR_HEADERFAULT_NAMESPACE_UNDEFINED";
+ private final String _ERROR_INVALID_FAULT_NAME = "_ERROR_INVALID_FAULT_NAME";
+ private final String _ERROR_INVALID_FAULT_ENCODING_STYLE = "_ERROR_INVALID_FAULT_ENCODING_STYLE";
+ private final String _ERROR_INVALID_FAULT_NAMESPACE_FOR_ENCODED = "_ERROR_INVALID_FAULT_NAMESPACE_FOR_ENCODED";
+
+ private final String ENCODED = "encoded";
+ private final String LITERAL = "literal";
+ private final String RPC = "rpc";
+ private final String DOCUMENT = "document";
+
+ private final String QUOTE = "'";
+ private final String EMPTY_STRING = "";
+
+ protected MessageGenerator messagegenerator;
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator#validate(java.lang.Object, java.util.List, org.eclipse.wsdl.validate.wsdl11.IWSDL11ValidationInfo)
+ */
+ public void validate(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ // Port SOAP definition
+ // make sure every port has only one address element defined
+ // if it is an address element, validate it
+ if (parents.get(0).getClass() == PortImpl.class)
+ {
+ if (element.getClass() == SOAPAddressImpl.class)
+ {
+ validateAddress(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_PORT_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE), element);
+ }
+ }
+
+ // Binding SOAP definition
+ // A SOAP Binding must have a style or rpc or document or no style defined - defaults to document
+ // Must have a transport uri defined - check if the uri is empty
+ else if (parents.get(0).getClass() == BindingImpl.class)
+ {
+ if (element.getClass() == SOAPBindingImpl.class)
+ {
+ validateBinding(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BINDING_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE), element);
+ }
+ }
+ // Binding Operation SOAP definition
+ // A SOAP Operation may have a style defined in which case it must be document or rpc
+ // and may have a soapAction uri defined
+ else if (parents.get(0).getClass() == BindingOperationImpl.class)
+ {
+ if (element.getClass() == SOAPOperationImpl.class)
+ {
+ validateOperation(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_INVALID_BINDING_OPERATION_ELEMENT,
+ QUOTE + e.getElementType().getLocalPart() + QUOTE), element);
+ }
+
+ }
+ else if (
+ parents.get(0).getClass() == BindingInputImpl.class || parents.get(0).getClass() == BindingOutputImpl.class)
+ {
+ // validate the SOAP body
+ if (element.getClass() == SOAPBodyImpl.class)
+ {
+ validateBody(element, parents, valInfo);
+ }
+ // valiate the SOAP header
+ else if (element.getClass() == SOAPHeaderImpl.class)
+ {
+ validateHeader(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_HEADER_BODY_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE), element);
+ }
+ }
+ else if (parents.get(0).getClass() == BindingFaultImpl.class)
+ {
+ if (element.getClass() == SOAPFaultImpl.class)
+ {
+ validateFault(element, parents, valInfo);
+ }
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_FAULT_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE), element);
+ }
+ }
+ // in this case there has been a SOAP element defined that is not defined for this point in the SOAP namespace
+ else
+ {
+ ExtensibilityElement e = (ExtensibilityElement)element;
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_INVALID_SOAP_ELEMENT_FOR_LOCATION,
+ QUOTE + e.getElementType().getLocalPart() + QUOTE), element);
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.validator.IWSDL11Validator#setResourceBundle(java.util.ResourceBundle)
+ */
+ public void setResourceBundle(ResourceBundle rb)
+ {
+ if (messagegenerator == null)
+ {
+ messagegenerator = new MessageGenerator(rb);
+ }
+ }
+
+ /**
+ * Ensure that the SOAP address has a value specified for it's uri and that the binding has a SOAP
+ * Binding defined.
+ *
+ * @param element The SOAP address element.
+ * @param parents A list of parents of the SOAP address element.
+ * @param valInfo The validation info for this validation.
+ */
+ protected void validateAddress(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ SOAPAddressImpl sa = (SOAPAddressImpl)element;
+
+ String uri = sa.getLocationURI();
+ if (uri == null || uri.equalsIgnoreCase(EMPTY_STRING))
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_NO_LOCATION_FOR_ADDRESS), sa);
+ }
+
+ Port port = (Port)parents.get(0);
+
+ Binding binding = port.getBinding();
+
+ if (!hasSoapBinding(binding))
+ {
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_NO_SOAPBINDING_FOR_ADDRESS,
+ QUOTE + binding.getQName().getLocalPart() + QUOTE,
+ QUOTE + port.getName() + QUOTE), sa);
+ }
+ }
+
+ /**
+ * Ensure the SOAP Binding defined is valid. A SOAP Binding must have a style of rpc or document
+ * or no style defined (defaults to document.) A valid (non empty) URI must also be specified.
+ *
+ * @param element The SOAP binding element.
+ * @param parents A list of parents of the SOAP binding element.
+ * @param valInfo The validation info for this validation.
+ */
+ protected void validateBinding(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ SOAPBindingImpl sb = (SOAPBindingImpl)element;
+
+ String style = sb.getStyle();
+ String uri = sb.getTransportURI();
+
+ if (style != null && !style.equalsIgnoreCase(RPC) && !style.equalsIgnoreCase(DOCUMENT))
+ {
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BINDING_STYLE, QUOTE + sb.getStyle() + QUOTE), element);
+ }
+ if (uri.equalsIgnoreCase(EMPTY_STRING))
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_INVALID_BINDING_URI), element);
+ }
+ }
+
+ /**
+ * An operation may have a style defined. If it is defined it must be rpc or document. It may also have a
+ * uri defined which must be non empty. It may have a soapAction defined as well.
+ *
+ * @param element The SOAP operation element.
+ * @param parents A list of parents of the SOAP operation element.
+ * @param valInfo The validation info for this validation.
+ */
+ protected void validateOperation(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ SOAPOperation so = (SOAPOperation)element;
+
+ String soapStyle = so.getStyle();
+
+ if (soapStyle != null && !soapStyle.equalsIgnoreCase(RPC) && !soapStyle.equalsIgnoreCase(DOCUMENT))
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_INVALID_OPERATION_STYLE), element);
+ }
+
+ Binding binding = (Binding)parents.get(1);
+ if (!hasSoapBinding(binding))
+ {
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_NO_SOAPBINDING_FOR_OPERATION, QUOTE + binding.getQName().getLocalPart() + QUOTE), so);
+ }
+ }
+
+ /**
+ * Validate the SOAP body. If encoded a body must have an encodingStyle. Also,
+ * if specified, all of the parts listed must be defined parts and in the encoding use case, the parts
+ * must have types defined.
+ *
+ * @param element The SOAP body element.
+ * @param parents A list of parents of the SOAP body element.
+ * @param valInfo The validation info for this validation.
+ */
+ protected void validateBody(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ SOAPBodyImpl sb = (SOAPBodyImpl)element;
+
+ String use = sb.getUse();
+
+ // if the use = encoded then there must be encodingStyles.
+ if (use != null && use.equalsIgnoreCase(ENCODED))
+ {
+ List encodingStyles = sb.getEncodingStyles();
+ if (encodingStyles == null || encodingStyles.size() == 0)
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_INVALID_BODY_ENCODING_STYLE), sb);
+ }
+ }
+ else if (use != null && !use.equalsIgnoreCase(LITERAL))
+ {
+ valInfo.addError(messagegenerator.getString(_ERROR_INVALID_BODY_USE, QUOTE + use + QUOTE), sb);
+ }
+
+ //Check that the parts are valid
+ // parts must be defined in the message specified for the operation
+ List parts = sb.getParts();
+
+ if (parts != null)
+ {
+ Iterator partsIterator = parts.iterator();
+ while (partsIterator.hasNext())
+ {
+ String part = (String)partsIterator.next();
+ BindingOperation bo = (BindingOperation)parents.get(1);
+ Operation o = bo.getOperation();
+
+ if (o != null && !o.isUndefined())
+ {
+ // get the message from the input or output if it exists
+ Message mess = null;
+ if (parents.get(0).getClass() == BindingInputImpl.class)
+ {
+ Input input = o.getInput();
+
+ if (input != null)
+ {
+ mess = input.getMessage();
+ }
+ }
+ else if (parents.get(0).getClass() == BindingOutputImpl.class)
+ {
+ Output output = o.getOutput();
+
+ if (output != null)
+ {
+ mess = output.getMessage();
+ }
+ }
+
+ if (mess != null && !mess.isUndefined())
+ {
+ Part p = mess.getPart(part);
+
+ if (p != null)
+ {
+ // if the use is encoded the parts must all have a type defined
+ if (use != null && use.equalsIgnoreCase(ENCODED))
+ {
+ if (p.getTypeName() == null)
+ {
+ // part error - part needs to be type and isn't
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BODY_PART_NOT_TYPE, QUOTE + part + QUOTE), sb);
+ }
+ }
+ }
+ else
+ {
+ //part error - part isn't defined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BODY_PART_UNDEFINED, QUOTE + part + QUOTE), sb);
+ }
+ }
+ else
+ {
+ //part error - input isn't defined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BODY_PART_UNDEFINED, QUOTE + part + QUOTE), sb);
+ }
+ }
+ else
+ {
+ // parts error - operation isn't defined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_BODY_PART_UNDEFINED, QUOTE + part + QUOTE), sb);
+ }
+ }
+ }
+
+ Binding binding = (Binding)parents.get(2);
+ if (!hasSoapBinding(binding))
+ {
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_NO_SOAPBINDING_FOR_BODY, QUOTE + binding.getQName().getLocalPart() + QUOTE), sb);
+ }
+ }
+
+ /**
+ * A SOAP header must have a message, part and use defined. If the use is encoded, must
+ * also have a non-empty encodingStyle and namespace defined.
+ * A SOAP header may have headerfaults defined as well.
+ *
+ * @param element The SOAP header element.
+ * @param parents A list of parents of the SOAP header element.
+ * @param valInfo The validation info for this validation.
+ */
+ protected void validateHeader(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ SOAPHeaderImpl soapHeader = (SOAPHeaderImpl)element;
+
+ QName messageQName = soapHeader.getMessage();
+ Message message = ((Definition)parents.get(parents.size() - 1)).getMessage(messageQName);
+ if (message == null)
+ {
+ // message undefined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_HEADER_MESSAGE_UNDEFINED, QUOTE + messageQName.getLocalPart() + QUOTE), soapHeader);
+ }
+ else
+ {
+ String partname = soapHeader.getPart();
+ Part part = message.getPart(partname);
+ if (part == null)
+ {
+ // part undefined
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_HEADER_PART_UNDEFINED,
+ QUOTE + partname + QUOTE,
+ QUOTE + messageQName.getLocalPart() + QUOTE), soapHeader);
+ }
+ }
+
+ String use = soapHeader.getUse();
+ if (use != null && !use.equalsIgnoreCase(LITERAL) && !use.equalsIgnoreCase(ENCODED))
+ {
+ // use undefined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_HEADER_USE_UNDEFINED, QUOTE + use + QUOTE), soapHeader);
+ }
+
+ if (use.equalsIgnoreCase(ENCODED))
+ {
+ List encodingStyles = soapHeader.getEncodingStyles();
+ if (encodingStyles == null || encodingStyles.isEmpty())
+ {
+ // no encodingStyle defined
+ valInfo.addError(messagegenerator.getString(_ERROR_HEADER_ENCODINGSTYLE_UNDEFINED), soapHeader);
+ }
+
+ String namespace = soapHeader.getNamespaceURI();
+ if (namespace == null || namespace.equalsIgnoreCase(EMPTY_STRING))
+ {
+ // no namespace defined
+ valInfo.addError(messagegenerator.getString(_ERROR_HEADER_NAMESPACE_UNDEFINED), soapHeader);
+ }
+ }
+
+ List headerFaults = soapHeader.getSOAPHeaderFaults();
+ if (headerFaults != null)
+ {
+ Iterator iheaderFaults = headerFaults.iterator();
+ while (iheaderFaults.hasNext())
+ {
+ validateHeaderFault(iheaderFaults.next(), parents, valInfo);
+ }
+ }
+
+ Binding binding = (Binding)parents.get(2);
+ if (!hasSoapBinding(binding))
+ {
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_NO_SOAPBINDING_FOR_HEADER, QUOTE + binding.getQName().getLocalPart() + QUOTE), soapHeader);
+ }
+ }
+
+ /**
+ * A SOAP headerfault must have a message, part and use defined. If the use is encoded, must
+ * also have a non-empty encodingStyle and namespace defined.
+ *
+ * @param element The SOAP header fault element.
+ * @param parents A list of parents of the SOAP header fault element.
+ * @param valInfo The validation info for this validation.
+ */
+ protected void validateHeaderFault(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ SOAPHeaderFaultImpl soapHeaderFault = (SOAPHeaderFaultImpl)element;
+
+ QName messageQName = soapHeaderFault.getMessage();
+ Message message = ((Definition)parents.get(parents.size() - 1)).getMessage(messageQName);
+ if (message == null)
+ {
+ // message undefined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_HEADERFAULT_MESSAGE_UNDEFINED, QUOTE + messageQName.getLocalPart() + QUOTE), soapHeaderFault);
+ }
+ else
+ {
+ String partname = soapHeaderFault.getPart();
+ Part part = message.getPart(partname);
+ if (part == null)
+ {
+ // part undefined
+ valInfo.addError(
+ messagegenerator.getString(
+ _ERROR_HEADERFAULT_PART_UNDEFINED,
+ QUOTE + partname + QUOTE,
+ QUOTE + messageQName.getLocalPart() + QUOTE), soapHeaderFault);
+ }
+ }
+
+ String use = soapHeaderFault.getUse();
+ if (use != null && !use.equalsIgnoreCase(LITERAL) && !use.equalsIgnoreCase(ENCODED))
+ {
+ // use undefined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_HEADERFAULT_USE_UNDEFINED, QUOTE + use + QUOTE), soapHeaderFault);
+ }
+
+ if (use.equalsIgnoreCase(ENCODED))
+ {
+ List encodingStyles = soapHeaderFault.getEncodingStyles();
+ if (encodingStyles == null || encodingStyles.isEmpty())
+ {
+ // no encodingStyle defined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_HEADERFAULT_ENCODINGSTYLE_UNDEFINED), soapHeaderFault);
+ }
+
+ String namespace = soapHeaderFault.getNamespaceURI();
+ if (namespace == null || namespace.equalsIgnoreCase(EMPTY_STRING))
+ {
+ // no namespace defined
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_HEADERFAULT_NAMESPACE_UNDEFINED), soapHeaderFault);
+ }
+ }
+ }
+
+ /**
+ * Validate the SOAP fault. A SOAP fault must have a name defined that corresponds with the name
+ * specified in the portType. If encoded a fault must have an encodingStyle and a namespaceURI.
+ *
+ * @param element The SOAP fault element.
+ * @param parents A list of parents of the SOAP fault element.
+ * @param validationInfo The validation info for this validation.
+ */
+ protected void validateFault(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ SOAPFaultImpl fault = (SOAPFaultImpl)element;
+
+ String name = fault.getName();
+
+ String parentName = ((BindingFault)parents.get(0)).getName();
+
+ if (!name.equals(parentName))
+ {
+ valInfo.addError(
+ messagegenerator.getString(_ERROR_INVALID_FAULT_NAME, QUOTE + name + QUOTE, QUOTE + parentName + QUOTE), fault);
+ }
+
+ }
+
+ /**
+ * Method hasSoapBinding. - helper Method
+ * Given a binding returns true if it has a SOAP binding defined.
+ *
+ * @param binding - the SOAP binding to check
+ * @return true if a binding has a SOAP binding defined, false otherwise
+ */
+ protected boolean hasSoapBinding(Binding binding)
+ {
+ if (binding != null)
+ {
+ List extelems = binding.getExtensibilityElements();
+ if (extelems != null)
+ {
+ Iterator iextelems = extelems.iterator();
+ while (iextelems.hasNext())
+ {
+ if (iextelems.next().getClass() == SOAPBindingImpl.class)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/DOMError.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/DOMError.java
new file mode 100644
index 000000000..329b1118b
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/DOMError.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.xsd;
+
+/**
+ * This interface is used to signify error levels that are the result of
+ * XMLParseException. They conceptually correspond to org.w3c.dom.DOMError but
+ * we use our own interface, since DOMError is not in Java 1.4, and its
+ * package changes from Xerces 2.6.2 and Xerces 2.7.0.
+ */
+
+public interface DOMError {
+ int SEVERITY_WARNING = 1;
+ int SEVERITY_ERROR = 2;
+ int SEVERITY_FATAL_ERROR = 3;
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/FileEntityResolver.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/FileEntityResolver.java
new file mode 100644
index 000000000..2119778f3
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/FileEntityResolver.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.xerces.xni.XMLResourceIdentifier;
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.eclipse.wst.wsdl.validation.internal.util.LazyURLInputStream;
+
+/**
+ * Entity resolve to resolve file entities.
+ */
+public class FileEntityResolver implements XMLEntityResolver
+{
+
+ /**
+ * @see org.apache.xerces.xni.parser.XMLEntityResolver#resolveEntity(org.apache.xerces.xni.XMLResourceIdentifier)
+ */
+ public XMLInputSource resolveEntity(XMLResourceIdentifier resource) throws XNIException, IOException
+ {
+ String publicId = resource.getPublicId();
+ String systemId = resource.getExpandedSystemId();
+ String namespace = resource.getNamespace();
+ String url = null;
+ if(systemId != null)
+ {
+ url = systemId;
+ }
+ else if(publicId != null)
+ {
+ url = publicId;
+ }
+ else if(namespace != null)
+ {
+ url = namespace;
+ }
+ if(url != null)
+ {
+ InputStream is = new LazyURLInputStream(url);
+ return new XMLInputSource(publicId, resource.getExpandedSystemId(), resource.getExpandedSystemId(), is, null);
+ }
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaGenerator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaGenerator.java
new file mode 100644
index 000000000..1792ec172
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaGenerator.java
@@ -0,0 +1,667 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Vector;
+
+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;
+
+/**
+ * Generate a String representation of a schema for an inline schema. Will add imports for unresolved
+ * namespaces.
+ */
+public class InlineSchemaGenerator
+{
+ protected static final String SOAP_ENCODING_URI = "http://schemas.xmlsoap.org/soap/encoding/";
+ protected static final String FILE_PREFIX = "file:///";
+ protected static final String XMLNS = "xmlns";
+ protected static final String TARGETNAMESPACE = "targetNamespace";
+ protected static final String NAMESPACE = "namespace";
+ protected static final String IMPORT = "import";
+ protected static final String INCLUDE = "include";
+ protected static final String SCHEMA = "schema";
+ protected static final String SCHEMALOCATION = "schemaLocation";
+ protected static final String TYPE = "type";
+ protected static final String NAME = "name";
+ protected static final String[] ignoreNamespaces =
+ { Constants.NS_URI_XSD_1999, Constants.NS_URI_XSD_2000, Constants.NS_URI_XSD_2001 };
+
+ protected static InlineSchemaGenerator instance = null;
+
+ /**
+ * Constructor.
+ */
+ protected InlineSchemaGenerator()
+ {
+ }
+
+ /**
+ * Get the instance of the InlineSchemaGenerator.
+ *
+ * @return The instance of the inline schema generator.
+ */
+ protected static InlineSchemaGenerator getInstance()
+ {
+ if (instance == null)
+ {
+ instance = new InlineSchemaGenerator();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a string representation of a schema from the element provided.
+ *
+ * @param element The root element of the schema.
+ * @param elements A list of the elements in the schema in order.
+ * @param filelocation The URI of the file that contains the schema.
+ * @param validImportNSs A set of namespaces for which it's valid to create import statements.
+ * @return A string representation of a schema.
+ */
+ public static String createXSDString(Element element, List elements, String filelocation, Set validImportNSs)
+ {
+ return InlineSchemaGenerator.createXSDString(element, elements, filelocation, new Hashtable(), validImportNSs);
+ }
+
+ /**
+ * Creates a String representing the schema model with the root element of
+ * extElem. Calls createXSDStringRecursively to take care of building the String
+ * after it obtains the Element from the UnknownExtensibilityElement.
+ *
+ * @param element The root element of the schema.
+ * @param elements A list to contain the elements in the schema in order.
+ * @param filelocation The location of the file the schema is located in.
+ * @param parentNSs A hashtable of parent namespaces to used to resolve prefixes.
+ * @param validImportNSs A set of namespaces for which it's valid to create import statements.
+ * @return A string representation of the schema with the root element 'element'.
+ */
+ public static String createXSDString(Element element, List elements, String filelocation, Hashtable parentNSs, Set validImportNSs)
+ {
+ Set importNSs = new TreeSet();
+ importNSs.addAll(validImportNSs);
+ importNSs.add(SOAP_ENCODING_URI);
+
+ InlineSchemaGenerator schemaGenerator = InlineSchemaGenerator.getInstance();
+ Hashtable nsResolver = schemaGenerator.getNSResolver(element);
+ List reqns = schemaGenerator.getNamespacePrefixes(element);
+ Hashtable reqNSDecl = schemaGenerator.resolveNamespaces(reqns, nsResolver, parentNSs);
+ //Hashtable reqNSDecl = schemaGenerator.getRequiredNSDeclarations(reqns, nsResolver, parentNSs);
+ List importNS = schemaGenerator.getImportNamespaces(element);
+ reqns = schemaGenerator.removeImports(reqns, importNS);
+ reqns = schemaGenerator.removeLocalNamespaces(reqns, element);
+ reqns = schemaGenerator.restrictImports(reqns, validImportNSs);
+ return schemaGenerator.createXSDStringRecursively(element, elements, reqns, reqNSDecl, filelocation);
+ }
+ /**
+ * Returns true if the SOAP encoding namespace is required but not imported.
+ *
+ * @param element The root element of the schema.
+ * @param filelocation The location of the file containing the schema.
+ * @param parentNSs A hashtable of the parent namespaces.
+ * @return True if the soap encoding namespace is required but not imported, false otherwise.
+ */
+ public static boolean soapEncodingRequiredNotImported(Element element, String filelocation, Hashtable parentNSs)
+ {
+ InlineSchemaGenerator schemaGenerator = InlineSchemaGenerator.getInstance();
+ Hashtable nsResolver = schemaGenerator.getNSResolver(element);
+ List reqns = null;
+
+ reqns = schemaGenerator.getNamespacePrefixes(element);
+ schemaGenerator.resolveNamespaces(reqns, nsResolver, parentNSs);
+ //schemaGenerator.resolveUndeclaredNamespaces(reqns, parentNSs);
+ List importNS = schemaGenerator.getImportNamespaces(element);
+ reqns = schemaGenerator.removeImports(reqns, importNS);
+ reqns = schemaGenerator.removeLocalNamespaces(reqns, element);
+ return schemaGenerator.checkSOAPEncodingRequired(reqns);
+ }
+ /**
+ * Resolve the undeclared namespaces.
+ *
+ * @param unresolvedNSs A list of unresolved namespaces.
+ * @param nsResolver The namespace resolver to use.
+ * @return A hashtable of prefixes and namespaces.
+ */
+// protected Hashtable resolveUndeclaredNamespaces(List unresolvedNSs, Hashtable nsResolver)
+// {
+// Hashtable namespaces = new Hashtable();
+// if (unresolvedNSs != null && !unresolvedNSs.isEmpty() && nsResolver != null)
+// {
+// for (int i = unresolvedNSs.size() - 1; i >= 0; i--)
+// {
+// String ns = (String)unresolvedNSs.get(i);
+// if (ns.equals(""))
+// {
+// ns = XMLNS;
+// }
+// else
+// {
+// ns = XMLNS + ":" + ns;
+// }
+// if (nsResolver.containsKey(ns))
+// {
+// //namespaces.remove(i);
+// //namespaces.add(i, nsResolver.get(ns));
+// namespaces.put(ns, nsResolver.get(ns));
+// unresolvedNSs.remove(i);
+// unresolvedNSs.add(i, nsResolver.get(ns));
+// }
+// }
+// }
+// return namespaces;
+// }
+
+ /**
+ * This recursive method creates the schema String from the root Element.
+ *
+ * @param elem The root element of the schema.
+ * @param elements A list to be created of the elements in the schema in order.
+ * @param requiredNamespaces A list of required namespaces.
+ * @param reqNSDecl A hashtable of required namespace declarations.
+ * @param filelocation The uri of the file that contains this schema.
+ * @return A string representation of this schema.
+ */
+ protected String createXSDStringRecursively(
+ Element elem,
+ List elements,
+ List requiredNamespaces,
+ Hashtable reqNSDecl,
+ String filelocation)
+ {
+ if (elem == null)
+ return ""; // just in case
+
+ elements.add(elem);
+
+ StringBuffer xsdString = new StringBuffer();
+ String elementName = elem.getTagName();
+ xsdString.append("<").append(elementName);
+
+ boolean foundSchemaLocation = false; // flag if schemalocation is defined
+ String namespace = ""; // the namespace if we're checking an import or include
+ String namePrefix = ""; // the xmlns prefix used for the elements
+ // Get all of the attributes for this element and append them to the xsdString
+ NamedNodeMap atts = elem.getAttributes();
+ for (int i = 0; i < atts.getLength(); i++)
+ {
+ Node n = atts.item(i);
+ xsdString.append(" ").append(n.getNodeName()).append("=\"");
+ String nodeName = n.getNodeName();
+ if (nodeName.equalsIgnoreCase(SCHEMALOCATION) && filelocation != null)
+ {
+ foundSchemaLocation = true;
+ String relativePath = n.getNodeValue();
+ xsdString.append(relativePath).append("\"");
+ }
+ else
+ {
+ String nodeValue = n.getNodeValue();
+ if (nodeName.equalsIgnoreCase(NAMESPACE))
+ {
+ namespace = nodeValue;
+ }
+ // get the name prefix for this schema to use in generating import statements
+ else if (nodeName.indexOf(XMLNS) != -1)
+ {
+
+ if (nodeValue.equalsIgnoreCase(elem.getNamespaceURI()))
+ {
+ namePrefix = nodeName;
+ if (namePrefix.equalsIgnoreCase(XMLNS))
+ {
+ namePrefix = "";
+ }
+ else
+ {
+ namePrefix = namePrefix.substring(6) + ":";
+ }
+ }
+ }
+ // Replace old schema namespaces with the new schema namespace.
+ if(nodeValue.equals(Constants.NS_URI_XSD_1999) || nodeValue.equals(Constants.NS_URI_XSD_2000))
+ {
+ nodeValue = Constants.NS_URI_XSD_2001;
+ }
+ xsdString.append(nodeValue).append("\"");
+ }
+ }
+ if (elementName.equalsIgnoreCase("import") && !foundSchemaLocation)
+ {
+ xsdString.append(" ").append(SCHEMALOCATION).append("=\"").append(namespace).append("\"");
+ }
+ // add in any required NS declarations from parent elements
+ if (reqNSDecl != null)
+ {
+ Enumeration keys = reqNSDecl.keys();
+ while (keys.hasMoreElements())
+ {
+ String key = (String)keys.nextElement();
+ String declNS = (String)reqNSDecl.get(key);
+ if(declNS.equals(Constants.NS_URI_XSD_1999) || declNS.equals(Constants.NS_URI_XSD_2000))
+ {
+ declNS = Constants.NS_URI_XSD_2001;
+ }
+ xsdString.append(" ").append(key).append("=\"").append(declNS).append("\"");
+ }
+
+ }
+ xsdString.append(">");
+ if (requiredNamespaces != null)
+ {
+ Iterator iRequiredNamespaces = requiredNamespaces.iterator();
+ while (iRequiredNamespaces.hasNext())
+ {
+ String ns = (String)iRequiredNamespaces.next();
+
+ xsdString
+ .append("<")
+ .append(namePrefix)
+ .append(IMPORT)
+ .append(" ")
+ .append(NAMESPACE)
+ .append("=\"")
+ .append(ns)
+ .append("\" ")
+ .append(SCHEMALOCATION)
+ .append("=\"")
+ .append(ns)
+ .append("\"/>");
+ }
+
+ }
+ xsdString.append("\n");
+
+ // 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;
+ xsdString.append(createXSDStringRecursively(child, elements, null, null, filelocation));
+ }
+ }
+
+ xsdString.append("</").append(elem.getTagName()).append(">");
+
+ return xsdString.toString();
+
+ }
+ /**
+ * Get a list of all the namespace prefixes that are used for elements or types in the schema.
+ *
+ * @param elem The root element of the schema to check for namespace prefixes.
+ * @return A list of namespace prefixes for the element and all its children.
+ */
+ protected List getNamespacePrefixes(Element elem)
+ {
+ List namespace = new ArrayList();
+
+ // call the method recursively for each child element
+ // register all the child types first
+ NodeList childNodes = elem.getChildNodes();
+ int numChildren = childNodes.getLength();
+ for (int i = 0; i < numChildren; i++)
+ {
+ Node n = childNodes.item(i);
+ // we only want nodes that are Elements
+ if (n instanceof Element)
+ {
+ Element child = (Element)n;
+ List childns = getNamespacePrefixes(child);
+ for (int j = childns.size() - 1; j >= 0; j--)
+ {
+ String ns = (String)childns.get(j);
+
+ if (!namespace.contains(ns))
+ {
+ namespace.add(ns);
+ }
+ }
+ }
+ }
+ // Add the namespace of the current element
+ String elemNS = elem.getPrefix();
+ // if there is no namespace prefix set it to the empty prefix.
+ if(elemNS == null)
+ {
+ elemNS = "";
+ }
+ if (!namespace.contains(elemNS))
+ {
+ namespace.add(elemNS);
+ }
+ // now add all of the current element's namespaces
+ // don't include import and schema elements
+ String localname = elem.getLocalName();
+ if (!localname.equals(IMPORT) && !localname.equals(INCLUDE) && !localname.equals(SCHEMA))
+ {
+ NamedNodeMap atts = elem.getAttributes();
+ for (int i = 0; i < atts.getLength(); i++)
+ {
+ Node n = atts.item(i);
+
+ String nodeName = n.getNodeName();
+ // removed restriction that we're only looking at types
+ // if (nodeName.equalsIgnoreCase(TYPE))
+ // {
+ // don't take namespace info from attributes defining namespaces.
+ // that includes xmlns, targetNamespace
+ if (nodeName.indexOf(XMLNS) != -1 || nodeName.equals(TARGETNAMESPACE) || nodeName.equals(NAME))
+ {
+ continue;
+ }
+ // Grab namespace prefixes from attributes.
+ else
+ {
+ int colonIndex = nodeName.indexOf(":");
+ if(colonIndex != -1 && (colonIndex + 1 < nodeName.length() && nodeName.charAt(colonIndex + 1) != '/'))
+ {
+ String prefix = nodeName.substring(0, colonIndex);
+ if (!namespace.contains(prefix))
+ {
+
+ namespace.add(prefix);
+ }
+ }
+ }
+ String nodeValue = n.getNodeValue();
+
+
+ int colonIndex = nodeValue.indexOf(":");
+ // Don't take namespace info from attributes with the default namespace, that is attributes
+ // that are not prefixed. (colonIndex == -1)
+ // If the colonIndex is followed by a / then it is a URI and not
+ // namespace qualified.
+ if (colonIndex == -1 || (colonIndex + 1 < nodeValue.length() && nodeValue.charAt(colonIndex + 1) == '/'))
+ {
+ continue;
+ }
+ // here we have found a colon delimiter so we need the namespace defined here
+ else
+ {
+ nodeValue = nodeValue.substring(0, colonIndex);
+ }
+ if (!namespace.contains(nodeValue))
+ {
+
+ namespace.add(nodeValue);
+ }
+ }
+ }
+
+ return namespace;
+
+ }
+
+ /**
+ * Get a list of all the namespaces that have an import statement.
+ *
+ * @param elem The root element of the schema.
+ * @return A list of all the namespaces that are imported.
+ */
+ protected List getImportNamespaces(Element elem)
+ {
+ List namespace = new Vector();
+
+ // call the method recursively for each child element
+ // register all the child types first
+ 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;
+ List childns = getImportNamespaces(child);
+ for (int j = childns.size() - 1; j >= 0; j--)
+ {
+ String ns = (String)childns.get(j);
+ if (!namespace.contains(ns))
+ {
+ namespace.add(ns);
+ }
+ }
+ }
+ }
+ // if this is an import element get the namespace and add it to the list
+ if (elem.getLocalName().equalsIgnoreCase(IMPORT))
+ {
+ NamedNodeMap atts = elem.getAttributes();
+ for (int i = 0; i < atts.getLength(); i++)
+ {
+ Node n = atts.item(i);
+
+ String nodeName = n.getNodeName();
+ if (nodeName.equalsIgnoreCase(NAMESPACE))
+ {
+ String nodeValue = n.getNodeValue();
+ if (!namespace.contains(nodeValue))
+ {
+
+ namespace.add(nodeValue);
+ }
+ }
+ }
+ }
+
+ return namespace;
+
+ }
+
+ /**
+ * Return a Hashtable with namespace prefixes as keys from the given element.
+ *
+ * @param elem The root element of the schema.
+ * @return A hashtable with namespace prefixes mapped to namespaces.
+ */
+ protected Hashtable getNSResolver(Element elem)
+ {
+ Hashtable nsResolver = new Hashtable();
+
+ NamedNodeMap atts = elem.getAttributes();
+ for (int i = 0; i < atts.getLength(); i++)
+ {
+ Node n = atts.item(i);
+
+ String nodeName = n.getNodeName();
+ if (nodeName.indexOf(XMLNS) != -1)
+ {
+ String nodeValue = n.getNodeValue();
+ String namePrefix = nodeName;
+
+ if (namePrefix.equalsIgnoreCase(XMLNS))
+ {
+ namePrefix = "";
+ }
+ else
+ {
+ namePrefix = namePrefix.substring(6);
+ }
+ nsResolver.put(namePrefix, nodeValue);
+
+ }
+ }
+ return nsResolver;
+
+ }
+
+ /**
+ * Resolve the namespaces in the given namespaces list with the two namespace
+ * resolver hashtables provided. Return a list of all the namespace that need
+ * to be declared.
+ * First resolve against the local namespaces with nsResolver.
+ * Next resolve against the parent namespace with parentNSResolver.
+ * A side affect of this method is the namespaces list is left with only those
+ * namespaces that are resolved and the resolved entities are placed in the
+ * list instead of the original entries.
+ * For ex. If you provide a list such as {xsd, intf} and only xsd can be resolved
+ * you will end up with the list {http://www.w3.org/2001/XMLSchema}
+ *
+ * @param namespaces The list of namespaces to resolve.
+ * @param nsResolver The hashtable to be used as the local resolver.
+ * @param parentNSResolver The hashtable to be used as the parent namespace resolver.
+ * @return A Hashtable of namespaces that must be declared.
+ */
+ protected Hashtable resolveNamespaces(List namespaces, Hashtable nsResolver, Hashtable parentNSResolver)
+ {
+ Hashtable reqNSDecl = new Hashtable();
+ if (namespaces != null && !namespaces.isEmpty() && nsResolver != null)
+ {
+ for (int i = namespaces.size() - 1; i >= 0; i--)
+ {
+ String ns = (String)namespaces.get(i);
+ // Remove the namespace from the list.
+ namespaces.remove(i);
+ // First try to resolve against the local namespace resolver.
+ if (nsResolver.containsKey(ns))
+ {
+ Object resolvedNS = nsResolver.get(ns);
+ // Only add the namespace if it's not already in the list.
+ if(!namespaces.contains(resolvedNS))
+ {
+ namespaces.add(i, nsResolver.get(ns));
+ }
+ }
+ // Next try to resolve against the parent namespace resolver.
+ else
+ {
+ if (ns.equals(""))
+ {
+ ns = XMLNS;
+ }
+ else
+ {
+ ns = XMLNS + ":" + ns;
+ }
+ if (parentNSResolver.containsKey(ns))
+ {
+ Object resolvedNS = parentNSResolver.get(ns);
+ // Only add the namespace if it's not already in the list.
+ if(!namespaces.contains(resolvedNS))
+ {
+ namespaces.add(i, resolvedNS);
+ }
+ // Still need to declare the namespace though.
+ reqNSDecl.put(ns, resolvedNS);
+ }
+ }
+
+ }
+ }
+ return reqNSDecl;
+ }
+
+ /**
+ * Remove any namespace from the namespaces list if it is in the import list.
+ *
+ * @param namespaces The namespaces list.
+ * @param importedNamespaces A list of imported namespaces.
+ * @return The list of namespaces without the imported namespaces.
+ */
+ protected List removeImports(List namespaces, List importedNamespaces)
+ {
+ if (namespaces != null && importedNamespaces != null && !importedNamespaces.isEmpty())
+ {
+ Iterator iImportedNS = importedNamespaces.iterator();
+ while (iImportedNS.hasNext())
+ {
+ String iNS = (String)iImportedNS.next();
+
+ namespaces.remove(iNS);
+ }
+ }
+ return namespaces;
+ }
+
+ /**
+ * Remove the local namespace for the schema and the namespaces listed in the ignoreNamespaces
+ * list from the namespaces list provided.
+ *
+ * @param namespaces The list of local namespaces.
+ * @param elem The root element of the schema.
+ * @return The list of namespaces with the local namespaces removed.
+ */
+ protected List removeLocalNamespaces(List namespaces, Element elem)
+ {
+ if (namespaces != null && elem != null)
+ {
+ String ns = elem.getAttribute(TARGETNAMESPACE);
+ namespaces.remove(ns);
+
+ for (int i = ignoreNamespaces.length - 1; i >= 0; i--)
+ {
+ // keep removing the namespace until it is not in the list
+ if (namespaces.remove(ignoreNamespaces[i]))
+ {
+ i++;
+ }
+ }
+ }
+ return namespaces;
+ }
+
+ /**
+ * Remove all the namespaces in the namespaces list that aren't contained in the
+ * validImportNSs set.
+ *
+ * @param namespaces A list of namespaces.
+ * @param validImportNSs A set of valid namespaces.
+ * @return A list of namespaces that does not contain any members which aren't in the validImportNSs set.
+ */
+ protected List restrictImports(List namespaces, Set validImportNSs)
+ {
+ Iterator nsIter = namespaces.iterator();
+ while(nsIter.hasNext())
+ {
+ String ns = (String)nsIter.next();
+ if(!validImportNSs.contains(ns))
+ {
+ namespaces.remove(ns);
+ nsIter = namespaces.iterator();
+ }
+ }
+ return namespaces;
+ }
+
+ /**
+ * Returns true if the SOAP encoding namespace is in the list of required namespaces,
+ * false otherwise.
+ *
+ * @param reqns The list of namespaces to check for the SOAP encoding namespace.
+ * @return True if the SOAP encoding namespaces is in the list, false otherwise.
+ */
+ protected boolean checkSOAPEncodingRequired(List reqns)
+ {
+ if (reqns.contains(SOAP_ENCODING_URI))
+ {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaValidator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaValidator.java
new file mode 100644
index 000000000..5b58f211c
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineSchemaValidator.java
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Types;
+import javax.wsdl.extensions.UnknownExtensibilityElement;
+
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xs.XSModel;
+import org.eclipse.wst.wsdl.validation.internal.util.ErrorMessage;
+import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator;
+import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11ValidationInfo;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import com.ibm.wsdl.Constants;
+
+/**
+ * Plugin validator for the WSDL Validation framework. Validates inline schema found in a WSDL document.
+ */
+public class InlineSchemaValidator implements IWSDL11Validator
+{
+ private final String _WARN_OLD_SCHEMA_NAMESPACE = "_WARN_OLD_SCHEMA_NAMESPACE";
+ private final String _WARN_SOAPENC_IMPORTED_SCHEMA = "_WARN_SOAPENC_IMPORTED_SCHEMA";
+ private final String EMPTY_STRING = "";
+ private final String QUOTE = "'";
+ MessageGenerator messagegenerator = null;
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator#validate(java.lang.Object, java.util.List, org.eclipse.wsdl.validate.wsdl11.WSDL11ValidationInfo)
+ */
+ public void validate(Object element, List parents, IWSDL11ValidationInfo valInfo)
+ {
+ List elements = new ArrayList();
+ UnknownExtensibilityElement elem = (UnknownExtensibilityElement) element;
+ Definition wsdlDefinition = (Definition) parents.get(parents.size() - 1);
+ String baseLocation = wsdlDefinition.getDocumentBaseURI();
+ // Add in the namespaces defined in the doc already that aren't defined locally in this schema.
+ // There is no need to check for namespaces other then in the defintions and types elements as
+ // inline schema can not have any other parents and must have there two parents.
+ // First take care of the definitions element
+
+ // create the inline schema string
+ Element w3celement = elem.getElement();
+ Hashtable parentnamespaces = getNamespaceDeclarationsFromParents(wsdlDefinition,w3celement);
+ String targetNamespace = w3celement.getAttribute(Constants.ATTR_TARGET_NAMESPACE);
+ // if the targetNamespace hasn't been defined for the schema use the
+ // targetNamespace of the definitions element
+ if(targetNamespace == null || targetNamespace.equals(EMPTY_STRING))
+ {
+ targetNamespace = wsdlDefinition.getTargetNamespace();
+ w3celement.setAttribute(Constants.ATTR_TARGET_NAMESPACE,targetNamespace);
+ }
+
+ // If the namespace given is one of the old schema namespaces produce a warning.
+ String namespace = w3celement.getNamespaceURI();
+ if(namespace.equals(Constants.NS_URI_XSD_1999) || namespace.equals(Constants.NS_URI_XSD_2000))
+ {
+ valInfo.addWarning(
+ messagegenerator.getString(_WARN_OLD_SCHEMA_NAMESPACE, QUOTE + Constants.NS_URI_XSD_2001 + QUOTE), element);
+ }
+
+ // now create and call the validator for the inline schema
+ XSDValidator schemav = new XSDValidator();
+
+ //String fileLocation = new URL(validatormanager.getFilename()).getPath();
+ InlineXSDResolver inlineEntityResolver =
+ getEntityResolver(wsdlDefinition, (Types) parents.get(0), baseLocation, targetNamespace);
+ // add in the external XSD Catalog to resolve schemas offline
+ XMLEntityResolverChain entityResolverChain = new XMLEntityResolverChain();
+ entityResolverChain.addEntityResolver(inlineEntityResolver);
+ entityResolverChain.addEntityResolver((XMLEntityResolver)valInfo.getURIResolver());
+ //entityResolverChain.addEntityResolver(XMLCatalogResolver.getInstance());
+ entityResolverChain.addEntityResolver(new FileEntityResolver());
+
+ // Create the string representation of the inline schema.
+ String xsd = InlineSchemaGenerator.createXSDString(w3celement, elements, baseLocation, parentnamespaces, inlineEntityResolver.getInlineSchemaNSs());
+
+
+ schemav.validateInlineSchema(xsd, targetNamespace, baseLocation, entityResolverChain, inlineEntityResolver);
+
+// check if the SOAP Encoding namespace is required but not imported
+ if (InlineSchemaGenerator.soapEncodingRequiredNotImported(elem.getElement(), baseLocation, parentnamespaces))
+ {
+ valInfo.addWarning(messagegenerator.getString(_WARN_SOAPENC_IMPORTED_SCHEMA), element);
+ }
+
+ // If the schema isn't valid add the error messages produced to valinfo.
+ // Don't add the errors if they are located on another inline schema. These
+ // will be reported when the other schema is validated.
+
+ if (!schemav.isValid())
+ {
+ Iterator errors = schemav.getErrors().iterator();
+ while (errors.hasNext())
+ {
+ ErrorMessage err = (ErrorMessage) errors.next();
+ String uri = err.getURI();
+ int line = err.getErrorLine();
+ String errmess = err.getErrorMessage();
+ errmess = replaceNamespace(errmess, namespace);
+ if(line > 0)
+ {
+ if(uri == null || uri.equals(valInfo.getFileURI()))
+ {
+ valInfo.addError(errmess, getObjectAtLine(line - 1, elements));
+ }
+ else if(!inlineEntityResolver.isInlineSchema(uri) && !uri.equals(valInfo.getFileURI() + InlineXSDResolver.INLINE_SCHEMA_ID))
+ {
+ valInfo.addError(errmess, line, err.getErrorColumn(), uri);
+ }
+ }
+ else if(uri != null && !inlineEntityResolver.isInlineSchema(uri) && !uri.equals(valInfo.getFileURI() + InlineXSDResolver.INLINE_SCHEMA_ID))
+ {
+ valInfo.addError(errmess, 0,0, uri);
+ }
+ }
+ }
+ // if the schema is valid, assign the model to the validatormanager
+ else
+ {
+ XSModel xsModel = schemav.getXSModel();
+ valInfo.addSchema(xsModel);
+ }
+ }
+
+ /**
+ * Get an entity resolver that will resolve inline schemas. Every inline schema is preregistered with
+ * the resolver.
+ *
+ * @param wsdlDefinition The WSDL definitions element.
+ * @param types The types element.
+ * @param referenceLocation The location of the file that contains this schema.
+ * @param targetNamespace The targetNamespace of the schema.
+ * @return An entity resolver that can resolve inline schemas.
+ */
+ protected InlineXSDResolver getEntityResolver(Definition wsdlDefinition, Types types, String referenceLocation, String targetNamespace)
+ {
+ InlineXSDResolver entityResolver = new InlineXSDResolver();
+// entityResolver.setReferenceLocation(referenceLocation);
+ List schemas = types.getExtensibilityElements();
+ if (schemas != null)
+ {
+ Iterator iSchemas = schemas.iterator();
+ Set namespaces = new TreeSet();
+ while (iSchemas.hasNext())
+ {
+ UnknownExtensibilityElement extElem = (UnknownExtensibilityElement) iSchemas.next();
+ String thisNamespace = extElem.getElement().getAttribute(Constants.ATTR_TARGET_NAMESPACE);
+ if(thisNamespace != null)
+ {
+ namespaces.add(thisNamespace);
+ }
+ }
+ iSchemas = schemas.iterator();
+
+ while (iSchemas.hasNext())
+ {
+ UnknownExtensibilityElement extElem = (UnknownExtensibilityElement) iSchemas.next();
+ String thisNamespace = extElem.getElement().getAttribute(Constants.ATTR_TARGET_NAMESPACE);
+ if (thisNamespace != null && !thisNamespace.equalsIgnoreCase(targetNamespace))
+ {
+
+ Element element = extElem.getElement();
+
+// create the inline schema string
+ //Element w3celement = elem.getElement();
+ Hashtable parentnamespaces = getNamespaceDeclarationsFromParents(wsdlDefinition,element);
+ String xsd = InlineSchemaGenerator.createXSDString(element, new ArrayList(), referenceLocation, parentnamespaces, namespaces);
+ //addNamespaceDeclarationsFromParents(wsdlDefinition,element);
+ entityResolver.add(thisNamespace, xsd);
+ }
+
+ }
+ }
+ return entityResolver;
+ }
+
+ /**
+ * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.validator.IWSDL11Validator#setResourceBundle(java.util.ResourceBundle)
+ */
+ public void setResourceBundle(ResourceBundle rb)
+ {
+ messagegenerator = new MessageGenerator(rb);
+ }
+
+ public void setMessageGenerator(MessageGenerator messgen)
+ {
+ messagegenerator = messgen;
+ }
+
+ /**
+ * Get the namespace declarations as in the form
+ * xmlns="somenamespace"
+ * from the definitions and types elements and add them to the schema element so the schema
+ * validator will have access to them.
+ *
+ * @param wsdlDefinition The WSDL definitions element.
+ * @param element The types element.
+ * @return A hashtable with the namespace elements from the elements provided.
+ */
+ protected Hashtable getNamespaceDeclarationsFromParents(Definition wsdlDefinition, Element element)
+ {
+ Hashtable nss = new Hashtable();
+ Iterator nameSpaces = wsdlDefinition.getNamespaces().keySet().iterator();
+
+ String XMLNS = Constants.ATTR_XMLNS;
+
+ String schemaLocation = "";
+ while (nameSpaces.hasNext())
+ {
+ String nsprefix = XMLNS;
+ String ns = (String) nameSpaces.next();
+ if (!ns.equalsIgnoreCase(""))
+ {
+ nsprefix += ":";
+ }
+ if (!element.hasAttribute(nsprefix + ns))
+ {
+ nss.put(nsprefix + ns, wsdlDefinition.getNamespace(ns));
+// element.setAttribute(nsprefix + ns, wsdlDefinition.getNamespace(ns));
+ }
+
+ }
+ // Next handle the parent types element
+ NamedNodeMap atts = element.getParentNode().getAttributes();
+ int attslength = atts.getLength();
+ for (int i = 0; i < attslength; i++)
+ {
+ Node tempnode = atts.item(i);
+ String nodename = tempnode.getNodeName();
+ // if this is a namespace attribute
+ if (nodename.indexOf(XMLNS) != -1)
+ {
+ nss.put(nodename, tempnode.getNodeValue());
+ //element.setAttribute(nodename, tempnode.getNodeValue());
+ }
+ }
+ return nss;
+ }
+
+ /**
+ * Given a line number for the schema returns the element found on that line.
+ * Useful for obtaining elements from schema Strings.
+ *
+ * @param line The line number for the schema.
+ * @param elements The list of elements to check.
+ * @return The object located at the line or at line 0 if the line is invalid.
+ */
+ protected Object getObjectAtLine(int line, List elements)
+ {
+ if(line < 0 || line >= elements.size())
+ {
+ line = 0;
+ }
+ return elements.get(line);
+ }
+
+ /**
+ * Replace any instance of the 2001 schema namespace in the given message with
+ * the given namespace.
+ *
+ * @param message The message to replace the namespace in.
+ * @param namespace The namespace used for replacement.
+ * @return The message with the 2001 schema namespace replaced by the given namespace.
+ */
+ private String replaceNamespace(String message, String namespace)
+ {
+ String xsd2001 = Constants.NS_URI_XSD_2001;
+ int start = message.indexOf(xsd2001);
+ int end = start + xsd2001.length();
+ if(start < 0)
+ {
+ return message;
+ }
+ String startString = message.substring(0,start);
+ String endString = message.substring(end,message.length());
+ return startString + namespace + endString;
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineXSDResolver.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineXSDResolver.java
new file mode 100644
index 000000000..5f87b3951
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/InlineXSDResolver.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Hashtable;
+import java.util.Set;
+
+import org.apache.xerces.xni.XMLResourceIdentifier;
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xni.parser.XMLInputSource;
+
+/**
+ * An XMLEntityResolver that allows inline schemas to resolve each other through imports.
+ */
+public class InlineXSDResolver implements XMLEntityResolver
+{
+ public static final String INLINE_SCHEMA_ID = "#inlineschema";
+ protected final String FILE_PREFIX = "file:";
+ protected final String XMLNS = "xmlns";
+ protected Hashtable entities = new Hashtable();
+// protected String refLocation = null;
+ protected XMLEntityResolver externalResolver = null;
+ protected XMLInputSource referringSchemaInputSource = null;
+ protected String referringSchemaNamespace = null;
+
+ /**
+ * Constuctor.
+ */
+ public InlineXSDResolver()
+ {
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.xerces.xni.parser.XMLEntityResolver#resolveEntity(org.apache.xerces.xni.XMLResourceIdentifier)
+ */
+ public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier)
+ throws XNIException, IOException {
+ String systemId = resourceIdentifier.getExpandedSystemId();
+ String publicId = resourceIdentifier.getPublicId();
+ String namespace = resourceIdentifier.getNamespace();
+ XMLInputSource is = null;
+ Reader reader = null;
+ String schema = null;
+ if (systemId == null)
+ {
+ if(publicId == null)
+ {
+ if(namespace == null)
+ {
+ return null;
+ }
+ else
+ {
+ systemId = namespace;
+ }
+ }
+ else
+ {
+ systemId = publicId;
+ }
+ }
+
+ if(referringSchemaNamespace != null && referringSchemaNamespace.equals(systemId))
+ {
+ if(referringSchemaInputSource!=null)
+ {
+ return referringSchemaInputSource;
+ }
+ }
+ else if ((schema = (String) entities.get(systemId)) != null && !schema.equals(""))
+ {
+ is = new XMLInputSource(publicId, referringSchemaInputSource.getSystemId() + INLINE_SCHEMA_ID, null, new StringReader(schema),null);
+ }
+
+ //if(is == null)
+ //{
+ // throw new IOException();
+ //}
+ return is;
+ }
+
+ /**
+ * Add an inline schema.
+ *
+ * @param targetNamespace - the target namespace of the schema
+ * @param schema - a string representation of the schema
+ */
+ public void add(String targetNamespace, String schema)
+ {
+ entities.put(targetNamespace, schema);
+ }
+
+ /**
+ * Add the referring inline schema.
+ *
+ * @param inputSource - a representation of the inline schema
+ * @param namespace - the namespace of the inline schema
+ */
+ public void addReferringSchema(XMLInputSource inputSource, String namespace)
+ {
+ referringSchemaInputSource = inputSource;
+ referringSchemaNamespace = namespace;
+ }
+
+ /**
+ * Return true if the namespace corresponds to an inline schema, false otherwise.
+ *
+ * @param namespace The namespace of the schema.
+ * @return True if the namespace corresponds to an inline schema, false otherwise.
+ */
+ public boolean isInlineSchema(String namespace)
+ {
+ return entities.containsKey(namespace);
+ }
+
+ /**
+ * Get the set of the inline schema namespaces.
+ *
+ * @return The set of the inline schema namespaces.
+ */
+ public Set getInlineSchemaNSs()
+ {
+ return entities.keySet();
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/SchemaAttributeTable.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/SchemaAttributeTable.java
new file mode 100644
index 000000000..fe43e121c
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/SchemaAttributeTable.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import org.apache.xerces.impl.xs.SchemaSymbols;
+import org.apache.xerces.util.SymbolTable;
+/**
+ * This class will allow the calling code to see if the attribute is defined in schema.
+ * This serves as schema for schema.
+ */
+public class SchemaAttributeTable extends SymbolTable
+{
+
+ /**
+ * Constructor.
+ */
+ public SchemaAttributeTable()
+ {
+ // add all of the sybols to the table. SchemaSymbols probably should have
+ // a SymbolTable for these but it doesn't
+
+ super.addSymbol(SchemaSymbols.ATTVAL_TWOPOUNDANY);
+ super.addSymbol(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL);
+ super.addSymbol(SchemaSymbols.ATTVAL_TWOPOUNDOTHER);
+ super.addSymbol(SchemaSymbols.ATTVAL_TWOPOUNDTARGETNS);
+ super.addSymbol(SchemaSymbols.ATTVAL_POUNDALL);
+ super.addSymbol(SchemaSymbols.ATTVAL_FALSE_0);
+ super.addSymbol(SchemaSymbols.ATTVAL_TRUE_1);
+ super.addSymbol(SchemaSymbols.ATTVAL_ANYSIMPLETYPE);
+ super.addSymbol(SchemaSymbols.ATTVAL_ANYTYPE);
+ super.addSymbol(SchemaSymbols.ATTVAL_ANYURI);
+ super.addSymbol(SchemaSymbols.ATTVAL_BASE64BINARY);
+ super.addSymbol(SchemaSymbols.ATTVAL_BOOLEAN);
+ super.addSymbol(SchemaSymbols.ATTVAL_BYTE);
+ super.addSymbol(SchemaSymbols.ATTVAL_COLLAPSE);
+ super.addSymbol(SchemaSymbols.ATTVAL_DATE);
+ super.addSymbol(SchemaSymbols.ATTVAL_DATETIME);
+ super.addSymbol(SchemaSymbols.ATTVAL_DAY);
+ super.addSymbol(SchemaSymbols.ATTVAL_DECIMAL);
+ super.addSymbol(SchemaSymbols.ATTVAL_DOUBLE);
+ super.addSymbol(SchemaSymbols.ATTVAL_DURATION);
+ super.addSymbol(SchemaSymbols.ATTVAL_ENTITY);
+ super.addSymbol(SchemaSymbols.ATTVAL_ENTITIES);
+ super.addSymbol(SchemaSymbols.ATTVAL_EXTENSION);
+ super.addSymbol(SchemaSymbols.ATTVAL_FALSE);
+ super.addSymbol(SchemaSymbols.ATTVAL_FLOAT);
+ super.addSymbol(SchemaSymbols.ATTVAL_HEXBINARY);
+ super.addSymbol(SchemaSymbols.ATTVAL_ID);
+ super.addSymbol(SchemaSymbols.ATTVAL_IDREF);
+ super.addSymbol(SchemaSymbols.ATTVAL_IDREFS);
+ super.addSymbol(SchemaSymbols.ATTVAL_INT);
+ super.addSymbol(SchemaSymbols.ATTVAL_INTEGER);
+ super.addSymbol(SchemaSymbols.ATTVAL_LANGUAGE);
+ super.addSymbol(SchemaSymbols.ATTVAL_LAX);
+ super.addSymbol(SchemaSymbols.ATTVAL_LIST);
+ super.addSymbol(SchemaSymbols.ATTVAL_LONG);
+ super.addSymbol(SchemaSymbols.ATTVAL_NAME);
+ super.addSymbol(SchemaSymbols.ATTVAL_NEGATIVEINTEGER);
+ super.addSymbol(SchemaSymbols.ATTVAL_MONTH);
+ super.addSymbol(SchemaSymbols.ATTVAL_MONTHDAY);
+ super.addSymbol(SchemaSymbols.ATTVAL_NCNAME);
+ super.addSymbol(SchemaSymbols.ATTVAL_NMTOKEN);
+ super.addSymbol(SchemaSymbols.ATTVAL_NMTOKENS);
+ super.addSymbol(SchemaSymbols.ATTVAL_NONNEGATIVEINTEGER);
+ super.addSymbol(SchemaSymbols.ATTVAL_NONPOSITIVEINTEGER);
+ super.addSymbol(SchemaSymbols.ATTVAL_NORMALIZEDSTRING);
+ super.addSymbol(SchemaSymbols.ATTVAL_NOTATION);
+ super.addSymbol(SchemaSymbols.ATTVAL_OPTIONAL);
+ super.addSymbol(SchemaSymbols.ATTVAL_POSITIVEINTEGER);
+ super.addSymbol(SchemaSymbols.ATTVAL_PRESERVE);
+ super.addSymbol(SchemaSymbols.ATTVAL_PROHIBITED);
+ super.addSymbol(SchemaSymbols.ATTVAL_QNAME);
+ super.addSymbol(SchemaSymbols.ATTVAL_QUALIFIED);
+ super.addSymbol(SchemaSymbols.ATTVAL_REPLACE);
+ super.addSymbol(SchemaSymbols.ATTVAL_REQUIRED);
+ super.addSymbol(SchemaSymbols.ATTVAL_RESTRICTION);
+ super.addSymbol(SchemaSymbols.ATTVAL_SHORT);
+ super.addSymbol(SchemaSymbols.ATTVAL_SKIP);
+ super.addSymbol(SchemaSymbols.ATTVAL_STRICT);
+ super.addSymbol(SchemaSymbols.ATTVAL_STRING);
+ super.addSymbol(SchemaSymbols.ATTVAL_SUBSTITUTION);
+ super.addSymbol(SchemaSymbols.ATTVAL_TIME);
+ super.addSymbol(SchemaSymbols.ATTVAL_TOKEN);
+ super.addSymbol(SchemaSymbols.ATTVAL_TRUE);
+ super.addSymbol(SchemaSymbols.ATTVAL_UNBOUNDED);
+ super.addSymbol(SchemaSymbols.ATTVAL_UNION);
+ super.addSymbol(SchemaSymbols.ATTVAL_UNQUALIFIED);
+ super.addSymbol(SchemaSymbols.ATTVAL_UNSIGNEDBYTE);
+ super.addSymbol(SchemaSymbols.ATTVAL_UNSIGNEDINT);
+ super.addSymbol(SchemaSymbols.ATTVAL_UNSIGNEDLONG);
+ super.addSymbol(SchemaSymbols.ATTVAL_UNSIGNEDSHORT);
+ super.addSymbol(SchemaSymbols.ATTVAL_YEAR);
+ super.addSymbol(SchemaSymbols.ATTVAL_YEARMONTH);
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/ValidateErrorHandler.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/ValidateErrorHandler.java
new file mode 100644
index 000000000..fda40a4d9
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/ValidateErrorHandler.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.parser.XMLErrorHandler;
+import org.apache.xerces.xni.parser.XMLParseException;
+import org.eclipse.wst.wsdl.validation.internal.util.ErrorMessage;
+
+/**
+ * An implementation of XMLErrorHandler that captures error from Xerces.
+ */
+public class ValidateErrorHandler implements XMLErrorHandler
+{
+ ArrayList errorList = new ArrayList();
+
+
+
+ /**
+ * Get the error messages created by Xerces.
+ *
+ * @return The errors list.
+ */
+ public List getErrorMessages()
+ {
+ return errorList;
+ }
+
+ /**
+ * Create a validation message from the exception and severity.
+ *
+ * @param error The error.
+ * @param severity The severity.
+ * @return An error message.
+ */
+ protected ErrorMessage createValidationMessageForException(XMLParseException error, int severity)
+ {
+ String uri = error.getLiteralSystemId();
+ if(uri == null)
+ {
+ uri = error.getPublicId();
+ }
+ ErrorMessage errorMessage = new ErrorMessage();
+ errorMessage.setErrorLine(error.getLineNumber());
+ errorMessage.setErrorMessage(error.getMessage());
+ errorMessage.setErrorColumn(error.getColumnNumber());
+ errorMessage.setURI(uri);
+ errorMessage.setSeverity(severity);
+ return errorMessage;
+ }
+
+ /**
+ * @see org.apache.xerces.xni.parser.XMLErrorHandler#error(java.lang.String, java.lang.String, org.apache.xerces.xni.parser.XMLParseException)
+ */
+ public void error(String arg0, String arg1, XMLParseException exception) throws XNIException
+ {
+ errorList.add(createValidationMessageForException(exception, DOMError.SEVERITY_ERROR));
+ }
+
+ /**
+ * @see org.apache.xerces.xni.parser.XMLErrorHandler#fatalError(java.lang.String, java.lang.String, org.apache.xerces.xni.parser.XMLParseException)
+ */
+ public void fatalError(String arg0, String arg1, XMLParseException exception) throws XNIException
+ {
+ errorList.add(createValidationMessageForException(exception, DOMError.SEVERITY_FATAL_ERROR));
+ }
+
+ /**
+ * @see org.apache.xerces.xni.parser.XMLErrorHandler#warning(java.lang.String, java.lang.String, org.apache.xerces.xni.parser.XMLParseException)
+ */
+ public void warning(String arg0, String arg1, XMLParseException exception) throws XNIException
+ {
+ errorList.add(createValidationMessageForException(exception, DOMError.SEVERITY_WARNING));
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XMLEntityResolverChain.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XMLEntityResolverChain.java
new file mode 100644
index 000000000..cf936152a
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XMLEntityResolverChain.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.xerces.xni.XMLResourceIdentifier;
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xni.parser.XMLInputSource;
+
+/**
+ * Handle a chain of entity resolvers.
+ */
+public class XMLEntityResolverChain implements XMLEntityResolver
+{
+ private List entityResolvers = new Vector();
+
+ /**
+ * @see org.apache.xerces.xni.parser.XMLEntityResolver#resolveEntity(org.apache.xerces.xni.XMLResourceIdentifier)
+ */
+ public XMLInputSource resolveEntity(XMLResourceIdentifier xmlResourceIdentifier) throws XNIException, IOException
+ {
+ XMLInputSource is = null;
+ Iterator entityResolverIter = entityResolvers.iterator();
+ while (entityResolverIter.hasNext())
+ {
+ XMLEntityResolver entityResolver = (XMLEntityResolver)entityResolverIter.next();
+ try
+ {
+ is = entityResolver.resolveEntity(xmlResourceIdentifier);
+ }
+ catch (XNIException e)
+ {
+ }
+ catch (IOException e)
+ {
+ }
+ if (is != null)
+ {
+ break;
+ }
+ }
+ // Throw and IOException if the file isn't found
+ if (is == null)
+ {
+ throw new IOException("Unable to locate file");
+ }
+ return is;
+ }
+
+ /**
+ * Add an entity resolver to this chain.
+ *
+ * @param entityResolver The resolver to add to the chain.
+ */
+ public void addEntityResolver(XMLEntityResolver entityResolver)
+ {
+ entityResolvers.add(entityResolver);
+ }
+}
diff --git a/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XSDValidator.java b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XSDValidator.java
new file mode 100644
index 000000000..1ed97f647
--- /dev/null
+++ b/bundles/org.eclipse.wst.wsdl.validation/src/org/eclipse/wst/wsdl/validation/internal/wsdl11/xsd/XSDValidator.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.xsd;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.List;
+
+import org.apache.xerces.parsers.XMLGrammarPreparser;
+import org.apache.xerces.util.XMLGrammarPoolImpl;
+import org.apache.xerces.xni.grammars.XMLGrammarDescription;
+import org.apache.xerces.xni.grammars.XMLGrammarLoader;
+import org.apache.xerces.xni.grammars.XMLGrammarPool;
+import org.apache.xerces.xni.grammars.XSGrammar;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.apache.xerces.xs.XSModel;
+
+
+/**
+ * Validate schemas from files or String.
+ */
+public class XSDValidator
+{
+ protected final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
+ protected final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
+ protected final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
+ protected final String SCHEMA_FULL_CHECKING_FEATURE_ID =
+ "http://apache.org/xml/features/validation/schema-full-checking";
+ protected final String CONTINUE_AFTER_FATAL_ERROR_ID = "http://apache.org/xml/features/continue-after-fatal-error";
+ protected final String FILE_PREFIX = "file:";
+ protected final String XMLNS = "xmlns";
+ protected final String TARGETNAMESPACE = "targetNamespace";
+ protected final String NAMESPACE = "namespace";
+ protected final String IMPORT = "import";
+ protected final String SCHEMALOCATION = "schemaLocation";
+ protected final String TYPE = "type";
+ protected final String[] ignoreNamespaces =
+ { "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/1999/XMLSchema" };
+
+ protected XSModel xsModel;
+ protected boolean isValidXSD;
+ protected List errors;
+ protected String filelocation;
+
+ /**
+ * Constructor.
+ */
+ public XSDValidator()
+ {
+ xsModel = null;
+ isValidXSD = false;
+ errors = null;
+ }
+ /**
+ * Validate an inline schema.
+ *
+ * @param schema A schema represented as a string.
+ * @param targetNamespace The target namespace of the schema.
+ * @param fileloc The uri of the file that contains the schema.
+ */
+ public void validateInlineSchema(String schema, String targetNamespace, String fileloc)
+ {
+ validateInlineSchema(schema, targetNamespace, fileloc, null, null);
+ }
+
+ /**
+ * Validate an inline schema and specify an entity resolver.
+ *
+ * @param schema This schema represented as a string.
+ * @param targetNamespace The target namespace of the schema.
+ * @param fileloc The uri of the file that contains this schema.
+ * @param entityResolverChain The entity resolver chain.
+ * @param inlineSchemaEntityResolver An inline schema resolver for this schema.
+ */
+ public void validateInlineSchema(
+ String schema,
+ String targetNamespace,
+ String fileloc,
+ XMLEntityResolver entityResolverChain,
+ XMLEntityResolver inlineSchemaEntityResolver)
+ {
+ filelocation = fileloc;
+
+ validateXSD(schema, true, entityResolverChain,targetNamespace, inlineSchemaEntityResolver);
+ }
+
+ /**
+ * Validate the file located at the uri specified with the given entity resolver.
+ *
+ * @param uri An absolute uri for the schema location.
+ * @param entityResolver An entity resolver to be used.
+ */
+ public void validate(String uri, XMLEntityResolver entityResolver)
+ {
+ validateXSD(uri, false, entityResolver, null, null);
+ }
+
+ /**
+ * Validate the schema.
+ *
+ * @param schema The schema or it's location.
+ * @param inlineXSD True if an inline schema, false otherwise.
+ * @param entityResolver An entity resolver to use.
+ * @param targetNamespace The target namespace of the schema being validated.
+ * @param inlineSchemaEntityResolver An inline schema entity resolver.
+ */
+ protected void validateXSD(String schema, boolean inlineXSD, XMLEntityResolver entityResolver, String targetNamespace, XMLEntityResolver inlineSchemaEntityResolver)
+ {
+ ValidateErrorHandler errorHandler = new ValidateErrorHandler();
+ errorHandler.getErrorMessages().clear();
+ try
+ {
+ XMLGrammarPreparser grammarPreparser = new XMLGrammarPreparser();
+ XMLGrammarPool grammarPool = new XMLGrammarPoolImpl();
+ grammarPreparser.setGrammarPool(grammarPool);
+
+ grammarPreparser.setErrorHandler(errorHandler);
+ if (entityResolver != null)
+ {
+ grammarPreparser.setEntityResolver(entityResolver);
+ }
+
+ try
+ {
+ XMLInputSource is = null;
+ // this allows support for the inline schema in WSDL documents
+ if (inlineXSD)
+ {
+
+ Reader reader = new StringReader(schema);
+ is = new XMLInputSource(null,filelocation,filelocation,reader,null);
+
+ ((InlineXSDResolver)inlineSchemaEntityResolver).addReferringSchema(is,targetNamespace);
+
+ }
+ // get the input source for an external schema file
+ else
+ {
+ is = new XMLInputSource(null,schema,schema);
+ }
+
+ grammarPreparser.registerPreparser(XMLGrammarDescription.XML_SCHEMA,null/*schemaLoader*/);
+ XMLGrammarLoader schemaLoader = grammarPreparser.getLoader(XMLGrammarDescription.XML_SCHEMA);
+
+ XSGrammar grammar = (XSGrammar)grammarPreparser.preparseGrammar(XMLGrammarDescription.XML_SCHEMA,is);
+ xsModel = grammar.toXSModel();
+ }
+ catch (Exception e)
+ {
+ //parser will return null pointer exception if the document is structurally invalid
+ //TODO: log error message
+ System.out.println(e);
+ }
+
+ errors = errorHandler.getErrorMessages();
+ }
+ catch (Exception e)
+ {
+ System.out.println(e);
+ }
+ if (errors.isEmpty())
+ {
+ isValidXSD = true;
+ }
+ }
+
+ /**
+ * Returns the XSModel created.
+ *
+ * @return The XSModel created.
+ */
+
+ public XSModel getXSModel()
+ {
+ return xsModel;
+ }
+ /**
+ * Returns true if the schema is valid, false otherwise.
+ *
+ * @return True if the schema is valid, false otherwise.
+ */
+ public boolean isValid()
+ {
+ return isValidXSD;
+ }
+
+ /**
+ * Return the error list.
+ *
+ * @return A list of error from the schema.
+ */
+ public List getErrors()
+ {
+ return errors;
+ }
+}

Back to the top