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