1 package org.apache.turbine.services.rundata;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.Map;
22
23 import javax.servlet.ServletConfig;
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27 import org.apache.commons.configuration.Configuration;
28
29 import org.apache.turbine.services.InitializationException;
30 import org.apache.turbine.services.TurbineBaseService;
31 import org.apache.turbine.services.pool.PoolService;
32 import org.apache.turbine.services.pool.TurbinePool;
33 import org.apache.turbine.util.RunData;
34 import org.apache.turbine.util.ServerData;
35 import org.apache.turbine.util.TurbineException;
36 import org.apache.turbine.util.parser.CookieParser;
37 import org.apache.turbine.util.parser.DefaultCookieParser;
38 import org.apache.turbine.util.parser.DefaultParameterParser;
39 import org.apache.turbine.util.parser.ParameterParser;
40
41 /***
42 * The RunData Service provides the implementations for RunData and
43 * related interfaces required by request processing. It supports
44 * different configurations of implementations, which can be selected
45 * by specifying a configuration key. It may use pooling, in which case
46 * the implementations should implement the Recyclable interface.
47 *
48 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
49 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
50 * @version $Id: TurbineRunDataService.java 264148 2005-08-29 14:21:04Z henning $
51 */
52 public class TurbineRunDataService
53 extends TurbineBaseService
54 implements RunDataService
55 {
56 /*** @deprecated Use RunDataService.RUN_DATA_KEY */
57 public static final String RUN_DATA =
58 RunDataService.RUN_DATA_KEY;
59
60 /*** @deprecated Use RunDataService.PARAMETER_PARSER_KEY */
61 public static final String PARAMETER_PARSER =
62 RunDataService.PARAMETER_PARSER_KEY;
63
64 /*** @deprecated Use RunDataService.COOKIE_PARSER_KEY */
65 public static final String COOKIE_PARSER =
66 RunDataService.COOKIE_PARSER_KEY;
67
68 /*** The default implementation of the RunData object*/
69 private static final String DEFAULT_RUN_DATA =
70 DefaultTurbineRunData.class.getName();
71
72 /*** The default implementation of the Parameter Parser object */
73 private static final String DEFAULT_PARAMETER_PARSER =
74 DefaultParameterParser.class.getName();
75
76 /*** The default implementation of the Cookie parser object */
77 private static final String DEFAULT_COOKIE_PARSER =
78 DefaultCookieParser.class.getName();
79
80 /*** The map of configurations. */
81 private Map configurations = new HashMap();
82
83 /*** Private reference to the pool service for object recycling */
84 private PoolService pool = null;
85
86 /***
87 * Constructs a RunData Service.
88 */
89 public TurbineRunDataService()
90 {
91 }
92
93 /***
94 * Initializes the service by setting the pool capacity.
95 *
96 * @throws InitializationException if initialization fails.
97 */
98 public void init()
99 throws InitializationException
100 {
101
102 String[] def = new String[]
103 {
104 DEFAULT_RUN_DATA,
105 DEFAULT_PARAMETER_PARSER,
106 DEFAULT_COOKIE_PARSER
107 };
108 configurations.put(DEFAULT_CONFIG, def.clone());
109
110
111 Configuration conf = getConfiguration();
112 if (conf != null)
113 {
114 String key,value;
115 String[] config;
116 String[] plist = new String[]
117 {
118 RUN_DATA_KEY,
119 PARAMETER_PARSER_KEY,
120 COOKIE_PARSER_KEY
121 };
122 for (Iterator i = conf.getKeys(); i.hasNext();)
123 {
124 key = (String) i.next();
125 value = conf.getString(key);
126 for (int j = 0; j < plist.length; j++)
127 {
128 if (key.endsWith(plist[j]) &&
129 (key.length() > (plist[j].length() + 1)))
130 {
131 key = key.substring(0, key.length() - plist[j].length() - 1);
132 config = (String[]) configurations.get(key);
133 if (config == null)
134 {
135 config = (String[]) def.clone();
136 configurations.put(key, config);
137 }
138 config[j] = value;
139 break;
140 }
141 }
142 }
143 }
144 pool = TurbinePool.getService();
145
146 if (pool == null)
147 {
148 throw new InitializationException("RunData Service requires"
149 + " configured Pool Service!");
150 }
151
152 setInit(true);
153 }
154
155 /***
156 * Gets a default RunData object.
157 *
158 * @param req a servlet request.
159 * @param res a servlet response.
160 * @param config a servlet config.
161 * @return a new or recycled RunData object.
162 * @throws TurbineException if the operation fails.
163 */
164 public RunData getRunData(HttpServletRequest req,
165 HttpServletResponse res,
166 ServletConfig config)
167 throws TurbineException
168 {
169 return getRunData(DEFAULT_CONFIG, req, res, config);
170 }
171
172 /***
173 * Gets a RunData instance from a specific configuration.
174 *
175 * @param key a configuration key.
176 * @param req a servlet request.
177 * @param res a servlet response.
178 * @param config a servlet config.
179 * @return a new or recycled RunData object.
180 * @throws TurbineException if the operation fails.
181 * @throws IllegalArgumentException if any of the parameters are null.
182 */
183 public RunData getRunData(String key,
184 HttpServletRequest req,
185 HttpServletResponse res,
186 ServletConfig config)
187 throws TurbineException,
188 IllegalArgumentException
189 {
190
191
192
193
194
195
196 if ((req == null)
197 || (res == null)
198 || (config == null))
199 {
200 throw new IllegalArgumentException("HttpServletRequest, "
201 + "HttpServletResponse or ServletConfig was null.");
202 }
203
204
205 String[] cfg = (String[]) configurations.get(key);
206 if (cfg == null)
207 {
208 throw new TurbineException("RunTime configuration '" + key + "' is undefined");
209 }
210
211 TurbineRunData data;
212 try
213 {
214 data = (TurbineRunData) pool.getInstance(cfg[0]);
215 data.setParameterParser((ParameterParser) pool.getInstance(cfg[1]));
216 data.setCookieParser((CookieParser) pool.getInstance(cfg[2]));
217 }
218 catch (ClassCastException x)
219 {
220 throw new TurbineException("RunData configuration '" + key + "' is illegal", x);
221 }
222
223
224 data.setRequest(req);
225 data.setResponse(res);
226
227
228 data.setServletConfig(config);
229
230
231 data.setServerData(new ServerData(req));
232
233 return data;
234 }
235
236 /***
237 * Puts the used RunData object back to the factory for recycling.
238 *
239 * @param data the used RunData object.
240 * @return true, if pooling is supported and the object was accepted.
241 */
242 public boolean putRunData(RunData data)
243 {
244 if (data instanceof TurbineRunData)
245 {
246 pool.putInstance(((TurbineRunData) data).getParameterParser());
247 pool.putInstance(((TurbineRunData) data).getCookieParser());
248
249 return pool.putInstance(data);
250 }
251 else
252 {
253 return false;
254 }
255 }
256 }