Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ResourceServlet |
|
| 2.076923076923077;2.077 |
1 | /* | |
2 | * Copyright 2000-2004 The Apache Software Foundation. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | package org.apache.commons.scaffold.http; | |
18 | ||
19 | import java.io.BufferedInputStream; | |
20 | import java.io.IOException; | |
21 | import java.io.InputStream; | |
22 | import java.util.Map; | |
23 | import java.util.Properties; | |
24 | ||
25 | import javax.servlet.ServletException; | |
26 | import javax.servlet.UnavailableException; | |
27 | import javax.servlet.http.HttpServlet; | |
28 | ||
29 | import org.apache.commons.logging.Log; | |
30 | import org.apache.commons.logging.LogFactory; | |
31 | ||
32 | /** | |
33 | * Base servlet for loading application resources. | |
34 | * | |
35 | * @author Ted Husted | |
36 | * @author Steve Raeburn | |
37 | */ | |
38 | 0 | public class ResourceServlet extends HttpServlet { |
39 | ||
40 | // TODO: Externalize messages using commons resources. | |
41 | // Previous suggestion was to use MessageResources, but this would | |
42 | // create a dependency on Struts. A better option would be to use | |
43 | // Commons Resources, which Struts will eventually migrate to. | |
44 | ||
45 | // ------------------------------------------------------- Class variables | |
46 | ||
47 | /** | |
48 | * Commons logging instance | |
49 | */ | |
50 | 0 | private static Log log = LogFactory.getLog(ResourceServlet.class); |
51 | ||
52 | // ------------------------------------------------------ Logging Messages | |
53 | ||
54 | private static final String INIT_FAILED_EVENT = | |
55 | "ResourceServlet: init() failed."; | |
56 | ||
57 | private static final String RELOAD_EVENT = | |
58 | "Reloading ResourceServlet"; | |
59 | ||
60 | private static final String DESTROY_EVENT = | |
61 | "Destroying ResourceServlet"; | |
62 | ||
63 | private static final String RESOURCE_LOADING = | |
64 | "Loading resources from path: "; | |
65 | ||
66 | private static final String RESOURCE_NOT_FOUND = | |
67 | "Resources not found"; | |
68 | ||
69 | // --------------------------------------------------- Parameter Utilities | |
70 | ||
71 | /** | |
72 | * Check for a parameter and returns a default value if not found. | |
73 | * | |
74 | * @param parameter The attribute name to look for | |
75 | * @param defaultValue The default to return if the parameter is not found | |
76 | * @return The customized value or the default value | |
77 | */ | |
78 | public String getInitString(String parameter, String defaultValue) { | |
79 | ||
80 | 0 | String stringValue = getServletConfig().getInitParameter(parameter); |
81 | 0 | if (null == stringValue) |
82 | 0 | return defaultValue; |
83 | 0 | return stringValue; |
84 | ||
85 | } | |
86 | ||
87 | /** | |
88 | * Check for a parameter and returns a default value if not found, | |
89 | * or if the value does not convert to an <code>int</code>. | |
90 | * | |
91 | * @param parameter The attribute name to look for | |
92 | * @defaultValue The default to return if the parameter is not found | |
93 | * @return The customized value or the default value | |
94 | */ | |
95 | public int getInitInt(String parameter, int defaultValue) { | |
96 | ||
97 | 0 | String stringValue = null; |
98 | 0 | int intValue = defaultValue; |
99 | ||
100 | try { | |
101 | ||
102 | 0 | stringValue = getServletConfig().getInitParameter(parameter); |
103 | 0 | intValue = Integer.parseInt(stringValue); |
104 | ||
105 | 0 | } catch (Throwable t) { |
106 | 0 | intValue = defaultValue; |
107 | 0 | } |
108 | ||
109 | 0 | return intValue; |
110 | } | |
111 | ||
112 | /** | |
113 | * Return a map of this servlet's initialization parameters. | |
114 | * | |
115 | * @return A map of this servlet's initialization parameters. | |
116 | * @fixme Not tested yet | |
117 | */ | |
118 | public Map getInitParameters() { | |
119 | ||
120 | // :FIXME: Not tested yet. | |
121 | ||
122 | 0 | java.util.Enumeration names = |
123 | getServletConfig().getInitParameterNames(); | |
124 | 0 | java.util.HashMap map = new java.util.HashMap(); |
125 | 0 | while (names.hasMoreElements()) { |
126 | 0 | String name = (String) names.nextElement(); |
127 | 0 | String value = getServletConfig().getInitParameter(name); |
128 | 0 | map.put(name, value); |
129 | 0 | } |
130 | 0 | return map; |
131 | } | |
132 | ||
133 | // --------------------------------------------------- Internal Properties | |
134 | ||
135 | /** | |
136 | * The parameter to check for a new path to the default properties | |
137 | * ["default"]. | |
138 | */ | |
139 | private static final String DEFAULT_PARAMETER = "default"; | |
140 | ||
141 | /** | |
142 | * The default path to use if parameter is not set | |
143 | *["resources/default.properties"]. | |
144 | */ | |
145 | private static final String DEFAULT_PATH = "resources/default.properties"; | |
146 | ||
147 | /** | |
148 | * The default attribute for the application properties. | |
149 | * The properties are exposed in the servlet context | |
150 | * under this attribute name | |
151 | * [lang.Tokens.PROPERTIES_KEY]. | |
152 | */ | |
153 | private static final String DEFAULT_ATTRIBUTE = | |
154 | org.apache.commons.scaffold.lang.Tokens.PROPERTIES_KEY; | |
155 | ||
156 | /** | |
157 | * Our default properties object. | |
158 | * <p> | |
159 | * The default properties can be used to store applications | |
160 | * settings that do not need to be localized and may | |
161 | * not even be displayed to the user. | |
162 | */ | |
163 | 0 | Properties properties = null; |
164 | ||
165 | /** | |
166 | * Set the default properties object. | |
167 | */ | |
168 | public void setProperties(Properties properties) { | |
169 | 0 | this.properties = properties; |
170 | 0 | } |
171 | ||
172 | /** | |
173 | * Return the default properties object. | |
174 | * | |
175 | * @return The default properties object | |
176 | */ | |
177 | public Properties getProperties() { | |
178 | 0 | return this.properties; |
179 | } | |
180 | ||
181 | /** | |
182 | * A utility method for loading a Properties file | |
183 | * specified by an initialization parameter. | |
184 | * | |
185 | * The initialization parameter should specify the | |
186 | * package and folder for the Properties in system | |
187 | * path format (resources/custom.properties). | |
188 | * | |
189 | * @param parameter The name of the initialization | |
190 | * parameter | |
191 | * @param defaultPath The path to use if the | |
192 | * parameter is not found | |
193 | * @param attribute If not null, store in | |
194 | * application scope under this attribute name | |
195 | */ | |
196 | public Properties loadProperties( | |
197 | String parameter, | |
198 | String defaultPath, | |
199 | String attribute) | |
200 | throws ServletException { | |
201 | ||
202 | 0 | String path = getInitString(parameter, defaultPath); |
203 | ||
204 | 0 | if (log.isDebugEnabled()) { |
205 | 0 | log.debug(RESOURCE_LOADING); |
206 | 0 | log.debug(path); |
207 | } | |
208 | ||
209 | 0 | InputStream is = null; |
210 | 0 | is = this.getClass().getClassLoader().getResourceAsStream(path); |
211 | 0 | if (null == is) |
212 | 0 | throw new UnavailableException(RESOURCE_NOT_FOUND); |
213 | ||
214 | 0 | Properties p = null; |
215 | 0 | BufferedInputStream bis = new BufferedInputStream(is); |
216 | ||
217 | try { | |
218 | ||
219 | 0 | p = new Properties(); |
220 | 0 | p.load(bis); |
221 | 0 | bis.close(); |
222 | 0 | is.close(); |
223 | 0 | } catch (IOException e) { |
224 | ||
225 | 0 | p = null; |
226 | ||
227 | } finally { | |
228 | 0 | is = null; |
229 | 0 | bis = null; |
230 | 0 | } |
231 | ||
232 | 0 | if ((null != p) && (null != attribute)) { |
233 | ||
234 | 0 | this.getServletContext().setAttribute(attribute, p); |
235 | ||
236 | } | |
237 | ||
238 | 0 | if (log.isDebugEnabled()) { |
239 | 0 | log.debug(p.toString()); |
240 | } | |
241 | ||
242 | 0 | return p; |
243 | } | |
244 | ||
245 | /** | |
246 | * Initialize the default properties for this application. | |
247 | * <p> | |
248 | * Use the <code>default</code> initialization parameter to specify | |
249 | * another path. Otherwise ["resources/default.properties"] is used. | |
250 | * <p> | |
251 | * If the default properties will not be used or specified, | |
252 | * override this method with one that does not try to load the | |
253 | * default properties. | |
254 | * | |
255 | * @exception IOException if an input/output error is encountered | |
256 | * @exception ServletException if we cannot initialize these resources | |
257 | * @todo The PROPERTIES_KEY could be made configurable, | |
258 | * but the BaseAction would need to be notified. | |
259 | */ | |
260 | protected void initDefault() throws IOException, ServletException { | |
261 | ||
262 | 0 | setProperties( |
263 | loadProperties(DEFAULT_PARAMETER, DEFAULT_PATH, DEFAULT_ATTRIBUTE)); | |
264 | 0 | } |
265 | ||
266 | /** | |
267 | * Release any default resources created at initialization | |
268 | */ | |
269 | protected void destroyDefault() { | |
270 | 0 | setProperties(null); |
271 | 0 | } |
272 | ||
273 | // --------------------------------------------------- HttpServlet Methods | |
274 | ||
275 | /** | |
276 | * Initialize this servlet by caling three extension points: | |
277 | * <ul> | |
278 | * <li><code>initLogging</code></li> | |
279 | * <li><code>initDefault</code></li> | |
280 | * <li><code>initCustom</code></li> | |
281 | * </ul> | |
282 | * The main extension point is <code><b>initCustom</b></code> | |
283 | * The default implementation does nothing. | |
284 | * The other two methods have reasonable default behaviors that most | |
285 | * subclasses could use as-is. | |
286 | * This may be called again from <code>reload</code> and should be | |
287 | * "re-enterant". | |
288 | * | |
289 | * @exception ServletException if we cannot configure ourselves | |
290 | * correctly | |
291 | */ | |
292 | public void init() throws ServletException { | |
293 | ||
294 | try { | |
295 | ||
296 | 0 | initDefault(); |
297 | // initMessages(); | |
298 | 0 | initCustom(); |
299 | ||
300 | 0 | } catch (IOException e) { |
301 | ||
302 | 0 | throw new UnavailableException(INIT_FAILED_EVENT); |
303 | ||
304 | 0 | } |
305 | 0 | } |
306 | ||
307 | /** | |
308 | * Gracefully shut down this controller servlet, releasing any resources | |
309 | * that were allocated at initialization. | |
310 | */ | |
311 | public void destroy() { | |
312 | ||
313 | 0 | if (log.isDebugEnabled()) { |
314 | 0 | log.debug(DESTROY_EVENT); |
315 | } | |
316 | ||
317 | 0 | destroyCustom(); |
318 | // destroyMessages(); | |
319 | 0 | destroyDefault(); |
320 | ||
321 | 0 | } |
322 | ||
323 | // ------------------------------------------------------ Extension Points | |
324 | ||
325 | /** | |
326 | * Initialize the custom properties or objects for this application. | |
327 | * | |
328 | * @exception IOException if an input/output error is encountered | |
329 | * @exception ServletException if we cannot initialize these resources | |
330 | */ | |
331 | protected void initCustom() throws IOException, ServletException { | |
332 | ||
333 | // Override with custom initializations | |
334 | ||
335 | 0 | } |
336 | ||
337 | /** | |
338 | * Release any custom resources created at initialization | |
339 | */ | |
340 | protected void destroyCustom() { | |
341 | // override to provide functionality if needed | |
342 | 0 | } |
343 | ||
344 | // -------------------------------------------------------- Public Methods | |
345 | ||
346 | /** | |
347 | * Reload the configuration of this controller servlet from our | |
348 | * underlying configuration files. | |
349 | * | |
350 | * @exception IOException if an input/output error occurs | |
351 | * @exception ServletException if a servlet exception occurs | |
352 | */ | |
353 | public void reload() throws IOException, ServletException { | |
354 | ||
355 | 0 | if (log.isDebugEnabled()) { |
356 | 0 | log.debug(RELOAD_EVENT); |
357 | } | |
358 | ||
359 | // Re-initialize | |
360 | 0 | init(); |
361 | 0 | } |
362 | ||
363 | } // end ResourceServlet |