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 java.io.InputStream;
23  import java.io.IOException;
24  import java.util.Iterator;
25  import org.apache.commons.beanutils.BeanUtils;
26  import org.apache.commons.collections.ExtendedProperties;
27  
28  /**
29   * <p> This reads in configuration info formatted as a property
30   * file using {@link ExtendedProperties} from Commons-Collections.</p>
31   * <p>Example usage:
32   * <pre>
33   * FactoryConfiguration cfg = new PropertiesFactoryConfiguration();
34   * cfg.read("my.properties");
35   * ToolboxFactory factory = cfg.createFactory();
36   * </pre></p>
37   * <p>This reads in a configuration such as:
38   * <pre>
39   * tools.toolbox = request,application
40   * tools.property.locale = en_us
41   * tools.property.locale.class = java.util.Locale
42   * tools.property.locale.converter = org.apache.velocity.tools.config.LocaleConverter
43   * tools.request.property.xhtml = true
44   * tools.request.render = org.apache.velocity.tools.view.ViewRenderTool
45   * tools.request.render.parseDepth = 5
46   * tools.request.search = com.foo.tools.MySearchTool
47   * tools.request.search.itemsPerPage = 10
48   * tools.application.math = org.apache.velocity.tools.generic.MathTool
49   * tools.data.foo = bar
50   * tools.data.foo.class = java.lang.String
51   * tools.data.foo.converter = org.apache.commons.beanutils.converter.StringConverter
52   * tools.data.version = 1.0
53   * tools.data.version.type = number
54   * tools.data.debug = false
55   * tools.data.debug.type = boolean
56   * </pre>
57   * <strong>NOTE</strong>: "property", "data", and "toolbox" are
58   * reserved words do not use them as tool keys or toolbox scopes.</p>
59   *
60   * @author Nathan Bubna
61   * @version $Id: PropertiesFactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $
62   */
63  public class PropertiesFactoryConfiguration extends FileFactoryConfiguration
64  {
65      public PropertiesFactoryConfiguration()
66      {
67          this("");
68      }
69  
70      /**
71       * Creates an instance using the specified string
72       * as an identifier to distinguish this instance when debugging.
73       *
74       * @param id the name of the "source" of this instance
75       * @see FactoryConfiguration#setSource(String)
76       */
77      public PropertiesFactoryConfiguration(String id)
78      {
79          super(PropertiesFactoryConfiguration.class, id);
80      }
81  
82      /**
83       * <p>Reads an properties file from an {@link InputStream}
84       * and uses it to configure this {@link FactoryConfiguration}.</p>
85       * 
86       * @param input the InputStream to read from
87       */
88      public void read(InputStream input) throws IOException
89      {
90          ExtendedProperties props = new ExtendedProperties();
91          props.load(input);
92  
93          // all factory settings should be prefixed with "tools"
94          read(props.subset("tools"));
95      }
96  
97      public void read(ExtendedProperties factory)
98      {
99          // get the global properties
100         readProperties(factory, this);
101 
102         // get the toolboxes
103         readToolboxes(factory);
104 
105         // get the data
106         readData(factory.subset("data"));
107     }
108 
109 
110     protected void readProperties(ExtendedProperties configProps,
111                                   Configuration config)
112     {
113         ExtendedProperties properties = configProps.subset("property");
114         if (properties != null)
115         {
116             for (Iterator i = properties.getKeys(); i.hasNext(); )
117             {
118                 String name = (String)i.next();
119                 String value = properties.getString(name);
120 
121                 ExtendedProperties propProps = properties.subset(name);
122                 if (propProps.size() == 1)
123                 {
124                     // then set this as a 'simple' property
125                     config.setProperty(name, value);
126                 }
127                 else
128                 {
129                     // add it as a convertable property
130                     Property property = new Property();
131                     property.setName(name);
132                     property.setValue(value);
133 
134                     // set the type/converter properties
135                     setProperties(propProps, property);
136                 }
137             }
138         }
139     }
140 
141     protected void readToolboxes(ExtendedProperties factory)
142     {
143         String[] scopes = factory.getStringArray("toolbox");
144         for (String scope : scopes)
145         {
146             ToolboxConfiguration toolbox = new ToolboxConfiguration();
147             toolbox.setScope(scope);
148             addToolbox(toolbox);
149 
150             ExtendedProperties toolboxProps = factory.subset(scope);
151             readTools(toolboxProps, toolbox);
152             readProperties(toolboxProps, toolbox);
153         }
154     }
155 
156     protected void readTools(ExtendedProperties tools,
157                              ToolboxConfiguration toolbox)
158     {
159         for (Iterator i = tools.getKeys(); i.hasNext(); )
160         {
161             String key = (String)i.next();
162             // if it contains a period, it can't be a context key; 
163             // it must be a tool property. ignore it for now.
164             if (key.indexOf('.') >= 0)
165             {
166                 continue;
167             }
168 
169             String classname = tools.getString(key);
170             ToolConfiguration tool = new ToolConfiguration();
171             tool.setClassname(classname);
172             tool.setKey(key);
173             toolbox.addTool(tool);
174 
175             // get tool properties prefixed by 'property'
176             ExtendedProperties toolProps = tools.subset(key);
177             readProperties(toolProps, tool);
178 
179             // ok, get tool properties that aren't prefixed by 'property'
180             for (Iterator j = toolProps.getKeys(); j.hasNext(); )
181             {
182                 String name = (String)j.next();
183                 if (!name.equals(tool.getKey()))
184                 {
185                     tool.setProperty(name, toolProps.getString(name));
186                 }
187             }
188 
189             // get special props explicitly
190             String restrictTo = toolProps.getString("restrictTo");
191             tool.setRestrictTo(restrictTo);
192         }
193     }
194 
195     protected void readData(ExtendedProperties dataset)
196     {
197         if (dataset != null)
198         {
199             for (Iterator i = dataset.getKeys(); i.hasNext(); )
200             {
201                 String key = (String)i.next();
202                 // if it contains a period, it can't be a context key; 
203                 // it must be a data property. ignore it for now.
204                 if (key.indexOf('.') >= 0)
205                 {
206                     continue;
207                 }
208 
209                 Data data = new Data();
210                 data.setKey(key);
211                 data.setValue(dataset.getString(key));
212 
213                 // get/set the type/converter properties
214                 ExtendedProperties props = dataset.subset(key);
215                 setProperties(props, data);
216 
217                 addData(data);
218             }
219         }
220     }
221 
222     protected void setProperties(ExtendedProperties props, Data data)
223     {
224         // let's just set/convert anything we can
225         // this could be simplified to just check for type/class/converter
226         try
227         {
228             BeanUtils.populate(data, props);
229         }
230         catch (Exception e)
231         {
232             throw new RuntimeException(e);
233         }
234     }
235 
236 }