craigmcc 01/08/04 16:14:57
Modified: digester/src/java/org/apache/commons/digester Digester.java
Added: digester/src/java/org/apache/commons/digester Rules.java
RulesBase.java
Log:
Refactor the collection of registered rules, and the associated policy
for picking the matching ones, into a Rules interface. Provide a default
implementation that supports the previous standard functionality.
Revision Changes Path
1.10 +55 -47
jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java
Index: Digester.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Digester.java 2001/08/04 22:26:37 1.9
+++ Digester.java 2001/08/04 23:14:57 1.10
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java,v
1.9 2001/08/04 22:26:37 craigmcc Exp $
- * $Revision: 1.9 $
- * $Date: 2001/08/04 22:26:37 $
+ * $Header:
/home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java,v
1.10 2001/08/04 23:14:57 craigmcc Exp $
+ * $Revision: 1.10 $
+ * $Date: 2001/08/04 23:14:57 $
*
* ====================================================================
*
@@ -106,7 +106,7 @@
*
* @author Craig McClanahan
* @author Scott Sanders
- * @version $Revision: 1.9 $ $Date: 2001/08/04 22:26:37 $
+ * @version $Revision: 1.10 $ $Date: 2001/08/04 23:14:57 $
*/
public class Digester extends DefaultHandler {
@@ -222,12 +222,12 @@
/**
- * The set of Rules that have been registered with this Digester. The
- * key is the matching pattern against the current element stack, and
- * the value is a List containing the Rules for that pattern, in the
- * order that they were registered.
+ * The <code>Rules</code> implementation containing our collection of
+ * <code>Rule</code> instances and associated matching policy. If not
+ * established before the first rule is added, a default implementation
+ * will be provided.
*/
- protected HashMap rules = new HashMap();
+ protected Rules rules = null;
/**
@@ -403,6 +403,35 @@
/**
+ * Return the <code>Rules</code> implementation object containing our
+ * rules collection and associated matching policy. If none has been
+ * established, a default implementation will be created and returned.
+ */
+ public Rules getRules() {
+
+ if (this.rules == null) {
+ this.rules = new RulesBase();
+ this.rules.setDigester(this);
+ }
+ return (this.rules);
+
+ }
+
+
+ /**
+ * Set the <code>Rules</code> implementation object containing our
+ * rules collection and associated matching policy.
+ *
+ * @param rules New Rules implementation
+ */
+ public void setRules(Rules rules) {
+
+ this.rules = rules;
+
+ }
+
+
+ /**
* Return the validating parser flag.
*/
public boolean getValidating() {
@@ -514,18 +543,15 @@
pop();
// Fire "finish" events for all defined rules
- Iterator keys = this.rules.keySet().iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- List rules = (List) this.rules.get(key);
- for (int i = 0; i < rules.size(); i++) {
- try {
- ((Rule) rules.get(i)).finish();
- } catch (Exception e) {
- log("Finish event threw exception", e);
- throw new SAXException(e);
- }
- }
+ Iterator rules = getRules().rules().iterator();
+ while (rules.hasNext()) {
+ Rule rule = (Rule) rules.next();
+ try {
+ rule.finish();
+ } catch (Exception e) {
+ log("Finish event threw exception", e);
+ throw new SAXException(e);
+ }
}
// Perform final cleanup
@@ -551,7 +577,7 @@
// if (debug >= 3)
// log("endElement(" + match + ")");
- List rules = getRules(match);
+ List rules = getRules().match(match);
// Fire "body" events for all relevant rules
if (rules != null) {
@@ -699,7 +725,7 @@
// Fire "begin" events for all relevant rules
- List rules = getRules(match);
+ List rules = getRules().match(match);
if (rules != null) {
// if (debug >= 3)
// log(" Firing 'begin' events for " + rules.size() + " rules");
@@ -991,12 +1017,7 @@
*/
public void addRule(String pattern, Rule rule) {
- List list = (List) rules.get(pattern);
- if (list == null) {
- list = new ArrayList();
- rules.put(pattern, list);
- }
- list.add(rule);
+ getRules().add(pattern, rule);
}
@@ -1233,6 +1254,7 @@
match = "";
bodyTexts.clear();
stack.clear();
+ getRules().clear();
}
@@ -1322,27 +1344,13 @@
* is preferred.
*
* @param match The current match position
+ *
+ * @deprecated Call <code>match()</code> on the <code>Rules</code>
+ * implementation returned by <code>getRules()</code>
*/
List getRules(String match) {
- List rulesList = (List) this.rules.get(match);
- if (rulesList == null) {
- // Find the longest key, ie more discriminant
- String longKey = "";
- Iterator keys = this.rules.keySet().iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- if (key.startsWith("*/")) {
- if (match.endsWith(key.substring(1))) {
- if (key.length() > longKey.length()) {
- rulesList = (List) this.rules.get(key);
- longKey = key;
- }
- }
- }
- }
- }
- return (rulesList);
+ return (getRules().match(match));
}
1.1
jakarta-commons/digester/src/java/org/apache/commons/digester/Rules.java
Index: Rules.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/Rules.java,v
1.1 2001/08/04 23:14:57 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2001/08/04 23:14:57 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.digester;
import java.util.List;
/**
* Public interface defining a collection of Rule instances (and corresponding
* matching patterns, plus an implementation of a matching policy that selects
* the rules that match a particular pattern of nested elements discovered
* during parsing.
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2001/08/04 23:14:57 $
*/
public interface Rules {
// ------------------------------------------------------------- Properties
/**
* Return the Digester instance with which this Rules instance is
* associated.
*/
public Digester getDigester();
/**
* Set the Digester instance with which this Rules instance is associated.
*
* @param digester The newly associated Digester instance
*/
public void setDigester(Digester digester);
// --------------------------------------------------------- Public Methods
/**
* Register a new Rule instance matching the specified pattern.
*
* @param pattern Nesting pattern to be matched for this Rule
* @param rule Rule instance to be registered
*/
public void add(String pattern, Rule rule);
/**
* Clear all existing Rule instance registrations.
*/
public void clear();
/**
* Return a List of all registered Rule instances that match the specified
* nesting pattern, or a zero-length List if there are no matches. If more
* than one Rule instance matches, they <strong>must</strong> be returned
* in the order originally registered through the <code>add()</code>
* method.
*
* @param pattern Nesting pattern to be matched
*/
public List match(String pattern);
/**
* Return a List of all registered Rule instances, or a zero-length List
* if there are no registered Rule instances. If more than one Rule
* instance has been registered, they <strong>must</strong> be returned
* in the order originally registered through the <code>add()</code>
* method.
*/
public List rules();
}
1.1
jakarta-commons/digester/src/java/org/apache/commons/digester/RulesBase.java
Index: RulesBase.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/RulesBase.java,v
1.1 2001/08/04 23:14:57 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2001/08/04 23:14:57 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.digester;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/**
* <p>Default implementation of the <code>Rules</code> interface that supports
* the standard rule matching behavior. This class can also be used as a
* base class for specialized <code>Rules</code> implementations.</p>
*
* <p>The matching policies implemented by this class support two different
* types of pattern matching rules:</p>
* <ul>
* <li><em>Exact Match</em> - A pattern "a/b/c" exactly matches a
* <code><c></code> element, nested inside a <code><b></code>
* element, which is nested inside an <code><a></code> element.</li>
* <li><em>Tail Match</em> - A pattern "*\/a/b" matches a
* <code><b></code> element, nested inside an <code><a></code>
* element, no matter how deeply the pair is nested.</li>
* </ul>
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2001/08/04 23:14:57 $
*/
public class RulesBase implements Rules {
// ----------------------------------------------------- Instance Variables
/**
* The set of registered Rule instances, keyed by the matching pattern.
* Each value is a List containing the Rules for that pattern, in the
* order that they were orginally registered.
*/
protected HashMap cache = new HashMap();
/**
* The Digester instance with which this Rules instance is associated.
*/
protected Digester digester = null;
/**
* The set of registered Rule instances, in the order that they were
* originally registered.
*/
protected ArrayList rules = new ArrayList();
// ------------------------------------------------------------- Properties
/**
* Return the Digester instance with which this Rules instance is
* associated.
*/
public Digester getDigester() {
return (this.digester);
}
/**
* Set the Digester instance with which this Rules instance is associated.
*
* @param digester The newly associated Digester instance
*/
public void setDigester(Digester digester) {
this.digester = digester;
}
// --------------------------------------------------------- Public Methods
/**
* Register a new Rule instance matching the specified pattern.
*
* @param pattern Nesting pattern to be matched for this Rule
* @param rule Rule instance to be registered
*/
public void add(String pattern, Rule rule) {
List list = (List) cache.get(pattern);
if (list == null) {
list = new ArrayList();
cache.put(pattern, list);
}
list.add(rule);
rules.add(rule);
}
/**
* Clear all existing Rule instance registrations.
*/
public void clear() {
cache.clear();
rules.clear();
}
/**
* Return a List of all registered Rule instances that match the specified
* nesting pattern, or a zero-length List if there are no matches. If more
* than one Rule instance matches, they <strong>must</strong> be returned
* in the order originally registered through the <code>add()</code>
* method.
*
* @param pattern Nesting pattern to be matched
*/
public List match(String pattern) {
List rulesList = (List) this.cache.get(pattern);
if (rulesList == null) {
// Find the longest key, ie more discriminant
String longKey = "";
Iterator keys = this.cache.keySet().iterator();
while (keys.hasNext()) {
String key = (String) keys.next();
if (key.startsWith("*/")) {
if (pattern.endsWith(key.substring(1))) {
if (key.length() > longKey.length()) {
rulesList = (List) this.cache.get(key);
longKey = key;
}
}
}
}
}
return (rulesList);
}
/**
* Return a List of all registered Rule instances, or a zero-length List
* if there are no registered Rule instances. If more than one Rule
* instance has been registered, they <strong>must</strong> be returned
* in the order originally registered through the <code>add()</code>
* method.
*/
public List rules() {
return (this.rules);
}
}