blob: cce15cd303436cd8cd2a9b69de628deda3fb5709 [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.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import javax.wsdl.Definition;
import javax.wsdl.Types;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.WSITag;
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.util.ErrorList;
import org.eclipse.wst.wsi.internal.core.util.StringTokenizer;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* BP2011.
* The imported XML schema is a well-formed XML 1.0 document and if it contains an
* XML declaration, it is version 1.0.
*
* @version 1.0.1 27.06.2003
* @author Vitali Fedosenko
**/
public class BP2011 extends AssertionProcess implements WSITag
{
private final WSDLValidatorImpl validator;
/**
* @param WSDLValidatorImpl
*/
public BP2011(WSDLValidatorImpl impl)
{
super(impl);
this.validator = impl;
}
private ErrorList errors = new ErrorList();
private final char[] OMMITED_XML_DECLARATION_DELIMITERS =
new char[] { 0x20, 0x9, 0xD, 0xA, '\'', '\"' };
private final char[] XML_DECLARATION_DELIMITERS = new char[] { '=' };
private final String VERSION_TOKEN = "version";
private final String VERSION = "1.0";
/* 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
{
result = result = AssertionResult.RESULT_NOT_APPLICABLE;
//Definition def = (Definition) entryContext.getEntry().getEntryDetail();
Types types = (Types) entryContext.getEntry().getEntryDetail();
List exts = null;
//if (def.getTypes()!=null)
if (types != null)
{
exts = types.getExtensibilityElements();
}
if (exts != null)
{
Definition definition = null;
if ((definition =
validator.analyzerContext.getCandidateInfo().getDefinition(types))
== null)
{
throw new WSIException("Could not find types definition in any WSDL document.");
}
Iterator it = exts.iterator();
while (it.hasNext())
{
ExtensibilityElement el = (ExtensibilityElement) it.next();
if (el instanceof UnknownExtensibilityElement)
searchForSchema(((UnknownExtensibilityElement) el).getElement(),
definition.getDocumentBaseURI());
}
}
if (!errors.isEmpty())
{
result = AssertionResult.RESULT_FAILED;
failureDetail = this.validator.createFailureDetail(errors.toString(), entryContext);
} /*else
result = AssertionResult.RESULT_PASSED;*/
return validator.createAssertionResult(testAssertion, result, failureDetail);
}
/* Search xsd schema or xsd import from node. If node is xsd import it's loading schema.
* @param n - UnknownExtencibilityElement
*/
private void searchForSchema(Node n, String context)
{
while (n != null)
{
// searches for xsd:import element
if (Node.ELEMENT_NODE == n.getNodeType())
{
// if xsd:schema element is found -> process schema
if (XMLUtils.equals(n, ELEM_XSD_SCHEMA))
processSchema(n, context);
else
// if xsd:import element is found -> load schema and process schema
// FIXED: if xsd:import is found and parent element is xsd:schema
if (XMLUtils.equals(n, ELEM_XSD_IMPORT)
&& XMLUtils.equals(n.getParentNode(), ELEM_XSD_SCHEMA))
loadSchema(n, context);
else
// else iterate element recursively
searchForSchema(n.getFirstChild(), context);
}
n = n.getNextSibling();
}
}
/*
* It loads xsd schema and then check the version 1.0 and looking for xsd:schema element for next process.
* @param importNode xsd schema
*/
private void loadSchema(Node importNode, String context)
{
Element im = (Element) importNode;
Attr schemaLocation = XMLUtils.getAttribute(im, ATTR_XSD_SCHEMALOCATION);
// try to parse imported XSD
if (schemaLocation != null && schemaLocation.getValue() != null)
{
try
{
// if any error or root element is not XSD schema -> error
String decl =
readXMLDeclarationStatement(schemaLocation.getValue(), context);
if (!validVersion(decl))
{
Attr a = XMLUtils.getAttribute(im, ATTR_XSD_NAMESPACE);
errors.add((a != null) ? a.getValue() : "");
}
Document schema =
validator.parseXMLDocumentURL(schemaLocation.getValue(), context);
if (XMLUtils.equals(schema.getDocumentElement(), ELEM_XSD_SCHEMA))
{
Attr a = XMLUtils.getAttribute(im, ATTR_XSD_NAMESPACE);
String namespace = (a != null) ? a.getValue() : "";
processSchema(schema.getDocumentElement(),
XMLUtils.createURLString(schemaLocation.getValue(), context));
}
result = AssertionResult.RESULT_PASSED;
}
catch (Throwable t)
{
}
}
// else if there is only the namespace attribute, the import relates to inline schema
else if (XMLUtils.getAttribute(im, ATTR_XSD_NAMESPACE) != null)
{
result = AssertionResult.RESULT_PASSED;
}
}
/**
* Reads an XML declaration statement.
* @param location
* @return String
*/
private String readXMLDeclarationStatement(String location, String baseURI)
{
String result = null;
try
{
new URL(location);
}
catch (Throwable t)
{
// nothing
int i = baseURI.lastIndexOf('/');
int j = baseURI.lastIndexOf('\\');
if (j > i)
i = j;
location = baseURI.substring(0, i + 1) + location;
}
if (location != null)
{
URL url = null;
Reader reader = null;
try
{
try
{
url = new URL(location);
}
catch (MalformedURLException e)
{
// we should try to access location as file
}
if (url != null)
{
reader = new InputStreamReader(url.openStream());
}
else
{
reader = new InputStreamReader(new FileInputStream(location));
}
int charCode;
boolean end = false;
if (reader.ready())
{
charCode = reader.read();
while (reader.ready() && !(charCode == '<'))
{
charCode = reader.read();
}
StringBuffer buf = new StringBuffer();
if (charCode == '<')
{
buf.append((char) charCode);
while (reader.ready() && !end)
{
charCode = reader.read();
buf.append((char) charCode);
end = charCode == '>';
}
}
else
{
// NOTE: This result does not get propogated back!
result = AssertionResult.RESULT_FAILED;
failureDetailMessage =
"Cannot read the XML declaration statement.";
}
result = buf.toString();
}
}
catch (Exception e)
{
}
finally
{
if (reader != null)
{
try
{
reader.close();
}
catch (Throwable e)
{
}
}
}
}
return result;
}
/*
* @param xmlDecl - xml declaration
* @return if xml declaration contains version="1.0" it retirns true.
*/
private boolean validVersion(String xmlDecl)
{
//boolean result = false;
boolean result = true;
if (xmlDecl != null)
{
StringTokenizer st =
new StringTokenizer(
OMMITED_XML_DECLARATION_DELIMITERS,
XML_DECLARATION_DELIMITERS);
Enumeration tokens = st.parse(xmlDecl);
boolean found = false;
while (tokens.hasMoreElements() && !found)
{
String token = (String) tokens.nextElement();
if (token.equalsIgnoreCase(VERSION_TOKEN))
{
found = true;
tokens.nextElement();
String ver = (String) tokens.nextElement();
result = VERSION.equals(ver);
}
}
}
return result;
}
/*
* It's loking for xsd import and load it if find.
* @param schema xsd schema
*/
private void processSchema(Node schema, String context)
{
Node n = schema.getFirstChild();
while (n != null)
{
if (Node.ELEMENT_NODE == n.getNodeType()
&& XMLUtils.equals(n, ELEM_XSD_IMPORT))
loadSchema(n, context);
n = n.getNextSibling();
}
}
}