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>&lt;c&gt;</code> element, nested inside a <code>&lt;b&gt;</code>
   *     element, which is nested inside an <code>&lt;a&gt;</code> element.</li>
   * <li><em>Tail Match</em> - A pattern "*\/a/b" matches a
   *     <code>&lt;b&gt;</code> element, nested inside an <code>&lt;a&gt;</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);
  
      }
  
  
  
  }
  
  
  

Reply via email to