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