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