blob: 5208c8af35c137cfc9f218883d0cecaf93e86237 [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.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.wsdl.Binding;
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.WSITag;
import org.eclipse.wst.wsi.internal.core.analyzer.AssertionFailException;
import org.eclipse.wst.wsi.internal.core.analyzer.AssertionNotApplicableException;
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.impl.AssertionProcess;
import org.eclipse.wst.wsi.internal.core.report.AssertionResult;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* AP2908
*
* <context>For a candidate wsdl:binding</context>
* <assertionDescription>The mime:part element in a DESCRIPTION does not have a name attribute.</assertionDescription>
*/
public class AP2908 extends AssertionProcess implements WSITag
{
private final WSDLValidatorImpl validator;
/**
* @param WSDLValidatorImpl
*/
public AP2908(WSDLValidatorImpl impl)
{
super(impl);
this.validator = impl;
}
/* Validates the test assertion.
* @see org.wsi.test.profile.validator.impl.BaseValidatorImpl.AssertionProcess#validate(org.wsi.test.profile.TestAssertion, org.wsi.test.profile.validator.EntryContext)
*/
public AssertionResult validate(
TestAssertion testAssertion,
EntryContext entryContext)
throws WSIException
{
try
{
// Getting a wsdl:binding
Binding wsdlBinding = (Binding) entryContext.getEntry().getEntryDetail();
// Since WSDL4J 1.4 ignores any attributes of mime:part, use Xerces 2.6.2 instead
Document doc = XMLUtils.parseXMLDocument(validator.wsdlURL);
// Finding the wsdl:binding element being processed
Element binding = getBindingElement(
doc.getDocumentElement(), wsdlBinding.getQName().getLocalPart());
List ops = getChildElements(binding, WSDL_OPERATION);
// A variable that indicates a binding contains at least one
// mime:multipartRelated element
boolean multipartsFound = false;
// Going through the operation elements
for (int i = 0; i < ops.size(); i++)
{
Element bindingOperation = (Element) ops.get(i);
// Getting wsdl:input and wsdl:output elements of an operation
Element bindingInput = getChildElement(bindingOperation, WSDL_INPUT);
Element bindingOutput = getChildElement(bindingOperation, WSDL_OUTPUT);
// Collecting all the mime:multipartRelated elements from wsdl:input and wsdl:output
List inputMultiparts = getMimeMultipartElements(bindingInput);
List outputMultiparts = getMimeMultipartElements(bindingOutput);
// If the wsdl:input contains mime:multipartRelated elements
if (!inputMultiparts.isEmpty())
{
multipartsFound = true;
// If there is a mime:part element containing a name attribute,
// the assertion failed
if (containsInvalidMimePart(inputMultiparts))
{
throw new AssertionFailException("The invalid "
+ "mime:part element is in the wsdl:input of the \""
+ bindingOperation.getAttribute(WSIConstants.ATTR_NAME)
+ "\" binding operation.");
}
}
// If the wsdl:output contains mime:multipartRelated elements
if (!outputMultiparts.isEmpty())
{
multipartsFound = true;
// If there is a mime:part element containing a name attribute,
// the assertion failed
if (containsInvalidMimePart(outputMultiparts))
{
throw new AssertionFailException("The invalid "
+ "mime:part element is in the wsdl:output of the \""
+ bindingOperation.getAttribute(WSIConstants.ATTR_NAME)
+ "\" binding operation.");
}
}
}
// If the binding contains no one mime:multipartRelated element,
// the assertion is not applicable
if (!multipartsFound)
throw new AssertionNotApplicableException();
}
catch (IOException ioe)
{
result = AssertionResult.RESULT_NOT_APPLICABLE;
}
catch (AssertionNotApplicableException anae)
{
result = AssertionResult.RESULT_NOT_APPLICABLE;
}
catch (AssertionFailException afe)
{
result = AssertionResult.RESULT_FAILED;
failureDetail = validator.createFailureDetail(
afe.getMessage(), entryContext);
}
// Return assertion result
return validator.createAssertionResult(
testAssertion, result, failureDetail);
}
/**
* Validates mime:part elements for each of mime:multipartRelated element.
* @param multiparts a list of mime:multipartRelated elements.
* @return true, if any mime:part contains a name attribute, false otherwise.
*/
private boolean containsInvalidMimePart(List multiparts) {
// Going through a list of mime:multipartRelated elements
for (int i = 0; i < multiparts.size(); i++)
{
// Getting a list of mime:part elements
List mimeParts =
getChildElements((Element) multiparts.get(i), WSDL_MIME_PART);
// Going through all the mime:part elements
for (int j = 0; j < mimeParts.size(); j++)
{
Element mimePart = (Element) mimeParts.get(j);
// If the mime:part element contains a name attribute,
// return true
if (mimePart.getAttributeNode(WSIConstants.ATTR_NAME) != null)
{
return true;
}
}
}
// No one invalid mime:part element is found, return false
return false;
}
/**
* Collects all mime:multipartRelated elements.
* @param parent an element which the child elements are gathered from.
* @return the list of mime:multipartRelated elements found.
*/
private List getMimeMultipartElements(Element parent)
{
List mimeMultipartElements = new ArrayList();
// If the parent is not null
if (parent != null)
{
// Getting the first parent's child
Element child = XMLUtils.getFirstChild(parent);
while (child != null)
{
// If the child is a mime:multipartRelated element
if (child.getNamespaceURI().equals(WSDL_MIME_MULTIPART.getNamespaceURI())
&& child.getLocalName().equals(WSDL_MIME_MULTIPART.getLocalPart()))
{
// Adding the element to the list being returned
mimeMultipartElements.add(child);
// Getting mime:partS from the element
List mimeParts = getChildElements(child, WSDL_MIME_PART);
// Going through all the mime:part elements
for (int i = 0; i < mimeParts.size(); i++)
{
// Collecting all the mime:multipartRelated elements of this mime:part
List elems = getMimeMultipartElements((Element) mimeParts.get(i));
// Adding the elements to the list being returned
mimeMultipartElements.addAll(elems);
}
}
// Getting the next child
child = XMLUtils.getNextSibling(child);
}
}
return mimeMultipartElements;
}
/**
* Looks for an element's child element.
* @param parent a parent element.
* @param childName a qualified element name being found.
* @return an element or null if it is not found.
*/
private Element getChildElement(Element parent, QName childName)
{
// Getting the first parent's child
Element child = XMLUtils.getFirstChild(parent);
while (child != null)
{
// If the child has the required qualified name
if (child.getNamespaceURI().equals(childName.getNamespaceURI())
&& child.getLocalName().equals(childName.getLocalPart()))
{
// return the child
return child;
}
// Getting the next child
child = XMLUtils.getNextSibling(child);
}
return null;
}
/**
* Collects element's child elements.
* @param parent a parent element.
* @param childName a qualified element name being found.
* @return a list of elements found.
*/
private List getChildElements(Element parent, QName childName)
{
List children = new ArrayList();
if (parent != null)
{
// Getting the first parent's child
Element child = XMLUtils.getFirstChild(parent);
while (child != null)
{
// If the child has the required qualified name
if (child.getNamespaceURI().equals(childName.getNamespaceURI())
&& child.getLocalName().equals(childName.getLocalPart()))
{
// Adding the child to the list
children.add(child);
}
// Getting the next binding's child
child = XMLUtils.getNextSibling(child);
}
}
return children;
}
/**
* Looks for wsdl:binding element.
* @param definitions a wsdl:definitions element.
* @param bindingName a name of wsdl:binding element.
* @return a wsdl:binding element or null if it is not found.
*/
private Element getBindingElement(Element definitions, String bindingName)
{
// Getting the first definitions' child
Element child = XMLUtils.getFirstChild(definitions);
while (child != null)
{
// If definitions' child is wsdl:binding element
// and is the same that is being processed by WSDLValidator
if (child.getNamespaceURI().equals(WSDL_BINDING.getNamespaceURI())
&& child.getLocalName().equals(WSDL_BINDING.getLocalPart())
&& child.getAttribute(WSIConstants.ATTR_NAME).equals(bindingName))
{
// return the wsdl:binding element
return child;
}
// Getting the next definitions' child
child = XMLUtils.getNextSibling(child);
}
// return null, is there is no such wsdl:binding
return null;
}
}