View Javadoc
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 }