View Javadoc

1   /*
2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3    *
4    * This software is open source.
5    * See the bottom of this file for the licence.
6    */
7   
8   package org.dom4j.rule;
9   
10  import java.util.HashMap;
11  
12  import org.dom4j.Document;
13  import org.dom4j.Element;
14  import org.dom4j.Node;
15  import org.dom4j.rule.pattern.NodeTypePattern;
16  
17  /***
18   * <p>
19   * <code>RuleManager</code> manages a set of rules such that a rule can be
20   * found for a given DOM4J Node using the XSLT processing model.
21   * </p>
22   * 
23   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
24   * @version $Revision: 1.9 $
25   */
26  public class RuleManager {
27      /*** Map of modes indexed by mode */
28      private HashMap modes = new HashMap();
29  
30      /***
31       * A counter so that rules can be ordered by the order in which they were
32       * added to the rule base
33       */
34      private int appearenceCount;
35  
36      /*** Holds value of property valueOfAction. */
37      private Action valueOfAction;
38  
39      public RuleManager() {
40      }
41  
42      /***
43       * DOCUMENT ME!
44       * 
45       * @param modeName
46       *            DOCUMENT ME!
47       * 
48       * @return the Mode instance for the given mode name. If one does not exist
49       *         then it will be created.
50       */
51      public Mode getMode(String modeName) {
52          Mode mode = (Mode) modes.get(modeName);
53  
54          if (mode == null) {
55              mode = createMode();
56              modes.put(modeName, mode);
57          }
58  
59          return mode;
60      }
61  
62      public void addRule(Rule rule) {
63          rule.setAppearenceCount(++appearenceCount);
64  
65          Mode mode = getMode(rule.getMode());
66          Rule[] childRules = rule.getUnionRules();
67  
68          if (childRules != null) {
69              for (int i = 0, size = childRules.length; i < size; i++) {
70                  mode.addRule(childRules[i]);
71              }
72          } else {
73              mode.addRule(rule);
74          }
75      }
76  
77      public void removeRule(Rule rule) {
78          Mode mode = getMode(rule.getMode());
79          Rule[] childRules = rule.getUnionRules();
80  
81          if (childRules != null) {
82              for (int i = 0, size = childRules.length; i < size; i++) {
83                  mode.removeRule(childRules[i]);
84              }
85          } else {
86              mode.removeRule(rule);
87          }
88      }
89  
90      /***
91       * Performs an XSLT processing model match for the rule which matches the
92       * given Node the best.
93       * 
94       * @param modeName
95       *            is the name of the mode associated with the rule if any
96       * @param node
97       *            is the DOM4J Node to match against
98       * 
99       * @return the matching Rule or no rule if none matched
100      */
101     public Rule getMatchingRule(String modeName, Node node) {
102         Mode mode = (Mode) modes.get(modeName);
103 
104         if (mode != null) {
105             return mode.getMatchingRule(node);
106         } else {
107             System.out.println("Warning: No Mode for mode: " + mode);
108 
109             return null;
110         }
111     }
112 
113     public void clear() {
114         modes.clear();
115         appearenceCount = 0;
116     }
117 
118     // Properties
119     // -------------------------------------------------------------------------
120 
121     /***
122      * DOCUMENT ME!
123      * 
124      * @return the default value-of action which is used in the default rules
125      *         for the pattern "text()|&#64;"
126      */
127     public Action getValueOfAction() {
128         return valueOfAction;
129     }
130 
131     /***
132      * Sets the default value-of action which is used in the default rules for
133      * the pattern "text()|&#64;"
134      * 
135      * @param valueOfAction
136      *            DOCUMENT ME!
137      */
138     public void setValueOfAction(Action valueOfAction) {
139         this.valueOfAction = valueOfAction;
140     }
141 
142     // Implementation methods
143     // -------------------------------------------------------------------------
144 
145     /***
146      * A factory method to return a new {@link Mode}instance which should add
147      * the necessary default rules
148      * 
149      * @return DOCUMENT ME!
150      */
151     protected Mode createMode() {
152         Mode mode = new Mode();
153         addDefaultRules(mode);
154 
155         return mode;
156     }
157 
158     /***
159      * Adds the default stylesheet rules to the given {@link Mode}instance
160      * 
161      * @param mode
162      *            DOCUMENT ME!
163      */
164     protected void addDefaultRules(final Mode mode) {
165         // add an apply templates rule
166         Action applyTemplates = new Action() {
167             public void run(Node node) throws Exception {
168                 if (node instanceof Element) {
169                     mode.applyTemplates((Element) node);
170                 } else if (node instanceof Document) {
171                     mode.applyTemplates((Document) node);
172                 }
173             }
174         };
175 
176         Action valueOf = getValueOfAction();
177 
178         addDefaultRule(mode, NodeTypePattern.ANY_DOCUMENT, applyTemplates);
179         addDefaultRule(mode, NodeTypePattern.ANY_ELEMENT, applyTemplates);
180 
181         if (valueOf != null) {
182             addDefaultRule(mode, NodeTypePattern.ANY_ATTRIBUTE, valueOf);
183             addDefaultRule(mode, NodeTypePattern.ANY_TEXT, valueOf);
184         }
185     }
186 
187     protected void addDefaultRule(Mode mode, Pattern pattern, Action action) {
188         Rule rule = createDefaultRule(pattern, action);
189         mode.addRule(rule);
190     }
191 
192     protected Rule createDefaultRule(Pattern pattern, Action action) {
193         Rule rule = new Rule(pattern, action);
194         rule.setImportPrecedence(-1);
195 
196         return rule;
197     }
198 }
199 
200 /*
201  * Redistribution and use of this software and associated documentation
202  * ("Software"), with or without modification, are permitted provided that the
203  * following conditions are met:
204  * 
205  * 1. Redistributions of source code must retain copyright statements and
206  * notices. Redistributions must also contain a copy of this document.
207  * 
208  * 2. Redistributions in binary form must reproduce the above copyright notice,
209  * this list of conditions and the following disclaimer in the documentation
210  * and/or other materials provided with the distribution.
211  * 
212  * 3. The name "DOM4J" must not be used to endorse or promote products derived
213  * from this Software without prior written permission of MetaStuff, Ltd. For
214  * written permission, please contact dom4j-info@metastuff.com.
215  * 
216  * 4. Products derived from this Software may not be called "DOM4J" nor may
217  * "DOM4J" appear in their names without prior written permission of MetaStuff,
218  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
219  * 
220  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
221  * 
222  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
223  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
225  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
226  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
227  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
228  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
229  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
230  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
231  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
232  * POSSIBILITY OF SUCH DAMAGE.
233  * 
234  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
235  */