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.Iterator;
23 import java.util.Locale;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap;
26
27 import javax.servlet.ServletConfig;
28 import javax.servlet.ServletContext;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31
32 import org.apache.commons.configuration2.Configuration;
33 import org.apache.fulcrum.parser.CookieParser;
34 import org.apache.fulcrum.parser.DefaultCookieParser;
35 import org.apache.fulcrum.parser.DefaultParameterParser;
36 import org.apache.fulcrum.parser.ParameterParser;
37 import org.apache.fulcrum.parser.ParserService;
38 import org.apache.fulcrum.pool.PoolException;
39 import org.apache.fulcrum.pool.PoolService;
40 import org.apache.turbine.Turbine;
41 import org.apache.turbine.services.InitializationException;
42 import org.apache.turbine.services.TurbineBaseService;
43 import org.apache.turbine.services.TurbineServices;
44 import org.apache.turbine.util.RunData;
45 import org.apache.turbine.util.ServerData;
46 import org.apache.turbine.util.TurbineException;
47 import org.apache.turbine.util.TurbineRuntimeException;
48
49
50
51
52
53
54
55
56
57
58
59
60 public class TurbineRunDataService
61 extends TurbineBaseService
62 implements RunDataService
63 {
64
65
66 private static final String DEFAULT_RUN_DATA =
67 DefaultTurbineRunData.class.getName();
68
69
70 private static final String DEFAULT_PARAMETER_PARSER =
71 DefaultParameterParser.class.getName();
72
73
74 private static final String DEFAULT_COOKIE_PARSER =
75 DefaultCookieParser.class.getName();
76
77
78 private final ConcurrentMap<String, Object> configurations = new ConcurrentHashMap<>();
79
80
81 private final ConcurrentMap<String, Class<?>> classCache = new ConcurrentHashMap<>();
82
83
84 private PoolService pool = null;
85
86
87 private ParserService parserService = null;
88
89
90
91
92 public TurbineRunDataService()
93 {
94 super();
95 }
96
97
98
99
100
101
102 @Override
103 public void init()
104 throws InitializationException
105 {
106
107 String[] def = new String[]
108 {
109 DEFAULT_RUN_DATA,
110 DEFAULT_PARAMETER_PARSER,
111 DEFAULT_COOKIE_PARSER
112 };
113 configurations.put(DEFAULT_CONFIG, def.clone());
114
115
116 Configuration conf = getConfiguration();
117 if (conf != null)
118 {
119 String key,value;
120 String[] config;
121 String[] plist = new String[]
122 {
123 RUN_DATA_KEY,
124 PARAMETER_PARSER_KEY,
125 COOKIE_PARSER_KEY
126 };
127 for (Iterator<String> i = conf.getKeys(); i.hasNext();)
128 {
129 key = i.next();
130 value = conf.getString(key);
131 int j = 0;
132 for (String plistKey : plist)
133 {
134 if (key.endsWith(plistKey) && key.length() > plistKey.length() + 1)
135 {
136 key = key.substring(0, key.length() - plistKey.length() - 1);
137 config = (String[]) configurations.get(key);
138 if (config == null)
139 {
140 config = def.clone();
141 configurations.put(key, config);
142 }
143 config[j] = value;
144 break;
145 }
146 j++;
147 }
148 }
149 }
150
151 pool = (PoolService)TurbineServices.getInstance().getService(PoolService.ROLE);
152
153 if (pool == null)
154 {
155 throw new InitializationException("RunData Service requires"
156 + " configured Pool Service!");
157 }
158
159 parserService = (ParserService)TurbineServices.getInstance().getService(ParserService.ROLE);
160
161 if (parserService == null)
162 {
163 throw new InitializationException("RunData Service requires"
164 + " configured Parser Service!");
165 }
166
167 setInit(true);
168 }
169
170
171
172
173
174
175 @Override
176 public void shutdown()
177 {
178 classCache.clear();
179 super.shutdown();
180 }
181
182
183
184
185
186
187
188
189
190
191 @Override
192 public RunData getRunData(HttpServletRequest req,
193 HttpServletResponse res,
194 ServletConfig config)
195 throws TurbineException
196 {
197 return getRunData(DEFAULT_CONFIG, req, res, config);
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211
212 @Override
213 public RunData getRunData(String key,
214 HttpServletRequest req,
215 HttpServletResponse res,
216 ServletConfig config)
217 throws TurbineException,
218 IllegalArgumentException
219 {
220
221
222
223
224
225
226 if (req == null || res == null || config == null)
227 {
228 throw new IllegalArgumentException("HttpServletRequest, "
229 + "HttpServletResponse or ServletConfig was null.");
230 }
231
232
233 String[] cfg = (String[]) configurations.get(key);
234 if (cfg == null)
235 {
236 throw new TurbineException("RunTime configuration '" + key + "' is undefined");
237 }
238
239 TurbineRunData data;
240 try
241 {
242 Class<?> runDataClazz = classCache.computeIfAbsent(cfg[0], this::classForName);
243 Class<?> parameterParserClazz = classCache.computeIfAbsent(cfg[1], this::classForName);
244 Class<?> cookieParserClazz = classCache.computeIfAbsent(cfg[2], this::classForName);
245
246 data = (TurbineRunData) pool.getInstance(runDataClazz);
247 @SuppressWarnings("unchecked")
248 ParameterParser pp = parserService.getParser((Class<ParameterParser>)parameterParserClazz);
249 data.get(Turbine.class).put(ParameterParser.class, pp);
250
251 @SuppressWarnings("unchecked")
252 CookieParser cp = parserService.getParser((Class<CookieParser>)cookieParserClazz);
253 data.get(Turbine.class).put(CookieParser.class, cp);
254
255 Locale locale = req.getLocale();
256
257 if (locale == null)
258 {
259
260 locale = data.getLocale();
261 }
262
263
264 data.setLocale(locale);
265 }
266 catch (PoolException pe)
267 {
268 throw new TurbineException("RunData configuration '" + key + "' is illegal caused a pool exception", pe);
269 }
270 catch (TurbineRuntimeException | ClassCastException | InstantiationException x)
271 {
272 throw new TurbineException("RunData configuration '" + key + "' is illegal", x);
273 }
274
275
276 data.get(Turbine.class).put(HttpServletRequest.class, req);
277 data.get(Turbine.class).put(HttpServletResponse.class, res);
278
279
280 data.get(Turbine.class).put(ServletConfig.class, config);
281 data.get(Turbine.class).put(ServletContext.class, config.getServletContext());
282
283
284 data.get(Turbine.class).put(ServerData.class, new ServerData(req));
285
286 return data;
287 }
288
289
290
291
292
293
294
295 @Override
296 public boolean putRunData(RunData data)
297 {
298 if (data instanceof TurbineRunData)
299 {
300 parserService.putParser(((TurbineRunData) data).getParameterParser());
301 parserService.putParser(((TurbineRunData) data).getCookieParser());
302
303 return pool.putInstance(data);
304 }
305 else
306 {
307 return false;
308 }
309 }
310
311 @SuppressWarnings("unchecked")
312 private <T> Class<T> classForName(String className) throws TurbineRuntimeException
313 {
314 try
315 {
316 return (Class<T>) Class.forName(className);
317 }
318 catch (ClassNotFoundException e)
319 {
320 throw new TurbineRuntimeException("Could not load class " + className, e);
321 }
322 }
323 }