1 package org.apache.turbine.services.rundata;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.lang.reflect.Method;
58 import java.util.HashMap;
59 import java.util.Iterator;
60 import javax.servlet.ServletConfig;
61 import javax.servlet.http.HttpServletRequest;
62 import javax.servlet.http.HttpServletResponse;
63 import org.apache.commons.configuration.Configuration;
64 import org.apache.turbine.services.InitializationException;
65 import org.apache.turbine.services.TurbineBaseService;
66 import org.apache.turbine.services.TurbineServices;
67 import org.apache.turbine.services.pool.PoolService;
68 import org.apache.turbine.util.CookieParser;
69 import org.apache.turbine.util.ParameterParser;
70 import org.apache.turbine.util.RunData;
71 import org.apache.turbine.util.ServerData;
72 import org.apache.turbine.util.TurbineException;
73
74 /***
75 * The RunData Service provides the implementations for RunData and
76 * related interfaces required by request processing. It supports
77 * different configurations of implementations, which can be selected
78 * by specifying a configuration key. It may use pooling, in which case
79 * the implementations should implement the Recyclable interface.
80 *
81 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
82 * @version $Id: TurbineRunDataService.java,v 1.4 2002/07/11 16:53:25 mpoeschl Exp $
83 */
84 public class TurbineRunDataService
85 extends TurbineBaseService
86 implements RunDataService
87 {
88 /***
89 * The property for the implemention of RunData.
90 */
91 public static final String RUN_DATA = "run.data";
92
93 /***
94 * The property for the implemention of ParameterParser.
95 */
96 public static final String PARAMETER_PARSER = "parameter.parser";
97
98 /***
99 * The property for the implemention of CookieParser.
100 */
101 public static final String COOKIE_PARSER = "cookie.parser";
102
103 /***
104 * The default implementations.
105 */
106 private static final String DEFAULT_RUN_DATA =
107 "org.apache.turbine.services.rundata.DefaultTurbineRunData";
108 private static final String DEFAULT_PARAMETER_PARSER =
109 "org.apache.turbine.util.parser.DefaultParameterParser";
110 private static final String DEFAULT_COOKIE_PARSER =
111 "org.apache.turbine.util.parser.DefaultCookieParser";
112
113 /***
114 * The map of configurations.
115 */
116 private HashMap configurations = new HashMap();
117
118 /***
119 * The getContextPath method from servet API >2.0.
120 */
121 private Method getContextPath;
122
123 /***
124 * Constructs a RunData Service.
125 */
126 public TurbineRunDataService()
127 {
128 // Allow Turbine to work with both 2.2 (and 2.1) and 2.0 Servlet API.
129 try
130 {
131 getContextPath =
132 HttpServletRequest.class.getDeclaredMethod("getContextPath",null);
133 }
134 catch (NoSuchMethodException x)
135 {
136 // Ignore a NoSuchMethodException because
137 // it means we are using Servlet API 2.0.
138 }
139 }
140
141 /***
142 * Initializes the service by setting the pool capacity.
143 *
144 * @throws InitializationException if initialization fails.
145 */
146 public void init()
147 throws InitializationException
148 {
149 // Create a default configuration.
150 String[] def = new String[]
151 {
152 DEFAULT_RUN_DATA,
153 DEFAULT_PARAMETER_PARSER,
154 DEFAULT_COOKIE_PARSER
155 };
156 configurations.put(DEFAULT_CONFIG,def.clone());
157
158 // Check other configurations.
159 Configuration conf = getConfiguration();
160 if (conf != null)
161 {
162 String key,value;
163 String[] config;
164 String[] plist = new String[]
165 {
166 RUN_DATA,
167 PARAMETER_PARSER,
168 COOKIE_PARSER
169 };
170 for (Iterator i = conf.getKeys(); i.hasNext();)
171 {
172 key = (String) i.next();
173 value = conf.getString(key);
174 for (int j = 0; j < plist.length; j++)
175 {
176 if (key.endsWith(plist[j]) &&
177 (key.length() > (plist[j].length() + 1)))
178 {
179 key = key.substring(0,key.length() - plist[j].length() - 1);
180 config = (String[]) configurations.get(key);
181 if (config == null)
182 {
183 config = (String[]) def.clone();
184 configurations.put(key,config);
185 }
186 config[j] = value;
187 break;
188 }
189 }
190 }
191 }
192 setInit(true);
193 }
194
195 /***
196 * Gets a default RunData object.
197 *
198 * @param req a servlet request.
199 * @param res a servlet response.
200 * @param config a servlet config.
201 * @return a new or recycled RunData object.
202 * @throws TurbineException if the operation fails.
203 */
204 public RunData getRunData(HttpServletRequest req,
205 HttpServletResponse res,
206 ServletConfig config)
207 throws TurbineException
208 {
209 return getRunData(DEFAULT_CONFIG,req,res,config);
210 }
211
212 /***
213 * Gets a RunData instance from a specific configuration.
214 *
215 * @param key a configuration key.
216 * @param req a servlet request.
217 * @param res a servlet response.
218 * @param config a servlet config.
219 * @return a new or recycled RunData object.
220 * @throws TurbineException if the operation fails.
221 * @throws IllegalArgumentException if any of the parameters are null.
222 */
223 public RunData getRunData(String key,
224 HttpServletRequest req,
225 HttpServletResponse res,
226 ServletConfig config)
227 throws TurbineException,
228 IllegalArgumentException
229 {
230 // The RunData object caches all the information that is needed for
231 // the execution lifetime of a single request. A RunData object
232 // is created/recycled for each and every request and is passed
233 // to each and every module. Since each thread has its own RunData
234 // object, it is not necessary to perform syncronization for
235 // the data within this object.
236 if ((req == null) ||
237 (res == null) ||
238 (config == null) )
239 {
240 throw new IllegalArgumentException(
241 "RunDataFactory fatal error: HttpServletRequest, HttpServletResponse or ServletConfig was null.");
242 }
243
244 // Get the specified configuration.
245 String[] cfg = (String[]) configurations.get(key);
246 if (cfg == null)
247 {
248 throw new TurbineException("RunTime configuration '" + key + "' is undefined");
249 }
250
251 // Use the Pool Service for recycling the implementing objects.
252 PoolService pool = (PoolService)
253 TurbineServices.getInstance().getService(PoolService.SERVICE_NAME);
254
255 TurbineRunData data;
256 try
257 {
258 data = (TurbineRunData) pool.getInstance(cfg[0]);
259 data.setParameterParser((ParameterParser) pool.getInstance(cfg[1]));
260 data.setCookieParser((CookieParser) pool.getInstance(cfg[2]));
261 }
262 catch (ClassCastException x)
263 {
264 throw new TurbineException("RunData configuration '" + key + "' is illegal",x);
265 }
266
267 // Set the request and response.
268 data.setRequest(req);
269 data.setResponse(res);
270
271 // Set the session object.
272 data.setSession(data.getRequest().getSession(true));
273
274 // Set the servlet configuration.
275 data.setServletConfig(config);
276
277 // Set the ServerData.
278 String contextPath;
279 try
280 {
281 contextPath = getContextPath != null ?
282 (String) getContextPath.invoke(req,null) : "";
283 }
284 catch (Exception x)
285 {
286 contextPath = "";
287 }
288 String scriptName = contextPath + req.getServletPath();
289 data.setServerData(new ServerData(req.getServerName(),
290 req.getServerPort(),
291 req.getScheme(),
292 scriptName,
293 contextPath));
294
295 return (RunData) data;
296 }
297
298 /***
299 * Puts the used RunData object back to the factory for recycling.
300 *
301 * @param data the used RunData object.
302 * @return true, if pooling is supported and the object was accepted.
303 */
304 public boolean putRunData(RunData data)
305 {
306 if (data instanceof TurbineRunData)
307 {
308 PoolService pool = (PoolService)
309 TurbineServices.getInstance().getService(PoolService.SERVICE_NAME);
310 pool.putInstance(((TurbineRunData) data).getParameterParser());
311 pool.putInstance(((TurbineRunData) data).getCookieParser());
312 return pool.putInstance(data);
313 }
314 else
315 {
316 return false;
317 }
318 }
319 }
This page was automatically generated by Maven