1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.struts.tiles.xmlDefinition;
21
22 import java.io.BufferedInputStream;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URL;
27
28 import org.apache.commons.digester.Digester;
29 import org.xml.sax.SAXException;
30
31 /***
32 * Parse an XML definitions file.
33 */
34 public class XmlParser
35 {
36
37 /*** Associated digester. */
38 protected Digester digester;
39 /***
40 * Should we use a validating XML parser to read the configuration file.
41 * Default is <code>false</code>.
42 */
43 protected boolean validating = false;
44 /***
45 * The set of public identifiers, and corresponding resource names for
46 * the versions of the configuration file DTDs we know about. There
47 * <strong>MUST</strong> be an even number of Strings in this list!
48 */
49 protected String registrations[] = {
50 "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN",
51 "/org/apache/struts/resources/tiles-config_1_1.dtd",
52 "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN",
53 "/org/apache/struts/resources/tiles-config_1_3.dtd"
54 };
55
56 /***
57 * Constructor.
58 * Creates a digester parser and initializes syntax rules.
59 */
60 public XmlParser()
61 {
62 digester = new Digester();
63 digester.setValidating(validating);
64 digester.setNamespaceAware(true);
65 digester.setUseContextClassLoader(true);
66
67 for (int i = 0; i < registrations.length; i += 2) {
68 URL url = this.getClass().getResource(registrations[i+1]);
69 if (url != null)
70 {
71 digester.register(registrations[i], url.toString());
72 }
73 }
74
75 initDigester( digester );
76 }
77
78 /***
79 * Set digester validating flag.
80 */
81 public void setValidating( boolean validating )
82 {
83 digester.setValidating( validating);
84 }
85
86
87 /***
88 * Init digester for components syntax.
89 * This is an old set of rules, left for backward compatibility.
90 * @param digester Digester instance to use.
91 */
92 private void initDigesterForComponentsDefinitionsSyntax( Digester digester )
93 {
94
95 String PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
96 String DEFINITION_TAG = "component-definitions/definition";
97 String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";
98
99 String PUT_TAG = DEFINITION_TAG + "/put";
100 String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
101
102 String LIST_TAG = DEFINITION_TAG + "/putList";
103 String listHandlerClass = PACKAGE_NAME + ".XmlListAttribute";
104
105 String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
106
107
108 digester.addObjectCreate( DEFINITION_TAG, definitionHandlerClass );
109 digester.addSetProperties( DEFINITION_TAG);
110 digester.addSetNext( DEFINITION_TAG, "putDefinition", definitionHandlerClass);
111
112 digester.addObjectCreate( PUT_TAG, putAttributeHandlerClass);
113 digester.addSetNext( PUT_TAG, "addAttribute", putAttributeHandlerClass);
114 digester.addSetProperties( PUT_TAG);
115 digester.addCallMethod( PUT_TAG, "setBody", 0);
116
117 digester.addObjectCreate( LIST_TAG, listHandlerClass);
118 digester.addSetProperties( LIST_TAG);
119 digester.addSetNext( LIST_TAG, "addAttribute", putAttributeHandlerClass);
120
121
122
123 digester.addObjectCreate( ADD_LIST_ELE_TAG, putAttributeHandlerClass);
124 digester.addSetNext( ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
125 digester.addSetProperties( ADD_LIST_ELE_TAG);
126 digester.addCallMethod( ADD_LIST_ELE_TAG, "setBody", 0);
127 }
128
129 /***
130 * Init digester for Tiles syntax.
131 * Same as components, but with first element = tiles-definitions
132 * @param digester Digester instance to use.
133 */
134 private void initDigesterForTilesDefinitionsSyntax( Digester digester )
135 {
136
137 String PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
138 String DEFINITION_TAG = "tiles-definitions/definition";
139 String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";
140
141 String PUT_TAG = DEFINITION_TAG + "/put";
142 String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
143
144
145
146 String LIST_TAG = "putList";
147 String DEF_LIST_TAG = DEFINITION_TAG + "/" + LIST_TAG;
148 String listHandlerClass = PACKAGE_NAME + ".XmlListAttribute";
149
150 String ADD_LIST_ELE_TAG = "*/" + LIST_TAG + "/add";
151
152
153 digester.addObjectCreate( DEFINITION_TAG, definitionHandlerClass );
154 digester.addSetProperties( DEFINITION_TAG);
155 digester.addSetNext( DEFINITION_TAG, "putDefinition", definitionHandlerClass);
156
157
158
159
160
161 digester.addObjectCreate( PUT_TAG, putAttributeHandlerClass);
162 digester.addSetNext( PUT_TAG, "addAttribute", putAttributeHandlerClass);
163 digester.addSetProperties( PUT_TAG);
164 digester.addCallMethod( PUT_TAG, "setBody", 0);
165
166
167 digester.addObjectCreate( DEF_LIST_TAG, listHandlerClass);
168 digester.addSetProperties( DEF_LIST_TAG);
169 digester.addSetNext( DEF_LIST_TAG, "addAttribute", putAttributeHandlerClass);
170
171
172
173 digester.addObjectCreate( ADD_LIST_ELE_TAG, putAttributeHandlerClass);
174 digester.addSetNext( ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
175 digester.addSetProperties( ADD_LIST_ELE_TAG);
176 digester.addCallMethod( ADD_LIST_ELE_TAG, "setBody", 0);
177
178
179
180 String NESTED_LIST = "*/" + LIST_TAG + "/" + LIST_TAG;
181 digester.addObjectCreate( NESTED_LIST, listHandlerClass);
182 digester.addSetProperties( NESTED_LIST);
183 digester.addSetNext( NESTED_LIST, "add", putAttributeHandlerClass);
184
185
186
187
188
189
190 String ADD_WILDCARD = "*/item";
191 String menuItemDefaultClass = "org.apache.struts.tiles.beans.SimpleMenuItem";
192 digester.addObjectCreate( ADD_WILDCARD, menuItemDefaultClass, "classtype");
193 digester.addSetNext( ADD_WILDCARD, "add", "java.lang.Object");
194 digester.addSetProperties( ADD_WILDCARD);
195
196
197 String BEAN_TAG = "*/bean";
198 String beanDefaultClass = "org.apache.struts.tiles.beans.SimpleMenuItem";
199 digester.addObjectCreate( BEAN_TAG, beanDefaultClass, "classtype");
200 digester.addSetNext( BEAN_TAG, "add", "java.lang.Object");
201 digester.addSetProperties( BEAN_TAG);
202
203
204 digester.addSetProperty(BEAN_TAG+ "/set-property", "property", "value");
205 }
206
207 /***
208 * Init digester in order to parse instances definition file syntax.
209 * Instances is an old name for "definition". This method is left for
210 * backwards compatibility.
211 * @param digester Digester instance to use.
212 */
213 private void initDigesterForInstancesSyntax( Digester digester )
214 {
215
216 String PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
217 String INSTANCE_TAG = "component-instances/instance";
218 String instanceHandlerClass = PACKAGE_NAME + ".XmlDefinition";
219
220 String PUT_TAG = INSTANCE_TAG + "/put";
221 String PUTATTRIBUTE_TAG = INSTANCE_TAG + "/putAttribute";
222 String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
223
224 String LIST_TAG = INSTANCE_TAG + "/putList";
225 String listHandlerClass = PACKAGE_NAME + ".XmlListAttribute";
226
227 String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
228
229
230 digester.addObjectCreate( INSTANCE_TAG, instanceHandlerClass );
231 digester.addSetProperties( INSTANCE_TAG);
232 digester.addSetNext( INSTANCE_TAG, "putDefinition", instanceHandlerClass);
233
234 digester.addObjectCreate( PUTATTRIBUTE_TAG, putAttributeHandlerClass);
235 digester.addSetProperties( PUTATTRIBUTE_TAG);
236 digester.addSetNext( PUTATTRIBUTE_TAG, "addAttribute", putAttributeHandlerClass);
237
238 digester.addObjectCreate( PUT_TAG, putAttributeHandlerClass);
239 digester.addSetProperties( PUT_TAG);
240 digester.addSetNext( PUT_TAG, "addAttribute", putAttributeHandlerClass);
241
242 digester.addObjectCreate( LIST_TAG, listHandlerClass);
243 digester.addSetProperties( LIST_TAG);
244 digester.addSetNext( LIST_TAG, "addAttribute", putAttributeHandlerClass);
245
246
247
248 digester.addObjectCreate( ADD_LIST_ELE_TAG, putAttributeHandlerClass);
249 digester.addSetProperties( ADD_LIST_ELE_TAG);
250 digester.addSetNext( ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
251 }
252
253 /***
254 * Init digester.
255 * @param digester Digester instance to use.
256 */
257 protected void initDigester( Digester digester )
258 {
259 initDigesterForTilesDefinitionsSyntax( digester );
260 initDigesterForComponentsDefinitionsSyntax( digester );
261 initDigesterForInstancesSyntax( digester );
262 }
263
264 /***
265 * Parse input reader and add encountered definitions to definitions set.
266 * @param in Input stream.
267 * @param definitions Xml Definitions set to which encountered definition are added.
268 * @throws IOException On errors during file parsing.
269 * @throws SAXException On errors parsing XML.
270 */
271 public void parse( InputStream in, XmlDefinitionsSet definitions ) throws IOException, SAXException
272 {
273 try
274 {
275
276
277 digester.push(definitions);
278
279 digester.parse(in);
280 in.close();
281 }
282 catch (SAXException e)
283 {
284
285 throw e;
286 }
287
288 }
289
290 /***
291 * Main method to check file syntax.
292 */
293 public static void main(String[] args)
294 {
295
296 String filename = "E:/programs/jakarta-tomcat-4.0.3/webapps/wtiles-struts/WEB-INF/tiles-examples-defs.xml";
297
298
299
300
301
302 if( args.length > 1 )
303 {
304 filename = args[1];
305 }
306
307 System.out.println( "Read file '" + filename +"'" );
308
309 InputStream input = null;
310
311
312 try
313 {
314 input = new BufferedInputStream(
315 new FileInputStream( filename) );
316
317
318 }
319 catch( IOException ex )
320 {
321 System.out.println( "can't open file '" + filename + "' : " + ex.getMessage() );
322 }
323
324 try
325 {
326 XmlParser parser = new XmlParser();
327 parser.setValidating(true);
328 XmlDefinitionsSet definitions = new XmlDefinitionsSet();
329 System.out.println( " Parse file" );
330 parser.parse( input, definitions);
331
332
333 System.out.println( " done." );
334 System.out.println( " Result : " + definitions.toString() );
335 }
336 catch( Exception ex )
337 {
338 System.out.println( "Error during parsing '" + filename + "' : " + ex.getMessage() );
339 ex.printStackTrace();
340 }
341 }
342
343 }