| /******************************************************************************* |
| * 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.ArrayList; |
| 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 = 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(), new ArrayList()); |
| } |
| } |
| |
| 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, List processedSchemas) |
| { |
| if ((n!= null) && (!processedSchemas.contains(n))) |
| { |
| 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, processedSchemas); |
| 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, processedSchemas); |
| else |
| // else iterate element recursively |
| searchForSchema(n.getFirstChild(), context, processedSchemas); |
| } |
| 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, List processedSchemas) |
| { |
| 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)) |
| { |
| processSchema(schema.getDocumentElement(), |
| XMLUtils.createURLString(schemaLocation.getValue(), context), processedSchemas); |
| } |
| 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, List processedSchemas) |
| { |
| if ((schema != null) && (!processedSchemas.contains(schema))) |
| { |
| processedSchemas.add(schema); |
| Node n = schema.getFirstChild(); |
| while (n != null) |
| { |
| if (Node.ELEMENT_NODE == n.getNodeType() |
| && XMLUtils.equals(n, ELEM_XSD_IMPORT)) |
| loadSchema(n, context, processedSchemas); |
| |
| n = n.getNextSibling(); |
| } |
| } |
| } |
| } |