diff options
Diffstat (limited to 'bundles/org.eclipse.wst.wsi/wsitools/org/eclipse/wst/wsi/internal/profile/validator/impl/wsdl/WSDLValidatorImpl.java')
-rw-r--r-- | bundles/org.eclipse.wst.wsi/wsitools/org/eclipse/wst/wsi/internal/profile/validator/impl/wsdl/WSDLValidatorImpl.java | 2319 |
1 files changed, 2319 insertions, 0 deletions
diff --git a/bundles/org.eclipse.wst.wsi/wsitools/org/eclipse/wst/wsi/internal/profile/validator/impl/wsdl/WSDLValidatorImpl.java b/bundles/org.eclipse.wst.wsi/wsitools/org/eclipse/wst/wsi/internal/profile/validator/impl/wsdl/WSDLValidatorImpl.java new file mode 100644 index 000000000..7293901cf --- /dev/null +++ b/bundles/org.eclipse.wst.wsi/wsitools/org/eclipse/wst/wsi/internal/profile/validator/impl/wsdl/WSDLValidatorImpl.java @@ -0,0 +1,2319 @@ +/******************************************************************************* + * Copyright (c) 2002-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 - Initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.wsi.internal.profile.validator.impl.wsdl; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +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.Import; +import javax.wsdl.Message; +import javax.wsdl.Operation; +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.wsdl.extensions.UnknownExtensibilityElement; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.wsdl.extensions.soap.SOAPBody; +import javax.wsdl.extensions.soap.SOAPFault; +import javax.wsdl.extensions.soap.SOAPHeader; +import javax.wsdl.extensions.soap.SOAPHeaderFault; +import javax.wsdl.extensions.soap.SOAPOperation; +import javax.xml.namespace.QName; + +import org.eclipse.wst.wsi.internal.WSIConstants; +import org.eclipse.wst.wsi.internal.WSIException; +import org.eclipse.wst.wsi.internal.WSIRuntimeException; +import org.eclipse.wst.wsi.internal.analyzer.AnalyzerContext; +import org.eclipse.wst.wsi.internal.analyzer.AssertionFailException; +import org.eclipse.wst.wsi.internal.analyzer.CandidateInfo; +import org.eclipse.wst.wsi.internal.analyzer.ServiceReference; +import org.eclipse.wst.wsi.internal.analyzer.config.WSDLElement; +import org.eclipse.wst.wsi.internal.profile.ProfileArtifact; +import org.eclipse.wst.wsi.internal.profile.TestAssertion; +import org.eclipse.wst.wsi.internal.profile.validator.EntryContext; +import org.eclipse.wst.wsi.internal.profile.validator.WSDLValidator; +import org.eclipse.wst.wsi.internal.profile.validator.impl.BaseValidatorImpl; +import org.eclipse.wst.wsi.internal.report.Entry; +import org.eclipse.wst.wsi.internal.report.EntryContainer; +import org.eclipse.wst.wsi.internal.report.FailureDetail; +import org.eclipse.wst.wsi.internal.report.ReportArtifact; +import org.eclipse.wst.wsi.internal.report.Reporter; +import org.eclipse.wst.wsi.internal.util.EntryType; +import org.eclipse.wst.wsi.internal.wsdl.WSDLDocument; +import org.eclipse.wst.wsi.internal.wsdl.WSDLElementList; +import org.eclipse.wst.wsi.internal.wsdl.WSDLUtils; +import org.eclipse.wst.wsi.internal.xml.dom.ElementLocation; +import org.eclipse.wst.wsi.internal.xml.schema.TargetNamespaceProcessor; +import org.eclipse.wst.wsi.internal.xml.schema.XMLSchemaValidator; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + + +/** + * The WSDL validator will verify that the WSDL and associated XML schema definitions + * are in conformance with the profile. + * + * @version 1.0.1 + * @author Peter Brittenham (peterbr@us.ibm.com) + * @author Graham Turrell (gturrell@uk.ibm.com) + */ +public class WSDLValidatorImpl + extends BaseValidatorImpl + implements WSDLValidator +{ + /** + * WSDL URL. + */ + protected String wsdlURL; + + /** + * WSDL document. + */ + protected WSDLDocument wsdlDocument = null; + + /** + * Entry container map. + */ + protected HashMap containerMap = new HashMap(); + + /* (non-Javadoc) + * @see org.wsi.test.profile.validator.WSDLValidator#init(org.wsi.test.analyzer.AnalyzerContext, org.wsi.test.profile.ProfileArtifact, org.wsi.test.report.ReportArtifact, java.lang.String, org.wsi.wsdl.WSDLDocument, org.wsi.test.report.Reporter) + */ + public void init( + AnalyzerContext analyzerContext, + ProfileArtifact profileArtifact, + ReportArtifact reportArtifact, + String wsdlURL, + WSDLDocument wsdlDocument, + Reporter reporter) + throws WSIException + { + // BaseValidatorImpl + super.init(analyzerContext, profileArtifact, reportArtifact, reporter); + + this.wsdlDocument = wsdlDocument; + if (wsdlDocument != null) + this.wsdlURL = wsdlDocument.getLocation(); + + if (wsdlURL != null) + this.wsdlURL = wsdlURL; + } + + /* (non-Javadoc) + * @see org.wsi.test.profile.validator.WSDLValidator#validate() + */ + public WSDLDocument validate() throws WSIException + { + //WSDLDocument wsdlDocument = null; + Entry entry = null; + + Service service = null; + Port port = null; + Binding binding = null; + PortType portType = null; + Operation operation = null; + Message message = null; + + // it depricated after refactoring + // now the inner classes moved out from validator + //String classPrefix = this.getClass().getName() + "$"; + String classPrefix = this.getClass().getPackage().getName()+"."; + + try + { + // Validate the WSDL service description + if (this.wsdlDocument == null) + this.wsdlDocument = new WSDLDocument(wsdlURL); + } + + catch (Exception e) + { + // ADD: Certain exceptions should result in validation errors + + throw new WSIException(e.getMessage(), e); + } + + // Get the definition element + Definition definition = wsdlDocument.getDefinitions(); + + // Get service reference from analyzer context + ServiceReference serviceReference = analyzerContext.getServiceReference(); + + // Create normalized data about the service under test. + CandidateInfo candidate = new CandidateInfo(serviceReference, wsdlDocument); + + analyzerContext.setCandidateInfo(candidate); + + // Set prereq type to entry container + reporter.setPrereqType(Reporter.PREREQ_TYPE_ENTRY_CONTAINER); + + // always process Import, Definitions & Types assertions + // TEMP: + processDefinitionAssertions(classPrefix, candidate); + processTypesAssertions(classPrefix, candidate); + processImportAssertions(classPrefix, candidate); + + // Process the element hierarchy in the WSDL document starting with the one that was specified + // FIX: Element finding already completed by CandidateInfo constructor - so use that rather than retest here + + // --------------------------- + // wsdl:port + // --------------------------- + if (serviceReference.getWSDLElement().isPort()) + { + // Find the service element + if ((service = + definition.getService( + serviceReference.getWSDLElement().getParentElementQName())) + == null) + { + throw new WSIRuntimeException( + "Could not locate WSDL service: " + + serviceReference.getWSDLElement().getParentElementName()); + } + + // Find the port element + if ((port = service.getPort(serviceReference.getWSDLElement().getName())) + == null) + { + throw new WSIRuntimeException( + "Could not locate WSDL port: " + + serviceReference.getWSDLElement().getName()); + } + + // TEMP: Remove until there are port test assertions + //processPortAssertions(port, serviceReference, classPrefix, wsdlDocument); + + // Next, process the binding + if (((binding = port.getBinding()) == null) || (binding.isUndefined())) + { + //throw new WSIRuntimeException("Could not locate WSDL binding for port: " + port.getName()); + // Set missingInput for all binding, portType, operation and message test assertions + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_BINDING)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORTTYPE)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_MESSAGE)); + } + + else + { + processBindingAssertions( + binding, + serviceReference, + classPrefix, + wsdlDocument); + + // Next, process the portType + if (((portType = binding.getPortType()) == null) + || (portType.isUndefined())) + { + //throw new WSIRuntimeException("Could not locate WSDL portType for binding: " + binding.getQName().getLocalPart()); + // Set missingInput for all portType, operation and message test assertions + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORTTYPE)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_MESSAGE)); + } + + else + { + processMessageAssertions( + binding, + serviceReference, + classPrefix, + wsdlDocument); + processPortTypeAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + processOperationAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + processMessageAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + } + } + + } + + // --------------------------- + // wsdl:binding + // --------------------------- + else if (serviceReference.getWSDLElement().isBinding()) + { + WSDLElement wsdlElement = serviceReference.getWSDLElement(); + // Find the binding element + if (wsdlElement.getQName() != null + && wsdlElement.getQName().getLocalPart() != null + && wsdlElement.getQName().getLocalPart().length() > 0) + { + if (((binding = + definition.getBinding(serviceReference.getWSDLElement().getQName())) + == null) + || (binding.isUndefined())) + { + throw new WSIRuntimeException( + "Could not locate WSDL binding: " + + serviceReference.getWSDLElement().getName()); + } + + processBindingAssertions( + binding, + serviceReference, + classPrefix, + wsdlDocument); + processMessageAssertions( + binding, + serviceReference, + classPrefix, + wsdlDocument); + + // Next, process the portType + if (((portType = binding.getPortType()) == null) + || (portType.isUndefined())) + { + //throw new WSIRuntimeException("Could not locate WSDL PortType for Binding: " + binding.getQName().getLocalPart()); + + // Set missingInput for all portType, operation and message test assertions + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORTTYPE)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_MESSAGE)); + } + + else + { + processPortTypeAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + processOperationAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + + // Process each message within each operation of the portType associated with the binding + processMessageAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + } + } + + // There was a problem with the binding element specification. This can + // happen when a UDDI tModel did not have a valid binding reference. + else + { + // Set missingInput for all binding, portType, operation and message test assertions + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_BINDING)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORTTYPE)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_MESSAGE)); + } + } + + // --------------------------- + // wsdl:portType + // --------------------------- + else if (serviceReference.getWSDLElement().isPortType()) + { + // Find the PortType element + if (((portType = + definition.getPortType(serviceReference.getWSDLElement().getQName())) + == null) + || (portType.isUndefined())) + { + throw new WSIRuntimeException( + "Could not locate WSDL PortType: " + + serviceReference.getWSDLElement().getName()); + } + + // Set missingInput for all binding test assertions + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_BINDING)); + + processPortTypeAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + processOperationAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + + // Process each message within each operation of the portType + processMessageAssertions( + portType, + serviceReference, + classPrefix, + wsdlDocument); + } + + // --------------------------- + // wsdl:operation + // --------------------------- + else if (serviceReference.getWSDLElement().isOperation()) + { + // Find the operation + // get portType from config parent element + if (((portType = + definition.getPortType( + serviceReference.getWSDLElement().getParentElementQName())) + == null) + || (portType.isUndefined())) + { + throw new WSIRuntimeException( + "Could not locate WSDL portType: " + + serviceReference.getWSDLElement().getParentElementQName()); + } + + if (((operation = + getOperationFromPortType( + portType, + serviceReference.getWSDLElement().getName())) + == null) + || (operation.isUndefined())) + { + throw new WSIRuntimeException( + "Could not locate WSDL Operation: " + + serviceReference.getWSDLElement().getName() + + "in portType: " + + portType.getQName()); + } + + // Set missingInput for all binding and portType test assertions + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_BINDING)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORTTYPE)); + + processOperationAssertions( + operation, + portType, + serviceReference, + classPrefix, + wsdlDocument); + processMessageAssertions( + operation, + serviceReference, + classPrefix, + wsdlDocument); + } + + // --------------------------- + // wsdl:message + // --------------------------- + else if (serviceReference.getWSDLElement().isMessage()) + { + // Find the message + if (((message = + definition.getMessage(serviceReference.getWSDLElement().getQName())) + == null) + || (message.isUndefined())) + { + throw new WSIRuntimeException( + "Could not locate WSDL Message: " + + serviceReference.getWSDLElement().getName()); + } + + // Set missingInput for all binding, portType, and operation test assertions + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_BINDING)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORTTYPE)); + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + + processMessageAssertions( + message, + serviceReference, + classPrefix, + wsdlDocument); + } + + else + { + throw new WSIRuntimeException( + "The following WSDL type is not supported: " + + serviceReference.getWSDLElement().getType()); + } + + // Cleanup + cleanup(); + + // Return WSDL document + return this.wsdlDocument; + } + + /** + * Get entry container using the filename for WSDL document. + * @param filename a file name. + * @return entry container using the filename for WSDL document. + */ + protected EntryContainer getEntryContainer(String filename) + { + EntryContainer entryContainer = null; + + // If the entry container already exists, then use it + if ((entryContainer = (EntryContainer) containerMap.get(filename)) == null) + { + // Create new entry container + entryContainer = this.reporter.createEntryContainer(); + + // Set container id using the filename for the WSDL document + entryContainer.setId(filename); + + // Put the new entry container into the container map + containerMap.put(filename, entryContainer); + } + + return entryContainer; + } + + /** + * Get operation from port type. + * @param portType port type. + * @param operationName operation name. + * @return operation from port type. + */ + protected Operation getOperationFromPortType( + PortType portType, + String operationName) + { + // FIX: wsdl4j available method call below implies that only + // name+inputname+outputname uniquely defines operation + // Use this instead for now: - get the first operation we find... + Operation op = null; + if (portType.getOperations() != null) + { + Iterator opIt = portType.getOperations().iterator(); + + while (opIt.hasNext()) + { + op = (Operation) opIt.next(); + if (operationName.equals(op.getName())) + { + return op; + } + } + } + + return null; // no matching operation found + } + + /** + * Process definition assertions. + * @param classPrefix class prefix. + * @param candidate candidate. + * @throws WSIException if problems occur during processing. + */ + protected void processDefinitionAssertions( + String classPrefix, + CandidateInfo candidate) + throws WSIException + { + + Entry entry = null; + + Definition[] wsdlDefinitions = candidate.getDefinitions(); + + for (int i = 0; i < wsdlDefinitions.length; i++) + { + Definition definition = wsdlDefinitions[i]; + if (definition == null) + continue; + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_DEFINITIONS)); + entry.setReferenceID(definition.getDocumentBaseURI()); + entry.setEntryDetail(definition); + + // Set entry container + entry.setEntryContainer( + getEntryContainer(definition.getDocumentBaseURI())); + + // Process all of the definition related test assertions + processAssertions( + classPrefix, + new EntryContext(entry, candidate.getWsdlDocument())); + // ADD: need to use here the specific document corresponding to the definition?? + + } + } + + /** + * Process types assertions. + * @param classPrefix class prefix. + * @param candidate candidate. + * @throws WSIException if problem occurs during processing + * type assertions. + */ + protected void processTypesAssertions( + String classPrefix, + CandidateInfo candidate) + throws WSIException + { + Entry entry = null; + + Types[] wsdlTypes = candidate.getTypes(); + Definition[] wsdlDefinitions = candidate.getDefinitions(); + + // If there are no types elements, then set all results to missingInput + if (wsdlTypes == null || wsdlTypes.length == 0) + { + // Set missingInput for all test assertions with this entry type + setMissingInput(EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_TYPES)); + } + + else + { + for (int i = 0; i < wsdlTypes.length; i++) + { + Types types = wsdlTypes[i]; + if (types == null) + { + // no Types element in i-th document + continue; + } + + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_TYPES)); + entry.setReferenceID( + candidate.getDefinition(types).getDocumentBaseURI() + "-Types"); + entry.setEntryDetail(types); + + // Set entry container + entry.setEntryContainer( + getEntryContainer(wsdlDefinitions[i].getDocumentBaseURI())); + + // Process all of the Types related test assertions + processAssertions( + classPrefix, + new EntryContext(entry, candidate.getWsdlDocument())); + } + } + } + + /** + * Process import assertions. + * @param classPrefix class prefix. + * @param candidate candidate. + * @throws WSIException if problem occurs during processing + * import assertions. + */ + protected void processImportAssertions( + String classPrefix, + CandidateInfo candidate) + throws WSIException + { + + Entry entry = null; + + Import[] wsdlImports = candidate.getImports(); + + // If there are no import elements, then set all results to missingInput + if (wsdlImports == null || wsdlImports.length == 0) + { + // Set missingInput for all test assertions with this entry type + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_IMPORT)); + } + + else + { + for (int i = 0; i < wsdlImports.length; i++) + { + Import wsdlImport = wsdlImports[i]; + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_IMPORT)); + entry.setReferenceID(wsdlImport.getNamespaceURI()); + entry.setEntryDetail(wsdlImport); + + // Set entry container + entry.setEntryContainer(getEntryContainer(wsdlImport.getLocationURI())); + + // Process all of the import related test assertions + processAssertions( + classPrefix, + new EntryContext(entry, candidate.getWsdlDocument())); + // ADD: need to use here the specific document corresponding to the import!! + } + } + } + + /** + * Process port assertions. + * @param port a port. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * port assertions. + */ + protected void processPortAssertions( + Port port, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + Entry entry = null; + + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType(EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORT)); + entry.setReferenceID(port.getName()); + entry.setParentElementName( + serviceReference.getWSDLElement().getParentElementName()); + entry.setEntryDetail(port); + + // Process assertions for this artifact against the target context + processAssertions(classPrefix, new EntryContext(entry, wsdlDocument)); + } + + /** + * Process binding assertions. + * @param binding binding. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * binding assertions. + */ + protected void processBindingAssertions( + Binding binding, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + Entry entry = null; + QName bindingQName = binding.getQName(); + + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_BINDING)); + entry.setReferenceID(bindingQName.toString()); + entry.setEntryDetail(binding); + + // Set entry container + Definition definition = + analyzerContext.getCandidateInfo().getDefinition(binding); + entry.setEntryContainer( + getEntryContainer( + (definition == null ? null : definition.getDocumentBaseURI()))); + + // Process binding test assertions + processAssertions(classPrefix, new EntryContext(entry, wsdlDocument)); + } + + /** + * Process port type assertions. + * @param portType port type. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * port type assertions. + */ + protected void processPortTypeAssertions( + PortType portType, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + + Entry entry = null; + QName portTypeQName = portType.getQName(); + + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_PORTTYPE)); + entry.setReferenceID(portTypeQName.toString()); + entry.setEntryDetail(portType); + + // Set entry container + Definition definition = + analyzerContext.getCandidateInfo().getDefinition(portType); + entry.setEntryContainer( + getEntryContainer( + (definition == null ? null : definition.getDocumentBaseURI()))); + + // Process test assertions + processAssertions(classPrefix, new EntryContext(entry, wsdlDocument)); + } + + /** + * Process operation assertions. + * @param operation an operation. + * @param portType port type. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * operation assertions. + */ + protected void processOperationAssertions( + Operation operation, + PortType portType, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + // qualify operation with service location from config. + Entry entry = null; + + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + entry.setReferenceID(operation.getName()); + entry.setParentElementName(portType.getQName().getLocalPart()); + entry.setEntryDetail(operation); + + // Set entry container + Definition definition = + analyzerContext.getCandidateInfo().getDefinition(portType); + entry.setEntryContainer( + getEntryContainer( + (definition == null ? null : definition.getDocumentBaseURI()))); + + // Process test assertions + processAssertions(classPrefix, new EntryContext(entry, wsdlDocument)); + } + + /** + * Process operation assertions. + * @param portType port type. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * operation assertions. + */ + protected void processOperationAssertions( + PortType portType, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + // For each operation, + if (portType.getOperations() == null) + { + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + } + + else + { + Operation operation; + Iterator opIt = portType.getOperations().iterator(); + while (opIt.hasNext()) + { + operation = (Operation) opIt.next(); + if (operation == null || operation.isUndefined()) + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_OPERATION)); + else + processOperationAssertions( + operation, + portType, + serviceReference, + classPrefix, + wsdlDocument); + } + } + } + + /** + * Process message assertions. + * @param message a message. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * message assertions. + */ + protected void processMessageAssertions( + Message message, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + + Entry entry = null; + QName messageQName = message.getQName(); + + // Create entry + entry = this.reporter.getReport().createEntry(); + entry.setEntryType( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_MESSAGE)); + entry.setReferenceID(messageQName.toString()); + entry.setEntryDetail(message); + + // Set entry container + Definition definition = + analyzerContext.getCandidateInfo().getDefinition(message); + entry.setEntryContainer( + getEntryContainer( + (definition == null ? null : definition.getDocumentBaseURI()))); + + // Process binding test assertions + processAssertions(classPrefix, new EntryContext(entry, wsdlDocument)); + } + + /** + * Process message assertions. + * @param binding a binding. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * message assertions. + */ + protected void processMessageAssertions( + Binding binding, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + HashSet messageSet; + + if (binding.getBindingOperations() != null) + { // can do nothing if have no operations defined + messageSet = + WSDLUtils.findMessages(wsdlDocument.getDefinitions(), binding); + + // Process any messages that were found + if (messageSet.size() > 0) + { + Iterator messageIt = messageSet.iterator(); + while (messageIt.hasNext()) + { + Message message = (Message) messageIt.next(); + if (!message.isUndefined()) + processMessageAssertions( + message, + serviceReference, + classPrefix, + wsdlDocument); + } + } + } + } + + /** + * Process message assertions. + * @param portType port type. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * message assertions. + */ + protected void processMessageAssertions( + PortType portType, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + + HashSet messageSet = new HashSet(); + + if (portType.getOperations() != null) + { + // can do nothing if have no operations defined + + Iterator opIt = portType.getOperations().iterator(); + + while (opIt.hasNext()) + { + Operation op = (Operation) opIt.next(); + + // Since there is no guarantee that we have both and input and output message, + // check for its existence before adding it + if (op.getInput() != null && !op.getInput().getMessage().isUndefined()) + messageSet.add(op.getInput().getMessage()); + + if (op.getOutput() != null + && !op.getOutput().getMessage().isUndefined()) + messageSet.add(op.getOutput().getMessage()); + + // also messages from any Faults defined within the operation + if (op.getFaults() != null) + { + Iterator faultIt = op.getFaults().values().iterator(); + Message message; + while (faultIt.hasNext()) + { + message = ((Fault) faultIt.next()).getMessage(); + if (!message.isUndefined()) + messageSet.add(message); + } + } + } + + if (messageSet.size() == 0) + { + // Set all message test assertion results to missingInput + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_MESSAGE)); + } + + else + { + // now step through each derived Message + Iterator messageIt = messageSet.iterator(); + while (messageIt.hasNext()) + { + processMessageAssertions( + (Message) (messageIt.next()), + serviceReference, + classPrefix, + wsdlDocument); + } + } + } + } + + /** + * Process message assertions. + * @param op - operation. + * @param serviceReference service reference. + * @param classPrefix class prefix. + * @param wsdlDocument WSDL document. + * @throws WSIException if problem occurs during processing + * message assertions. + */ + protected void processMessageAssertions( + Operation op, + ServiceReference serviceReference, + String classPrefix, + WSDLDocument wsdlDocument) + throws WSIException + { + + HashSet messageSet = new HashSet(); + if (op.getInput() != null && !op.getInput().getMessage().isUndefined()) + messageSet.add(op.getInput().getMessage()); + + if (op.getOutput() != null && !op.getOutput().getMessage().isUndefined()) + messageSet.add(op.getOutput().getMessage()); + + // also messages from any Faults defined within the operation + Iterator faultIt = op.getFaults().values().iterator(); + Message message; + while (faultIt.hasNext()) + { + message = ((Fault) faultIt.next()).getMessage(); + if (!message.isUndefined()) + messageSet.add(message); + } + + if (messageSet.size() == 0) + { + // Set all message test assertion results to missingInput + setMissingInput( + EntryType.getEntryType(EntryType.TYPE_DESCRIPTION_MESSAGE)); + } + + else + { + // now step through each derived Message + Iterator messageIt = messageSet.iterator(); + while (messageIt.hasNext()) + { + processMessageAssertions( + (Message) (messageIt.next()), + serviceReference, + classPrefix, + wsdlDocument); + } + } + } + + /* (non-Javadoc) + * @see org.wsi.test.profile.validator.impl.BaseValidatorImpl#isPrimaryEntryTypeMatch(org.wsi.test.profile.TestAssertion, org.wsi.test.profile.validator.EntryContext) + */ + protected boolean isPrimaryEntryTypeMatch( + TestAssertion testAssertion, + EntryContext targetContext) + { + boolean match = false; + + // If the test assertion entry type matches the target context entry type, then contine + if (testAssertion + .getEntryTypeName() + .equals(targetContext.getEntry().getEntryType().getTypeName())) + { + match = true; + } + + return match; + } + + /* (non-Javadoc) + * @see org.wsi.test.profile.validator.impl.BaseValidatorImpl#isNotApplicable(org.wsi.test.profile.TestAssertion) + */ + protected boolean isNotApplicable(TestAssertion testAssertion) + { + boolean notApplicable = false; + + // ADD: + + return notApplicable; + } + + /** + * Method getSoapFaults. + * + * @param inBinding in binding. + * @return soap faults. + * @throws WSIException if problems occur while processing binding faults. + */ + protected SOAPFault[] getSoapFaults(Binding inBinding) throws WSIException + { + + Vector soapFaults = new Vector(); + + // Go through each bindingFault one at a time + BindingFault[] bindingFaults = getAllBindingFaults(inBinding); + for (int fault = 0; fault < bindingFaults.length; fault++) + { + SOAPFault soapFault = getSoapFault(bindingFaults[fault]); + if (soapFault != null) + { + soapFaults.add(soapFault); + } + } + + SOAPFault[] soapFaultArray = new SOAPFault[soapFaults.size()]; + soapFaults.copyInto(soapFaultArray); + + return soapFaultArray; + } + + /** + * Method getAllBindingFaults. + * + * @param inBinding binding. + * @return all binding faults. + * @throws WSIException if problems occur during processing. + */ + protected BindingFault[] getAllBindingFaults(Binding inBinding) + throws WSIException + { + + Vector faults = new Vector(); + + try + { + + Iterator bindingOperations = inBinding.getBindingOperations().iterator(); + + while (bindingOperations.hasNext()) + { + + try + { + BindingOperation bo = (BindingOperation) bindingOperations.next(); + Iterator bindingFaults = bo.getBindingFaults().values().iterator(); + while (bindingFaults.hasNext()) + { + + faults.add((BindingFault) bindingFaults.next()); + } + } + catch (NullPointerException e) + { + + } + } + } + catch (NullPointerException e) + { + // no binding operations in this binding - ignore & continue + } + + BindingFault[] faultArray = new BindingFault[faults.size()]; + faults.copyInto(faultArray); + + return faultArray; + } + + /** + * Method getWSDLFaults. + * + * @param bindingFault a binding fault. + * @return WSDL faults. + * @throws WSIException if problems occur during processing. + */ + protected SOAPFault getSoapFault(BindingFault bindingFault) + throws WSIException + { + + SOAPFault soapFault = null; + try + { + Iterator faultExtensibles = + bindingFault.getExtensibilityElements().iterator(); + + while (faultExtensibles.hasNext() && soapFault == null) + { + try + { + soapFault = (SOAPFault) faultExtensibles.next(); + } + catch (ClassCastException e) + { // ignore everything but SOAP Fault elements. + } + } + } + catch (NullPointerException e) + { + } + + return soapFault; + } + + /** + * Method getSoapHeader. + * + * @param inBinding a binding. + * @return SOAP headers. + * @throws WSIException if problems occur during processing. + */ + protected SOAPHeader[] getSoapHeaders(Binding inBinding) throws WSIException + { + // Get all bindings + Binding[] bindingList = new Binding[1]; + bindingList[0] = inBinding; + + Vector soapHeaderList = new Vector(); + + // Go through each binding one at a time + for (int binding = 0; binding < bindingList.length; binding++) + { + try + { + // get the list of binding Operations + BindingOperation[] bindingOperations = + (BindingOperation[]) bindingList[binding] + .getBindingOperations() + .toArray( + new BindingOperation[0]); + + // get references to the extensible elements within the <input> and <output> elements of this binding <operation>. + for (int bo = 0; bo < bindingOperations.length; bo++) + { + + // Iterate over all input/output extensibles, looking for <SOAP:Body> elements. + try + { + BindingInput bindingInput = bindingOperations[bo].getBindingInput(); + BindingOutput bindingOutput = + bindingOperations[bo].getBindingOutput(); + + Iterator extElements = + bindingInput.getExtensibilityElements().iterator(); + while (extElements.hasNext()) + { + try + { + soapHeaderList.add((SOAPHeader) extElements.next()); + } + catch (ClassCastException e) + { // ignore everything but SOAP Header. + } + } + + extElements = bindingOutput.getExtensibilityElements().iterator(); + while (extElements.hasNext()) + { + try + { + soapHeaderList.add((SOAPHeader) extElements.next()); + } + catch (ClassCastException e) + { // ignore everything but SOAP Header. + } + } + } + catch (NullPointerException e) + { // no extensibility elements for <input> or <output> - ignore : not checking this here. + } + } + } + catch (NullPointerException e) + { + // no binding operations in this binding - ignore & continue + } + } + + SOAPHeader[] soapHeaderArray = new SOAPHeader[soapHeaderList.size()]; + soapHeaderList.copyInto(soapHeaderArray); + + return soapHeaderArray; + } + + /** + * Method getSoapHeaderFaults. + * + * WSDLDocument getter method - maybe better off in class WSDLDocument... + * + * @param inBinding a binding. + * @return SOAP header faults. + * @throws WSIException if problems occur during processing. + */ + protected SOAPHeaderFault[] getSoapHeaderFaults(Binding inBinding) + throws WSIException + { + Vector soapHeaderFaultList = new Vector(); + + // Get the list of SOAP headers + SOAPHeader[] soapHeaderArray = getSoapHeaders(inBinding); + + // Go through the list and get the header faults + List list = null; + for (int header = 0; header < soapHeaderArray.length; header++) + { + // Get list for this header + if ((list = soapHeaderArray[header].getSOAPHeaderFaults()) != null) + { + // Add to primary list + soapHeaderFaultList.addAll(list); + } + } + + SOAPHeaderFault[] soapHeaderFaultArray = + new SOAPHeaderFault[soapHeaderFaultList.size()]; + soapHeaderFaultList.copyInto(soapHeaderFaultArray); + + return soapHeaderFaultArray; + } + + /** + * Method getSoapBodies. + * + * WSDLDocument getter method - maybe better off in class WSDLDocument... + * + * @param inBinding a binding. + * @return SOAP bodies. + * @throws WSIException if if problems occur during processing. + */ + protected SOAPBody[] getSoapBodies(Binding inBinding) throws WSIException + { + // REMOVE: Get all bindings + //Binding[] bindingList = wsdlDocument.getBindings(); + Binding[] bindingList = new Binding[1]; + bindingList[0] = inBinding; + + Vector soapBodies = new Vector(); + + // Go through each binding one at a time + for (int binding = 0; binding < bindingList.length; binding++) + { + // get the list of binding Operations + BindingOperation[] bindingOperations = + (BindingOperation[]) bindingList[binding] + .getBindingOperations() + .toArray( + new BindingOperation[0]); + + // get references to the extensible elements within the <input> and <output> elements of this binding <operation>. + for (int bo = 0; bo < bindingOperations.length; bo++) + { + + // Iterate over all input/output extensibles, looking for <SOAP:Body> elements. + try + { + Iterator inputExtensibles = + bindingOperations[bo] + .getBindingInput() + .getExtensibilityElements() + .iterator(); + while (inputExtensibles.hasNext()) + { + try + { + soapBodies.add((SOAPBody) inputExtensibles.next()); + } + catch (ClassCastException e) + { // ignore everything but SOAP Body elements. + } + } + } + catch (NullPointerException e) + { // no extensibility elements for <input> - ignore : not checking this here. + } + + try + { + Iterator outputExtensibles = + bindingOperations[bo] + .getBindingOutput() + .getExtensibilityElements() + .iterator(); + while (outputExtensibles.hasNext()) + { + try + { + soapBodies.add((SOAPBody) outputExtensibles.next()); + } + catch (ClassCastException e) + { // ignore everything but SOAP Body elements. + } + } + } + catch (NullPointerException e) + { // no extensibility elements for <output>. + } + } + } + + SOAPBody[] soapBodyArray = new SOAPBody[soapBodies.size()]; + soapBodies.copyInto(soapBodyArray); + + return soapBodyArray; + } + + /** + * Method getSoapBody. + * + * @param bindingInput a BindingInput object. + * @return body. + * @throws WSIException if problems occur during processing. + */ + protected SOAPBody getSoapBody(BindingInput bindingInput) throws WSIException + { + + SOAPBody soapBody = null; + + Iterator extensibles = bindingInput.getExtensibilityElements().iterator(); + while (extensibles.hasNext()) + { + Object extensible = extensibles.next(); + if (extensible instanceof SOAPBody) + { + soapBody = (SOAPBody) extensible; + break; + } + } + return soapBody; + } + + /** + * Method getSoapBody. + * + * @param bindingOutput a BindingOutput object. + * @return SOAP body. + * @throws WSIException if problems occur during processing. + */ + protected SOAPBody getSoapBody(BindingOutput bindingOutput) + throws WSIException + { + + SOAPBody soapBody = null; + + Iterator extensibles = bindingOutput.getExtensibilityElements().iterator(); + while (extensibles.hasNext()) + { + Object extensible = extensibles.next(); + if (extensible instanceof SOAPBody) + { + soapBody = (SOAPBody) extensible; + break; + } + } + return soapBody; + } + + /** + * Get schema used. + * @param def definition. + * @return Schema used. + * @throws AssertionFailException if problem getting WSDL defintions + * namespace. + */ + protected String getSchemaUsed(Definition def) throws AssertionFailException + { + String schemaUsed = ""; + + try + { + // Need to read the file directly, since WSDL4J always puts in the default WSDL namespace + Document document = parseXMLDocumentURL(def.getDocumentBaseURI(), null); + + if (document != null) + { + // Get the root element + Element element = document.getDocumentElement(); + + // Get the namespace for this element + if (element != null) + schemaUsed = element.getNamespaceURI(); + } + } + + catch (WSIException we) + { + throw new AssertionFailException("problem getting WSDL defintions namespace"); + } + + /* + // Get the default namespace + String schemaUsed = def.getNamespace(""); + + // If the default was set, then process it to get the namespace + if (schemaUsed == null) { + // do it the hard way (still better than another DOM parse)... + //WSDLWriter w = new WSDLWriterImpl(); + try { + WSDLWriter w = WSDLFactory.newInstance().newWSDLWriter(); + Document doc = w.getDocument(def); + Element e = doc.getDocumentElement(); + schemaUsed = e.getNamespaceURI(); + } + catch (NullPointerException e) { + throw new AssertionFailException("problem getting WSDL defintions namespace"); + } + catch (WSDLException e) { + throw new AssertionFailException("problem getting document defintion"); + } + } + */ + + return schemaUsed; + } + + /** + * Method getSoapBinding. + * + * Get the SOAP binding for a Binding. + * + * @param binding a binding. + * @return a SOAP binding. + * @throws WSIException if problems occur during processing. + */ + public static SOAPBinding getSoapBinding(Binding binding) throws WSIException + { + SOAPBinding soapBinding = null; + + // Get the list of extensibility elements + List exElements = binding.getExtensibilityElements(); + if (exElements != null) + { + Iterator iterator = binding.getExtensibilityElements().iterator(); + + // Check for <soap:binding> element + while ((iterator.hasNext()) && (soapBinding == null)) + { + try + { + soapBinding = (SOAPBinding) iterator.next(); + } + catch (ClassCastException e) + { // ignore everything but SOAP Binding element + } + } + } + + return soapBinding; + } + + /** + * Create XML schema validator. This is done here because some compilers do not allow + * the documentList field to be accessed from within an inner class. + * @param documentBaseURI the base URL. + * @return newly created XML schema validator. + */ + protected XMLSchemaValidator createXMLSchemaValidator(String documentBaseURI) + { + // Create XML schema validator + return new XMLSchemaValidator(documentBaseURI, documentList); + } + + /** + * Search xsd schema or xsd import from node. If node is xsd import it's loading schema. + * @param definition a Definition object. + * @return a list of schema target namespaces. + * @throws WSIException if problem during processing method. + */ + protected List getSchemaTargetNamespaceList(Definition definition) + throws WSIException + { + List list = null, nextList = null; + + // Get list of extension elements within the types element + Types types = null; + if ((types = definition.getTypes()) != null) + { + Iterator iterator = types.getExtensibilityElements().iterator(); + + ExtensibilityElement extElement = null; + while (iterator.hasNext()) + { + // Get next ext. element + extElement = (ExtensibilityElement) iterator.next(); + // If this is an unknown ext. element, then see if it is a schema element + TargetNamespaceProcessor tnsProcessor = null; + if (extElement instanceof UnknownExtensibilityElement) + { + tnsProcessor = + new TargetNamespaceProcessor( + definition.getDocumentBaseURI(), + documentList); + + if ((nextList = + tnsProcessor.processAllSchema( + ((UnknownExtensibilityElement) extElement).getElement())) + != null) + if (list == null) + list = new Vector(); + list.addAll(nextList); + } + } + } + + return list; + } + /** + * Search xsd schema or xsd import from node. If node is xsd import it's loading schema. + * @param definition a Definition object. + * @return a list of schema target namespaces. + * @throws WSIException if problem during processing method. + */ + protected List getSchemaNamespaceList(Definition definition) + throws WSIException + { + List list = new Vector(); + + // Always add current document targetNamespace + List targetNamespaceList = getSchemaTargetNamespaceList(definition); + + if ((targetNamespaceList != null) && !targetNamespaceList.isEmpty()) + list.addAll(targetNamespaceList); + + // Get list of imported WSDL documents + Map importMap = definition.getImports(); + + Import imp; + + // Add each imports targetNamespace to the list + if (importMap != null && !importMap.isEmpty()) + { + Iterator values = importMap.values().iterator(); + List importList; + while (values.hasNext()) + { + importList = (List) values.next(); + Iterator imports = importList.iterator(); + while (imports.hasNext()) + { + imp = (Import) imports.next(); + if (imp != null && imp.getDefinition() != null) + list.addAll(getSchemaNamespaceList(imp.getDefinition())); + } + } + } + + return list; + } + + /** + * Build list of WSDL targetNamespaces. + * @param definition a Definition object. + * @return list of WSDL targetNamespaces. + */ + protected List getWSDLTargetNamespaceList(Definition definition) + { + List list = new Vector(); + + // Always add current document targetNamespace + if (definition.getTargetNamespace() != null) + list.add(definition.getTargetNamespace()); + + // Get list of imported WSDL documents + Map importMap = definition.getImports(); + + Import imp; + + // Add each imports targetNamespace to the list + if (importMap != null && !importMap.isEmpty()) + { + Iterator values = importMap.values().iterator(); + List importList; + while (values.hasNext()) + { + importList = (List) values.next(); + Iterator imports = importList.iterator(); + while (imports.hasNext()) + { + imp = (Import) imports.next(); + if (imp != null && imp.getDefinition() != null) + list.addAll(getWSDLTargetNamespaceList(imp.getDefinition())); + // list.add(imp.getDefinition().getTargetNamespace()); + } + } + } + + return list; + } + + protected class BindingMatch + { + private Binding binding; + private BindingOperation bindingOperation; + private SOAPBinding soapBinding; + //private Vector bindingArgs; // set of BindingInputs and BindingOutputs + private BindingInput bindingInput; + private BindingOutput bindingOutput; + + // ADD: need to include BindingFault support... + public BindingMatch( + Binding b, + BindingOperation bo, + SOAPBinding sb, + BindingInput bin, + BindingOutput bout) + { + binding = b; + bindingOperation = bo; + soapBinding = sb; + //bindingArgs = new Vector(); + //if (bin != null) { bindingArgs.add(bin); } + //if (bout != null) { bindingArgs.add(bout); } + bindingInput = bin; + bindingOutput = bout; + } + + public BindingMatch( + Binding b, + BindingOperation bo, + SOAPBinding sb, + BindingInput bin) + { + this(b, bo, sb, bin, null); + } + + public BindingMatch( + Binding b, + BindingOperation bo, + SOAPBinding sb, + BindingOutput bout) + { + this(b, bo, sb, null, bout); + } + + /** + * Returns the soapBinding. + * @return SOAPBinding + */ + public SOAPBinding getSoapBinding() + { + return soapBinding; + } + + /** + * Returns the bindingOperation. + * @return BindingOperation + */ + public BindingOperation getBindingOperation() + { + return bindingOperation; + } + + /** + * Returns the bindingInput. + * @return BindingInput + */ + public BindingInput getBindingInput() + { + return bindingInput; + } + + /** + * Returns the bindingOutput. + * @return BindingOutput + */ + public BindingOutput getBindingOutput() + { + return bindingOutput; + } + + public boolean hasBindingInput() + { + return (this.bindingInput != null); + } + + public boolean hasBindingOutput() + { + return (this.bindingOutput != null); + } + + /** + * Returns the binding. + * @return Binding + */ + public Binding getBinding() + { + return binding; + } + + } + + /** + * Get binding matches. + * @param binding a binding. + * @param soapBindingStyle soap binding style. + * @param soapBodyUse soap body use. + * @return binding matches. + * @throws WSIException if problems occur during processing. + */ + public BindingMatch[] getBindingMatches( + Binding binding, + String soapBindingStyle, + String soapBodyUse) + throws WSIException + { + + Vector bindingMatches = new Vector(); + + // Check binding + SOAPBinding soapBinding = getSoapBinding(binding); + + // check that the soap:binding for this WSDL binding is the specified style + // ADD: check for null pointer + if (soapBinding != null) + { + String defaultStyle = soapBinding.getStyle(); + + if (defaultStyle == null) + { + defaultStyle = WSIConstants.ATTRVAL_SOAP_BIND_STYLE_DOC; + } + + // Get the set of operations for this WSDL binding + List bindingOpsList = binding.getBindingOperations(); + if (bindingOpsList != null) + { + Iterator bindingOps = bindingOpsList.iterator(); + // for each binding operation: + while (bindingOps.hasNext()) + { + BindingOperation bindingOp = (BindingOperation) bindingOps.next(); + + SOAPOperation soapOp = getSoapOperation(bindingOp); + + if ((soapOp == null && defaultStyle.equals(soapBindingStyle)) + || (soapOp != null + && soapOp.getStyle() == null + && defaultStyle.equals(soapBindingStyle)) + || (soapOp != null + && soapOp.getStyle() != null + && soapOp.getStyle().equals(soapBindingStyle))) + { + // check binding input & output + BindingInput bInput = bindingOp.getBindingInput(); + if (bInput != null) + { + SOAPBody inputSoapBody = getSoapBody(bInput); + if (inputSoapBody == null + || (inputSoapBody.getUse() != null + && !inputSoapBody.getUse().equals(soapBodyUse))) + { + bInput = null; + } + } + + BindingOutput bOutput = bindingOp.getBindingOutput(); + if (bOutput != null) + { + SOAPBody outputSoapBody = getSoapBody(bOutput); + + if (outputSoapBody == null + || (outputSoapBody.getUse() != null + && !outputSoapBody.getUse().equals(soapBodyUse))) + { + bOutput = null; + } + } + + if ((bOutput != null) || (bInput != null)) + { + // we have a match, add to the vector + bindingMatches.add( + new BindingMatch( + binding, + bindingOp, + soapBinding, + bInput, + bOutput)); + } + } + } + } + } + + BindingMatch[] BindingMatchArray = new BindingMatch[bindingMatches.size()]; + bindingMatches.copyInto(BindingMatchArray); + return BindingMatchArray; + } + + /** + * Method getSoapOperation. + * + * @param bindingOperation a binding operation. + * @return a soap operation. + * @throws WSIException if problems while processing. + */ + public static SOAPOperation getSoapOperation(BindingOperation bindingOperation) + throws WSIException + { + + if (bindingOperation.getExtensibilityElements() == null) + { + return null; + } + + Iterator extensibles = + bindingOperation.getExtensibilityElements().iterator(); + while (extensibles.hasNext()) + { + Object extensible = extensibles.next(); + if (extensible instanceof SOAPOperation) + { + return (SOAPOperation) extensible; + } + } + return null; + } + + /* + * Returns an array of SOAPOperations corresponding to the wsdl:binding supplied. + */ + protected HashMap getSoapOperations(Binding binding) throws WSIException + { + HashMap soapOperationList = new HashMap(); + + if (binding.getBindingOperations() == null) + { + return null; + } + + //Vector soapOpVector = new Vector(); + + // Get the list of binding operations + Iterator operations = binding.getBindingOperations().iterator(); + + // Check each binding operation to see if it has a soap operation element + BindingOperation bindingOperation = null; + while (operations.hasNext()) + { + bindingOperation = (BindingOperation) operations.next(); + Iterator extensibles = + bindingOperation.getExtensibilityElements().iterator(); + while (extensibles.hasNext()) + { + Object extensible = extensibles.next(); + if (extensible instanceof SOAPOperation) + { + soapOperationList.put(extensible, bindingOperation.getName()); + } + } + } + + //return (SOAPOperation[])soapOpVector.toArray(new SOAPOperation[] {}); + return soapOperationList; + } + + /** + * Check part attributes. + * @param bindingMatch an array of BindingMatch objects. + * @param inOrOut a String object. + * @param attrib attribute. + * @return a boolean. + * @throws AssertionFailException if the part is not compliant. + */ + // GT - rework this method with a better way of parameterizing the getters required for the invocation. + protected boolean checkPartAttributes( + BindingMatch[] bindingMatch, + String inOrOut, + String attrib) + throws AssertionFailException + { + + if (!(inOrOut.equals("useInput") || inOrOut.equals("useOutput")) + || !(attrib.equals("useType") || attrib.equals("useElement"))) + { + // invalid argument value supplied by calling method - "internal error" + return false; + } + + for (int i = 0; i < bindingMatch.length; i++) + { + BindingMatch nextMatch = bindingMatch[i]; + + // check the associated parts + Message msg; + Map parts; + Iterator partIteration; + + BindingOperation bindingOp = nextMatch.getBindingOperation(); + if (bindingOp == null) + { + continue; // no Binding Operation for some reason + } + + Operation op = bindingOp.getOperation(); + + /* ADD: handle soap:faults in similar way + try { + // check faults - remarkably similar.... (need to retain operation id for failuredetail msg) + if (nextMatch.hasBindingFault()) { + + msg = op.getFault().getMessage(); + parts = msg.getParts(); + + //check that each part has an element attribute + partIteration = parts.values().iterator(); + while (partIteration.hasNext()) { + Part part = (Part)partIteration.next(); + if (part.getElementName() == null) { + throw new AssertionFailException("OPERATION: " + op + "MESSAGE: " + msg); + } + } + } + } + catch (NullPointerException n) { + // no parts found - this qualifies an assertion failure + throw new AssertionFailException(n.getMessage()); + } + */ + + try + { + + QName attributeName; + + //GT: Do we need to check BindingInput / Output here ?? + + if (inOrOut.equals("useInput")) + { + if (op.getInput() == null || !nextMatch.hasBindingInput()) + { + // No Input so nothing to check + continue; + } + + msg = op.getInput().getMessage(); + + } + else + { // Looking for Output + if (op.getOutput() == null || !nextMatch.hasBindingOutput()) + { + // No Output so nothing to check + continue; + } + + msg = op.getOutput().getMessage(); + } + + if (msg == null) + { + continue; // nothing to check from this Binding Match (?) + } + + // Get the list of parts + parts = msg.getParts(); + + // If there is a parts attribute, then only process those parts + List partsNameList = null; + if ((partsNameList = getPartsList(nextMatch, inOrOut)) != null) + { + Vector partsList = new Vector(); + Iterator partsNameIterator = partsNameList.iterator(); + while (partsNameIterator.hasNext()) + { + partsList.add(parts.get((String) partsNameIterator.next())); + } + partIteration = partsList.iterator(); + } + + // Otherwise use the complete list of parts + else + { + partIteration = parts.values().iterator(); + } + + //check that each part has an element or type attribute + while (partIteration.hasNext()) + { + Part part = (Part) partIteration.next(); + if (attrib.equals("useElement")) + { + attributeName = part.getElementName(); + } + else + { // "useType" + attributeName = part.getTypeName(); + } + + if (attributeName == null) + { + throw new AssertionFailException( + "Name of operation that failed: " + + op.getName() + + "\n" + + op.toString() + + "\n" + + "\nName of message that failed: " + + msg.getQName() + + "\n" + + msg.toString()); + } + } + } + catch (NullPointerException n) + { + // no parts found - this qualifies an assertion failure + throw new AssertionFailException(n.toString()); + } + } + return true; // tests successful + } + + /** + * Get parts list from a soapbind:body element. + */ + private List getPartsList(BindingMatch bindingMatch, String type) + { + List partsList = null; + Iterator iterator = null; + + BindingOperation bindingOp; + + try + { + // Get the binding operation + bindingOp = bindingMatch.getBindingOperation(); + + // Determine if the binding operation contains a soapbind:body with a parts attribute + if (type.equals("useInput")) + { + iterator = + bindingOp.getBindingInput().getExtensibilityElements().iterator(); + } + else + { + iterator = + bindingOp.getBindingOutput().getExtensibilityElements().iterator(); + } + } + catch (NullPointerException e) + { + return null; + // either no binding operation, binding input/output, or SOAP element + } + + // Determine if the binding operation contains a soapbind:body with a parts attribute + while ((iterator.hasNext()) && (partsList == null)) + { + try + { + SOAPBody soapBody = (SOAPBody) iterator.next(); + partsList = soapBody.getParts(); + } + catch (ClassCastException cce) + { // not a SOAPBody extensibility element so ignore + } + } + + return partsList; + } + + /** + * Get element location. + * @param wsdlDocument WSDL document. + * @param wsdlElement WSDL element. + * @return element location. + */ + protected ElementLocation getElementLocation( + WSDLDocument wsdlDocument, + Object wsdlElement) + { + ElementLocation elementLocation = null; + WSDLElementList wsdlElementList; + + if ((wsdlElementList = wsdlDocument.getElementList()) != null) + { + elementLocation = wsdlElementList.getElementLocation(wsdlElement); + } + + return elementLocation; + } + + /** + * Create failure detail. + * @param message a message. + * @param entryContext entry context. + * @return failure detail. + */ + protected FailureDetail createFailureDetail( + String message, + EntryContext entryContext) + { + return createFailureDetail( + message, + entryContext, + entryContext.getEntry().getEntryDetail()); + } + + /** + * Create failure detail. + * @param message a message. + * @param entryContext entry context. + * @param wsdlElement WSDL element. + * @return failure detail. + */ + protected FailureDetail createFailureDetail( + String message, + EntryContext entryContext, + Object wsdlElement) + { + FailureDetail failureDetail = reporter.createFailureDetail(); + failureDetail.setFailureMessage(message); + failureDetail.setElementLocation( + getElementLocation(entryContext.getWSDLDocument(), wsdlElement)); + return failureDetail; + } + + /** + * SOAPBody, SOAPFault, SOAPHeader and SOAPHeaderFault class + * interfaces have compatible getUse() and getNamespaceURI() + * methods, but wsdl4j does not declare them at the parent interface. + * Therefore use reflection to access these common methods. + * + * @param extElement extensibility element. + * @return true if namespace is found in SOAP literal. + * @throws NoSuchMethodException if this method cannot be found. + * @throws InvocationTargetException if problems occur in an invoked method or constructor + * @throws IllegalAccessException if there is am attempt to load a + * class that it does not have access to. + */ + protected boolean namespaceFoundInSoapLiteral(ExtensibilityElement extElement) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException + { + Class c = extElement.getClass(); + Method getUseMethod = c.getMethod("getUse", new Class[0]); + Method getNamespaceURIMethod = c.getMethod("getNamespaceURI", new Class[0]); + + // (use attribute is mandatory but the null case is checked for since a missing use is not + // checked with this TA. If its missing its invalid but we don't know whether we have doc-lit). + if (getUseMethod.invoke(extElement, null) == null + || !getUseMethod.invoke(extElement, null).equals( + WSIConstants.ATTRVAL_SOAP_BODY_USE_LIT)) + { + return false; + } + + // return true if namespace found + boolean namespaceFound = + (getNamespaceURIMethod.invoke(extElement, null) != null); + + // return true if namespace found + return namespaceFound; + + } + + /** + * Verify extensibility element uses literal. + * @param extensible - extensibility element + * @return boolean + * @throws NoSuchMethodException if this method cannot be found. + * @throws InvocationTargetException if problems occur in an invoked method or constructor + * @throws IllegalAccessException if there is am attempt to load a + * class that it does not have access to. + */ + protected boolean isLiteral(ExtensibilityElement extensible) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException + { + + Class c = extensible.getClass(); + Method getUseMethod = c.getMethod("getUse", new Class[0]); + + // (use attribute is mandatory but the null case is checked for since a missing use is not + // checked with this TA. If its missing its invalid but we don't know whether we have doc-lit). + if (getUseMethod.invoke(extensible, null) == null + || !getUseMethod.invoke(extensible, null).equals( + WSIConstants.ATTRVAL_SOAP_BODY_USE_LIT)) + { + return false; + } + + // return true if shown to have use="literal" + return true; + + } +} |