Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/struts/tiles/xmlDefinition/XmlParser.java


1   /*
2    * $Id: XmlParser.java 54929 2004-10-16 16:38:42Z germuska $ 
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    * 
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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      };
53  
54       /**
55        * Constructor.
56        * Creates a digester parser and initializes syntax rules.
57        */
58    public XmlParser()
59    {
60    digester = new Digester();
61    digester.setValidating(validating);
62    digester.setNamespaceAware(true);
63    digester.setUseContextClassLoader(true);
64    // Register our local copy of the DTDs that we can find
65    for (int i = 0; i < registrations.length; i += 2) {
66        URL url = this.getClass().getResource(registrations[i+1]);
67        if (url != null)
68            {
69            digester.register(registrations[i], url.toString());
70            }
71    }
72      // Init syntax rules
73    initDigester( digester );
74    }
75  
76      /**
77       * Set digester validating flag.
78       */
79    public void setValidating( boolean validating )
80      {
81      digester.setValidating( validating);
82      }
83  
84  
85     /**
86      * Init digester for components syntax.
87      * This is an old set of rules, left for backward compatibility.
88      * @param digester Digester instance to use.
89      */
90    private void initDigesterForComponentsDefinitionsSyntax( Digester digester )
91    {
92     // Common constants
93    String PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
94    String DEFINITION_TAG = "component-definitions/definition";
95    String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";
96  
97    String PUT_TAG  = DEFINITION_TAG + "/put";
98    String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
99  
100   String LIST_TAG = DEFINITION_TAG + "/putList";
101   String listHandlerClass     = PACKAGE_NAME + ".XmlListAttribute";
102 
103   String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
104 
105     // syntax rules
106   digester.addObjectCreate(  DEFINITION_TAG, definitionHandlerClass );
107   digester.addSetProperties( DEFINITION_TAG);
108   digester.addSetNext(       DEFINITION_TAG, "putDefinition", definitionHandlerClass);
109     // put / putAttribute rules
110   digester.addObjectCreate(  PUT_TAG, putAttributeHandlerClass);
111   digester.addSetNext(       PUT_TAG, "addAttribute", putAttributeHandlerClass);
112   digester.addSetProperties( PUT_TAG);
113   digester.addCallMethod(    PUT_TAG, "setBody", 0);
114     // list rules
115   digester.addObjectCreate(  LIST_TAG, listHandlerClass);
116   digester.addSetProperties( LIST_TAG);
117   digester.addSetNext(       LIST_TAG, "addAttribute", putAttributeHandlerClass);
118     // list elements rules
119     // We use Attribute class to avoid rewriting a new class.
120     // Name part can't be used in listElement attribute.
121   digester.addObjectCreate(  ADD_LIST_ELE_TAG, putAttributeHandlerClass);
122   digester.addSetNext(       ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
123   digester.addSetProperties( ADD_LIST_ELE_TAG);
124   digester.addCallMethod(    ADD_LIST_ELE_TAG, "setBody", 0);
125   }
126 
127    /**
128     * Init digester for Tiles syntax.
129     * Same as components, but with first element = tiles-definitions
130     * @param digester Digester instance to use.
131     */
132   private void initDigesterForTilesDefinitionsSyntax( Digester digester )
133   {
134    // Common constants
135   String PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
136   String DEFINITION_TAG = "tiles-definitions/definition";
137   String definitionHandlerClass = PACKAGE_NAME + ".XmlDefinition";
138 
139   String PUT_TAG  = DEFINITION_TAG + "/put";
140   String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
141 
142   //String LIST_TAG = DEFINITION_TAG + "/putList";
143     // List tag value
144   String LIST_TAG = "putList";
145   String DEF_LIST_TAG = DEFINITION_TAG + "/" + LIST_TAG;
146   String listHandlerClass     = PACKAGE_NAME + ".XmlListAttribute";
147     // Tag value for adding an element in a list
148   String ADD_LIST_ELE_TAG = "*/" + LIST_TAG + "/add";
149 
150     // syntax rules
151   digester.addObjectCreate(  DEFINITION_TAG, definitionHandlerClass );
152   digester.addSetProperties( DEFINITION_TAG);
153   digester.addSetNext(       DEFINITION_TAG, "putDefinition", definitionHandlerClass);
154     // put / putAttribute rules
155     // Rules for a same pattern are called in order, but rule.end() are called
156     // in reverse order.
157     // SetNext and CallMethod use rule.end() method. So, placing SetNext in
158     // first position ensure it will be called last (sic).
159   digester.addObjectCreate(  PUT_TAG, putAttributeHandlerClass);
160   digester.addSetNext(       PUT_TAG, "addAttribute", putAttributeHandlerClass);
161   digester.addSetProperties( PUT_TAG);
162   digester.addCallMethod(    PUT_TAG, "setBody", 0);
163     // Definition level list rules
164     // This is rules for lists nested in a definition
165   digester.addObjectCreate(  DEF_LIST_TAG, listHandlerClass);
166   digester.addSetProperties( DEF_LIST_TAG);
167   digester.addSetNext(       DEF_LIST_TAG, "addAttribute", putAttributeHandlerClass);
168     // list elements rules
169     // We use Attribute class to avoid rewriting a new class.
170     // Name part can't be used in listElement attribute.
171   digester.addObjectCreate(  ADD_LIST_ELE_TAG, putAttributeHandlerClass);
172   digester.addSetNext(       ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
173   digester.addSetProperties( ADD_LIST_ELE_TAG);
174   digester.addCallMethod(    ADD_LIST_ELE_TAG, "setBody", 0);
175 
176     // nested list elements rules
177     // Create a list handler, and add it to parent list
178   String NESTED_LIST = "*/" + LIST_TAG + "/" + LIST_TAG;
179   digester.addObjectCreate(  NESTED_LIST, listHandlerClass);
180   digester.addSetProperties( NESTED_LIST);
181   digester.addSetNext(       NESTED_LIST, "add", putAttributeHandlerClass);
182 
183     // item elements rules
184     // We use Attribute class to avoid rewriting a new class.
185     // Name part can't be used in listElement attribute.
186   //String ADD_WILDCARD = LIST_TAG + "/addItem";
187   // non String ADD_WILDCARD = LIST_TAG + "/addx*";
188   String ADD_WILDCARD = "*/item";
189   String menuItemDefaultClass = "org.apache.struts.tiles.beans.SimpleMenuItem";
190   digester.addObjectCreate(  ADD_WILDCARD, menuItemDefaultClass, "classtype");
191   digester.addSetNext(       ADD_WILDCARD, "add", "java.lang.Object");
192   digester.addSetProperties( ADD_WILDCARD);
193 
194     // bean elements rules
195   String BEAN_TAG = "*/bean";
196   String beanDefaultClass = "org.apache.struts.tiles.beans.SimpleMenuItem";
197   digester.addObjectCreate(  BEAN_TAG, beanDefaultClass, "classtype");
198   digester.addSetNext(       BEAN_TAG, "add", "java.lang.Object");
199   digester.addSetProperties( BEAN_TAG);
200 
201     // Set properties to surrounding element
202   digester.addSetProperty(BEAN_TAG+ "/set-property", "property", "value");
203   }
204 
205    /**
206     * Init digester in order to parse instances definition file syntax.
207     * Instances is an old name for "definition". This method is left for
208     * backwards compatibility.
209     * @param digester Digester instance to use.
210     */
211   private void initDigesterForInstancesSyntax( Digester digester )
212   {
213       // Build a digester to process our configuration resource
214   String PACKAGE_NAME = "org.apache.struts.tiles.xmlDefinition";
215   String INSTANCE_TAG = "component-instances/instance";
216   String instanceHandlerClass = PACKAGE_NAME + ".XmlDefinition";
217 
218   String PUT_TAG = INSTANCE_TAG + "/put";
219   String PUTATTRIBUTE_TAG = INSTANCE_TAG + "/putAttribute";
220   String putAttributeHandlerClass = PACKAGE_NAME + ".XmlAttribute";
221 
222   String LIST_TAG     = INSTANCE_TAG + "/putList";
223   String listHandlerClass     = PACKAGE_NAME + ".XmlListAttribute";
224 
225   String ADD_LIST_ELE_TAG = LIST_TAG + "/add";
226 
227     // component instance rules
228   digester.addObjectCreate(  INSTANCE_TAG, instanceHandlerClass );
229   digester.addSetProperties( INSTANCE_TAG);
230   digester.addSetNext(       INSTANCE_TAG, "putDefinition", instanceHandlerClass);
231     // put / putAttribute rules
232   digester.addObjectCreate(  PUTATTRIBUTE_TAG, putAttributeHandlerClass);
233   digester.addSetProperties( PUTATTRIBUTE_TAG);
234   digester.addSetNext(       PUTATTRIBUTE_TAG, "addAttribute", putAttributeHandlerClass);
235     // put / putAttribute rules
236   digester.addObjectCreate(  PUT_TAG, putAttributeHandlerClass);
237   digester.addSetProperties( PUT_TAG);
238   digester.addSetNext(       PUT_TAG, "addAttribute", putAttributeHandlerClass);
239     // list rules
240   digester.addObjectCreate(  LIST_TAG, listHandlerClass);
241   digester.addSetProperties( LIST_TAG);
242   digester.addSetNext(       LIST_TAG, "addAttribute", putAttributeHandlerClass);
243     // list elements rules
244     // We use Attribute class to avoid rewriting a new class.
245     // Name part can't be used in listElement attribute.
246   digester.addObjectCreate(  ADD_LIST_ELE_TAG, putAttributeHandlerClass);
247   digester.addSetProperties( ADD_LIST_ELE_TAG);
248   digester.addSetNext(       ADD_LIST_ELE_TAG, "add", putAttributeHandlerClass);
249   }
250 
251    /**
252     * Init digester.
253     * @param digester Digester instance to use.
254     */
255   protected void initDigester( Digester digester )
256   {
257   initDigesterForTilesDefinitionsSyntax( digester );
258   initDigesterForComponentsDefinitionsSyntax( digester );
259   initDigesterForInstancesSyntax( digester );
260   }
261 
262   /**
263    * Parse input reader and add encountered definitions to definitions set.
264    * @param in Input stream.
265    * @param definitions Xml Definitions set to which encountered definition are added.
266    * @throws IOException On errors during file parsing.
267    * @throws SAXException On errors parsing XML.
268    */
269   public void parse( InputStream in, XmlDefinitionsSet definitions ) throws IOException, SAXException
270   {
271   try
272     {
273       // set first object in stack
274     //digester.clear();
275     digester.push(definitions);
276       // parse
277     digester.parse(in);
278     in.close();
279     }
280   catch (SAXException e)
281     {
282     //throw new ServletException( "Error while parsing " + mappingConfig, e);
283     throw e;
284     }
285 
286   }
287 
288     /**
289      * Main method to check file syntax.
290      */
291   public static void main(String[] args)
292   {
293   //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-struts/WEB-INF/tiles-examples-defs.xml";
294   String filename = "E:/programs/jakarta-tomcat-4.0.3/webapps/wtiles-struts/WEB-INF/tiles-examples-defs.xml";
295   //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-struts/WEB-INF/tilesDefinitions.xml";
296   //String filename = "E:/programs/jakarta-tomcat/webapps/wtiles-channel/WEB-INF/componentDefinitions.xml";
297   //String filename2 = "E:/programs/jakarta-tomcat/webapps/wtiles-tutorial/WEB-INF/componentDefinitions.xml";
298 
299 
300     if( args.length > 1 )
301       {
302       filename = args[1];
303       } // end if
304 
305   System.out.println( "Read file '" + filename  +"'" );
306 
307   InputStream input = null;
308   // InputStream input2 = null;
309     // Open file
310     try
311       {
312       input = new BufferedInputStream(
313                              new FileInputStream( filename) );
314   //    input2 = new BufferedInputStream(
315           //                   new FileInputStream( filename2) );
316       }
317      catch( IOException ex )
318       {
319       System.out.println( "can't open file '" + filename + "' : " + ex.getMessage() );
320       }
321     // Check file syntax
322     try
323       {
324       XmlParser parser = new XmlParser();
325       parser.setValidating(true);
326       XmlDefinitionsSet definitions = new XmlDefinitionsSet();
327         System.out.println( "  Parse file" );
328       parser.parse( input, definitions);
329       //  System.out.println( "  Check file 2" );
330       //parser.parse( input2, definitions);
331         System.out.println( "  done." );
332       System.out.println( "  Result : " + definitions.toString() );
333       }
334      catch( Exception ex )
335       {
336       System.out.println( "Error during parsing '" + filename + "' : " + ex.getMessage() );
337       ex.printStackTrace();
338       }
339   }
340 
341 }