1
2
3
4
5
6
7
8
9
10 package org.dom4j.rule;
11
12 import java.util.HashMap;
13
14 import org.dom4j.Document;
15 import org.dom4j.Element;
16 import org.dom4j.Node;
17 import org.dom4j.rule.pattern.NodeTypePattern;
18
19
20 /*** <p><code>RuleManager</code> manages a set of rules such that a rule
21 * can be found for a given DOM4J Node using the XSLT processing model.</p>
22 *
23 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
24 * @version $Revision: 1.7 $
25 */
26 public class RuleManager {
27
28 /*** Map of modes indexed by mode */
29 private HashMap modes = new HashMap();
30
31 /*** A counter so that rules can be ordered by the order in which they
32 * were added to the rule base
33 */
34 private int appearenceCount;
35
36 /*** Holds value of property valueOfAction. */
37 private Action valueOfAction;
38
39
40 public RuleManager() {
41 }
42
43 /*** @return the Mode instance for the given mode name. If one does not exist
44 * then it will be created.
45 */
46 public Mode getMode( String modeName ) {
47 Mode mode = (Mode) modes.get(modeName);
48 if ( mode == null ) {
49 mode = createMode();
50 modes.put(modeName, mode);
51 }
52 return mode;
53 }
54
55 public void addRule(Rule rule) {
56 rule.setAppearenceCount( ++appearenceCount );
57
58 Mode mode = getMode( rule.getMode() );
59 Rule[] childRules = rule.getUnionRules();
60 if ( childRules != null ) {
61 for ( int i = 0, size = childRules.length; i < size; i++ ) {
62 mode.addRule( childRules[i] );
63 }
64 }
65 else {
66 mode.addRule( rule );
67 }
68 }
69
70 public void removeRule(Rule rule) {
71 Mode mode = getMode( rule.getMode() );
72 Rule[] childRules = rule.getUnionRules();
73 if ( childRules != null ) {
74 for ( int i = 0, size = childRules.length; i < size; i++ ) {
75 mode.removeRule( childRules[i] );
76 }
77 }
78 else {
79 mode.removeRule( rule );
80 }
81 }
82
83 /*** Performs an XSLT processing model match for the rule
84 * which matches the given Node the best.
85 *
86 * @param modeName is the name of the mode associated with the rule if any
87 * @param node is the DOM4J Node to match against
88 * @return the matching Rule or no rule if none matched
89 */
90 public Rule getMatchingRule(String modeName, Node node) {
91 Mode mode = (Mode) modes.get(modeName);
92 if ( mode != null ) {
93 return mode.getMatchingRule( node );
94 }
95 else {
96 System.out.println( "Warning: No Mode for mode: " + mode );
97 return null;
98 }
99 }
100
101 public void clear() {
102 modes.clear();
103 appearenceCount = 0;
104 }
105
106
107
108
109
110 /*** @return the default value-of action which is used
111 * in the default rules for the pattern "text()|@*"
112 */
113 public Action getValueOfAction() {
114 return valueOfAction;
115 }
116
117 /*** Sets the default value-of action which is used
118 * in the default rules for the pattern "text()|@*"
119 */
120 public void setValueOfAction(Action valueOfAction) {
121 this.valueOfAction = valueOfAction;
122 }
123
124
125
126
127 /*** A factory method to return a new {@link Mode} instance
128 * which should add the necessary default rules
129 */
130 protected Mode createMode() {
131 Mode mode = new Mode();
132 addDefaultRules( mode );
133 return mode;
134 }
135
136 /*** Adds the default stylesheet rules to the given
137 * {@link Mode} instance
138 */
139 protected void addDefaultRules(final Mode mode) {
140
141 Action applyTemplates = new Action() {
142 public void run( Node node ) throws Exception {
143 if ( node instanceof Element ) {
144 mode.applyTemplates( (Element) node );
145 }
146 else if ( node instanceof Document ) {
147 mode.applyTemplates( (Document) node );
148 }
149 }
150 };
151
152 Action valueOfAction = getValueOfAction();
153
154 addDefaultRule( mode, NodeTypePattern.ANY_DOCUMENT, applyTemplates );
155 addDefaultRule( mode, NodeTypePattern.ANY_ELEMENT, applyTemplates );
156
157 if ( valueOfAction != null ) {
158 addDefaultRule( mode, NodeTypePattern.ANY_ATTRIBUTE, valueOfAction );
159 addDefaultRule( mode, NodeTypePattern.ANY_TEXT, valueOfAction );
160 }
161 }
162
163 protected void addDefaultRule( Mode mode, Pattern pattern, Action action ) {
164 Rule rule = createDefaultRule( pattern, action );
165 mode.addRule( rule );
166 }
167
168 protected Rule createDefaultRule( Pattern pattern, Action action ) {
169 Rule rule = new Rule( pattern, action );
170 rule.setImportPrecedence( -1 );
171 return rule;
172 }
173
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
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