View Javadoc

1   package org.apache.velocity.tools.config;
2   
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  import org.apache.commons.digester.Digester;
23  import org.apache.commons.digester.Rule;
24  import org.apache.commons.digester.RuleSetBase;
25  import org.xml.sax.Attributes;
26  
27  /**
28   * <p>This provides set of {@link Rule}s used by 
29   * Commons-{@link Digester} to process configuration info
30   * formatted as XML.  This is the default RuleSet used by
31   * {@link XmlFactoryConfiguration}.</p>
32   * <p>Here is a short example XML:
33   * <pre><code>
34   * &lt;tools&gt; 
35   *     &lt;data type="number" key="version" value="1.1"/&gt;
36   *     &lt;data key="isConvertedProp" value="false" class="java.lang.Boolean" converter="org.apache.commons.beanutils.converters.BooleanConverter"/&gt;
37   *     &lt;data type="boolean" key="isKnownType" value="true"/&gt;
38   *     &lt;data key="isAutoType" value="true"/&gt;
39   *     &lt;data key="foo" value="this is foo."/&gt;
40   *     &lt;data key="bar"&gt;this is bar.&lt;/data&gt;
41   *     &lt;toolbox scope="request" xhtml="true"&gt;
42   *         &lt;tool key="toytool" class="ToyTool" restrictTo="index.vm"/&gt;
43   *     &lt;/toolbox&gt;
44   *     &lt;toolbox scope="session"&gt;
45   *         &lt;property name="createSession" value="true" type="boolean"/&gt;
46   *         &lt;tool key="map" class="java.util.HashMap"/&gt;
47   *     &lt;/toolbox&gt;
48   *     &lt;toolbox scope="application"&gt;
49   *         &lt;tool class="org.apache.velocity.tools.generic.DateTool"/&gt;
50   *     &lt;/toolbox&gt;
51   * &lt;/tools&gt;
52   * </code></pre></p>
53   *
54   * @author Nathan Bubna
55   * @version $Id: XmlConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $
56   */
57  public class XmlFactoryConfigurationRuleSet extends RuleSetBase
58  {
59      protected Class toolboxConfigurationClass = ToolboxConfiguration.class;
60      protected Class toolConfigurationClass = ToolConfiguration.class;
61      protected Class dataClass = Data.class;
62      protected Class propertyClass = Property.class;
63  
64      public void setToolboxConfigurationClass(Class clazz)
65      {
66          this.toolboxConfigurationClass = clazz;
67      }
68  
69      public void setToolConfigurationClass(Class clazz)
70      {
71          this.toolConfigurationClass = clazz;
72      }
73  
74      public void setDataClass(Class clazz)
75      {
76          this.dataClass = clazz;
77      }
78  
79      public void setPropertyClass(Class clazz)
80      {
81          this.propertyClass = clazz;
82      }
83  
84      /**
85       * <p>Add the set of Rule instances defined in this RuleSet to the
86       * specified <code>Digester</code> instance, associating them with
87       * our namespace URI (if any).  This method should only be called
88       * by a Digester instance.  These rules assume that an instance of
89       * <code>org.apache.velocity.tools.view.ToolboxManager</code> is pushed
90       * onto the evaluation stack before parsing begins.</p>
91       *
92       * @param digester Digester instance to which the new Rule instances
93       *        should be added.
94       */
95      public void addRuleInstances(Digester digester)
96      {
97          // create the config objects
98          digester.addObjectCreate("tools/property", propertyClass);
99          digester.addObjectCreate("tools/*/property", propertyClass);
100         digester.addObjectCreate("tools/data", dataClass);
101         digester.addObjectCreate("tools/toolbox", toolboxConfigurationClass);
102         digester.addObjectCreate("tools/toolbox/tool", toolConfigurationClass);
103 
104         // to apply matching attributes to specific setters of config objects
105         digester.addSetProperties("tools/property");
106         digester.addSetProperties("tools/*/property");
107         digester.addSetProperties("tools");
108         digester.addSetProperties("tools/data");
109         digester.addSetProperties("tools/toolbox");
110         digester.addSetProperties("tools/toolbox/tool");
111 
112         // to add all attributes to config via setProperty(name,value)
113         digester.addRule("tools", new PropertyAttributeRule());
114         digester.addRule("tools/toolbox", new PropertyAttributeRule());
115         digester.addRule("tools/toolbox/tool", new PropertyAttributeRule());
116 
117         // for config data & properties whose values are in the body of the tag
118         digester.addRule("tools/data", new DataValueInBodyRule());
119         digester.addRule("tools/*/property", new DataValueInBodyRule());
120 
121         // to finish a config and move on to the next
122         digester.addSetNext("tools/property", "addProperty");
123         digester.addSetNext("tools/*/property", "addProperty");
124         digester.addSetNext("tools/data", "addData");
125         digester.addSetNext("tools/toolbox", "addToolbox");
126         digester.addSetNext("tools/toolbox/tool", "addTool");
127     }
128 
129 
130     /****************************** Custom Rules *****************************/
131 
132     /**
133      * Rule for adding configuration properties
134      */
135     public static class DataValueInBodyRule extends Rule
136     {
137         public void body(String namespace, String element, String value)
138             throws Exception
139         {
140             Data data = (Data)digester.peek();
141             if (data.getValue() == null)
142             {
143                 data.setValue(value);
144             }
145         }
146     }
147 
148     public static class PropertyAttributeRule extends Rule
149     {
150         public void begin(String namespace, String element, Attributes attributes)
151             throws Exception
152         {
153             Configuration config = (Configuration)digester.peek();
154 
155             for (int i=0; i < attributes.getLength(); i++)
156             {
157                 String name = attributes.getLocalName(i);
158                 if ("".equals(name))
159                 {
160                     name = attributes.getQName(i);
161                 }
162 
163                 // don't treat "class" as a property
164                 if (!"class".equals(name))
165                 {
166                     String value = attributes.getValue(i);
167                     config.setProperty(name, value);
168                 }
169             }
170         }
171     }
172 
173 }