1   
2   
3   
4   
5   
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     
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()|@"
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()|@"
134      * 
135      * @param valueOfAction
136      *            DOCUMENT ME!
137      */
138     public void setValueOfAction(Action valueOfAction) {
139         this.valueOfAction = valueOfAction;
140     }
141 
142     
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         
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 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 
233 
234 
235