View Javadoc

1   package org.apache.velocity.tools.view;
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.File;
23  import java.io.FileInputStream;
24  import java.io.InputStream;
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Map;
30  
31  import org.apache.commons.digester.Digester;
32  import org.apache.commons.digester.RuleSet;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  
36  
37  /**
38   * A ToolboxManager for loading a toolbox from xml.
39   *
40   * <p>A toolbox manager is responsible for automatically filling the Velocity
41   * context with a set of view tools. This class provides the following
42   * features:</p>
43   * <ul>
44   *   <li>configurable through an XML-based configuration file</li>
45   *   <li>assembles a set of view tools (the toolbox) on request</li>
46   *   <li>supports any class with a public constructor without parameters
47   *     to be used as a view tool</li>
48   *   <li>supports adding primitive data values to the context(String,Number,Boolean)</li>
49   * </ul>
50   *
51   *
52   * <p><strong>Configuration</strong></p>
53   * <p>The toolbox manager is configured through an XML-based configuration
54   * file. The configuration file is passed to the {@link #load(java.io.InputStream input)}
55   * method. The format is shown in the following example:</p>
56   * <pre>
57   * &lt;?xml version="1.0"?&gt;
58   * &lt;toolbox&gt;
59   *   &lt;tool&gt;
60   *      &lt;key&gt;date&lt;/key&gt;
61   *      &lt;class&gt;org.apache.velocity.tools.generic.DateTool&lt;/class&gt;
62   *   &lt;/tool&gt;
63   *   &lt;data type="Number"&gt;
64   *      &lt;key&gt;luckynumber&lt;/key&gt;
65   *      &lt;value&gt;1.37&lt;/value&gt;
66   *   &lt;/data&gt;
67   *   &lt;data type="String"&gt;
68   *      &lt;key&gt;greeting&lt;/key&gt;
69   *      &lt;value&gt;Hello World!&lt;/value&gt;
70   *   &lt;/data&gt;
71   * &lt;/toolbox&gt;
72   * </pre>
73   *
74   *
75   * @author Nathan Bubna
76   * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
77   * @author <a href="mailto:henning@schmiedehausen.org">Henning P. Schmiedehausen</a>
78   * @version $Id: XMLToolboxManager.java 651470 2008-04-25 00:47:52Z nbubna $
79   * @deprecated Use {@link org.apache.velocity.tools.config.XmlFactoryConfiguration}
80   */
81  @Deprecated
82  public class XMLToolboxManager implements ToolboxManager
83  {
84      protected static final Log LOG = LogFactory.getLog(XMLToolboxManager.class);
85  
86      private List toolinfo;
87      private Map data;
88  
89      private static RuleSet ruleSet = new ToolboxRuleSet();
90  
91  
92      /**
93       * Default constructor
94       */
95      public XMLToolboxManager()
96      {
97          toolinfo = new ArrayList();
98          data = new HashMap();
99  
100         LOG.warn("XMLToolboxManager has been deprecated. Please use "+
101                  "org.apache.velocity.tools.ToolboxFactory instead.");
102     }
103 
104 
105     // ------------------------------- ToolboxManager interface ------------
106 
107 
108     public void addTool(ToolInfo info)
109     {
110         if (validateToolInfo(info))
111         {
112             toolinfo.add(info);
113             if (LOG.isDebugEnabled())
114             {
115                 LOG.debug("Added "+info.getClassname()+" to the toolbox as "+info.getKey());
116             }
117         }
118     }
119 
120     public void addData(ToolInfo info)
121     {
122         if (validateToolInfo(info))
123         {
124             data.put(info.getKey(), info.getInstance(null));
125             if (LOG.isDebugEnabled())
126             {
127                 LOG.debug("Added '"+info.getInstance(null)+"' to the toolbox as "+info.getKey());
128             }
129         }
130     }
131 
132     /**
133      * Checks whether an object described by a ToolInfo passes
134      * some basic sanity checks.
135      *
136      * @param info A ToolInfo object
137      *
138      * @return true if the ToolInfo is valid
139      */
140     protected boolean validateToolInfo(ToolInfo info)
141     {
142         if (info == null)
143         {
144             LOG.error("ToolInfo is null!");
145             return false;
146         }
147         if (info.getKey() == null || info.getKey().length() == 0)
148         {
149             LOG.error("Tool has no key defined!");
150             return false;
151         }
152         if (info.getClassname() == null)
153         {
154             LOG.error("Tool " + info.getKey() + " has no Class definition!");
155             return false;
156         }
157         return true;
158     }
159 
160 
161     public Map getToolbox(Object initData)
162     {
163         Map toolbox = new HashMap(data);
164         Iterator i = toolinfo.iterator();
165         while(i.hasNext())
166         {
167             ToolInfo info = (ToolInfo)i.next();
168             toolbox.put(info.getKey(), info.getInstance(initData));
169         }
170         return toolbox;
171     }
172 
173 
174     // ------------------------------- toolbox loading methods ------------
175 
176     /**
177      * <p>Reads an XML document from the specified file path
178      * and sets up the toolbox from that. If the file does not
179      * exist, an {@link IllegalArgumentException} will be thrown.</p>
180      *
181      * @param path the path to the file to be read from
182      * @since VelocityTools 1.3
183      */
184     public void load(String path) throws Exception
185     {
186         if (path == null)
187         {
188             throw new IllegalArgumentException("Path value cannot be null");
189         }
190 
191         File file = new File(path);
192         if (!file.exists())
193         {
194             throw new IllegalArgumentException("Could not find toolbox config file at: "+path);
195         }
196 
197         // ok, load the file
198         load(new FileInputStream(file));
199     }
200 
201     /**
202      * <p>Reads an XML document from an {@link InputStream}
203      * and sets up the toolbox from that.</p>
204      *
205      * @param input the InputStream to read from
206      */
207     public void load(InputStream input) throws Exception
208     {
209         LOG.trace("Loading toolbox...");
210 
211         Digester digester = new Digester();
212         digester.setValidating(false);
213         digester.setUseContextClassLoader(true);
214         digester.push(this);
215         digester.addRuleSet(getRuleSet());
216         digester.parse(input);
217 
218         LOG.trace("Toolbox loaded.");
219     }
220 
221 
222     /**
223      * <p>Retrieves the rule set Digester should use to parse and load
224      * the toolbox for this manager.</p>
225      *
226      * <p>The DTD corresponding to the default ToolboxRuleSet is:
227      * <pre>
228      *  &lt;?xml version="1.0"?&gt;
229      *  &lt;!ELEMENT toolbox (tool*,data*,#PCDATA)&gt;
230      *  &lt;!ELEMENT tool    (key,class,parameter*,#PCDATA)&gt;
231      *  &lt;!ELEMENT data    (key,value)&gt;
232      *      &lt;!ATTLIST data type (string|number|boolean) "string"&gt;
233      *  &lt;!ELEMENT key     (#CDATA)&gt;
234      *  &lt;!ELEMENT class   (#CDATA)&gt;
235      *  &lt;!ELEMENT parameter (EMPTY)&gt;
236      *      &lt;!ATTLIST parameter name CDATA #REQUIRED&gt;
237      *      &lt;!ATTLIST parameter value CDATA #REQUIRED&gt;
238      *  &lt;!ELEMENT value   (#CDATA)&gt;
239      * </pre></p>
240      *
241      * @since VelocityTools 1.1
242      */
243     protected RuleSet getRuleSet()
244     {
245         return ruleSet;
246     }
247 
248 }