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.util.List;
23  import org.apache.velocity.tools.ToolboxFactory;
24  
25  /**
26   * <p>{@link FactoryConfiguration} subclass that simplifies the process of
27   * configuring a {@link ToolboxFactory} in Java without the use of an
28   * xml or properties configuration file.  Below is an example:
29   *
30   * <pre><code>
31   * EasyFactoryConfiguration config = new EasyFactoryConfiguration();
32   * config.toolbox(Scope.REQUEST).property("locale", Locale.US)
33   *  .tool(DateTool.class)
34   *  .tool("myTool", MyTool.class);
35   * config.toolbox(Scope.APPLICATION)
36   *  .tool(NumberTool.class).property("locale", Locale.FR);
37   * ToolboxFactory factory = config.createFactory();
38   * </code></pre></p>
39   *
40   * <p>Doing the above without this class would require the following to
41   *    create an equivalent {@link FactoryConfiguration} in Java:
42   *
43   * <pre><code>
44   * FactoryConfiguration factoryConfig = new FactoryConfiguration();
45   * ToolboxConfiguration toolbox = new ToolboxConfiguration();
46   * toolbox.setScope(Scope.REQUEST);
47   * toolbox.setProperty("locale", Locale.US);
48   * ToolConfiguration tool = new ToolConfiguration();
49   * tool.setClassname(DateTool.class.getName());
50   * tool = new ToolConfiguration();
51   * tool.setKey("myTool");
52   * tool.setClassname(MyTool.class.getName());
53   * toolbox.addTool(tool);
54   * toolbox = new ToolboxConfiguration();
55   * toolbox.setScope(Scope.APPLICATION);
56   * tool = new ToolConfiguration();
57   * tool.setClassname(NumberTool.class.getName());
58   * tool.setProperty("locale", Locale.FR);
59   * toolbox.addTool(tool);
60   * factoryConfig.addToolbox(toolbox);
61   * ToolboxFactory factory = factoryConfig.createFactory();
62   * </code></pre></p>
63   *
64   * <p>Of course, you could directly configure a {@link ToolboxFactory}
65   *    with relatively little effort as well:
66   *
67   * <pre><code>
68   * ToolboxFactory factory = new ToolboxFactory();
69   * factory.putProperty(Scope.REQUEST, "locale", Locale.US);
70   * factory.addToolInfo(Scope.REQUEST, new ToolInfo("date", DateTool.class));
71   * factory.addToolInfo(Scope.REQUEST, new ToolInfo("render", ViewRenderTool.class));
72   * ToolInfo info = new ToolInfo("number", NumberTool.class);
73   * info.setProperty("locale", Locale.FR);
74   * factory.addToolInfo(Scope.APPLICATION, info);
75   * </code></pre>
76   *
77   * But this is not reusable.  Why does that matter?  Well, it doesn't matter
78   * for application developers.  But, if another framework wishes to provide
79   * a common VelocityTools configuration for application developers, this may
80   * come in handy.  Or it may not.  In any case, it was mildly fun to write. :)
81   * </p>
82   *
83   * @author Nathan Bubna
84   * @version $Id: EasyFactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $
85   */
86  public class EasyFactoryConfiguration extends FactoryConfiguration
87  {
88      private boolean addedDefaults = false;
89      private EasyWrap<ToolboxConfiguration> toolbox;
90  
91      public EasyFactoryConfiguration()
92      {
93          this(false);
94      }
95  
96      /**
97       * @param includeDefaults Sets whether this instance should start with the
98       *        {@link ConfigurationUtils#getDefaultTools()} configuration or not.
99       */
100     public EasyFactoryConfiguration(boolean includeDefaults)
101     {
102         // just give the param name as source
103         this(includeDefaults, String.valueOf(includeDefaults));
104     }
105 
106     /**
107      * @param includeDefaults Sets whether this instance should start with the
108      *        {@link ConfigurationUtils#getDefaultTools()} configuration or not.
109      * @param source a string identify where this instance was created, or
110      *        something else useful to identify this instance during debugging
111      */
112     public EasyFactoryConfiguration(boolean includeDefaults, String source)
113     {
114         super(EasyFactoryConfiguration.class, source);
115 
116         if (includeDefaults)
117         {
118             addDefaultTools();
119             // now put the root source last, since the defaults were really first
120             // and nothing could have been added prior to them
121             List<String> sources = getSources();
122             String first = sources.remove(0);
123             sources.add(first);
124         }
125     }
126 
127     /**
128      * Adds the {@link ConfigurationUtils#getDefaultTools()} configuration to this
129      * the current configuration.
130      */
131     public EasyFactoryConfiguration addDefaultTools()
132     {
133         if (!addedDefaults)
134         {
135             addConfiguration(ConfigurationUtils.getDefaultTools());
136             addedDefaults = true;
137         }
138         return this;
139     }
140 
141     public EasyFactoryConfiguration autoLoad()
142     {
143         return autoLoad(true);
144     }
145 
146     public EasyFactoryConfiguration autoLoad(boolean includeDefaults)
147     {
148         addConfiguration(ConfigurationUtils.getAutoLoaded(includeDefaults));
149         addedDefaults = true;
150         return this;
151     }
152 
153     public EasyData data(String key, Object value)
154     {
155         Data datum = new Data();
156         datum.setKey(key);
157         datum.setValue(value);
158         addData(datum);
159         return new EasyData(datum, this);
160     }
161 
162     public EasyFactoryConfiguration data(String key, String type, Object value)
163     {
164         EasyData datum = data(key, value);
165         datum.type(type);
166         return this;
167     }
168 
169     protected EasyFactoryConfiguration data(String key, Data.Type type, Object value)
170     {
171         EasyData datum = data(key, value);
172         datum.type(type);
173         return this;
174     }
175 
176     public EasyFactoryConfiguration string(String key, Object value)
177     {
178         return data(key, Data.Type.STRING, value);
179     }
180 
181     public EasyFactoryConfiguration number(String key, Object value)
182     {
183         return data(key, Data.Type.NUMBER, value);
184     }
185 
186     public EasyFactoryConfiguration bool(String key, Object value)
187     {
188         return data(key, Data.Type.BOOLEAN, value);
189     }
190 
191     public EasyWrap<ToolboxConfiguration> toolbox(String scope)
192     {
193         ToolboxConfiguration toolbox = new ToolboxConfiguration();
194         toolbox.setScope(scope);
195         addToolbox(toolbox);
196         this.toolbox =
197             new EasyWrap<ToolboxConfiguration>(toolbox, this);
198         return this.toolbox;
199     }
200 
201     public EasyWrap<ToolConfiguration> tool(String classname)
202     {
203         return tool(null, classname);
204     }
205 
206     public EasyWrap<ToolConfiguration> tool(Class clazz)
207     {
208         return tool(null, clazz);
209     }
210 
211     public EasyWrap<ToolConfiguration> tool(String key, String classname)
212     {
213         if (toolbox == null)
214         {
215             toolbox(ToolboxFactory.DEFAULT_SCOPE);
216         }
217         return toolbox.tool(key, classname);
218     }
219 
220     public EasyWrap<ToolConfiguration> tool(String key, Class clazz)
221     {
222         return tool(key, clazz.getName());
223     }
224 
225     public EasyFactoryConfiguration property(String name, Object value)
226     {
227         setProperty(name, value);
228         return this;
229     }
230 
231 
232     public static class EasyData
233     {
234         private final Data datum;
235         private final Configuration parent;
236 
237         public EasyData(Data datum, Configuration parent)
238         {
239             this.datum = datum;
240             this.parent = parent;
241         }
242 
243         public Data getData()
244         {
245             return this.datum;
246         }
247 
248         public Configuration getParent()
249         {
250             return this.parent;
251         }
252 
253         public EasyData type(String type)
254         {
255             this.datum.setType(type);
256             return this;
257         }
258 
259         protected EasyData type(Data.Type type)
260         {
261             this.datum.setType(type);
262             return this;
263         }
264 
265         public EasyData target(Class clazz)
266         {
267             this.datum.setTargetClass(clazz);
268             return this;
269         }
270 
271         public EasyData classname(String classname)
272         {
273             this.datum.setClassname(classname);
274             return this;
275         }
276 
277         public EasyData converter(String converter)
278         {
279             this.datum.setConverter(converter);
280             return this;
281         }
282 
283         public EasyData converter(Class clazz)
284         {
285             this.datum.setConverter(clazz);
286             return this;
287         }
288     }
289 
290 
291     public class EasyWrap<C extends Configuration>
292     {
293         private final C config;
294         private final Configuration parent;
295 
296         public EasyWrap(C config, Configuration parent)
297         {
298             this.config = config;
299             this.parent = parent;
300         }
301 
302         public C getConfiguration()
303         {
304             return this.config;
305         }
306 
307         public Configuration getParent()
308         {
309             return this.parent;
310         }
311 
312         public EasyWrap<C> property(String name, Object value)
313         {
314             this.config.setProperty(name, value);
315             return this;
316         }
317 
318         public EasyWrap<C> restrictTo(String path)
319         {
320             if (this.config instanceof ToolConfiguration)
321             {
322                 ToolConfiguration tool = (ToolConfiguration)this.config;
323                 tool.setRestrictTo(path);
324                 return this;
325             }
326             else if (this.config instanceof ToolboxConfiguration)
327             {
328                 ToolboxConfiguration toolbox = (ToolboxConfiguration)this.config;
329                 for (ToolConfiguration tool : toolbox.getTools())
330                 {
331                     tool.setRestrictTo(path);
332                 }
333                 return this;
334             }
335             throw new IllegalStateException("Wrapping unknown "+Configuration.class.getName()+": "+getConfiguration());
336         }
337 
338         public EasyWrap addDefaultTools()
339         {
340             EasyFactoryConfiguration.this.addDefaultTools();
341             return this;
342         }
343 
344         public EasyWrap tool(Class clazz)
345         {
346             return tool(null, clazz);
347         }
348 
349         public EasyWrap tool(String classname)
350         {
351             return tool(null, classname);
352         }
353 
354         public EasyWrap tool(String key, Class clazz)
355         {
356             return tool(key, clazz.getName());
357         }
358 
359         public EasyWrap tool(String key, String classname)
360         {
361             ToolConfiguration tool = new ToolConfiguration();
362             if (key != null)
363             {
364                 tool.setKey(key);
365             }
366             tool.setClassname(classname);
367             if (this.config instanceof ToolConfiguration)
368             {
369                 ToolboxConfiguration toolbox = (ToolboxConfiguration)getParent();
370                 toolbox.addTool(tool);
371                 return new EasyWrap(tool, toolbox);
372             }
373             else if (this.config instanceof ToolboxConfiguration)
374             {
375                 ToolboxConfiguration toolbox = (ToolboxConfiguration)getConfiguration();
376                 toolbox.addTool(tool);
377                 return new EasyWrap(tool, toolbox);
378             }
379             throw new IllegalStateException("Wrapping unknown "+Configuration.class.getName()+": "+getConfiguration());
380         }
381     }
382 
383 }