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