[117266] Updated XSD validator to use grammar preparser.
diff --git a/bundles/org.eclipse.wst.xsd.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.xsd.core/META-INF/MANIFEST.MF
index 4885259..a7c6808 100644
--- a/bundles/org.eclipse.wst.xsd.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.xsd.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %_UI_PLUGIN_NAME
Bundle-SymbolicName: org.eclipse.wst.xsd.core; singleton:=true
-Bundle-Version: 1.0.0.qualifer
+Bundle-Version: 1.0.1.qualifer
Bundle-Activator: org.eclipse.wst.xsd.core.internal.XSDCorePlugin
Bundle-Vendor: Eclipse.org
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.wst.xsd.core/src-validation/org/eclipse/wst/xsd/core/internal/validation/XSDValidator.java b/bundles/org.eclipse.wst.xsd.core/src-validation/org/eclipse/wst/xsd/core/internal/validation/XSDValidator.java
index a346aa0..f16d9c0 100644
--- a/bundles/org.eclipse.wst.xsd.core/src-validation/org/eclipse/wst/xsd/core/internal/validation/XSDValidator.java
+++ b/bundles/org.eclipse.wst.xsd.core/src-validation/org/eclipse/wst/xsd/core/internal/validation/XSDValidator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2006 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
@@ -10,159 +10,102 @@
*******************************************************************************/
package org.eclipse.wst.xsd.core.internal.validation;
-import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.net.URL;
-import org.apache.xerces.parsers.SAXParser;
+import org.apache.xerces.impl.Constants;
+import org.apache.xerces.parsers.XMLGrammarPreparser;
+import org.apache.xerces.util.XMLGrammarPoolImpl;
import org.apache.xerces.xni.XMLResourceIdentifier;
import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.grammars.XMLGrammarDescription;
import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xni.parser.XMLErrorHandler;
import org.apache.xerces.xni.parser.XMLInputSource;
+import org.apache.xerces.xni.parser.XMLParseException;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.xml.core.internal.validation.XMLValidator;
import org.eclipse.wst.xml.core.internal.validation.core.ValidationInfo;
import org.eclipse.wst.xml.core.internal.validation.core.ValidationReport;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.XMLReader;
+import org.w3c.dom.DOMError;
/**
* The XSDValidator will validate XSD files.
- *
- * @author Lawrence Mandel, IBM
*/
public class XSDValidator
{
-
- private final String XML_INSTANCE_DOC_TOP = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<root \n" //$NON-NLS-1$//$NON-NLS-2$
- + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"; //$NON-NLS-1$
-
- private final String XML_INSTANCE_DOC_MID = " xsi:noNamespaceSchemaLocation=\""; //$NON-NLS-1$
-
- private final String XML_INSTANCE_DOC_BOT = "\">\n" + "</root>\n"; //$NON-NLS-1$//$NON-NLS-2$
-
- private final String DUMMY_URI = "http://example.org/dummy"; //$NON-NLS-1$
-
private URIResolver uriresolver = null;
public ValidationReport validate(String uri)
{
return validate(uri, null);
}
-
+
/**
* Validate the XSD file specified by the URI.
*
* @param uri
* The URI of the XSD file to validate.
+ * @param inputStream An input stream representing the XSD file to validate.
*/
public ValidationReport validate(String uri, InputStream inputStream)
{
- ValidationInfo valinfo = new ValidationInfo(uri);
- try
- {
- String ns = null;
- String schemaLocationString = "";
+ ValidationInfo valinfo = new ValidationInfo(uri);
+ XSDErrorHandler errorHandler = new XSDErrorHandler(valinfo);
+ try
+ {
+ XMLGrammarPreparser grammarPreparser = new XMLGrammarPreparser();
+ grammarPreparser.registerPreparser(XMLGrammarDescription.XML_SCHEMA,null/*schemaLoader*/);
+
+ grammarPreparser.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY, new XMLGrammarPoolImpl());
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE, false);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE, true);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE, true);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATION_FEATURE, true);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE, true);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING, false);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE, true);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE, true);
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE, true);
+
+ try
+ {
+ grammarPreparser.setFeature(Constants.XERCES_FEATURE_PREFIX + "http://apache.org/xml/features/honour-all-schemaLocations", true);
+ }
+ catch (Exception e)
+ {
+ // catch the exception and ignore
+ }
+
+ grammarPreparser.setErrorHandler(errorHandler);
+ if (uriresolver != null)
+ {
+ XSDEntityResolver resolver = new XSDEntityResolver(uriresolver, uri);
+ if (resolver != null)
+ {
+ grammarPreparser.setEntityResolver(resolver);
+ }
+ }
- URL url = new URL(uri);
- if (url != null)
- {
- BufferedReader bufreader = new BufferedReader(new InputStreamReader(url.openStream()));
-
- if (bufreader != null)
- {
- StringBuffer source = new StringBuffer();
- while (bufreader.ready())
- {
- source.append(bufreader.readLine());
- }
- bufreader.close();
- int tn = source.indexOf("targetNamespace");
- if (tn != -1)
- {
- int firstquote = source.indexOf("\"", tn) + 1;
- int secondquote = source.indexOf("\"", firstquote);
- ns = source.substring(firstquote, secondquote);
- }
- }
- bufreader.close();
+ try
+ {
+ XMLInputSource is = new XMLInputSource(null, uri, uri, inputStream, null);
+ grammarPreparser.getLoader(XMLGrammarDescription.XML_SCHEMA);
+ grammarPreparser.preparseGrammar(XMLGrammarDescription.XML_SCHEMA,is);
+ }
+ catch (Exception e)
+ {
+ //parser will return null pointer exception if the document is structurally invalid
+ //TODO: log error message
+ //System.out.println(e);
}
-
- XSDErrorHandler errorHandler = new XSDErrorHandler(valinfo);
- try
- {
- StringBuffer instanceDoc = new StringBuffer(XML_INSTANCE_DOC_TOP);
- if (ns != null && !ns.equals(""))
- {
- instanceDoc.append(" xmlns=\"").append(ns).append("\"\n");
- instanceDoc.append(" xsi:schemaLocation=\"");
- instanceDoc.append(ns);
- instanceDoc.append(" ");
- } else
- {
- instanceDoc.append(XML_INSTANCE_DOC_MID);
- }
- instanceDoc.append(uri.replaceAll(" ", "%20"));
- if (!schemaLocationString.equals(""))
- {
- instanceDoc.append(" ").append(schemaLocationString);
- }
- instanceDoc.append(XML_INSTANCE_DOC_BOT);
- InputSource is = new InputSource(new StringReader(instanceDoc.toString()));
- is.setSystemId(DUMMY_URI);
-
- String soapFile = "platform:/plugin/org.eclipse.wst.wsdl.validation./xsd/xml-soap.xsd";
- XMLReader reader = new SAXParser();
- try
- {
- reader.setFeature("http://apache.org/xml/features/continue-after-fatal-error", false);
- reader.setFeature("http://xml.org/sax/features/namespaces", true);
- reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
- reader.setFeature("http://xml.org/sax/features/validation", true);
- reader.setFeature("http://apache.org/xml/features/validation/schema", true);
- reader.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
- reader.setFeature("http://xml.org/sax/features/external-general-entities", true);
- reader.setFeature("http://xml.org/sax/features/external-parameter-entities", true);
- reader.setFeature("http://apache.org/xml/features/validation/warn-on-duplicate-attdef", true);
-
- reader.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation",
- "http://xml.apache.org/xml-soap " + soapFile);
- reader.setErrorHandler(errorHandler);
-
- if (uriresolver != null)
- {
- XSDEntityResolver resolver = new XSDEntityResolver(uriresolver, uri, inputStream);
- try
- {
- reader.setProperty("http://apache.org/xml/properties/internal/entity-resolver", resolver);
- }
- catch (Exception e)
- {
- // TODO: log failure to register the entity resolver.
- }
- }
-
- reader.parse(is);
-
- } catch (SAXException e)
- {
- //LoggerFactory.getLoggerInstance().logError("XSD Validator Exception: ", e);
- }
- } catch (IOException except)
- {
- //LoggerFactory.getLoggerInstance().logError("XSD Validator Exception: ", except);
- }
- } catch (Exception e)
- {
- //LoggerFactory.getLoggerInstance().logError("XSD Validator Exception: ", e);
- }
-
- return valinfo;
+ }
+ catch (Exception e)
+ {
+ // TODO: log error.
+ //System.out.println(e);
+ }
+ return valinfo;
}
/**
@@ -179,16 +122,10 @@
/**
* The XSDErrorHandler handle Xerces parsing errors and puts the errors
* into the given ValidationInfo object.
- *
- * @author Lawrence Mandel, IBM
*/
- protected class XSDErrorHandler implements org.xml.sax.ErrorHandler
+ protected class XSDErrorHandler implements XMLErrorHandler
{
-
- private final int ERROR = 0;
-
- private final int WARNING = 1;
-
+
private final ValidationInfo valinfo;
public XSDErrorHandler(ValidationInfo valinfo)
@@ -199,57 +136,49 @@
/**
* Add a validation message with the given severity.
*
+ * @param errorKey The Xerces error key.
* @param exception The exception that contains the information about the message.
* @param severity The severity of the validation message.
*/
- protected void addValidationMessage(SAXParseException exception, int severity)
+ protected void addValidationMessage(String errorKey, XMLParseException exception, int severity)
{
- // get the error key by taking the substring of what is before the ':' in the error message:
- String errorKey = exception.getLocalizedMessage();
- if (errorKey != null)
+ String systemId = exception.getExpandedSystemId();
+ if (systemId != null)
{
- int index = errorKey.indexOf(':');
- if (index != -1)
- { errorKey = errorKey.substring(0, index);
- }
- }
-
- if (exception.getSystemId() != null && !exception.getSystemId().equals(DUMMY_URI))
- {
- if (severity == WARNING)
+ if (severity == DOMError.SEVERITY_WARNING)
{
- valinfo.addWarning(exception.getLocalizedMessage(), exception.getLineNumber(), exception.getColumnNumber(), exception.getSystemId());
+ valinfo.addWarning(exception.getLocalizedMessage(), exception.getLineNumber(), exception.getColumnNumber(), systemId);
}
else
{
- valinfo.addError(exception.getLocalizedMessage(), exception.getLineNumber(), exception.getColumnNumber(), exception.getSystemId(), errorKey, null);
+ valinfo.addError(exception.getLocalizedMessage(), exception.getLineNumber(), exception.getColumnNumber(), systemId, errorKey, null);
}
}
}
/* (non-Javadoc)
- * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+ * @see org.apache.xerces.xni.parser.XMLErrorHandler#warning(java.lang.String, java.lang.String, org.apache.xerces.xni.parser.XMLParseException)
*/
- public void error(SAXParseException exception) throws SAXException
- {
- addValidationMessage(exception, ERROR);
- }
+ public void warning(String domain, String key, XMLParseException exception) throws XNIException
+ {
+ addValidationMessage(key, exception, DOMError.SEVERITY_WARNING);
+ }
/* (non-Javadoc)
- * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
+ * @see org.apache.xerces.xni.parser.XMLErrorHandler#error(java.lang.String, java.lang.String, org.apache.xerces.xni.parser.XMLParseException)
*/
- public void fatalError(SAXParseException exception) throws SAXException
+ public void error(String domain, String key, XMLParseException exception) throws XNIException
{
- addValidationMessage(exception, ERROR);
- }
+ addValidationMessage(key, exception, DOMError.SEVERITY_ERROR);
+ }
/* (non-Javadoc)
- * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+ * @see org.apache.xerces.xni.parser.XMLErrorHandler#fatalError(java.lang.String, java.lang.String, org.apache.xerces.xni.parser.XMLParseException)
*/
- public void warning(SAXParseException exception) throws SAXException
- {
- addValidationMessage(exception, WARNING);
- }
+ public void fatalError(String domain, String key, XMLParseException exception) throws XNIException
+ {
+ addValidationMessage(key, exception, DOMError.SEVERITY_FATAL_ERROR);
+ }
}
/**
@@ -260,8 +189,6 @@
{
private URIResolver uriresolver = null;
- private InputStream inputStream;
-
/**
* Constructor.
*
@@ -269,10 +196,9 @@
* The idresolver this entity resolver wraps.
* @param baselocation The base location to resolve with.
*/
- public XSDEntityResolver(URIResolver uriresolver, String baselocation, InputStream inputStream)
+ public XSDEntityResolver(URIResolver uriresolver, String baselocation)
{
this.uriresolver = uriresolver;
- this.inputStream = inputStream;
}
/* (non-Javadoc)
@@ -280,23 +206,17 @@
*/
public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) throws XNIException, IOException
{
- // consider the resourceIdentifier's fields to see we're actually in the dummy xml file
- // and if this is the reference to the schema we want to validate
- // ... if so return an XMLInputSource built from the dirty copy of the schema
- boolean isDummyXML = DUMMY_URI.equals(resourceIdentifier.getBaseSystemId());
- if (isDummyXML && inputStream != null)
+ String literalSystemId = resourceIdentifier.getLiteralSystemId();
+ if(literalSystemId != null)
{
- XMLInputSource inputSource = new XMLInputSource(null, resourceIdentifier.getLiteralSystemId(), null, inputStream, null);
- return inputSource;
+ resourceIdentifier.setLiteralSystemId(literalSystemId.replace('\\','/'));
}
- else
- {
// TODO cs: In revision 1.1 we explicitly opened a stream to ensure
// file I/O problems produced messages. I've remove this fudge for now
// since I can't seem to reproduce the problem it was intended to fix.
// I'm hoping the newer Xerces code base has fixed this problem and the fudge is defunct.
return XMLValidator._internalResolveEntity(uriresolver, resourceIdentifier);
- }
+
}
}
}