You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sk...@apache.org on 2005/02/04 02:51:54 UTC
svn commit: r151287 [3/7] - in
jakarta/commons/proper/digester/branches/digester2: ./ src/ src/conf/
src/examples/ src/examples/api/ src/examples/api/addressbook/ src/java/
src/java/org/ src/java/org/apache/ src/java/org/apache/commons/
src/java/org/apache/commons/digester2/
src/java/org/apache/commons/digester2/actions/
src/java/org/apache/commons/digester2/factory/ src/media/ src/test/
src/test/org/ src/test/org/apache/ src/test/org/apache/commons/
src/test/org/apache/commons/digester2/ xdocs/ xdocs/dtds/ xdocs/images/
xdocs/style/
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Digester.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Digester.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Digester.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Digester.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,688 @@
+/* $Id: $
+ *
+ * Copyright 2001-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.commons.digester2;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+
+/**
+ * <p>A <strong>Digester</strong> processes an XML input stream by matching a
+ * series of element nesting patterns to execute Actions that have been added
+ * prior to the start of parsing.</p>
+ *
+ * <p>This class is the one that users interact with to configure the
+ * parsing rules and initiate the parse. It is mostly just a user-friendly
+ * facade over the SAXHandler class.</p>
+ *
+ * <p>See the <a href="package-summary.html#package_description">Digester
+ * Developer Guide</a> for more information.</p>
+ *
+ * <p><strong>IMPLEMENTATION NOTES</strong>
+ * <ul>
+ * <li> A single Digester instance may only be used within the context of a
+ * single thread at a time, and a call to <code>parse()</code> must be
+ * completed before another can be initiated even from the same thread.</li>
+ * <li> This class requires that JAXP1.1 and a SAX2-compliant xml parser be
+ * present in the classpath. Versions of java prior to 1.4 include neither
+ * JAXP nor a parser, so simply including a modern xml parser plus a JAXP1.1
+ * implementation in the classpath solves this requirement. Most xml parsers
+ * provide a suitable implementation as a companion jar to the main download
+ * (eg xml-apis.jar for the Apache Xerces parser). The 1.4 version of java
+ * includes JAXP1.1, and bundles an xml parser. While the JAXP apis included
+ * are fine, the xml parser bundled with this version of java is not adequate
+ * for most tasks, and it is recommended that a better one be provided in the
+ * classpath. Using the latest Apache Xerces release can be tricky, however,
+ * as Sun's bundled parser is xerces, with package names unchanged, and
+ * classes in the runtime libraries override classes in the classpath by
+ * default. See documentation on the java "endorsed override" feature for
+ * solutions, or the apache xerces website.
+ * Versions of java from 1.5 onward provide xml parsers that are fine for
+ * most purposes.</li>
+ * </ul>
+ */
+
+public class Digester {
+
+ // --------------------------------------------------------- Constructors
+
+ /**
+ * Construct a new Digester with default properties.
+ */
+ public Digester() {
+ this.saxHandler = new SAXHandler();
+ }
+
+ /**
+ * This method allows customisation of the way that sax events are
+ * handled, by allowing a modified subclass of SAXHandler to be
+ * specified as the target for parsing events.
+ */
+ public Digester(SAXHandler saxHandler) {
+ this.saxHandler = saxHandler;
+ }
+
+ // --------------------------------------------------- Instance Variables
+
+ /**
+ * The object used to handle event callbacks from the SAX parser as
+ * the input xml is being processed. There is a 1:1 relation between
+ * a Digester and a SAXHandler.
+ */
+ private SAXHandler saxHandler;
+
+ /**
+ * The reader object used to generate SAX events representing the input.
+ * Normally, the object does this by parsing input text, but alternatives
+ * (like walking a DOM tree and generating appropriate events) are also
+ * possible. In any case, it's not relevant to this app how the sax
+ * events are generated.
+ */
+ private XMLReader reader = null;
+
+ /**
+ * See {@link #setValidating}.
+ */
+ private boolean validating = false;
+
+ // ------------------------------------------------------------- Properties
+
+ /**
+ * Determine whether we are to validate the xml input against a schema.
+ * If so, then an error will be reported by the parse() methods if the
+ * input doesn't comply with the schema. If validation is disabled, then
+ * performance will be improved, but no error will be reported if the
+ * input is not correct.
+ * <p>
+ * Note that even when validation is disabled, any external schema or DTD
+ * referenced by the input document must still be read, as it can declare
+ * default attributes and similar items which affect xml parsing.
+ *
+ * @param validating The new validating parser flag.
+ *
+ * This must be called before <code>parse()</code> is called the first time.
+ */
+ public void setValidating(boolean validating) {
+ this.validating = validating;
+ }
+
+ /**
+ * Get the validating parser flag. See {@link #setValidating}.
+ */
+ public boolean getValidating() {
+ return (this.validating);
+ }
+
+ /**
+ * <p>Specify the XMLReader to be used to parse the input.</p>
+ *
+ * <p>This can be particularly useful in environments that are unfriendly
+ * to JAXP; it should always be possible to directly instantiate a parser
+ * using parser-specific code, and all decent xml parsers should implement
+ * (ie be castable to) the org.xml.sax.XMLReader interface even when the
+ * JAXP apis are not available or do not function correctly.</p>
+ *
+ * <p>If you have a SAXParser instance that should be used as the source
+ * of the input, then use:
+ * <pre>
+ * setXMLReader(saxParser.getXMLReader());
+ * </pre>
+ * </p>
+ *
+ * <p>The reader passed here should be configured with namespace-aware
+ * parsing enabled, as the digester classes assume this.</p>
+ */
+ public void setXMLReader(XMLReader reader) {
+ this.reader = reader;
+ }
+
+ /**
+ * Set the class loader to be used for instantiating application objects
+ * when required. If a non-null value is passed to this method, then
+ * method {@link #useContextClassLoader} will have no effect.
+ * <p>
+ * When an Action is executed due to some xml input, and that Action
+ * wishes to create an object to represent the input, then the class
+ * used will be loaded via the specified classloader.
+ *
+ * @param classLoader The new class loader to use, or <code>null</code>
+ * to revert to the standard rules
+ */
+ public void setExplicitClassLoader(ClassLoader classLoader) {
+ saxHandler.setExplicitClassLoader(classLoader);
+ }
+
+ /**
+ * Get the explicit class loader to be used by Actions for instantiating
+ * objects when required. Null indicates that there is no explicit
+ * classloader set.
+ * <p>
+ * When no explicit classloader has been specified, either the context
+ * classloader (see {@link #setUseContextClassLoader}) or the classloader
+ * that loaded the SAXHandler instance will be used.
+ *
+ * @return the classloader previously passed to setExplicitClassLoader,
+ * or null if no explicit classloader has been set.
+ */
+ public ClassLoader getExplicitClassLoader() {
+ return saxHandler.getExplicitClassLoader();
+ }
+
+ /**
+ * Set the current logger for this Digester.
+ */
+ public void setLogger(Log log) {
+ saxHandler.setLogger(log);
+ }
+
+ /**
+ * Get the current Logger associated with this instance of the Digester
+ */
+ public Log getLogger() {
+ return saxHandler.getLogger();
+ }
+
+ /**
+ * Sets the logger used for logging SAX-related information.
+ * <strong>Note</strong> the output is finely grained.
+ * @param saxLog Log, not null
+ */
+ public void setSAXLogger(Log saxLog) {
+ saxHandler.setSAXLogger(saxLog);
+ }
+
+ /**
+ * Gets the logger used for logging SAX-related information.
+ * <strong>Note</strong> the output is finely grained.
+ */
+ public Log getSAXLogger() {
+ return saxHandler.getSAXLogger();
+ }
+
+ /**
+ * Set the <code>RuleManager</code> implementation object containing our
+ * rules collection and associated matching policy.
+ *
+ * @param ruleManager New RuleManager implementation
+ */
+ public void setRuleManager(RuleManager ruleManager) {
+ saxHandler.setRuleManager(ruleManager);
+ }
+
+ /**
+ * Get the <code>RuleManager</code> object containing our
+ * rule collection and associated matching policy. If none has been
+ * established, a default implementation will be created and returned.
+ */
+ public RuleManager getRuleManager() {
+ return saxHandler.getRuleManager();
+ }
+
+ /**
+ * Set the publid id of the current file being parsed. This will cause
+ * the declared DOCTYPE (if any) of the input document to be ignored.
+ *
+ * Instead the provided publicId will be looked up in the known entities,
+ * and the resource located at the associated URL will be used as the
+ * DTD for this input document.
+ * <p>
+ * NOTE: if the input document doesn't include a DOCTYPE, then the
+ * DTD specified by this call is not used. There is currently no way
+ * to force an input document to be validated against a specific DTD
+ * (due to a lack of this feature in the xml standard).
+ *
+ * @param publicId the DTD/Schema public's id.
+ */
+ public void setPublicId(String publicId){
+ saxHandler.setPublicId(publicId);
+ }
+
+ /**
+ * Get the public identifier of the DTD we are currently parsing under,
+ * if any. If setPublicId has been called previously, then the value
+ * returned here will be the one explicitly set. Otherwise, if we have
+ * already seen a DOCTYPE declaration in the input data, then the
+ * public id in that DOCTYPE will be returned. Otherwise (parsing hasn't
+ * started or the input document had no DOCTYPE) null is returned.
+ */
+ public String getPublicId() {
+ return saxHandler.getPublicId();
+ }
+
+ /**
+ * Set the XML Schema URI used for validating a XML Instance.
+ *
+ * @param schemaLocation a URI to the schema.
+ */
+ public void setSchema(String schemaLocation){
+ saxHandler.setSchema(schemaLocation);
+ }
+
+ /**
+ * Get the XML Schema URI used for validating an XML instance.
+ */
+ public String getSchema() {
+ return saxHandler.getSchema();
+ }
+
+ /**
+ * Set the XML Schema language used when parsing. By default, we use W3C.
+ *
+ * @param schemaLanguage a URI to the schema language.
+ */
+ public void setSchemaLanguage(String schemaLanguage){
+ saxHandler.setSchemaLanguage(schemaLanguage);
+ }
+
+ /**
+ * Get the XML Schema language used when parsing.
+ */
+ public String getSchemaLanguage() {
+ return saxHandler.getSchemaLanguage();
+ }
+
+ /**
+ * Determine whether to use the Context Classloader (the one found by
+ * calling <code>Thread.currentThread().getContextClassLoader()</code>)
+ * to resolve/load classes when an Action needs to create an instance of
+ * an object to represent data in the xml input. If this is set to false,
+ * and there is no explicit classloader set, then the same classloader
+ * that loaded the Action class is used.
+ * <p>
+ * See {@link #setClassLoader}.
+ *
+ * @param use determines whether to use the Context Classloader.
+ */
+ public void setUseContextClassLoader(boolean use) {
+ saxHandler.setUseContextClassLoader(use);
+ }
+
+ /**
+ * Indicates whether the context classloader will be used by Actions
+ * when instantiating objects. See {@link #setUseContextClassLoader}.
+ */
+ public boolean getUseContextClassLoader() {
+ return saxHandler.getUseContextClassLoader();
+ }
+
+ /**
+ * Sets the <code>Substitutor</code> to be used to perform pre-processing
+ * on xml attributes and body text before Actions are applied.
+ *
+ * @param substitutor the Substitutor to be used, or null if no
+ * substitution (pre-processing) is to be performed.
+ */
+ public void setSubstitutor(Substitutor substitutor) {
+ saxHandler.setSubstitutor(substitutor);
+ }
+
+ /**
+ * Gets the <code>Substitutor</code> used to perform pre-processing
+ * on xml attributes and body text before Actions are applied.
+ *
+ * @return Substitutor, null if no substitution (pre-processing) is to
+ * be performed.
+ */
+ public Substitutor getSubstitutor() {
+ return saxHandler.getSubstitutor();
+ }
+
+ /**
+ * Specifies a map of (publicId->URI) pairings that will be used by the
+ * default Entity Resolver when resolving entities in the input xml
+ * (including the DTD or schema specified with the DOCTYPE).
+ * <p>
+ * See {@link #getKnownEntities}, and {@link #setEntityResolver}.
+ */
+ public void setKnownEntities(Map knownEntities) {
+ saxHandler.setKnownEntities(knownEntities);
+ }
+
+ /**
+ * <p>Register a mapping between a public or system ID (denoting an external
+ * entity, aka resource) and a URL indicating where that resource can be
+ * found, for use by the default Entity Resolver. It is particularly useful
+ * to register local locations for DTDs or schemas that the input xml may
+ * reference.</p>
+ *
+ *<p>When the input xml refers to the entity via a public or system id, the
+ * resource pointed to by the registered URL is returned. This is commonly
+ * done for the input document's DTD, so that the DTD can be retrieved
+ * from a local file.</p>
+ *
+ * <p>This implementation provides only basic functionality. If more
+ * sophisticated features are required,using {@link #setEntityResolver} to
+ * set a custom resolver is recommended. Note in particular that if the
+ * input xml uses a system-ID to refer to an entity that is not registered,
+ * then the parser will attempt to use the system-id directly, potentially
+ * downloading the resource from a remote location.</p>
+ *
+ * <p>
+ * <strong>Note:</strong> This method will have no effect when a custom
+ * <code>EntityResolver</code> has been set. (Setting a custom
+ * <code>EntityResolver</code> overrides the internal implementation.)
+ * </p>
+ *
+ * @param publicOrSystemId Public or system identifier of the entity
+ * to be resolved
+ * @param entityURL The URL to use for reading this entity
+ */
+ public void registerKnownEntity(String publicOrSystemId, String entityURL) {
+ saxHandler.registerKnownEntity(publicOrSystemId, entityURL);
+ }
+
+ /**
+ * Returns a map of (publicId->URI) pairings that will be used by the
+ * default EntityResolver.
+ * <p>
+ * See {@link #setKnownEntities}, and {@link #setEntityResolver}.
+ */
+ public Map getKnownEntities() {
+ return saxHandler.getKnownEntities();
+ }
+
+ // ------------------------------------------------------- Public Methods
+
+ /**
+ * Parse the content of the specified file using this Digester. Returns
+ * the root element from the object stack (if any).
+ *
+ * @param file File containing the XML data to be parsed
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception SAXException if a parsing exception occurs
+ */
+ public Object parse(File file)
+ throws DigestionException, IOException, SAXException {
+ try {
+ InputSource input = new InputSource(new FileInputStream(file));
+ input.setSystemId(file.toURL().toString());
+ getXMLReader().parse(input);
+ return saxHandler.getRoot();
+ }
+ catch(RuntimeException re) {
+ throw new DigestionException(re);
+ }
+ }
+
+ /**
+ * Parse the content of the specified input source using this Digester.
+ * Returns the root element from the object stack (if any).
+ *
+ * @param input Input source containing the XML data to be parsed
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception SAXException if a parsing exception occurs
+ */
+ public Object parse(InputSource input)
+ throws DigestionException, IOException, SAXException {
+ try {
+ getXMLReader().parse(input);
+ return saxHandler.getRoot();
+ }
+ catch(RuntimeException re) {
+ throw new DigestionException(re);
+ }
+ }
+
+ /**
+ * Parse the content of the specified input stream using this Digester.
+ * Returns the root element from the object stack (if any).
+ * <p>
+ * Note that because the xml parser has no idea what the "real location"
+ * of the input is supposed to be, no relative referenced from the
+ * input xml document will work. If you need this behaviour, then
+ * use the parse(org.xml.sax.InputSource) variant, together with the
+ * InputSource.setSystemId method to tell the input source what the
+ * logical location of the input is supposed to be.
+ *
+ * @param input Input stream containing the XML data to be parsed
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception SAXException if a parsing exception occurs
+ */
+ public Object parse(InputStream input)
+ throws DigestionException, IOException, SAXException {
+ try {
+ InputSource is = new InputSource(input);
+ getXMLReader().parse(is);
+ return saxHandler.getRoot();
+ }
+ catch(RuntimeException re) {
+ throw new DigestionException(re);
+ }
+ }
+
+ /**
+ * Parse the content of the specified reader using this Digester.
+ * Returns the root element from the object stack (if any).
+ * <p>
+ * Note that because the xml parser has no idea what the "real location"
+ * of the input is supposed to be, no relative referenced from the
+ * input xml document will work. If you need this behaviour, then
+ * use the parse(org.xml.sax.InputSource) variant, together with the
+ * InputSource.setSystemId method to tell the input source what the
+ * logical location of the input is supposed to be.
+ *
+ * @param reader Reader containing the XML data to be parsed
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception SAXException if a parsing exception occurs
+ */
+ public Object parse(Reader reader)
+ throws DigestionException, IOException, SAXException {
+
+ try {
+ InputSource is = new InputSource(reader);
+ getXMLReader().parse(is);
+ return saxHandler.getRoot();
+ }
+ catch(RuntimeException re) {
+ throw new DigestionException(re);
+ }
+ }
+
+ /**
+ * Parse the content of the specified URI using this Digester.
+ * Returns the root element from the object stack (if any).
+ * <p>
+ * Note that because the xml parser has no idea what the "real location"
+ * of the input is supposed to be, no relative referenced from the
+ * input xml document will work. If you need this behaviour, then
+ * use the parse(org.xml.sax.InputSource) variant, together with the
+ * InputSource.setSystemId method to tell the input source what the
+ * logical location of the input is supposed to be.
+ *
+ * @param uri URI containing the XML data to be parsed
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception SAXException if a parsing exception occurs
+ */
+ public Object parse(String uri)
+ throws DigestionException, IOException, SAXException {
+ try {
+ InputSource is = new InputSource(uri);
+ getXMLReader().parse(is);
+ return saxHandler.getRoot();
+ }
+ catch(RuntimeException re) {
+ throw new DigestionException(re);
+ }
+ }
+
+ // --------------------------------------------------------- Rule Methods
+
+ /**
+ * <p>Register a new rule (pattern/action pair).
+ *
+ * @param pattern Element matching pattern
+ * @param action Action to be registered
+ */
+ public void addRule(String pattern, Action action)
+ throws InvalidRuleException {
+ saxHandler.addRule(pattern, action);
+ }
+
+ // --------------------------------------------------- Object Stack Methods
+
+ /**
+ * Set the initial object that will form the root of the tree of
+ * objects generated during a parse.
+ * <p>
+ * Note that this is optional; an ObjectCreateAction associated with the
+ * root element of the input document performs the same task.
+ *
+ * @param object The new object
+ */
+ public void setInitialObject(Object object) {
+ saxHandler.setInitialObject(object);
+ }
+
+ /**
+ * Returns the root element of the tree of objects created as a result
+ * of applying the rules to the input XML.
+ * <p>
+ * If the digester stack was "primed" by explicitly pushing a root
+ * object onto the stack before parsing started, then that root object
+ * is returned here.
+ * <p>
+ * Alternatively, if an Action which creates an object (eg ObjectCreateAction)
+ * matched the root element of the xml, then the object created will be
+ * returned here.
+ * <p>
+ * In other cases, the object most recently pushed onto an empty digester
+ * stack is returned. This would be a most unusual use of digester, however;
+ * one of the previous configurations is much more likely.
+ * <p>
+ * Note that when using one of the Digester.parse methods, the return
+ * value from the parse method is exactly the same as the return value
+ * from this method. However when the Digester is being used as a
+ * SAXContentHandler, no such return value is available; in this case, this
+ * method allows you to access the root object that has been created
+ * after parsing has completed.
+ *
+ * @return the root object that has been created after parsing
+ * or null if the digester has not parsed any XML yet.
+ */
+ public Object getRoot() {
+ return saxHandler.getRoot();
+ }
+
+ /**
+ * Return the XMLReader to be used for parsing the input document.
+ *
+ * @exception SAXException if no XMLReader can be instantiated
+ */
+ public XMLReader getXMLReader() throws SAXException {
+ if (reader != null) {
+ return reader;
+ }
+
+ try {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setValidating(validating);
+
+ SAXParser parser = factory.newSAXParser();
+ reader = parser.getXMLReader();
+ } catch (Exception e) {
+ Log log = saxHandler.getLogger();
+ log.error("Digester.getXMLReader: ", e);
+ return null;
+ }
+
+ reader.setDTDHandler(saxHandler);
+ reader.setContentHandler(saxHandler);
+ reader.setEntityResolver(saxHandler);
+ reader.setErrorHandler(saxHandler);
+ return reader;
+ }
+
+ /**
+ * Specify the Entity Resolver used to determine the physical location
+ * of resources (such as DTDs or schemas) referred to by the input xml.
+ * <p>
+ * The value <i>null</i> indicates that the SAXHandler object will be
+ * used as the entity resolver. In this case, see methods:
+ * <ul>
+ * <li>{@link #setKnownEntities}</li>
+ * <li>{@link #registerKnownEntity}</li>
+ * </ul>
+ *
+ * @param entityResolver a class that implement the
+ * <code>EntityResolver</code> interface, or <i>null</i> to restore
+ * the default behaviour.
+ */
+ public void setEntityResolver(EntityResolver entityResolver){
+ saxHandler.setEntityResolver(entityResolver);
+ }
+
+ /**
+ * Return the Entity Resolver used to determine the physical location
+ * of resources (such as DTDs or schemas) referred to by the input xml.
+ * <p>
+ * The value <i>null</i> indicates that the SAXHandler object will be
+ * used as the entity resolver. In this case, see methods:
+ * <ul>
+ * <li>{@link #setKnownEntities}</li>
+ * <li>{@link #registerKnownEntity}</li>
+ * </ul>
+ *
+ * @return the Entity Resolver to be used.
+ */
+ public EntityResolver getEntityResolver(){
+ return saxHandler.getEntityResolver();
+ }
+
+ /**
+ * Return the error handler which will be used if the xml parser detects
+ * errors in the xml input being parsed.
+ */
+ public ErrorHandler getErrorHandler() {
+ return saxHandler.getErrorHandler();
+ }
+
+ /**
+ * Set the error handler for this Digester.
+ *
+ * @param errorHandler The new error handler
+ */
+ public void setErrorHandler(ErrorHandler errorHandler) {
+ saxHandler.setErrorHandler(errorHandler);
+ }
+}
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/DigestionException.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/DigestionException.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/DigestionException.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/DigestionException.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,37 @@
+/* $Id: $
+ *
+ * Copyright 2001-2004 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.commons.digester2;
+
+/**
+ */
+
+public class DigestionException extends Exception {
+ public DigestionException(String msg) {
+ super(msg);
+ }
+
+ public DigestionException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+ public DigestionException(Throwable t) {
+ super(t);
+ }
+}
+
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/InvalidRuleException.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/InvalidRuleException.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/InvalidRuleException.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/InvalidRuleException.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,41 @@
+/* $Id: $
+ *
+ * Copyright 2001-2004 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.commons.digester2;
+
+/**
+ * Thrown when a problem is detected as a rule is added to a RuleManager.
+ * One possible cause is that the pattern is invalid, but there may be
+ * others depending upon the RuleManager and Action involved.
+ */
+
+public class InvalidRuleException extends DigestionException {
+ public InvalidRuleException(String msg) {
+ super(msg);
+ }
+
+ public InvalidRuleException(Throwable t) {
+ super(t);
+ }
+
+ public InvalidRuleException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+}
+
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/MultiHashMap.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/MultiHashMap.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/MultiHashMap.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/MultiHashMap.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2001-2004 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.commons.digester2;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * A <code>MultiMap</code> is a Map with slightly different semantics.
+ * Putting a value into the map will add the value to a Collection at that key.
+ * Getting a value will return a Collection, holding all the values put to that key.
+ * <p>
+ * This implementation uses an <code>ArrayList</code> as the collection.
+ * The internal storage list is made available without cloning via the
+ * <code>get(Object)</code> and <code>entrySet()</code> methods.
+ * The implementation returns <code>null</code> when there are no values mapped to a key.
+ * <p>
+ * For example:
+ * <pre>
+ * MultiMap mhm = new MultiHashMap();
+ * mhm.put(key, "A");
+ * mhm.put(key, "B");
+ * mhm.put(key, "C");
+ * List list = (List) mhm.get(key);</pre>
+ * <p>
+ * <code>list</code> will be a list containing "A", "B", "C".
+ *
+ * This code is derived from the class in apache-commons-collections v3.1.
+ * Thanks go to the authors of commons-collections!
+ *
+ */
+public class MultiHashMap extends HashMap {
+
+ private static final Iterator EMPTY_ITERATOR =
+ java.util.Collections.EMPTY_LIST.iterator();
+
+ // backed values collection
+ private transient Collection values = null;
+
+ // compatibility with commons-collection releases 2.0/2.1
+ private static final long serialVersionUID = 1943563828307035349L;
+
+ /**
+ * Constructor.
+ */
+ public MultiHashMap() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param initialCapacity the initial map capacity
+ */
+ public MultiHashMap(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param initialCapacity the initial map capacity
+ * @param loadFactor the amount 0.0-1.0 at which to resize the map
+ */
+ public MultiHashMap(int initialCapacity, float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ /**
+ * Constructor. Note that this class has special behaviour if the source
+ * object being copied is a MultiHashMap; in that case, a copy of the
+ * collection is made too, so that adding an entry to the original
+ * MultiHashMap does not cause the value in the copy to change!
+ *
+ * @param mapToCopy a Map to copy
+ */
+ public MultiHashMap(Map mapToCopy) {
+ super((int) mapToCopy.size());
+ if (mapToCopy instanceof MultiHashMap) {
+ for (Iterator it = mapToCopy.entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
+ Collection coll = (Collection) entry.getValue();
+ Collection newColl = createCollection(coll);
+ super.put(entry.getKey(), newColl);
+ }
+ } else {
+ putAll(mapToCopy);
+ }
+ }
+
+ /**
+ * Read the object during deserialization.
+ */
+ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+ // This method is needed because the 1.2/1.3 Java deserialisation called
+ // put and thus messed up that method
+
+ // default read object
+ s.defaultReadObject();
+
+ // problem only with jvm <1.4
+ String version = "1.2";
+ try {
+ version = System.getProperty("java.version");
+ } catch (SecurityException ex) {
+ // ignore and treat as 1.2/1.3
+ }
+
+ if (version.startsWith("1.2") || version.startsWith("1.3")) {
+ for (Iterator iterator = entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ // put has created a extra collection level, remove it
+ super.put(entry.getKey(), ((Collection) entry.getValue()).iterator().next());
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets the total size of the map by counting all the values.
+ *
+ * @return the total size of the map counting all values
+ * @since Commons Collections 3.1
+ */
+ public int totalSize() {
+ int total = 0;
+ Collection values = super.values();
+ for (Iterator it = values.iterator(); it.hasNext();) {
+ Collection coll = (Collection) it.next();
+ total += coll.size();
+ }
+ return total;
+ }
+
+ /**
+ * Gets the collection mapped to the specified key.
+ * This method is a convenience method to typecast the result of <code>get(key)</code>.
+ *
+ * @param key the key to retrieve
+ * @return the collection mapped to the key, null if no mapping
+ * @since Commons Collections 3.1
+ */
+ public Collection getCollection(Object key) {
+ return (Collection) get(key);
+ }
+
+ /**
+ * Gets the size of the collection mapped to the specified key.
+ *
+ * @param key the key to get size for
+ * @return the size of the collection at the key, zero if key not in map
+ * @since Commons Collections 3.1
+ */
+ public int size(Object key) {
+ Collection coll = getCollection(key);
+ if (coll == null) {
+ return 0;
+ }
+ return coll.size();
+ }
+
+ /**
+ * Gets an iterator for the collection mapped to the specified key.
+ *
+ * @param key the key to get an iterator for
+ * @return the iterator of the collection at the key, empty iterator if key not in map
+ * @since Commons Collections 3.1
+ */
+ public Iterator iterator(Object key) {
+ Collection coll = getCollection(key);
+ if (coll == null) {
+ return EMPTY_ITERATOR;
+ }
+ return coll.iterator();
+ }
+
+ /**
+ * Adds the value to the collection associated with the specified key.
+ * <p>
+ * Unlike a normal <code>Map</code> the previous value is not replaced.
+ * Instead the new value is added to the collection stored against the key.
+ *
+ * @param key the key to store against
+ * @param value the value to add to the collection at the key
+ * @return the value added if the map changed and null if the map did not change
+ */
+ public Object put(Object key, Object value) {
+ // NOTE:: put is called during deserialization in JDK < 1.4 !!!!!!
+ // so we must have a readObject()
+ Collection coll = getCollection(key);
+ if (coll == null) {
+ coll = createCollection(null);
+ super.put(key, coll);
+ }
+ boolean results = coll.add(value);
+ return (results ? value : null);
+ }
+
+ /**
+ * Adds a collection of values to the collection associated with the specified key.
+ *
+ * @param key the key to store against
+ * @param values the values to add to the collection at the key, null ignored
+ * @return true if this map changed
+ * @since Commons Collections 3.1
+ */
+ public boolean putAll(Object key, Collection values) {
+ if (values == null || values.size() == 0) {
+ return false;
+ }
+ Collection coll = getCollection(key);
+ if (coll == null) {
+ coll = createCollection(values);
+ if (coll.size() == 0) {
+ return false;
+ }
+ super.put(key, coll);
+ return true;
+ } else {
+ return coll.addAll(values);
+ }
+ }
+
+ /**
+ * Checks whether the map contains the value specified.
+ * <p>
+ * This checks all collections against all keys for the value, and thus could be slow.
+ *
+ * @param value the value to search for
+ * @return true if the map contains the value
+ */
+ public boolean containsValue(Object value) {
+ Set pairs = super.entrySet();
+
+ if (pairs == null) {
+ return false;
+ }
+ Iterator pairsIterator = pairs.iterator();
+ while (pairsIterator.hasNext()) {
+ Map.Entry keyValuePair = (Map.Entry) pairsIterator.next();
+ Collection coll = (Collection) keyValuePair.getValue();
+ if (coll.contains(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether the collection at the specified key contains the value.
+ *
+ * @param value the value to search for
+ * @return true if the map contains the value
+ * @since Commons Collections 3.1
+ */
+ public boolean containsValue(Object key, Object value) {
+ Collection coll = getCollection(key);
+ if (coll == null) {
+ return false;
+ }
+ return coll.contains(value);
+ }
+
+ /**
+ * Removes a specific value from map.
+ * <p>
+ * The item is removed from the collection mapped to the specified key.
+ * Other values attached to that key are unaffected.
+ * <p>
+ * If the last value for a key is removed, <code>null</code> will be returned
+ * from a subsequant <code>get(key)</code>.
+ *
+ * @param key the key to remove from
+ * @param item the value to remove
+ * @return the value removed (which was passed in), null if nothing removed
+ */
+ public Object remove(Object key, Object item) {
+ Collection valuesForKey = getCollection(key);
+ if (valuesForKey == null) {
+ return null;
+ }
+ valuesForKey.remove(item);
+
+ // remove the list if it is now empty
+ // (saves space, and allows equals to work)
+ if (valuesForKey.isEmpty()){
+ remove(key);
+ }
+ return item;
+ }
+
+ /**
+ * Clear the map.
+ * <p>
+ * This clears each collection in the map, and so may be slow.
+ */
+ public void clear() {
+ // For gc, clear each list in the map
+ Set pairs = super.entrySet();
+ Iterator pairsIterator = pairs.iterator();
+ while (pairsIterator.hasNext()) {
+ Map.Entry keyValuePair = (Map.Entry) pairsIterator.next();
+ Collection coll = (Collection) keyValuePair.getValue();
+ coll.clear();
+ }
+ super.clear();
+ }
+
+ /**
+ * Gets a collection containing all the values in the map.
+ * <p>
+ * This returns a collection containing the combination of values from all keys.
+ *
+ * @return a collection view of the values contained in this map
+ */
+ public Collection values() {
+ Collection vs = values;
+ return (vs != null ? vs : (values = new Values()));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Inner class to view the elements.
+ */
+ private class Values extends AbstractCollection {
+
+ public Iterator iterator() {
+ return new ValueIterator();
+ }
+
+ public int size() {
+ int compt = 0;
+ Iterator it = iterator();
+ while (it.hasNext()) {
+ it.next();
+ compt++;
+ }
+ return compt;
+ }
+
+ public void clear() {
+ MultiHashMap.this.clear();
+ }
+
+ }
+
+ /**
+ * Inner iterator to view the elements.
+ */
+ private class ValueIterator implements Iterator {
+ private Iterator backedIterator;
+ private Iterator tempIterator;
+
+ private ValueIterator() {
+ backedIterator = MultiHashMap.super.values().iterator();
+ }
+
+ private boolean searchNextIterator() {
+ while (tempIterator == null || tempIterator.hasNext() == false) {
+ if (backedIterator.hasNext() == false) {
+ return false;
+ }
+ tempIterator = ((Collection) backedIterator.next()).iterator();
+ }
+ return true;
+ }
+
+ public boolean hasNext() {
+ return searchNextIterator();
+ }
+
+ public Object next() {
+ if (searchNextIterator() == false) {
+ throw new NoSuchElementException();
+ }
+ return tempIterator.next();
+ }
+
+ public void remove() {
+ if (tempIterator == null) {
+ throw new IllegalStateException();
+ }
+ tempIterator.remove();
+ }
+
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Clone the map.
+ * <p>
+ * The clone will shallow clone the collections as well as the map.
+ *
+ * @return the cloned map
+ */
+ public Object clone() {
+ MultiHashMap obj = (MultiHashMap) super.clone();
+
+ // clone each Collection container
+ for (Iterator it = entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
+ Collection coll = (Collection) entry.getValue();
+ Collection newColl = createCollection(coll);
+ entry.setValue(newColl);
+ }
+ return obj;
+ }
+
+ /**
+ * Creates a new instance of the map value Collection container.
+ * <p>
+ * This method can be overridden to use your own collection type.
+ *
+ * @param coll the collection to copy, may be null
+ * @return the new collection
+ */
+ protected Collection createCollection(Collection coll) {
+ if (coll == null) {
+ return new ArrayList();
+ } else {
+ return new ArrayList(coll);
+ }
+ }
+
+}
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/NestedSAXException.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/NestedSAXException.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/NestedSAXException.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/NestedSAXException.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,47 @@
+/* $Id: $
+ *
+ * Copyright 2001-2004 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.commons.digester2;
+
+/**
+ * In some places in SAXHandler classes, we are permitted only to throw
+ * subclasses of SAXException. This class can be used to wrap the exception
+ * we really want to throw; the receiver should unwrap it via the getCause
+ * method.
+ * <p>
+ * We implement getCause directly here, in order to be able to support
+ * java platforms earlier than 1.4.
+ */
+
+public class NestedSAXException extends org.xml.sax.SAXException {
+ private Throwable cause;
+
+ public NestedSAXException(String msg, Throwable t) {
+ super(msg);
+ cause = t;
+ }
+
+ public NestedSAXException(Throwable t) {
+ cause = t;
+ }
+
+ public Throwable getCause() {
+ return cause;
+ }
+}
+
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/ParseException.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/ParseException.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/ParseException.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/ParseException.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,38 @@
+/* $Id: $
+ *
+ * Copyright 2001-2004 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.commons.digester2;
+
+/**
+ */
+
+public class ParseException extends DigestionException {
+ public ParseException(String msg) {
+ super(msg);
+ }
+
+ public ParseException(Throwable t) {
+ super(t);
+ }
+
+ public ParseException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+}
+
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Path.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Path.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Path.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/Path.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,57 @@
+/* $Id: $
+ *
+ * Copyright 2001-2004 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.commons.digester2;
+
+/**
+ * A simple class that represents the path to a particular XML element.
+ */
+
+public class Path {
+ StringBuffer buf = new StringBuffer();
+ ArrayStack lengths = new ArrayStack();
+
+ public Path() {
+ }
+
+ public void push(String namespace, String elementName) {
+ lengths.push(new Integer(buf.length()));
+ buf.append("/");
+ if ((namespace != null) && (namespace.length()>0)) {
+ buf.append('{');
+ buf.append(namespace);
+ buf.append('}');
+ }
+ buf.append(elementName);
+ }
+
+ public void pop() {
+ int length = ((Integer)lengths.pop()).intValue();
+ buf.setLength(length);
+ }
+
+ public String getPath() {
+ return buf.toString();
+ }
+
+ public void clear() {
+ buf.setLength(0);
+ lengths.clear();
+ }
+}
+
Added: jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/RuleManager.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/RuleManager.java?view=auto&rev=151287
==============================================================================
--- jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/RuleManager.java (added)
+++ jakarta/commons/proper/digester/branches/digester2/src/java/org/apache/commons/digester2/RuleManager.java Thu Feb 3 17:51:43 2005
@@ -0,0 +1,98 @@
+/* $Id: $
+ *
+ * Copyright 2001-2004 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.commons.digester2;
+
+import java.util.List;
+
+/**
+ * Public interface defining a collection of Action instances (and corresponding
+ * matching patterns) plus an implementation of a matching policy that selects
+ * the Actions that match a particular pattern of nested elements discovered
+ * during parsing.
+ * <p>
+ * Terminology:
+ * <ul>
+ * <li>Pattern: a string with namespace prefixes in it, eg "/foo:bob"</li>
+ * <li>Path: a string with namespace uris in it, eg /{urn:foo}bob"</li>
+ * </ul>
+ *
+ */
+
+public abstract class RuleManager {
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Returns a new instance with the same type as the concrete object this
+ * method is invoked on, complete with contained Actions and patterns. Note
+ * that the new RuleManager instance may contain references to the same
+ * Action instances as the old one, as Action instances are expected to be
+ * stateless and therefore can be safely shared between RuleManagers.
+ */
+ public abstract RuleManager copy();
+
+ /**
+ * Invoked before parsing each input document, this method gives the
+ * RuleManager and the managed Action objects the opportunity to do
+ * per-parse initialisation if required.
+ */
+ public void startParse(Context context) throws DigestionException {}
+
+ /**
+ * Invoked after parsing each input document, this method gives the
+ * RuleManager and the managed Action objects the opportunity to do
+ * per-parse cleanup if required.
+ */
+ public void finishParse(Context context) throws DigestionException {}
+
+ /**
+ * Define a mapping between xml element prefix and namespace uri
+ * for use when rule patterns contain namespace prefixes.
+ */
+ public abstract void addNamespace(String prefix, String uri);
+
+ /**
+ * Cause the specified Action to be invoked whenever an xml element
+ * is encountered in the input which matches the specified pattern.
+ * <p>
+ * If the pattern contains any namespace prefixes, eg "/myns:item",
+ * then an exception will be thrown unless that prefix has previously
+ * been defined via a call to method addNamespace.
+ * <p>
+ * Note that it is permitted for the same Action to be added multiple
+ * times with different associated patterns.
+ */
+ public abstract void addRule(String pattern, Action action)
+ throws InvalidRuleException;
+
+ /**
+ * Return a List of all registered Action instances that match the specified
+ * nesting pattern, or a zero-length List if there are no matches. If more
+ * than one Action instance matches, they <strong>must</strong> be returned
+ * in the order originally registered through the <code>addRule()</code>
+ * method.
+ *
+ * @param path is a string of form
+ * <pre>/{namespace}elementName/{namespace}elementName"</pre>
+ * identifying the path from the root of the input document to the element
+ * for which the caller wants the set of matching Action objects. If an
+ * element has no namespace, then the {} part is omitted.
+ */
+ public abstract List getMatchingActions(String path)
+ throws DigestionException;
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org