Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
LatkaProperties |
|
| 1.7142857142857142;1.714 | ||||
LatkaProperties$LatkaThreadLocal |
|
| 1.7142857142857142;1.714 |
1 | /* | |
2 | * Copyright 1999-2002,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.latka; | |
18 | ||
19 | import java.io.InputStream; | |
20 | import java.io.IOException; | |
21 | import java.util.Properties; | |
22 | ||
23 | import org.apache.log4j.Category; | |
24 | ||
25 | /** | |
26 | * Stores properties for Latka. This class is backed by a | |
27 | * ThreadLocal variable, so every Thread is guaranteed to | |
28 | * get a unique Properties object. Note, however, that | |
29 | * inside an environment utilizing a Thread pool, such | |
30 | * as many Servlet engines, it is possible for | |
31 | * the Properties object to travel quite widely. Use the | |
32 | * {@link #resetProperties()} method to reset the Properties | |
33 | * object for a Thread to its default values. | |
34 | * | |
35 | * @author Morgan Delagrange | |
36 | * @author dIon Gillard (javadoc changes) | |
37 | */ | |
38 | 0 | public class LatkaProperties { |
39 | ||
40 | /** log4j category to append output to */ | |
41 | 0 | protected static final Category _log = |
42 | 0 | Category.getInstance(LatkaProperties.class); |
43 | ||
44 | /** default Properties file for Latka */ | |
45 | 0 | protected static Properties _initProps = loadDefaultProps(); |
46 | ||
47 | static { | |
48 | 0 | _initProps.putAll(loadUserProps()); |
49 | } | |
50 | ||
51 | /** | |
52 | * This ThreadLocal is automatically instantiated per thread | |
53 | * with a Properties object containing the default properties. | |
54 | */ | |
55 | 0 | protected static ThreadLocal _propsThreadLocal = |
56 | new LatkaThreadLocal(_initProps); | |
57 | ||
58 | /** | |
59 | * Returns the unique Properties object for the current | |
60 | * Thread. The Properties object is initialized with | |
61 | * the default Latka Properties. | |
62 | * | |
63 | * @return Latka Properties object | |
64 | */ | |
65 | public static Properties getProperties() { | |
66 | 0 | return (Properties) _propsThreadLocal.get(); |
67 | } | |
68 | ||
69 | /** | |
70 | * Resets the Latka properties to their initial value | |
71 | * (getProperties() will still return the same Object). | |
72 | * One use for this method is to reset state inside | |
73 | * a Thread-pooling environment. | |
74 | */ | |
75 | public static void resetProperties() { | |
76 | 0 | Properties props = (Properties) _propsThreadLocal.get(); |
77 | 0 | props.clear(); |
78 | 0 | props.putAll(_initProps); |
79 | 0 | } |
80 | ||
81 | /** | |
82 | * Loads the default Properties from the | |
83 | * first "latka.properties" file located encountered | |
84 | * in the classpath. | |
85 | * | |
86 | * @return A Properties object generated from the contents of the | |
87 | * default property file | |
88 | */ | |
89 | protected static Properties loadDefaultProps() { | |
90 | ||
91 | 0 | Properties properties = new Properties(); |
92 | ||
93 | try { | |
94 | 0 | properties.putAll( |
95 | loadPropsFromClasspath("latka.properties.internal")); | |
96 | 0 | } catch (IOException e) { |
97 | 0 | _log.error( |
98 | "Couldn't find latka.properties.internal file in the classpath", | |
99 | e); | |
100 | 0 | } |
101 | ||
102 | 0 | return properties; |
103 | ||
104 | } | |
105 | ||
106 | /** | |
107 | * Load <em>latka.properties</em> from classpath | |
108 | * @return loaded properties | |
109 | */ | |
110 | protected static Properties loadUserProps() { | |
111 | ||
112 | 0 | Properties properties = new Properties(); |
113 | ||
114 | try { | |
115 | 0 | properties.putAll(loadPropsFromClasspath("latka.properties")); |
116 | 0 | } catch (IOException e) { |
117 | 0 | _log.debug(e); |
118 | 0 | _log.warn( |
119 | "No user-defined latka.properties file in the classpath (optional)" | |
120 | ); | |
121 | 0 | } |
122 | ||
123 | 0 | return properties; |
124 | ||
125 | } | |
126 | ||
127 | /** | |
128 | * Load properties specified from context class path | |
129 | * @param classpathLocation Resource name to load | |
130 | * @throws IOException from loading resource | |
131 | * @return initialized properties object | |
132 | */ | |
133 | protected static Properties | |
134 | loadPropsFromClasspath(String classpathLocation) | |
135 | throws IOException { | |
136 | 0 | Properties properties = new Properties(); |
137 | ||
138 | 0 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); |
139 | 0 | if (loader == null) { |
140 | // there may not be a context class loader | |
141 | 0 | loader = LatkaProperties.class.getClassLoader(); |
142 | } | |
143 | ||
144 | 0 | InputStream stream = loader.getResourceAsStream(classpathLocation); |
145 | ||
146 | 0 | if (stream == null) { |
147 | 0 | throw new IOException("Could not find this file in classpath: " |
148 | + classpathLocation); | |
149 | } | |
150 | ||
151 | 0 | properties.load(stream); |
152 | ||
153 | 0 | return properties; |
154 | } | |
155 | ||
156 | /** | |
157 | * Custom ThreadLocal class that automatically initialized | |
158 | * the default Properties for the Thread. | |
159 | * | |
160 | * @author Morgan Delagrange | |
161 | */ | |
162 | 0 | private static class LatkaThreadLocal extends ThreadLocal { |
163 | /** default properties for the thread */ | |
164 | 0 | protected Properties _initProps = null; |
165 | ||
166 | /** | |
167 | * Constructor specifying the default Properties object | |
168 | * for Latka | |
169 | * | |
170 | * @param initProps default Properties object | |
171 | */ | |
172 | 0 | public LatkaThreadLocal(Properties initProps) { |
173 | 0 | _initProps = initProps; |
174 | 0 | } |
175 | ||
176 | /** | |
177 | * Returns a clone of the default Properties file | |
178 | * for Latka | |
179 | * | |
180 | * @return Latka Properties file for the current Thread | |
181 | */ | |
182 | protected Object initialValue() { | |
183 | 0 | return _initProps.clone(); |
184 | } | |
185 | ||
186 | } | |
187 | ||
188 | } |