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 * <?xml version="1.0"?> 58 * <toolbox> 59 * <tool> 60 * <key>date</key> 61 * <class>org.apache.velocity.tools.generic.DateTool</class> 62 * </tool> 63 * <data type="Number"> 64 * <key>luckynumber</key> 65 * <value>1.37</value> 66 * </data> 67 * <data type="String"> 68 * <key>greeting</key> 69 * <value>Hello World!</value> 70 * </data> 71 * </toolbox> 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 * <?xml version="1.0"?> 229 * <!ELEMENT toolbox (tool*,data*,#PCDATA)> 230 * <!ELEMENT tool (key,class,parameter*,#PCDATA)> 231 * <!ELEMENT data (key,value)> 232 * <!ATTLIST data type (string|number|boolean) "string"> 233 * <!ELEMENT key (#CDATA)> 234 * <!ELEMENT class (#CDATA)> 235 * <!ELEMENT parameter (EMPTY)> 236 * <!ATTLIST parameter name CDATA #REQUIRED> 237 * <!ATTLIST parameter value CDATA #REQUIRED> 238 * <!ELEMENT value (#CDATA)> 239 * </pre></p> 240 * 241 * @since VelocityTools 1.1 242 */ 243 protected RuleSet getRuleSet() 244 { 245 return ruleSet; 246 } 247 248 }