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 [2/2] - in
/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon:
components/validation/ components/validation/impl/ transformation/
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidator.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidator.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/DefaultValidator.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DefaultValidator.java Sun Sep 11 18:09:57 2005
@@ -17,10 +17,8 @@
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
@@ -37,39 +35,38 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.validation.SchemaParser;
import org.apache.cocoon.components.validation.Validator;
/**
- * <p>The default implementation of the {@link Validator} interface.</p>
+ * <p>The default implementation of the {@link Validator} interface provides
+ * core management for a number of {@link SchemaParser} instances.</p>
+ *
+ * <p>Given the simplicity of this implementation, only {@link SchemaParser}s
+ * implementing the {@link ThreadSafe} interface can be managed, and they can be
+ * accessed directly (via its name) through the methods specified by the
+ * {@link ServiceSelector} interface.</p>
+ *
+ * <p>That said, normally selection would occur using the methods declared by the
+ * {@link AbstractValidator} class and implemented here.</p>
*
* @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
-public class DefaultValidator implements Validator, LogEnabled, ThreadSafe,
-Contextualizable, Serviceable, Configurable, Initializable, Disposable {
-
- /** <p>The default shorthand code to use in subcomponent configurations.</p> */
- public static final String DEFAULT_SHORTHAND = "schema-parser";
- /** <p>The default subcomponent {@link Class} instance.</p> */
- public static final Class DEFAULT_CLASS = SchemaParser.class;
-
- /** <p>The shorthand code to use in subcomponents configurations.</p> */
- private final String shorthand;
- /** <p>The {@link Class} of the subcomponents selected by this instance.</p> */
- private final Class componentClass;
- /** <p>The {@link Set} of all instantiated components.</p> */
- private final Set components;
- /** <p>A {@link Map} associating names with component instances.</p> */
- private final Map selections;
+public class DefaultValidator extends AbstractValidator implements LogEnabled,
+ThreadSafe, Contextualizable, Initializable, Disposable, ServiceSelector {
+
+ /** <p>A {@link Map} associating {@link SchemaParser}s with their names.</p> */
+ private final Map componentx = Collections.synchronizedMap(new HashMap());
+ /** <p>A {@link Map} associating component names with grammars.</p> */
+ private final Map grammars = Collections.synchronizedMap(new HashMap());
/** <p>The configured {@link Logger} instance.</p> */
- private Logger logger = null;
+ protected Logger logger = null;
/** <p>The configured {@link Context} instance.</p> */
private Context context = null;
- /** <p>The configured {@link ServiceManager} instance.</p> */
- private ServiceManager manager = null;
/** <p>The configured {@link Configuration} instance.</p> */
private Configuration conf = null;
@@ -77,20 +74,7 @@
* <p>Create a new {@link DefaultValidator} instance.</p>
*/
public DefaultValidator() {
- this(null, null);
- }
-
- /**
- * <p>Create a new {@link DefaultValidator} instance.</p>
- *
- * @param shorthand the shorthand code to use in subcomponents configurations.
- * @param componentClass the {@link Class} of the subcomponents selected by this.
- */
- public DefaultValidator(String shorthand, Class componentClass) {
- this.shorthand = shorthand == null? DEFAULT_SHORTHAND: shorthand;
- this.componentClass = componentClass == null? DEFAULT_CLASS: componentClass;
- this.components = Collections.synchronizedSet(new HashSet());
- this.selections = Collections.synchronizedMap(new HashMap());
+ super();
}
/**
@@ -109,14 +93,6 @@
}
/**
- * <p>Specify the {@link ServiceManager} available to this instance.</p>
- */
- public void service(ServiceManager manager)
- throws ServiceException {
- this.manager = manager;
- }
-
- /**
* <p>Configure this instance.</p>
*/
public void configure(Configuration conf)
@@ -126,9 +102,6 @@
/**
* <p>Initialize this instance.</p>
- *
- * <p>Required components lookup and sub-components initialization will occur
- * when this method is called.</p>
*/
public void initialize()
throws Exception {
@@ -138,64 +111,90 @@
if (this.context == null) throw new IllegalStateException("Null context");
if (this.manager == null) throw new IllegalStateException("Null manager");
if (this.conf == null) throw new IllegalStateException("Null configuration");
-
- Configuration configurations[] = this.conf.getChildren(this.shorthand);
+
+ Configuration configurations[] = this.conf.getChildren("schema-parser");
this.logger.debug("Configuring " + configurations.length + " schema parsers"
+ " from " + this.conf.getLocation());
+
+ /* Iterate through all the sub-confiuration instances */
for (int x = 0; x < configurations.length; x++) try {
- Configuration configuration = configurations[x];
- String className = configuration.getAttribute("class");
- String selectionKey = configuration.getAttribute("name");
+ final Configuration configuration = configurations[x];
+ final String className = configuration.getAttribute("class");
+ final String selectionKey = configuration.getAttribute("name");
+
+ /* Check that we don't have a duplicate schema parser name in configs */
+ if (this.componentx.containsKey(selectionKey)) {
+ String message = "Duplicate schema parser \"" + selectionKey + "\"";
+ throw new ConfigurationException(message, configuration);
+ }
+
+ /* Dump some debugging information, just in case */
this.logger.debug("Configuring schema parser " + selectionKey + " as "
+ className + " from " + configuration.getLocation());
- Class clazz;
+ /* Try to load and instantiate the SchemaParser */
+ final SchemaParser schemaParser;
try {
- clazz = Class.forName(className);
- } catch (Exception exception) {
- String message = "Unable to load class " + className;
- throw new ConfigurationException(message, configuration, exception);
- }
+ /* Load the class */
+ final Class clazz = Class.forName(className);
- if (!this.componentClass.isAssignableFrom(clazz)) {
- String message = "Class " + className + " does not represent a "
- + this.componentClass.getName();
- throw new ConfigurationException(message, configuration);
- }
+ /* ClassCastExceptions normally don't come with messages (darn) */
+ if (! SchemaParser.class.isAssignableFrom(clazz)) {
+ String message = "Class " + className + " doesn't implement the "
+ + SchemaParser.class.getName() + " interface";
+ throw new ConfigurationException(message, configuration);
+ }
- Object component;
- try {
- component = clazz.newInstance();
+ /* We only support ThreadSafe SchemaParser instances */
+ if (! ThreadSafe.class.isAssignableFrom(clazz)) {
+ String message = "Class " + className + " doesn't implement the "
+ + ThreadSafe.class.getName() + " interface";
+ throw new ConfigurationException(message, configuration);
+ }
+
+ /* Instantiate and set up the new SchemaParser */
+ schemaParser = (SchemaParser) clazz.newInstance();
+ this.setupComponent(schemaParser, configuration);
+
+ } catch (ConfigurationException exception) {
+ throw exception;
} catch (Exception exception) {
String message = "Unable to instantiate SchemaParser " + className;
throw new ConfigurationException(message, configuration, exception);
}
- this.components.add(this.setupComponent(component, configuration));
- this.selections.put(selectionKey, component);
- this.logger.debug("SchemaParser " + selectionKey + " class" + className);
- if (component instanceof SchemaParser) {
- SchemaParser parser = (SchemaParser) component;
- String grammars[] = parser.getSupportedGrammars();
- if (grammars != null) {
- for (int k = 0; k < grammars.length; k++) {
- if (this.selections.containsKey(grammars[k])) continue;
- this.selections.put(grammars[k], component);
- this.logger.debug("SchemaParser " + selectionKey +
- "provides grammar " + grammars[k]);
- }
- }
+ /* Store this instance (and report about it) */
+ this.componentx.put(selectionKey, schemaParser);
+ this.logger.debug("SchemaParser \"" + selectionKey + "\" instantiated" +
+ " from class " + className);
+
+ /* Analyze the grammars provided by the current SchemaParser */
+ String grammars[] = schemaParser.getSupportedGrammars();
+ if (grammars == null) continue;
+
+ /* Iterate through the grammars and store them (default lookup) */
+ for (int k = 0; k < grammars.length; k++) {
+ if (this.grammars.containsKey(grammars[k])) continue;
+
+ /* Noone yet supports this grammar, make this the default */
+ this.grammars.put(grammars[k], selectionKey);
+ this.logger.debug("SchemaParser \"" + selectionKey + "\" is the " +
+ "default grammar provider for " + grammars[k]);
}
+
} catch (Exception exception) {
+ /* Darn, we had an exception instantiating one of the components */
this.logger.warn("Exception creating schema parsers", exception);
- Iterator iterator = this.components.iterator();
+ /* Dispose all previously stored component instances */
+ Iterator iterator = this.componentx.values().iterator();
while (iterator.hasNext()) try {
this.decommissionComponent(iterator.next());
} catch (Exception nested) {
this.logger.fatalError("Error decommissioning component", nested);
}
+ /* Depending on the exception type, re-throw it or wrap it */
if (exception instanceof ConfigurationException) {
throw exception;
} else {
@@ -205,48 +204,113 @@
throw new ConfigurationException(message, configuration, exception);
}
}
- this.logger.debug("Configured successfully");
}
/**
- * <p>Select the subcomponent managed by this instance associated wit the
- * specified key.</p>
+ * <p>Dispose of this instance.</p>
+ *
+ * <p>All sub-components initialized previously will be disposed of when this
+ * method is called.</p>
*/
- public Object select(Object key)
- throws ServiceException {
- if (this.isSelectable(key)) return this.selections.get(key);
- throw new ServiceException((String) key, "Schema parser not configured");
+ public void dispose() {
+ Iterator iterator = this.componentx.values().iterator();
+ while (iterator.hasNext()) try {
+ this.decommissionComponent(iterator.next());
+ } catch (Exception exception) {
+ this.logger.fatalError("Error decommissioning component", exception);
+ }
}
+ /* =========================================================================== */
+ /* IMPLEMENTATION OF METHODS SPECIFIED BY THE ABSTRACTVALIDATOR CLASS */
+ /* =========================================================================== */
+
/**
- * <p>Ensure that a subcomponent is selectable for the specified key.</p>
- */
- public boolean isSelectable(Object key) {
- return this.selections.containsKey((String) key);
+ * <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 SchemaParser lookupParserByGrammar(String grammar) {
+ if (this.grammars.containsKey(grammar)) {
+ return this.lookupParserByName((String) this.grammars.get(grammar));
+ }
+ return null;
}
/**
- * <p>Release a previously selected subcomponent instance.</p>
+ * <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.
*/
- public void release(Object object) {
- // Nothing to do over here...
+ protected SchemaParser lookupParserByName(String name) {
+ if (this.isSelectable(name)) try {
+ return (SchemaParser) this.select(name);
+ } catch (ServiceException exception) {
+ return null;
+ }
+ return null;
}
/**
- * <p>Dispose of this instance.</p>
+ * <p>Release a previously acquired {@link SchemaParser} instance back to its
+ * original component manager.</p>
*
- * <p>All sub-components initialized previously will be disposed of when this
- * method is called.</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.
*/
- public void dispose() {
- Iterator iterator = this.components.iterator();
- while (iterator.hasNext()) try {
- this.decommissionComponent(iterator.next());
- } catch (Exception exception) {
- this.logger.fatalError("Error decommissioning component", exception);
+ protected void releaseParser(SchemaParser parser) {
+ this.release(parser);
+ }
+
+ /* =========================================================================== */
+ /* IMPLEMENTATION OF THE METHODS SPECIFIED BY THE SERVICESELECTOR INTERFACE */
+ /* =========================================================================== */
+
+ /**
+ * <p>Select a subcomponent ({@link SchemaParser}) associated with the specified
+ * selection key (its configured "name").</p>
+ */
+ public Object select(Object selectionKey)
+ throws ServiceException {
+ /* Look up for the specified component and return it if found */
+ if ( this.componentx.containsKey(selectionKey)) {
+ return this.componentx.get(selectionKey);
}
+
+ /* Fail miserably */
+ String message = "No component associated with " + selectionKey;
+ throw new ServiceException((String) selectionKey, message);
+ }
+
+ /**
+ * <p>Check whether a subcomponent ({@link SchemaParser}) associated with the
+ * specified selection key (its configured "name") is selectable in
+ * this {@link ServiceSelector} instance.</p>
+ */
+ public boolean isSelectable(Object selectionKey) {
+ return this.componentx.containsKey(selectionKey);
}
-
+
+ /**
+ * <p>Release a subcomponent ({@link SchemaParser}) instance previously selected
+ * from this {@link ServiceSelector} instance.</p>
+ */
+ public void release(Object component) {
+ // We don't need to do anything in this method.
+ }
+
+ /* =========================================================================== */
+ /* SUBCOMPONENTS (SCHEMA PARSERS) LIFECYCLE MANAGEMENT METHODS */
+ /* =========================================================================== */
+
/**
* <p>Manage the instantiation lifecycle of a specified component.</p>
*/
Added: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DraconianErrorHandler.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DraconianErrorHandler.java?rev=280229&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DraconianErrorHandler.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/DraconianErrorHandler.java Sun Sep 11 18:09:57 2005
@@ -0,0 +1,59 @@
+/*
+ * 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.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * <p>An implementation of the {@link ErrorHandler} interface re-throwing
+ * all exceptions passed to it.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
+ */
+public final class DraconianErrorHandler implements ErrorHandler {
+
+ /** <p>The singleton instance of the {@link DraconianErrorHandler}.</p> */
+ public static final DraconianErrorHandler INSTANCE = new DraconianErrorHandler();
+
+ /** <p>Deny normal construction of instances of this class.</p> */
+ private DraconianErrorHandler() { }
+
+ /**
+ * <p>Simply re-throw the specified {@link SAXParseException}.</p>
+ */
+ public void warning(SAXParseException exception)
+ throws SAXException {
+ throw exception;
+ }
+
+ /**
+ * <p>Simply re-throw the specified {@link SAXParseException}.</p>
+ */
+ public void error(SAXParseException exception)
+ throws SAXException {
+ throw exception;
+ }
+
+ /**
+ * <p>Simply re-throw the specified {@link SAXParseException}.</p>
+ */
+ public void fatalError(SAXParseException exception)
+ throws SAXException {
+ throw exception;
+ }
+}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchema.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchema.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/JingSchema.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchema.java Sun Sep 11 18:09:57 2005
@@ -15,7 +15,7 @@
*/
package org.apache.cocoon.components.validation.impl;
-import org.apache.cocoon.components.validation.Schema;
+import org.apache.cocoon.components.validation.ValidationHandler;
import org.apache.excalibur.source.SourceValidity;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
@@ -23,18 +23,21 @@
import com.thaiopensource.util.PropertyMap;
import com.thaiopensource.util.PropertyMapBuilder;
+import com.thaiopensource.validate.Schema;
import com.thaiopensource.validate.ValidateProperty;
import com.thaiopensource.validate.Validator;
import com.thaiopensource.xml.sax.DraconianErrorHandler;
/**
- * <p>The implementation of the {@link Schema} implementation from the
- * {@link JingSchemaParser} component.</p>
+ * <p>An extension of {@link AbstractSchema} used by the {@link JingSchemaParser}
+ * implementation.</p>
+ *
+ * @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
public class JingSchema extends AbstractSchema {
-
+
/** <p>The original schema instance to wrap.</p> */
- private final com.thaiopensource.validate.Schema schema;
+ private final Schema schema;
/**
* <p>Create a new {@link JingSchema} instance.</p>
@@ -42,33 +45,33 @@
* @param schema the JING original schema to wrap.
* @param validity the {@link SourceValidity} associated with the schema.
*/
- protected JingSchema(com.thaiopensource.validate.Schema schema,
- SourceValidity validity) {
+ protected JingSchema(Schema schema, SourceValidity validity) {
super(validity);
this.schema = schema;
}
/**
- * <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 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>
+ * {@link ValidationHandler}.</p>
*
- * <p>Once used, the returned {@link ContentHandler} <b>can't</b> be reused.</p>
+ * <p>Once used, the returned {@link ValidationHandler} <b>can't</b> be reused.</p>
*
* @param errorHandler an {@link ErrorHandler} to notify of validation errors.
- * @return a <b>non-null</b> {@link ContentHandler} instance.
+ * @return a <b>non-null</b> {@link ValidationHandler} instance.
* @throws SAXException if an error occurred creating the validation handler.
*/
- public ContentHandler newValidator(ErrorHandler errorHandler)
+ public ValidationHandler createValidator(ErrorHandler errorHandler)
throws SAXException {
if (errorHandler == null) errorHandler = new DraconianErrorHandler();
final PropertyMapBuilder builder = new PropertyMapBuilder();
ValidateProperty.ERROR_HANDLER.put(builder, errorHandler);
final PropertyMap properties = builder.toPropertyMap();
final Validator validator = this.schema.createValidator(properties);
- return validator.getContentHandler();
+ final ContentHandler handler = validator.getContentHandler();
+ return new DefaultValidationHandler(this.getValidity(), handler);
}
}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchemaParser.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchemaParser.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/JingSchemaParser.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/JingSchemaParser.java Sun Sep 11 18:09:57 2005
@@ -17,9 +17,11 @@
import java.io.IOException;
+import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.validation.Schema;
import org.apache.cocoon.components.validation.SchemaParser;
import org.apache.cocoon.components.validation.Validator;
+import org.apache.excalibur.source.Source;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -34,11 +36,7 @@
*
* @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
-public class JingSchemaParser extends CachingSchemaParser {
-
- /** <p>The list of grammars supported by the {@link JingSchemaParser}.</p> */
- private static final String[] GRAMMARS =
- new String[] { Validator.GRAMMAR_RELAX_NG };
+public class JingSchemaParser extends AbstractSchemaParser implements ThreadSafe {
/**
* <p>Create a new {@link JingSchemaParser} instance.</p>
@@ -48,25 +46,38 @@
}
/**
- * <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>The returned {@link Schema} must be able to validate multiple documents
+ * via multiple invocations of {@link Schema#createValidator(ErrorHandler)}.</p>
*
- * @param uri the URI of the {@link Schema} to return.
+ * @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 parseSchema(String uri)
+ public Schema getSchema(Source source, String grammar)
throws SAXException, IOException {
+ if (! Validator.GRAMMAR_RELAX_NG.equals(grammar)) {
+ throw new IllegalArgumentException("Unsupported grammar " + grammar);
+ }
+
SchemaReader schemaReader = SAXSchemaReader.getInstance();
JingContext context = new JingContext(sourceResolver, entityResolver);
- InputSource source = context.resolveEntity(null, uri);
+ InputSource input = new InputSource();
+ input.setByteStream(source.getInputStream());
+ input.setSystemId(source.getURI());
+ context.pushInputSource(input);
try {
final com.thaiopensource.validate.Schema schema;
- schema = schemaReader.createSchema(source, context.getProperties());
+ schema = schemaReader.createSchema(input, context.getProperties());
return new JingSchema(schema, context.getValidity());
} catch (IncorrectSchemaException exception) {
- String message = "Incorrect schema \"" + uri + "\"";
+ String message = "Incorrect schema \"" + source.getURI() + "\"";
throw new SAXException(message, exception);
}
}
@@ -79,6 +90,6 @@
* {@link Validator#GRAMMAR_RELAX_NG RELAX NG} grammar.</p>
*/
public String[] getSupportedGrammars() {
- return GRAMMARS;
+ return new String[] { Validator.GRAMMAR_RELAX_NG };
}
}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesGrammarParser.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesGrammarParser.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/XercesGrammarParser.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesGrammarParser.java Sun Sep 11 18:09:57 2005
@@ -19,11 +19,13 @@
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.SourceValidity;
import org.apache.xerces.util.XMLGrammarPoolImpl;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.grammars.XMLGrammarLoader;
import org.apache.xerces.xni.grammars.XMLGrammarPool;
+import org.apache.xerces.xni.parser.XMLInputSource;
import org.apache.xerces.xni.parser.XMLParseException;
import org.xml.sax.SAXException;
@@ -36,7 +38,7 @@
*
* @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
-public abstract class XercesGrammarParser extends CachingSchemaParser
+public abstract class XercesGrammarParser extends AbstractSchemaParser
implements SchemaParser {
/**
@@ -47,14 +49,20 @@
}
/**
- * <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>The returned {@link Schema} must be able to validate multiple documents
+ * via multiple invocations of {@link Schema#createValidator(ErrorHandler)}.</p>
*
- * @param uri the URI of the {@link Schema} to return.
+ * @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.
*/
- protected final Schema parseSchema(String uri)
+ public Schema getSchema(Source source, String grammar)
throws IOException, SAXException {
try {
/* Create a Xerces Grammar Pool and Entity Resolver */
@@ -70,8 +78,11 @@
context.initialize(loader);
/* Load (parse and interpret) the grammar */
+ String uri = source.getURI();
this.getLogger().debug("Loading grammar from " + uri);
- loader.loadGrammar(r.resolveUri(uri));
+ XMLInputSource input = new XMLInputSource(null, uri, uri);
+ input.setByteStream(source.getInputStream());
+ loader.loadGrammar(input);
this.getLogger().debug("Grammar successfully loaded from " + uri);
/* Return a new Schema instance */
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchema.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchema.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/XercesSchema.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchema.java Sun Sep 11 18:09:57 2005
@@ -15,6 +15,7 @@
*/
package org.apache.cocoon.components.validation.impl;
+import org.apache.cocoon.components.validation.ValidationHandler;
import org.apache.excalibur.source.SourceValidity;
import org.apache.xerces.xni.XMLDocumentHandler;
import org.apache.xerces.xni.grammars.XMLGrammarPool;
@@ -47,21 +48,23 @@
}
/**
- * <p>Return a {@link ContentHandler} able to receive SAX events and performing
- * validation according to the schema wrapped by this instance.</p>
+ * <p>Return a {@link ValidationHandler} able to receive SAX events and
+ * performing validation according to the schema wrapped by this instance.</p>
*
* @param errorHandler {@link ErrorHandler} to be notified of validation errors.
- * @return a <b>non-null</b> {@link ContentHandler} instance.
- * @throws SAXException if an error occurred creating the {@link ContentHandler}.
+ * @return a <b>non-null</b> {@link ValidationHandler} instance.
+ * @throws SAXException if an error occurred creating the handler.
*/
- public ContentHandler newValidator(ErrorHandler errorHandler)
+ public ValidationHandler createValidator(ErrorHandler errorHandler)
throws SAXException {
XercesContext context = new XercesContext(this.grammarPool,
new XercesEntityResolver(),
errorHandler);
try {
Object instance = context.initialize(this.validatorClass.newInstance());
- return new XercesContentHandler((XMLDocumentHandler) instance);
+ XMLDocumentHandler documentHandler = (XMLDocumentHandler) instance;
+ ContentHandler finalHandler = new XercesContentHandler(documentHandler);
+ return new DefaultValidationHandler(this.getValidity(), finalHandler);
} catch (Exception exception) {
throw new SAXException("Unable to access validator", exception);
}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchemaParser.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchemaParser.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/XercesSchemaParser.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/components/validation/impl/XercesSchemaParser.java Sun Sep 11 18:09:57 2005
@@ -32,9 +32,6 @@
*/
public class XercesSchemaParser extends XercesGrammarParser implements SchemaParser {
- private static final String[] GRAMMARS = new String[] { Validator.GRAMMAR_XML_SCHEMA };
- private static final Class VALIDATOR = XMLSchemaValidator.class;
-
/**
* <p>Create a new {@link XercesSchemaParser} instance.</p>
*/
@@ -50,7 +47,7 @@
* {@link Validator#GRAMMAR_XML_SCHEMA} grammar.</p>
*/
public String[] getSupportedGrammars() {
- return GRAMMARS;
+ return new String[] { Validator.GRAMMAR_XML_SCHEMA };
}
/**
@@ -64,6 +61,6 @@
* <p>Return a {@link Class} implementing the final validation handler.</p>
*/
protected Class getValidationHandlerClass() {
- return VALIDATOR;
+ return XMLSchemaValidator.class;
}
}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/transformation/ValidatingTransformer.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/transformation/ValidatingTransformer.java?rev=280229&r1=280228&r2=280229&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/transformation/ValidatingTransformer.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/validation/java/org/apache/cocoon/transformation/ValidatingTransformer.java Sun Sep 11 18:09:57 2005
@@ -29,15 +29,14 @@
import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.caching.CacheableProcessingComponent;
-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.environment.SourceResolver;
import org.apache.cocoon.xml.ContentHandlerWrapper;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.cocoon.xml.XMLMulticaster;
+import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceValidity;
-import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
/**
@@ -46,8 +45,15 @@
*
* <p>The only defined (but not required) configuration for this component is
* <code><grammar><i>...string...</i></grammar></code>
- * indicating the grammar (or optionally the component name) for the
- * {@link Validator} instance providing access to {@link Schema}s.</p>
+ * indicating the default grammar language of the schemas to use.</p>
+ *
+ * <p>This configuration parameter can be overridden by specifying the
+ * <code>grammar</code> parameter when using this {@link Transformer} in a
+ * pipeline.</p>
+ *
+ * <p>If no grammar is specified (either as a configuration, or a parameter) this
+ * transformer will instruct the {@link Validator} to try and guess the grammar
+ * of the schema being parsed.</p>
*
* @author <a href="mailto:pier@betaversion.org">Pier Fumagalli</a>
*/
@@ -56,9 +62,9 @@
private ServiceManager serviceManager = null;
private Validator validator = null;
- private SchemaParser schemaParser = null;
- private ContentHandler handler = null;
- private Schema schema = null;
+ private String grammar = null;
+
+ private ValidationHandler handler = null;
private String key = null;
/**
@@ -79,21 +85,15 @@
*
* <p>The only defined (but not required) configuration for this component is
* <code><grammar><i>...string...</i></grammar></code>
- * indicating the grammar (or optionally the component name) for the
- * {@link Validator} instance providing access to {@link Schema}s.</p>
+ * indicating the default grammar used by this transformer used for parsing
+ * schemas.</p>
*
* @param configuration a {@link Configuration} instance for this component.
* @throws ConfigurationException never thrown.
*/
public void configure(Configuration configuration)
throws ConfigurationException {
- String key = configuration.getChild("grammar").getValue();
- try {
- this.schemaParser = (SchemaParser) this.validator.select(key);
- } catch (ServiceException exception) {
- String message = "Grammar or instance \"" + key + "\" not recognized";
- throw new ConfigurationException(message, configuration, exception);
- }
+ this.grammar = configuration.getChild("grammar").getValue(null);
}
/**
@@ -101,7 +101,6 @@
* required instances back to the {@link ServiceManager}.</p>
*/
public void dispose() {
- this.validator.release(this.schemaParser);
this.serviceManager.release(this.validator);
}
@@ -117,10 +116,18 @@
public void setup(SourceResolver resolver, Map objectModel, String source,
Parameters parameters)
throws ProcessingException, SAXException, IOException {
- this.schema = this.schemaParser.getSchema(source);
- this.key = this.getClass().getName() + ":" +
- this.schemaParser.getClass().getName() + ":" + source;
- this.handler = this.schema.newValidator();
+ Source s = null;
+ try {
+ s = resolver.resolveURI(source);
+ String g = parameters.getParameter("grammar", this.grammar);
+ if (g == null) {
+ this.handler = this.validator.getValidationHandler(s);
+ } else{
+ this.handler = this.validator.getValidationHandler(s, g);
+ }
+ } finally {
+ if (source != null) resolver.release(s);
+ }
}
/**
@@ -130,7 +137,7 @@
* @param consumer the {@link XMLConsumer} to send SAX events to.
*/
public void setConsumer(XMLConsumer consumer) {
- XMLConsumer handler = new ContentHandlerWrapper(this.handler);
+ XMLConsumer handler = new ContentHandlerWrapper(this.handler, this.handler);
super.setConsumer(new XMLMulticaster(handler, consumer));
}
@@ -151,7 +158,7 @@
* @return a non null {@link SourceValidity} instance.
*/
public SourceValidity getValidity() {
- return this.schema.getValidity();
+ return this.handler.getValidity();
}
/**
@@ -159,7 +166,6 @@
*/
public void recycle() {
this.handler = null;
- this.schema = null;
this.key = null;
super.recycle();
}