Project Tiles has retired. For details please refer to its Attic page.
CompatibilityDigesterDefinitionsReader xref
View Javadoc

1   /*
2    * $Id: CompatibilityDigesterDefinitionsReader.java 947472 2010-05-23 19:32:49Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.tiles.compat.definition.digester;
23  
24  import org.apache.commons.digester.Digester;
25  import org.apache.commons.digester.Rule;
26  import org.apache.tiles.Attribute;
27  import org.apache.tiles.beans.SimpleMenuItem;
28  import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
29  import org.xml.sax.Attributes;
30  
31  /**
32   * Digester reader that can read Tiles 1.1, 1.2, 1.3, 1.4 and 2.0 files.
33   *
34   * @version $Rev: 947472 $ $Date: 2010-05-24 05:32:49 +1000 (Mon, 24 May 2010) $
35   * @since 2.1.0
36   */
37  public class CompatibilityDigesterDefinitionsReader extends
38          DigesterDefinitionsReader {
39  
40      /**
41       * Intercepts a <item> tag.
42       */
43      private static final String ADD_WILDCARD = "*/item";
44  
45      /**
46       * Intercepts a <bean> tag.
47       */
48      private static final String BEAN_TAG = "*/bean";
49  
50      /**
51       * The set of public identifiers, and corresponding resource names for the
52       * versions of the configuration file DTDs we know about. There <strong>MUST</strong>
53       * be an even number of Strings in this list!
54       *
55       * @since 2.1.0
56       */
57      protected String[] registrations;
58  
59      /** {@inheritDoc} */
60      @Override
61      protected void initSyntax(Digester digester) {
62          super.initSyntax(digester);
63          initDigesterForComponentsDefinitionsSyntax(digester);
64          initDigesterForInstancesSyntax(digester);
65          initDigesterForTilesDefinitionsSyntax(digester);
66          initDigesterForBeans(digester);
67      }
68  
69      /**
70       * Init digester for components syntax. This is an old set of rules, left
71       * for backward compatibility.
72       *
73       * @param digester Digester instance to use.
74       */
75      private void initDigesterForComponentsDefinitionsSyntax(Digester digester) {
76          // Common constants
77          String definitionTag = "component-definitions/definition";
78  
79          String putTag = definitionTag + "/put";
80  
81          String listTag = definitionTag + "/putList";
82  
83          String addListElementTag = listTag + "/add";
84  
85          // syntax rules
86          digester.addObjectCreate(definitionTag, DEFINITION_HANDLER_CLASS);
87          digester.addRule(definitionTag, new FillDefinitionRule());
88          digester.addSetNext(definitionTag, "addDefinition",
89                  DEFINITION_HANDLER_CLASS);
90          // put / putAttribute rules
91          digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
92          digester.addRule(putTag, new FillAttributeRule());
93          digester.addRule(putTag, new PutAttributeRule());
94          // list rules
95          digester.addObjectCreate(listTag, LIST_HANDLER_CLASS);
96          digester.addSetProperties(listTag);
97          digester.addRule(listTag, new PutAttributeRule());
98          // list elements rules
99          // We use Attribute class to avoid rewriting a new class.
100         // Name part can't be used in listElement attribute.
101         digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
102         digester.addRule(addListElementTag, new FillAttributeRule());
103         digester.addSetNext(addListElementTag, "add",
104                 PUT_ATTRIBUTE_HANDLER_CLASS);
105     }
106 
107     /**
108      * Init digester for Tiles syntax. Same as components, but with first
109      * element = tiles-definitions
110      *
111      * @param digester Digester instance to use.
112      */
113     private void initDigesterForTilesDefinitionsSyntax(Digester digester) {
114         // Common constants
115         String definitionTag = "tiles-definitions/definition";
116 
117         String putTag = definitionTag + "/put";
118 
119         // String LIST_TAG = DEFINITION_TAG + "/putList";
120         // List tag value
121         String listTag = "putList";
122         String definitionListTag = definitionTag + "/" + listTag;
123         // Tag value for adding an element in a list
124         String addListElementTag = "*/" + listTag + "/add";
125 
126         // put / putAttribute rules
127         // Rules for a same pattern are called in order, but rule.end() are
128         // called
129         // in reverse order.
130         // SetNext and CallMethod use rule.end() method. So, placing SetNext in
131         // first position ensure it will be called last (sic).
132         digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
133         digester.addRule(putTag, new FillAttributeRule());
134         digester.addRule(putTag, new PutAttributeRule());
135         // Definition level list rules
136         // This is rules for lists nested in a definition
137         digester.addObjectCreate(definitionListTag, LIST_HANDLER_CLASS);
138         digester.addSetProperties(definitionListTag);
139         digester.addRule(definitionListTag, new PutAttributeRule());
140         // list elements rules
141         // We use Attribute class to avoid rewriting a new class.
142         // Name part can't be used in listElement attribute.
143         digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
144         digester.addRule(addListElementTag, new FillAttributeRule());
145         digester.addSetNext(addListElementTag, "add",
146                 PUT_ATTRIBUTE_HANDLER_CLASS);
147 
148         // nested list elements rules
149         // Create a list handler, and add it to parent list
150         String nestedList = "*/" + listTag + "/" + listTag;
151         digester.addObjectCreate(nestedList, LIST_HANDLER_CLASS);
152         digester.addSetProperties(nestedList);
153         digester.addSetNext(nestedList, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
154     }
155 
156     /**
157      * Init digester in order to parse instances definition file syntax.
158      * Instances is an old name for "definition". This method is left for
159      * backwards compatibility.
160      *
161      * @param digester Digester instance to use.
162      */
163     private void initDigesterForInstancesSyntax(Digester digester) {
164         // Build a digester to process our configuration resource
165         String instanceTag = "component-instances/instance";
166 
167         String putTag = instanceTag + "/put";
168         String putAttributeTag = instanceTag + "/putAttribute";
169 
170         String listTag = instanceTag + "/putList";
171 
172         String addListElementTag = listTag + "/add";
173 
174         // component instance rules
175         digester.addObjectCreate(instanceTag, DEFINITION_HANDLER_CLASS);
176         digester.addRule(instanceTag, new FillDefinitionRule());
177         digester
178                 .addSetNext(instanceTag, "addDefinition", DEFINITION_HANDLER_CLASS);
179         // put / putAttribute rules
180         digester.addObjectCreate(putAttributeTag, PUT_ATTRIBUTE_HANDLER_CLASS);
181         digester.addRule(putTag, new FillAttributeRule());
182         digester.addRule(putTag, new PutAttributeRule());
183         // put / putAttribute rules
184         digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
185         digester.addSetProperties(putTag);
186         digester.addRule(putTag, new PutAttributeRule());
187         // list rules
188         digester.addObjectCreate(listTag, PUT_ATTRIBUTE_HANDLER_CLASS);
189         digester.addSetProperties(listTag);
190         digester.addRule(listTag, new PutAttributeRule());
191         // list elements rules
192         // We use Attribute class to avoid rewriting a new class.
193         // Name part can't be used in listElement attribute.
194         digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
195         digester.addRule(addListElementTag, new FillAttributeRule());
196         digester.addSetNext(addListElementTag, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
197     }
198 
199     /**
200      * Init digester for Tiles syntax with first element = tiles-definitions.
201      *
202      * @param digester Digester instance to use.
203      */
204     private void initDigesterForBeans(Digester digester) {
205 
206         // item elements rules
207         // We use Attribute class to avoid rewriting a new class.
208         // Name part can't be used in listElement attribute.
209         //String ADD_WILDCARD = LIST_TAG + "/addItem";
210         // non String ADD_WILDCARD = LIST_TAG + "/addx*";
211         String menuItemDefaultClass = SimpleMenuItem.class.getName();
212         digester.addObjectCreate(ADD_WILDCARD, menuItemDefaultClass, "classtype");
213         digester.addSetProperties(ADD_WILDCARD);
214         digester.addRule(ADD_WILDCARD, new SetValueToAttributeRule());
215         digester.addSetNext(ADD_WILDCARD, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
216 
217         // bean elements rules
218         String beanDefaultClass = SimpleMenuItem.class.getName();
219         digester.addObjectCreate(BEAN_TAG, beanDefaultClass, "classtype");
220         digester.addSetProperties(BEAN_TAG);
221         digester.addRule(BEAN_TAG, new SetValueToAttributeRule());
222         digester.addSetNext(BEAN_TAG, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
223 
224         // Set properties to surrounding element
225         digester.addSetProperty(BEAN_TAG + "/set-property", "property", "value");
226     }
227 
228     /** {@inheritDoc} */
229     @Override
230     protected String[] getRegistrations() {
231         if (registrations == null) {
232             registrations = new String[] {
233                 "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN",
234                 "/org/apache/tiles/resources/tiles-config_3_0.dtd",
235                 "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN",
236                 "/org/apache/tiles/compat/resources/tiles-config_2_0.dtd",
237                 "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN",
238                 "/org/apache/tiles/compat/resources/tiles-config_2_1.dtd",
239                 "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN",
240                 "/org/apache/tiles/compat/resources/tiles-config_1_1.dtd",
241                 "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN",
242                 "/org/apache/tiles/compat/resources/tiles-config_1_3.dtd",
243                 "-//Apache Software Foundation//DTD Tiles Configuration 1.4//EN",
244                 "/org/apache/tiles/compat/resources/tiles-config_1_4.dtd"};
245         }
246         return registrations;
247     }
248 
249     /**
250      * Digester rule to manage assignment of an object as an attribute value.
251      *
252      * @since 3.0.0
253      */
254     public static class SetValueToAttributeRule extends Rule {
255 
256         /** {@inheritDoc} */
257         @Override
258         public void begin(String namespace, String name, Attributes attributes) {
259             Object obj = digester.pop();
260             Attribute attribute = new Attribute(obj);
261             digester.push(attribute);
262         }
263     }
264 }