blob: 4df45afe3c63bd7b756383e586f48b4884f453c9 [file] [log] [blame]
/*******************************************************************************
* 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.core.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.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.WSIRuntimeException;
import org.eclipse.wst.wsi.internal.core.analyzer.AnalyzerContext;
import org.eclipse.wst.wsi.internal.core.analyzer.AssertionFailException;
import org.eclipse.wst.wsi.internal.core.analyzer.CandidateInfo;
import org.eclipse.wst.wsi.internal.core.analyzer.ServiceReference;
import org.eclipse.wst.wsi.internal.core.analyzer.config.WSDLElement;
import org.eclipse.wst.wsi.internal.core.profile.ProfileArtifact;
import org.eclipse.wst.wsi.internal.core.profile.TestAssertion;
import org.eclipse.wst.wsi.internal.core.profile.validator.EntryContext;
import org.eclipse.wst.wsi.internal.core.profile.validator.WSDLValidator;
import org.eclipse.wst.wsi.internal.core.profile.validator.impl.BaseValidatorImpl;
import org.eclipse.wst.wsi.internal.core.report.Entry;
import org.eclipse.wst.wsi.internal.core.report.EntryContainer;
import org.eclipse.wst.wsi.internal.core.report.FailureDetail;
import org.eclipse.wst.wsi.internal.core.report.ReportArtifact;
import org.eclipse.wst.wsi.internal.core.report.Reporter;
import org.eclipse.wst.wsi.internal.core.util.EntryType;
import org.eclipse.wst.wsi.internal.core.wsdl.WSDLDocument;
import org.eclipse.wst.wsi.internal.core.wsdl.WSDLElementList;
import org.eclipse.wst.wsi.internal.core.wsdl.WSDLUtils;
import org.eclipse.wst.wsi.internal.core.xml.dom.ElementLocation;
import org.eclipse.wst.wsi.internal.core.xml.schema.TargetNamespaceProcessor;
import org.eclipse.wst.wsi.internal.core.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.eclipse.wst.wsi.internal.core.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);
}
/**
* 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());
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;
}
}