1 /* 2 * $Id: DefinitionsUtil.java 471754 2006-11-06 14:55:09Z husted $ 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 package org.apache.struts.tiles; 23 24 import java.lang.reflect.InvocationTargetException; 25 import java.util.Enumeration; 26 import java.util.HashMap; 27 import java.util.Map; 28 29 import javax.servlet.ServletConfig; 30 import javax.servlet.ServletContext; 31 import javax.servlet.ServletRequest; 32 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 import org.apache.struts.tiles.taglib.ComponentConstants; 36 37 /** 38 * Utilities class for definitions factory. 39 * Also define userDebugLevel property (TODO to be moved from this class ?). 40 * @deprecated Use {@link TilesUtil#createDefinitionsFactory(ServletContext, DefinitionsFactoryConfig)} 41 */ 42 public class DefinitionsUtil extends TilesUtil implements ComponentConstants { 43 44 /** 45 * Commons Logging instance. 46 */ 47 protected static Log log = LogFactory.getLog(DefinitionsUtil.class); 48 49 /** 50 * Global user defined debug level. 51 * @deprecated This will be removed in a release after Struts 1.2. 52 */ 53 public static int userDebugLevel = 0; 54 55 /** 56 * User Debug level. 57 * @deprecated This will be removed in a release after Struts 1.2. 58 */ 59 public static final int NO_DEBUG = 0; 60 61 /** 62 * Name of init property carrying debug level. 63 */ 64 public static final String DEFINITIONS_CONFIG_USER_DEBUG_LEVEL = 65 "definitions-debug"; 66 67 /** 68 * Name of init property carrying factory class name. 69 */ 70 public static final String DEFINITIONS_FACTORY_CLASSNAME = 71 "definitions-factory-class"; 72 73 /** 74 * Constant name used to store factory in context. 75 */ 76 public static final String DEFINITIONS_FACTORY = 77 "org.apache.struts.tiles.DEFINITIONS_FACTORY"; 78 79 /** 80 * Constant name used to store definition in jsp context. 81 * Used to pass definition from a Struts action to servlet forward. 82 */ 83 public static final String ACTION_DEFINITION = 84 "org.apache.struts.tiles.ACTION_DEFINITION"; 85 86 /** 87 * Create Definition factory. 88 * If a factory class name is provided, a factory of this class is created. Otherwise, 89 * default factory is created. 90 * @param classname Class name of the factory to create. 91 * @param servletContext Servlet Context passed to newly created factory. 92 * @param properties Map of name/property used to initialize factory configuration object. 93 * @return newly created factory. 94 * @throws DefinitionsFactoryException If an error occur while initializing factory 95 * @deprecated Use createDefinitionsFactory(ServletContext servletContext, ServletConfig servletConfig) 96 */ 97 public static DefinitionsFactory createDefinitionsFactory( 98 ServletContext servletContext, 99 Map properties, 100 String classname) 101 throws DefinitionsFactoryException { 102 103 // Create config object 104 DefinitionsFactoryConfig factoryConfig = new DefinitionsFactoryConfig(); 105 // populate it from map. 106 try { 107 factoryConfig.populate(properties); 108 109 } catch (Exception ex) { 110 throw new DefinitionsFactoryException( 111 "Error - createDefinitionsFactory : Can't populate config object from properties map", 112 ex); 113 } 114 115 // Add classname 116 if (classname != null) 117 factoryConfig.setFactoryClassname(classname); 118 119 // Create factory using config object 120 return createDefinitionsFactory(servletContext, factoryConfig); 121 } 122 123 /** 124 * Create default Definition factory. 125 * @param servletContext Servlet Context passed to newly created factory. 126 * @param properties Map of name/property used to initialize factory configuration object. 127 * @return newly created factory of type ConfigurableDefinitionsFactory. 128 * @throws DefinitionsFactoryException If an error occur while initializing factory 129 */ 130 public static DefinitionsFactory createDefinitionsFactory( 131 ServletContext servletContext, 132 Map properties) 133 throws DefinitionsFactoryException { 134 135 return createDefinitionsFactory(servletContext, properties, null); 136 } 137 138 /** 139 * Create Definition factory. 140 * Create configuration object from servlet web.xml file, then create 141 * ConfigurableDefinitionsFactory and initialized it with object. 142 * <p> 143 * Convenience method. Calls createDefinitionsFactory(ServletContext servletContext, DefinitionsFactoryConfig factoryConfig) 144 * 145 * @param servletContext Servlet Context passed to newly created factory. 146 * @param servletConfig Servlet config containing parameters to be passed to factory configuration object. 147 * @return newly created factory of type ConfigurableDefinitionsFactory. 148 * @throws DefinitionsFactoryException If an error occur while initializing factory 149 */ 150 public static DefinitionsFactory createDefinitionsFactory( 151 ServletContext servletContext, 152 ServletConfig servletConfig) 153 throws DefinitionsFactoryException { 154 155 DefinitionsFactoryConfig factoryConfig = readFactoryConfig(servletConfig); 156 157 return createDefinitionsFactory(servletContext, factoryConfig); 158 } 159 160 /** 161 * Create Definition factory. 162 * Create configuration object from servlet web.xml file, then create 163 * ConfigurableDefinitionsFactory and initialized it with object. 164 * <p> 165 * If checkIfExist is true, start by checking if factory already exist. If yes, 166 * return it. If no, create a new one. 167 * <p> 168 * If checkIfExist is false, factory is always created. 169 * <p> 170 * Convenience method. Calls createDefinitionsFactory(ServletContext servletContext, DefinitionsFactoryConfig factoryConfig) 171 * 172 * @param servletContext Servlet Context passed to newly created factory. 173 * @param servletConfig Servlet config containing parameters to be passed to factory configuration object. 174 * @param checkIfExist Check if factory already exist. If true and factory exist, return it. 175 * If true and factory doesn't exist, create it. If false, create it in all cases. 176 * @return newly created factory of type ConfigurableDefinitionsFactory. 177 * @throws DefinitionsFactoryException If an error occur while initializing factory 178 */ 179 public static DefinitionsFactory createDefinitionsFactory( 180 ServletContext servletContext, 181 ServletConfig servletConfig, 182 boolean checkIfExist) 183 throws DefinitionsFactoryException { 184 185 if (checkIfExist) { 186 // Check if already exist in context 187 DefinitionsFactory factory = getDefinitionsFactory(servletContext); 188 if (factory != null) 189 return factory; 190 } 191 192 return createDefinitionsFactory(servletContext, servletConfig); 193 } 194 195 /** 196 * Get definition factory from appropriate servlet context. 197 * @return Definitions factory or null if not found. 198 * @deprecated Use {@link TilesUtil#getDefinitionsFactory(ServletRequest, ServletContext)} 199 * @since 20020708 200 */ 201 public static DefinitionsFactory getDefinitionsFactory(ServletContext servletContext) { 202 return (DefinitionsFactory) servletContext.getAttribute(DEFINITIONS_FACTORY); 203 } 204 205 /** 206 * Get Definition stored in jsp context by an action. 207 * @return ComponentDefinition or null if not found. 208 */ 209 public static ComponentDefinition getActionDefinition(ServletRequest request) { 210 return (ComponentDefinition) request.getAttribute(ACTION_DEFINITION); 211 } 212 213 /** 214 * Store definition in jsp context. 215 * Mainly used by Struts to pass a definition defined in an Action to the forward. 216 */ 217 public static void setActionDefinition( 218 ServletRequest request, 219 ComponentDefinition definition) { 220 221 request.setAttribute(ACTION_DEFINITION, definition); 222 } 223 224 /** 225 * Remove Definition stored in jsp context. 226 * Mainly used by Struts to pass a definition defined in an Action to the forward. 227 */ 228 public static void removeActionDefinition( 229 ServletRequest request, 230 ComponentDefinition definition) { 231 232 request.removeAttribute(ACTION_DEFINITION); 233 } 234 235 /** 236 * Populate Definition Factory Config from web.xml properties. 237 * @param factoryConfig Definition Factory Config to populate. 238 * @param servletConfig Current servlet config containing web.xml properties. 239 * @exception IllegalAccessException if the caller does not have 240 * access to the property accessor method 241 * @exception java.lang.reflect.InvocationTargetException if the property accessor method 242 * throws an exception 243 * @see org.apache.commons.beanutils.BeanUtils 244 * @since tiles 20020708 245 */ 246 public static void populateDefinitionsFactoryConfig( 247 DefinitionsFactoryConfig factoryConfig, 248 ServletConfig servletConfig) 249 throws IllegalAccessException, InvocationTargetException { 250 251 Map properties = new DefinitionsUtil.ServletPropertiesMap(servletConfig); 252 factoryConfig.populate(properties); 253 } 254 255 /** 256 * Create FactoryConfig and initialize it from web.xml. 257 * 258 * @param servletConfig ServletConfig for the module with which 259 * this plug in is associated 260 * @exception DefinitionsFactoryException if this <code>PlugIn</code> cannot 261 * be successfully initialized 262 */ 263 protected static DefinitionsFactoryConfig readFactoryConfig(ServletConfig servletConfig) 264 throws DefinitionsFactoryException { 265 266 // Create tiles definitions config object 267 DefinitionsFactoryConfig factoryConfig = new DefinitionsFactoryConfig(); 268 269 // Get init parameters from web.xml files 270 try { 271 DefinitionsUtil.populateDefinitionsFactoryConfig( 272 factoryConfig, 273 servletConfig); 274 275 } catch (Exception ex) { 276 ex.printStackTrace(); 277 throw new DefinitionsFactoryException( 278 "Can't populate DefinitionsFactoryConfig class from 'web.xml'.", 279 ex); 280 } 281 282 return factoryConfig; 283 } 284 285 /** 286 * Inner class. 287 * Wrapper for ServletContext init parameters. 288 * Object of this class is an hashmap containing parameters and values 289 * defined in the servlet config file (web.xml). 290 */ 291 static class ServletPropertiesMap extends HashMap { 292 /** 293 * Constructor. 294 */ 295 ServletPropertiesMap(ServletConfig config) { 296 // This implementation is very simple. 297 // It is possible to avoid creation of a new structure, but this need 298 // imply writing all Map interface. 299 Enumeration e = config.getInitParameterNames(); 300 while (e.hasMoreElements()) { 301 String key = (String) e.nextElement(); 302 put(key, config.getInitParameter(key)); 303 } 304 } 305 } // end inner class 306 307 }