You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by pi...@apache.org on 2005/09/12 03:10:13 UTC
svn commit: r280229 [1/2] - in
/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon:
components/validation/ components/validation/impl/ transformation/
Author: pier
Date: Sun Sep 11 18:09:57 2005
New Revision: 280229
URL: http://svn.apache.org/viewcvs?rev=280229&view=rev
Log:
Major overhaul of the validation API:
- rewrote contract for validation: now the Validator shields the inner workings of schemas / parsers / validators
- moved caching and automatic schema detection directly as extensions of the Validator
- modified Jing and Xerces implementation to work with the modified API
This should make life easier for people using validators. That said, this is currently UNTESTED.
I just want to commit those before (as I always do) I loose all my work.
Samples rewrite and testing will come tomorrow
Added:
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidationHandler.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidatorException.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchemaParser.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractValidator.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/CachingValidator.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidationHandler.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DraconianErrorHandler.java
Removed:
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AutomaticSchemaParser.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/CachingSchemaParser.java
Modified:
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Schema.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/SchemaParser.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Validator.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchema.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidator.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchema.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchemaParser.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesGrammarParser.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchema.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchemaParser.java
cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/transformation/ValidatingTransformer.java
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Schema.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Schema.java?rev=280229&r1=280228&r2=280229&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Schema.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Schema.java Sun Sep 11 18:09:57 2005
@@ -16,16 +16,26 @@
package org.apache.cocoon.components.validation;
import org.apache.excalibur.source.SourceValidity;
-import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
/**
- * <p>An interface defining a schema used for validation of XML documents.</p>
+ * <p>The {@link Schema} interface defines an abstraction of a schema usable to
+ * validate an XML document.</p>
+ *
+ * <p>This interface is not tied to any specific validation grammar language
+ * such as the <a href="http://www.w3.org/XML/Schema">W3C XML Shema</a> language
+ * or the <a href="http://www.relaxng.org/">RELAX-NG</a/> language.</p>
+ *
+ * <p>Selection and use of specific schema grammar languages is performed through
+ * the use of the {@link Validator} interface.</p>
*
- * <p>A schema, by itself, simply provide access to its {@link SourceValidity}
- * (if any, for caching), and is able to create instances of {@link ContentHandler}s
- * that will receive SAX Events and validate them.</p>
+ * <p>Once returned by the {@link SchemaParser#getSchema()}, a {@link Schema}
+ * instance must be able to validate a number of XML documents: each time a document
+ * needs to be validated, a new {@link ValidationHandler} can be obtained invoking the
+ * {@link #createValidator(ErrorHandler)} method. While validating an XML document,
+ * {@link SAXException}s should be thrown back to the caller only when the specified
+ * {@link ErrorHandler} is configured to do so.</p>
*
* @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
@@ -34,46 +44,34 @@
/**
* <p>Return the {@link SourceValidity} associated with this {@link Schema}.</p>
*
- * <p>If the current schema grammar allow inclusion of sub-schemas, the
- * {@link SourceValidity} returned by this method <b>must</b> validate both the
- * original schema URI <b>and</b> all its sub-schemas.</p>
+ * <p>If the schema represented by this instance was parsed from several sources
+ * (through the use of inclusions or referencing to external entities, for
+ * example) the {@link SourceValidity} returned by this method <b>must</b>
+ * consider all of them when the {@link SourceValidity#isValid()} or the
+ * {@link SourceValidity#isValid(SourceValidity)} methods are called.</p>
*
* @return a {@link SourceValidity} instance or <b>null</b> if not known.
*/
public SourceValidity getValidity();
/**
- * <p>Return a new {@link ContentHandler} instance that can be used to send SAX
- * events to for proper validation.</p>
+ * <p>Return a new {@link ValidationHandler} instance that can be used to
+ * validate an XML document by sending SAX events to it.</p>
*
- * <p>By default, this method will create a {@link ContentHandler} failing on the
- * first occurrence of an warning, error or fatal error . If this behavior is
- * not suitable, use the {@link #newValidator(ErrorHandler)} method instead and
- * specify an {@link ErrorHandler} suitable to your needs.</p>
- *
- * <p>Once used, the returned {@link ContentHandler} <b>can't</b> be reused.</p>
- *
- * @return a <b>non-null</b> {@link ContentHandler} instance.
- * @throws SAXException if an error occurred creating the validation handler.
- */
- public ContentHandler newValidator()
- throws SAXException;
-
- /**
- * <p>Return a new {@link ContentHandler} instance that can be used to send SAX
- * events to for proper validation.</p>
- *
* <p>The specified {@link ErrorHandler} will be notified of all warnings or
* errors encountered validating the SAX events sent to the returned
- * {@link ContentHandler}.</p>
- *
- * <p>Once used, the returned {@link ContentHandler} <b>can not</b> be reused.</p>
- *
- * @param handler an {@link ErrorHandler} to notify of validation errors.
- * @return a <b>non-null</b> {@link ContentHandler} instance.
+ * {@link ValidationHandler}, and <b>must not</b> be <b>null</b>.</p>
+ *
+ * <p>The returned {@link ValidationHandler} can be used to validate <b>only
+ * one</b> XML document. To validate more than one document, this method should
+ * be called once for each document to validate.</p>
+ *
+ * @param errorHandler an {@link ErrorHandler} to notify of validation errors.
+ * @return a <b>non-null</b> {@link ValidationHandler} instance.
+ * @throws NullPointerException if the {@link ErrorHandler} was <b>null</b>.
* @throws SAXException if an error occurred creating the validation handler.
*/
- public ContentHandler newValidator(ErrorHandler handler)
- throws SAXException;
+ public ValidationHandler createValidator(ErrorHandler handler)
+ throws NullPointerException, SAXException;
}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/SchemaParser.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/SchemaParser.java?rev=280229&r1=280228&r2=280229&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/SchemaParser.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/SchemaParser.java Sun Sep 11 18:09:57 2005
@@ -17,48 +17,45 @@
import java.io.IOException;
-import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.source.Source;
import org.xml.sax.SAXException;
/**
- * <p>A component parsing schemas usable for XML validation and returning them as
- * {@link Schema} instances.</p>
+ * <p>The {@link SchemaParser} interface defines the abstraction of a component able
+ * to parse sources and produce {@link Schema} instances suitable for validation of
+ * XML documents.</p>
*
- * <p>This interface does not imply any requirement in terms of the grammar used
- * to produce {@link Schema} instances. Normally multiple-grammar selection is
- * provided through the {@link Validator} class.</p>
+ * <p>A {@link SchemaParser} might be able to understand more than one grammar
+ * language at the same time. The list of all supported grammar languages must be
+ * returned by the {@link #getSupportedGrammars()} method.</p>
*
- * <p>The only requirement imposed by this interface is that the final class
- * implementing this interface must be {@link ThreadSafe}.</p>
- *
* @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
-public interface SchemaParser extends ThreadSafe {
+public interface SchemaParser {
- /** <p>Avalon Role name of this component.</p> */
+ /** <p>Avalon Role name of {@link SchemaParser} components.</p> */
public static final String ROLE = SchemaParser.class.getName();
/**
- * <p>Parse the specified URI and return a {@link Schema}.</p>
+ * <p>Parse the specified {@link Source} and return a new {@link Schema}.</p>
*
- * <p>Once parsed, the returned {@link Schema} can be used multiple time to
- * validate documents by sending their SAX events to the handler returned by
- * the {@link Schema#newValidator()}.</p>
- *
- * @param uri the URI of the {@link Schema} to return.
+ * <p>The returned {@link Schema} must be able to validate multiple documents
+ * via multiple invocations of {@link Schema#createValidator(ErrorHandler)}.</p>
+ *
+ * @param source the {@link Source} associated with the {@link Schema} to return.
* @return a <b>non-null</b> {@link Schema} instance.
- * @throws SAXException if an error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
* @throws IOException if an I/O error occurred parsing the schema.
+ * @throws IllegalArgumentException if the specified grammar type is not one
+ * of the grammar types returned by the
+ * {@link #getSupportedGrammars()} method.
*/
- public Schema getSchema(String uri)
- throws SAXException, IOException;
+ public Schema getSchema(Source source, String grammar)
+ throws SAXException, IOException, IllegalArgumentException;
/**
- * <p>Return an array of {@link String}s containing all schema grammars
+ * <p>Return an array of {@link String}s containing all the grammar languages
* supported by this {@link SchemaParser}.</p>
- *
- * <p>All {@link String}s in the array returned by this method should be
- * valid grammar names as defined in the {@link Validator} class.</p>
*
* @return a <b>non-null</b> array of {@link String}s.
*/
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidationHandler.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidationHandler.java?rev=280229&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidationHandler.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidationHandler.java Sun Sep 11 18:09:57 2005
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.validation;
+
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * <p>A {@link ValidationHandler} represents a {@link ContentHandler} validating
+ * SAX events according to a validation schema.</p>
+ *
+ * <p>As the handler might be tied to one (or more) resources from where the original
+ * schema was read from, the {@link #getValidity()} method provides a way to verify
+ * whether the validation instruction are still valid or not.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
+ */
+public interface ValidationHandler extends ContentHandler, LexicalHandler {
+
+ /**
+ * <p>Return a {@link SourceValidity} instance associated with the original
+ * resources of the schema describing the validation instructions.</p>
+ *
+ * <p>As the handler might be tied to one (or more) resources from where the
+ * original schema was read from, the {@link #getValidity()} method provides a
+ * way to verify whether the validation instruction are still valid or not.</p>
+ */
+ public SourceValidity getValidity();
+
+}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Validator.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Validator.java?rev=280229&r1=280228&r2=280229&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Validator.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/Validator.java Sun Sep 11 18:09:57 2005
@@ -15,54 +15,236 @@
*/
package org.apache.cocoon.components.validation;
-import org.apache.avalon.framework.service.ServiceSelector;
+import java.io.IOException;
+
+import org.apache.excalibur.source.Source;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
/**
- * <p>The {@link Validator} interface defines a {@link ServiceSelector} selecting
- * between different {@link SchemaParser}.</p>
+ * <p>The {@link Validator} interface provides the abstraction of a component able
+ * to validate XML documents using schemas defined in different languages.</p>
+ *
+ * <p>This is basically the main entry point of the validation API, allowing users
+ * to transparently access validators (in the form of {@link ValidationHandler}s
+ * receiving SAX events for the documents to be validated), in different grammar
+ * languages, using different implementations.</p>
+ *
+ * <p>As more than one {@link SchemaParser} might be able to parse and create
+ * {@link Schema} instances for a particular grammar language, this interface
+ * defines a unique lookup method to allow selection of a particular
+ * {@link SchemaParser} implementation.</p>
*
- * <p>Selection can occur either normally, based on a component name specified in
- * the configuration files, or on the {@link SchemaParser#getSupportedGrammars()
- * supported grammars} of the configured {@link SchemaParser}s.</p>
+ * <p>Assuming that two different {@link SchemaParser}s called <code>first</code>
+ * and <code>second</code> are both able to understand the
+ * {@link #GRAMMAR_RELAX_NG RELAX NG} grammar (identified by the
+ * <code>http://relaxng.org/ns/structure/0.9</code> identifier) one could select
+ * between the two implementation using the following two strings:</p>
+ *
+ * <ul>
+ * <li><code>first:http://relaxng.org/ns/structure/0.9</code></li>
+ * <li><code>second:http://relaxng.org/ns/structure/0.9</code></li>
+ * </ul>
*
* @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
-public interface Validator extends ServiceSelector {
+public interface Validator {
- /** <p>Role name to use when this component is accessed via a selector.</p> */
+ /** <p>Avalon Role name of {@link Validator} components.</p> */
public static final String ROLE = Validator.class.getName();
- /**
- * <p>An grammar identifer specifying tht the {@link SchemaParser} can
- * automatically detect the grammar while parsing.</p>
- */
- public static final String GRAMMAR_AUTOMATIC = "http://apache.org/cocoon/validation/grammars/automatic/1.0";
-
- /** <p>The <a href="http://www.schematron.com/">ISO SCHEMATRON</a/> grammar identifer.</p> */
+ /** <p>The <a href="http://www.schematron.com/">ISO Schematron</a/> grammar identifer.</p> */
public static final String GRAMMAR_ISO_SCHEMATRON = "http://purl.oclc.org/dsdl/schematron";
/** <p>The <a href="http://www.relaxng.org/">RELAX NG</a/> grammar identifer.</p> */
public static final String GRAMMAR_RELAX_NG = "http://relaxng.org/ns/structure/0.9";
- /** <p>The <a href="http://www.xml.gr.jp/relax">RELAX CORE</a/> grammar identifer.</p> */
+ /** <p>The <a href="http://www.xml.gr.jp/relax">RELAX Core</a/> grammar identifer.</p> */
public static final String GRAMMAR_RELAX_CORE = "http://www.xml.gr.jp/xmlns/relaxCore";
- /** <p>The <a href="http://www.xml.gr.jp/relax">RELAX NAMESPACE</a/> grammar identifer.</p> */
+ /** <p>The <a href="http://www.xml.gr.jp/relax">RELAX Namespace</a/> grammar identifer.</p> */
public static final String GRAMMAR_RELAX_NS = "http://www.xml.gr.jp/xmlns/relaxNamespace";
- /** <p>The <a href="http://xml.ascc.net/schematron/">SCHEMATRON</a/> grammar identifer.</p> */
+ /** <p>The <a href="http://xml.ascc.net/schematron/">Schematron</a/> grammar identifer.</p> */
public static final String GRAMMAR_SCHEMATRON = "http://www.ascc.net/xml/schematron";
- /** <p>The <a href="http://www.thaiopensource.com/trex/">TREX</a/> grammar identifer.</p> */
+ /** <p>The <a href="http://www.thaiopensource.com/trex/">Trex</a/> grammar identifer.</p> */
public static final String GRAMMAR_TREX = "http://www.thaiopensource.com/trex";
- /** <p>The <a href="http://www.w3.org/XML/Schema">XML SCHEMA</a/> grammar identifer.</p> */
+ /** <p>The <a href="http://www.w3.org/XML/Schema">XML Schema</a/> grammar identifer.</p> */
public static final String GRAMMAR_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
/** <p>The <a href="http://www.w3.org/TR/REC-xml">XML DTD</a/> grammar identifer.</p> */
public static final String GRAMMAR_XML_DTD = "http://www.w3.org/XML/1998/namespace";
-
- /** <p>The list of all known grammars excluding {@link #GRAMMAR_AUTOMATIC}.</p> */
- public static final String GRAMMARS[] = new String[] { GRAMMAR_ISO_SCHEMATRON,
- GRAMMAR_RELAX_NG,
- GRAMMAR_RELAX_CORE,
- GRAMMAR_RELAX_NS,
- GRAMMAR_SCHEMATRON,
- GRAMMAR_TREX,
- GRAMMAR_XML_SCHEMA,
- GRAMMAR_XML_DTD };
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, and each error or warning occurring while
+ * validating the document will trigger a {@link SAXException} to be thrown back
+ * to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri)
+ throws IOException, SAXException, ValidatorException;
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each error or warning occurring while validating the document will trigger
+ * a {@link SAXException} to be thrown back to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @param grammar the grammar language of the schema to parse.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri, String grammar)
+ throws IOException, SAXException, ValidatorException;
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, while each validation error or warning will
+ * be passed to the specified {@link ErrorHandler} which will have the ability
+ * to generate and throw a {@link SAXException} back to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri, ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException;
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each validation error or warning will be passed to the specified
+ * {@link ErrorHandler} which will have the ability to generate and throw a
+ * {@link SAXException} back to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @param grammar the grammar language of the schema to parse.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri, String grammar,
+ ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException;
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, and each error or warning occurring while
+ * validating the document will trigger a {@link SAXException} to be thrown back
+ * to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source)
+ throws IOException, SAXException, ValidatorException;
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each error or warning occurring while validating the document will trigger
+ * a {@link SAXException} to be thrown back to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @param grammar the grammar language of the schema to parse.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source, String grammar)
+ throws IOException, SAXException, ValidatorException;
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, while each validation error or warning will
+ * be passed to the specified {@link ErrorHandler} which will have the ability
+ * to generate and throw a {@link SAXException} back to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source,
+ ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException;
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each validation error or warning will be passed to the specified
+ * {@link ErrorHandler} which will have the ability to generate and throw a
+ * {@link SAXException} back to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @param grammar the grammar language of the schema to parse.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source, String grammar,
+ ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException;
}
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidatorException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidatorException.java?rev=280229&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidatorException.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/ValidatorException.java Sun Sep 11 18:09:57 2005
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.validation;
+
+import org.xml.sax.SAXException;
+
+/**
+ * <p>An exception representing that a {@link Validator} was not able to detect
+ * or did not support a specified schema grammar language.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
+ */
+public class ValidatorException extends SAXException {
+
+ /**
+ * <p>Create a new {@link ValidatorException} instance.</p>
+ */
+ public ValidatorException(String message) {
+ super(message);
+ }
+
+ /**
+ * <p>Create a new {@link ValidatorException} instance.</p>
+ */
+ public ValidatorException(String message, Exception exception) {
+ super(message, exception);
+ this.initCause(exception);
+ }
+
+}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchema.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchema.java?rev=280229&r1=280228&r2=280229&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchema.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchema.java Sun Sep 11 18:09:57 2005
@@ -17,10 +17,6 @@
import org.apache.cocoon.components.validation.Schema;
import org.apache.excalibur.source.SourceValidity;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
/**
* <p>A simple implementation of the {@link Schema} interface.</p>
@@ -46,35 +42,5 @@
*/
public SourceValidity getValidity() {
return this.validity;
- }
-
- /**
- * <p>Return a new {@link ContentHandler} instance that can be used to send SAX
- * events to for proper validation.</p>
- *
- * <p>By default, this method will create a {@link ContentHandler} failing on the
- * first occurrence of an warning, error or fatal error . If this behavior is
- * not suitable, use the {@link #newValidator(ErrorHandler)} method instead and
- * specify an {@link ErrorHandler} suitable to your needs.</p>
- *
- * <p>Once used, the returned {@link ContentHandler} <b>can't</b> be reused.</p>
- *
- * @return a <b>non-null</b> {@link ContentHandler} instance.
- * @throws SAXException if an error occurred creating the validation handler.
- */
- public ContentHandler newValidator()
- throws SAXException {
- ErrorHandler handler = new ErrorHandler() {
- public void warning(SAXParseException e) throws SAXException {
- throw e;
- }
- public void error(SAXParseException e) throws SAXException {
- throw e;
- }
- public void fatalError(SAXParseException e) throws SAXException {
- throw e;
- }
- };
- return this.newValidator(handler);
}
}
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchemaParser.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchemaParser.java?rev=280229&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchemaParser.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractSchemaParser.java Sun Sep 11 18:09:57 2005
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.validation.impl;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.components.validation.Schema;
+import org.apache.cocoon.components.validation.SchemaParser;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.xml.EntityResolver;
+
+/**
+ * <p>A {@link SchemaParser} caching {@link Schema} instance for multiple use.</p>
+ *
+ * <p>A {@link Schema} will be cached until its {@link SourceValidity} expires.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
+ */
+public abstract class AbstractSchemaParser extends AbstractLogEnabled
+implements Serviceable, Initializable, Disposable, SchemaParser {
+
+ /** <p>The {@link ServiceManager} configured for this instance.</p> */
+ protected ServiceManager serviceManager = null;
+ /** <p>The {@link SourceResolver} to resolve URIs into {@link Source}s.</p> */
+ protected SourceResolver sourceResolver = null;
+ /** <p>The {@link EntityResolver} resolving against catalogs of public IDs.</p> */
+ protected EntityResolver entityResolver = null;
+
+ /**
+ * <p>Contextualize this component specifying a {@link ServiceManager} instance.</p>
+ */
+ public void service(ServiceManager manager)
+ throws ServiceException {
+ this.serviceManager = manager;
+ }
+
+ /**
+ * <p>Initialize this component instance.</p>
+ *
+ * <p>A this point component resolution will happen.</p>
+ */
+ public void initialize()
+ throws Exception {
+ this.entityResolver = (EntityResolver) this.serviceManager.lookup(EntityResolver.ROLE);
+ this.sourceResolver = (SourceResolver) this.serviceManager.lookup(SourceResolver.ROLE);
+ }
+
+ /**
+ * <p>Dispose this component instance.</p>
+ */
+ public void dispose() {
+ if (this.entityResolver != null) this.serviceManager.release(this.entityResolver);
+ if (this.sourceResolver != null) this.serviceManager.release(this.sourceResolver);
+ }
+}
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractValidator.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractValidator.java?rev=280229&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractValidator.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/AbstractValidator.java Sun Sep 11 18:09:57 2005
@@ -0,0 +1,479 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.validation.impl;
+
+import java.io.IOException;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.components.validation.Schema;
+import org.apache.cocoon.components.validation.SchemaParser;
+import org.apache.cocoon.components.validation.ValidationHandler;
+import org.apache.cocoon.components.validation.Validator;
+import org.apache.cocoon.components.validation.ValidatorException;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.sax.NOPContentHandler;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * <p>The {@link AbstractValidator} provides a generic implementation of the methods
+ * specified by the {@link Validator} interface.</p>
+ *
+ * <p>Final implementations must implement three component management methods
+ * {@link #lookupParserByGrammar(String)}, {@link #lookupParserByName(String)} and
+ * {@link #releaseParser(SchemaParser)}.</p>
+ *
+ * <p>In addition to this, they might also override the default implementation of
+ * the {@link #getSchema(String, SchemaParser, String)} method, for example when
+ * caching {@link Schema} instances.</p>
+ *
+ * <p>This implementation provides a simple grammar identification mechanism, which
+ * can be overridden by reimplementing the {@link #detectGrammar(Source)} method
+ * provided by this class.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
+ */
+public abstract class AbstractValidator
+implements Validator, Serviceable, Disposable {
+
+ /** <p>The configured {@link ServiceManager} instance.</p> */
+ protected ServiceManager manager = null;
+ /** <p>The configured {@link SourceResolver} instance.</p> */
+ protected SourceResolver resolver = null;
+
+ /**
+ * <p>Create a new {@link AbstractValidator} instance.</p>
+ */
+ public AbstractValidator() {
+ super();
+ }
+
+ /**
+ * <p>Specify the {@link ServiceManager} available to this instance.</p>
+ */
+ public void service(ServiceManager manager)
+ throws ServiceException {
+ this.manager = manager;
+ this.resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+ }
+
+ /**
+ * <p>Dispose of this component instance.</p>
+ */
+ public void dispose() {
+ if (this.resolver != null) this.manager.release(this.resolver);
+ }
+
+ /* =========================================================================== */
+ /* IMPLEMENTATION OF THE VALIDATOR INTERFACE */
+ /* =========================================================================== */
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, and each error or warning occurring while
+ * validating the document will trigger a {@link SAXException} to be thrown back
+ * to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri)
+ throws IOException, SAXException, ValidatorException {
+ return this.getValidationHandler(uri, null, null);
+ }
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each error or warning occurring while validating the document will trigger
+ * a {@link SAXException} to be thrown back to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @param grammar the grammar language of the schema to parse.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri, String grammar)
+ throws IOException, SAXException, ValidatorException {
+ return this.getValidationHandler(uri, grammar, null);
+ }
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, while each validation error or warning will
+ * be passed to the specified {@link ErrorHandler} which will have the ability
+ * to generate and throw a {@link SAXException} back to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri, ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException {
+ return this.getValidationHandler(uri, null, errorHandler);
+ }
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each validation error or warning will be passed to the specified
+ * {@link ErrorHandler} which will have the ability to generate and throw a
+ * {@link SAXException} back to the caller.</p>
+ *
+ * @param uri the location of the schema to use to validate the document.
+ * @param grammar the grammar language of the schema to parse.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(String uri, String grammar,
+ ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException {
+ if (uri == null) throw new IOException("Specified schema URI was null");
+ Source source = null;
+ try {
+ source = this.resolver.resolveURI(uri);
+ return this.getValidationHandler(source, grammar, errorHandler);
+ } finally {
+ if (source != null) this.resolver.release(source);
+ }
+ }
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, and each error or warning occurring while
+ * validating the document will trigger a {@link SAXException} to be thrown back
+ * to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source)
+ throws IOException, SAXException, ValidatorException {
+ return this.getValidationHandler(source, null, null);
+ }
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each error or warning occurring while validating the document will trigger
+ * a {@link SAXException} to be thrown back to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @param grammar the grammar language of the schema to parse.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source, String grammar)
+ throws IOException, SAXException, ValidatorException {
+ return this.getValidationHandler(source, grammar, null);
+ }
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>The {@link Validator} will attempt to automatically detect the grammar
+ * language of the specified schema, while each validation error or warning will
+ * be passed to the specified {@link ErrorHandler} which will have the ability
+ * to generate and throw a {@link SAXException} back to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the grammar language of the specified schema
+ * could not be detected or was not supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source,
+ ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException {
+ return this.getValidationHandler(source, null, errorHandler);
+ }
+
+ /**
+ * <p>Return a {@link ValidationHandler} validating an XML document according to
+ * the schema found at the specified location.</p>
+ *
+ * <p>Each validation error or warning will be passed to the specified
+ * {@link ErrorHandler} which will have the ability to generate and throw a
+ * {@link SAXException} back to the caller.</p>
+ *
+ * @param source the {@link Source} identifying the schema to use for validation.
+ * @param grammar the grammar language of the schema to parse.
+ * @param errorHandler the {@link ErrorHandler} notified of validation problems.
+ * @return a <b>non null</b> {@link ValidationHandler} able to SAX events from
+ * the original XML document to validate.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws ValidatorException if the specified grammar language wasn't supported.
+ * @link SchemaParser#getSchema(String, String)
+ * @link Schema#createValidator(ErrorHandler)
+ */
+ public ValidationHandler getValidationHandler(Source source, String grammar,
+ ErrorHandler errorHandler)
+ throws IOException, SAXException, ValidatorException {
+ if (errorHandler == null) errorHandler = DraconianErrorHandler.INSTANCE;
+
+ SchemaParser parser = null;
+ try {
+ /* If no grammar was supplied, try to detect one */
+ if (grammar == null) grammar = this.detectGrammar(source);
+
+ /* Save the grammar name and try to find a schema parser */
+ String language = grammar;
+ parser = this.lookupParserByGrammar(grammar);
+
+ /*
+ * If the schema parser for the language was not found, we might have to
+ * look up for the form name:grammar as specified by Validator.
+ */
+ if (parser == null) {
+ int index = grammar.indexOf(':');
+ if (index > 0) {
+ String name = grammar.substring(0, index);
+ language = grammar.substring(index + 1);
+ parser = this.lookupParserByName(name);
+ }
+ }
+
+ /* If still we didn't find any parser, simply die of natural death */
+ if (parser == null) {
+ String message = "Unsupported grammar language" + grammar;
+ throw new ValidatorException(message);
+ }
+
+ /* Somehow we have a schema parser, check it supports the gramar */
+ String languages[] = parser.getSupportedGrammars();
+ for (int x = 0; x < languages.length; x++) {
+ if (! language.equals(languages[x])) continue;
+ /* Hah! language supported, go ahead and parse now */
+ Schema schema = this.getSchema(parser, source, language);
+ return schema.createValidator(errorHandler);
+ }
+
+ /* Something really odd going on, this should never happen */
+ String message = "Schema parser " + parser.getClass().getName() +
+ " does not support grammar " + grammar;
+ throw new ValidatorException(message);
+
+ } finally {
+ if (parser != null) this.releaseParser(parser);
+ }
+ }
+
+ /* =========================================================================== */
+ /* METHODS TO BE IMPLEMENTED BY THE EXTENDING CLASSES */
+ /* =========================================================================== */
+
+ /**
+ * <p>Attempt to acquire a {@link SchemaParser} interface able to understand
+ * the grammar language specified.</p>
+ *
+ * @param grammar the grammar language that must be understood by the returned
+ * {@link SchemaParser}
+ * @return a {@link SchemaParser} instance or <b>null</b> if none was found able
+ * to understand the specified grammar language.
+ */
+ protected abstract SchemaParser lookupParserByGrammar(String grammar);
+
+ /**
+ * <p>Attempt to acquire a {@link SchemaParser} interface associated with the
+ * specified instance name.</p>
+ *
+ * @param name the name associated with the {@link SchemaParser} to be returned.
+ * @return a {@link SchemaParser} instance or <b>null</b> if none was found.
+ */
+ protected abstract SchemaParser lookupParserByName(String name);
+
+ /**
+ * <p>Release a previously acquired {@link SchemaParser} instance back to its
+ * original component manager.</p>
+ *
+ * <p>This method is supplied in case solid implementations of this class relied
+ * on the {@link ServiceManager} to manage {@link SchemaParser}s instances.</p>
+ *
+ * @param parser the {@link SchemaParser} whose instance is to be released.
+ */
+ protected abstract void releaseParser(SchemaParser parser);
+
+ /* =========================================================================== */
+ /* METHODS SPECIFIC TO ABSTRACTVALIDATOR OVERRIDABLE BY OTHER IMPLEMENTATIONS */
+ /* =========================================================================== */
+
+ /**
+ * <p>Return a {@link Schema} instance from the specified {@link SchemaParser}
+ * associated with the given {@link Source} and grammar language.</p>
+ *
+ * <p>This method simply implements resolution returning the {@link Schema}
+ * instance acquired calling <code>parser.getSchema(source,grammar)</code>.</p>
+ *
+ * @param parser the {@link SchemaParser} producing the {@link Schema}.
+ * @param source the {@link Source} associated with the {@link Schema} to return.
+ * @param grammar the grammar language of the schema to produce.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ */
+ protected Schema getSchema(SchemaParser parser, Source source, String grammar)
+ throws IOException, SAXException {
+ try {
+ return parser.getSchema(source, grammar);
+ } catch (IllegalArgumentException exception) {
+ String message = "Schema parser " + parser.getClass().getName() +
+ " does not support grammar " + grammar;
+ throw new ValidatorException(message, exception);
+ }
+ }
+
+ /**
+ * <p>Attempt to detect the grammar language used by the schema identified
+ * by the specified {@link Source}.</p>
+ *
+ * @param source a {@link Source} instance pointing to the schema to be analyzed.
+ * @throws IOException if an I/O error occurred accessing the schema.
+ * @throws SAXException if an error occurred parsing the schema.
+ * @throws ValidatorException if the language of the schema could not be guessed.
+ */
+ protected String detectGrammar(Source source)
+ throws IOException, SAXException, ValidatorException {
+ SAXParser xmlParser = null;
+ String grammar = null;
+
+ try {
+ DetectionHandler handler = new DetectionHandler();
+ if (source instanceof XMLizable) {
+ XMLizable xmlizable = (XMLizable) source;
+ xmlizable.toSAX(handler);
+ } else {
+ xmlParser = (SAXParser) this.manager.lookup((SAXParser.ROLE));
+ InputSource input = new InputSource();
+ input.setSystemId(source.getURI());
+ input.setByteStream(source.getInputStream());
+ xmlParser.parse(input, handler);
+ }
+ } catch (ServiceException exception) {
+ throw new SAXException("Unable to access XML parser", exception);
+ } catch (DetectionException exception) {
+ grammar = exception.grammar;
+ } catch (SAXParseException exception) {
+ grammar = Validator.GRAMMAR_XML_DTD;
+ } finally {
+ if (xmlParser != null) this.manager.release(xmlParser);
+ }
+
+ if (("".equals(grammar)) || (grammar == null)) {
+ String message = "Unable to detect grammar for schema at ";
+ throw new ValidatorException(message + source.getURI());
+ } else {
+ return grammar;
+ }
+ }
+
+ /* =========================================================================== */
+ /* METHODS AND INNER CLASSES FOR AUTOMATIC GRAMMAR LANGUAGE DETECTION */
+ /* =========================================================================== */
+
+ /**
+ * <p>A simple implementation of a {@link ValidationHandler} detecting schemas
+ * based on the namespace of the root element.</p>
+ */
+ private static final class DetectionHandler extends NOPContentHandler {
+
+ /**
+ * <p>Detect the namespace of the root element and always throw a
+ * {@link SAXException} or a {@link DetectionException}.</p>
+ */
+ public void startElement(String ns, String lnam, String qnam, Attributes a)
+ throws SAXException {
+ throw new DetectionException(ns);
+ }
+ }
+
+ /**
+ * <p>An exception thrown by {@link DetectionHandler} representing that
+ * a grammar was successfully detected.</p>
+ */
+ private static final class DetectionException extends SAXException {
+
+ private final String grammar;
+
+ private DetectionException(String grammar) {
+ super ("Grammar detected: " + grammar);
+ this.grammar = grammar;
+ }
+ }
+}
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/CachingValidator.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/CachingValidator.java?rev=280229&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/CachingValidator.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/CachingValidator.java Sun Sep 11 18:09:57 2005
@@ -0,0 +1,186 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.validation.impl;
+
+import java.io.IOException;
+
+import org.apache.cocoon.components.validation.Schema;
+import org.apache.cocoon.components.validation.SchemaParser;
+import org.apache.cocoon.components.validation.ValidatorException;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.store.Store;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>An extension of the {@link DefaultValidator} class allowing {@link Schema}
+ * instances to be cached.</p>
+ *
+ * <p>The {@link #getSchema(SchemaParser, String, String)} method will manage
+ * whether to return a cached or a freshly parsed {@link Schema} instance.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
+ */
+public class CachingValidator extends DefaultValidator {
+
+ /** <p>The {@link Store} used for caching {@link Schema}s (if enabled).</p> */
+ private Store store = null;
+
+ /**
+ * <p>Initialize this component instance.</p>
+ */
+ public void initialize()
+ throws Exception {
+ this.store = (Store) this.manager.lookup(Store.TRANSIENT_STORE);
+ super.initialize();
+ }
+
+ /**
+ * <p>Dispose this component instance.</p>
+ */
+ public void dispose() {
+ try {
+ super.dispose();
+ } finally {
+ if (this.store != null) this.manager.release(this.store);
+ }
+ }
+
+ /**
+ * <p>Return a {@link Schema} instance from the specified {@link SchemaParser}
+ * associated with the given {@link Source} and grammar language.</p>
+ *
+ * <p>This method will overriding the default behaviour specified by the
+ * {@link AbstractValidator#getSchema(SchemaParser, Source, String)} method,
+ * and supports cacheability of {@link Schema} instances through the use of
+ * a {@link Store} looked up using the {@link Store#TRANSIENT_STORE} Avalon
+ * role.</p>
+ *
+ * <p>Cached {@link Schema} instances will be retained in the configured
+ * {@link Store} until the checks on the validity obtained calling the
+ * {@link Schema#getValidity()} method will declare that the schema is still
+ * valid.</p>
+ *
+ * @param parser the {@link SchemaParser} producing the {@link Schema}.
+ * @param source the {@link Source} associated with the {@link Schema} to return.
+ * @param grammar the grammar language of the schema to produce.
+ * @throws SAXException if a grammar error occurred parsing the schema.
+ * @throws IOException if an I/O error occurred parsing the schema.
+ */
+ public Schema getSchema(SchemaParser parser, Source source, String grammar)
+ throws IOException, SAXException {
+
+ /* Prepare a key, and try to get the cached copy of the schema */
+ String uri = source.getURI();
+ String key = this.getClass().getName() + "[" + parser.getClass().getName()
+ + ":" + grammar + "]@" + source.getURI();
+ Schema schema = null;
+ SourceValidity validity = null;
+ schema = (Schema) this.store.get(key);
+
+ /* If the schema was found verify its validity and optionally clear */
+ if (schema != null) {
+ validity = schema.getValidity();
+ if (validity == null) {
+ /* Why did we cache it in the first place? */
+ this.logger.warn("Cached schema " + uri + " has null validity");
+ this.store.remove(key);
+ schema = null;
+ } else if (validity.isValid() != SourceValidity.VALID) {
+ this.store.remove(key);
+ schema = null;
+ }
+ }
+
+ /* If the schema was not cached or was cleared, parse and cache it */
+ if (schema == null) {
+ this.logger.debug("Parsing schema \"" + uri + "\"");
+ schema = super.getSchema(parser, source, grammar);
+ validity = schema.getValidity();
+ if (validity != null) {
+ if (validity.isValid() == SourceValidity.VALID) {
+ this.store.store(key, schema);
+ }
+ }
+ }
+
+ /* Return the parsed or cached schema */
+ return schema;
+ }
+
+ /**
+ * <p>Attempt to detect the grammar language used by the schema identified
+ * by the specified {@link Source}.</p>
+ *
+ * <p>The grammar languages detected will be cached until the {@link Source}'s
+ * {@link SourceValidity} declares that the schema is valid.</p>
+ *
+ * @param source a {@link Source} instance pointing to the schema to be analyzed.
+ * @throws IOException if an I/O error occurred accessing the schema.
+ * @throws SAXException if an error occurred parsing the schema.
+ * @throws ValidatorException if the language of the schema could not be guessed.
+ */
+ protected String detectGrammar(Source source)
+ throws IOException, SAXException, ValidatorException {
+ /* Prepare a key, and try to get the cached copy of the schema */
+ String uri = source.getURI();
+ String key = this.getClass().getName() + "@" + source.getURI();
+
+ CachedGrammar grammar = null;
+ grammar = (CachedGrammar) this.store.get(key);
+
+ /* If the schema was found verify its validity and optionally clear */
+ if (grammar != null) {
+ if (grammar.validity == null) {
+ /* Why did we cache it in the first place? */
+ this.logger.warn("Cached grammar " + uri + " has null validity");
+ this.store.remove(key);
+ grammar = null;
+ } else if (grammar.validity.isValid() != SourceValidity.VALID) {
+ this.store.remove(key);
+ grammar = null;
+ }
+ }
+
+ /* If the schema was not cached or was cleared, parse and cache it */
+ if (grammar != null) {
+ return grammar.grammar;
+ } else {
+ this.logger.debug("Detecting grammar for schema \"" + uri + "\"");
+ String language = super.detectGrammar(source);
+ SourceValidity validity = source.getValidity();
+ if (validity != null) {
+ if (validity.isValid() == SourceValidity.VALID) {
+ this.store.store(key, new CachedGrammar(validity, language));
+ }
+ }
+ return language;
+ }
+ }
+
+ /**
+ * <p>A simple inner class associating grammar languages and source validity
+ * for caching of schema grammar detection.</p>
+ */
+ private static final class CachedGrammar {
+ private final SourceValidity validity;
+ private final String grammar;
+ private CachedGrammar(SourceValidity validity, String grammar) {
+ this.validity = validity;
+ this.grammar = grammar;
+ }
+ }
+}
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidationHandler.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidationHandler.java?rev=280229&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidationHandler.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidationHandler.java Sun Sep 11 18:09:57 2005
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.validation.impl;
+
+import org.apache.cocoon.components.validation.ValidationHandler;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.xml.sax.NOPContentHandler;
+import org.apache.excalibur.xml.sax.NOPLexicalHandler;
+import org.apache.excalibur.xml.sax.XMLConsumerProxy;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * <p>The default implementation of the {@link ValidationHandler} interface.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
+ */
+public class DefaultValidationHandler extends XMLConsumerProxy
+implements ValidationHandler {
+
+ /** <p>The {@link SourceValidity} associated with the schema.</p> */
+ private final SourceValidity validity;
+
+ /**
+ * <p>Create a new {@link DefaultValidationHandler} instance.</p>
+ */
+ public DefaultValidationHandler(SourceValidity validity,
+ ContentHandler handler) {
+ this(validity, handler, null);
+ }
+
+ /**
+ * <p>Create a new {@link DefaultValidationHandler} instance.</p>
+ */
+ public DefaultValidationHandler(SourceValidity validity,
+ ContentHandler contentHandler,
+ LexicalHandler lexicalHandler) {
+ super(contentHandler == null? new NOPContentHandler(): contentHandler,
+ lexicalHandler == null? new NOPLexicalHandler(): lexicalHandler);
+ this.validity = validity;
+ }
+
+ /**
+ * <p>Return a {@link SourceValidity} instance associated with the original
+ * resources of the schema describing the validation instructions.</p>
+ *
+ * <p>As the handler might be tied to one (or more) resources from where the
+ * original schema was read from, the {@link #getValidity()} method provides a
+ * way to verify whether the validation instruction are still valid or not.</p>
+ */
+ public SourceValidity getValidity() {
+ return this.validity;
+ }
+}