1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package net.sf.prefixedproperties;
27
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.net.URL;
31 import java.net.URLConnection;
32 import java.security.AccessController;
33 import java.security.PrivilegedActionException;
34 import java.security.PrivilegedExceptionAction;
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.Enumeration;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.Locale;
41 import java.util.ResourceBundle;
42
43 import net.sf.prefixedproperties.config.PrefixConfig;
44
45
46
47
48 public class PrefixedResourceBundle extends ResourceBundle {
49
50
51
52
53 public static class PrefixedControl extends ResourceBundle.Control {
54
55 private final String defaultPrefix;
56 private final PrefixConfig prefixConfig;
57
58
59 public static final List<String> FORMAT_DEFAULT;
60
61
62 public final static String FORMAT_XML = "pref.xml";
63
64
65 public final static String FORMAT_JSON = "pref.json";
66
67
68 public final static String FORMAT_PROPERTIES = "pref.properties";
69
70 static {
71 final List<String> formatList = new ArrayList<String>(3);
72 formatList.add(FORMAT_JSON);
73 formatList.add(FORMAT_PROPERTIES);
74 formatList.add(FORMAT_XML);
75 FORMAT_DEFAULT = Collections.unmodifiableList(formatList);
76 }
77
78 protected PrefixedControl() {
79 this.defaultPrefix = null;
80 this.prefixConfig = null;
81 }
82
83
84
85
86
87
88
89 protected PrefixedControl(final PrefixConfig prefixConfig) {
90 this.prefixConfig = prefixConfig;
91 this.defaultPrefix = null;
92 }
93
94
95
96
97
98
99
100 protected PrefixedControl(final String defaultPrefix) {
101 this.defaultPrefix = defaultPrefix;
102 this.prefixConfig = null;
103 }
104
105 private InputStream createInputStream(final ClassLoader loader, final boolean reload, final String resourceName)
106 throws IOException {
107 InputStream stream;
108 try {
109 stream = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() {
110 @Override
111 public InputStream run() throws IOException {
112 InputStream is = null;
113 if (reload) {
114 final URL url = loader.getResource(resourceName);
115 if (url != null) {
116 final URLConnection connection = url.openConnection();
117 if (connection != null) {
118 connection.setUseCaches(false);
119 is = connection.getInputStream();
120 }
121 }
122 } else {
123 is = loader.getResourceAsStream(resourceName);
124 }
125 return is;
126 }
127 });
128 } catch (final PrivilegedActionException e) {
129 throw (IOException) e.getException();
130 }
131 return stream;
132 }
133
134
135
136
137
138
139 @Override
140 public List<String> getFormats(final String baseName) {
141 if (baseName == null) {
142 throw new NullPointerException();
143 }
144 return FORMAT_DEFAULT;
145 }
146
147
148
149
150
151
152
153 @Override
154 public ResourceBundle newBundle(final String baseName, final Locale locale, final String format,
155 final ClassLoader loader, final boolean reload)
156 throws IllegalAccessException, InstantiationException, IOException {
157 final String bundleName = toBundleName(baseName, locale);
158 InputStream stream = null;
159 try {
160 final PrefixedProperties properties = (prefixConfig != null) ? new PrefixedProperties(prefixConfig)
161 : new PrefixedProperties();
162 if (defaultPrefix != null) {
163 properties.setDefaultPrefix(defaultPrefix);
164 }
165 if (FORMAT_JSON.equals(format)) {
166 final String resourceName = toResourceName(bundleName, "json");
167 stream = createInputStream(loader, reload, resourceName);
168 if (stream != null) {
169 properties.loadFromJSON(stream);
170 return new PrefixedResourceBundle(properties);
171 }
172 } else if (FORMAT_PROPERTIES.equals(format)) {
173 final String resourceName = toResourceName(bundleName, "properties");
174 stream = createInputStream(loader, reload, resourceName);
175 if (stream != null) {
176 properties.load(stream);
177 return new PrefixedResourceBundle(properties);
178 }
179 } else if (FORMAT_XML.equals(format)) {
180 final String resourceName = toResourceName(bundleName, "xml");
181 stream = createInputStream(loader, reload, resourceName);
182 if (stream != null) {
183 properties.loadFromXML(stream);
184 return new PrefixedResourceBundle(properties);
185 }
186 } else {
187 return super.newBundle(baseName, locale, format, loader, reload);
188 }
189 } finally {
190 if (stream != null) {
191 stream.close();
192 }
193 }
194 return null;
195 }
196 }
197
198 @SuppressWarnings("rawtypes")
199 private static class ResouceBundleEnumeration implements Enumeration {
200
201 private final Iterator it;
202
203 ResouceBundleEnumeration(final Iterator it) {
204 this.it = it;
205 }
206
207 @Override
208 public boolean hasMoreElements() {
209 return it.hasNext();
210 }
211
212 @Override
213 public Object nextElement() {
214 return it.next();
215 }
216
217 }
218
219 public static PrefixedResourceBundle getPrefixedResourceBundle(final String baseFileName, final Locale locale)
220 throws IOException {
221 ResourceBundle bundle = ResourceBundle.getBundle(baseFileName, locale, new PrefixedControl());
222 while (bundle != null && !(bundle instanceof PrefixedResourceBundle)) {
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 ResourceBundle.clearCache();
242 bundle = ResourceBundle.getBundle(baseFileName, locale, new PrefixedControl());
243 }
244 return (PrefixedResourceBundle) bundle;
245 }
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 public static PrefixedResourceBundle getPrefixedResourceBundle(final String baseFileName, final Locale locale,
261 final PrefixConfig prefixConfig) throws IOException {
262 ResourceBundle bundle = ResourceBundle.getBundle(baseFileName, locale, new PrefixedControl(prefixConfig));
263 while (bundle != null && !(bundle instanceof PrefixedResourceBundle)) {
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 ResourceBundle.clearCache();
283 bundle = ResourceBundle.getBundle(baseFileName, locale, new PrefixedControl(prefixConfig));
284 }
285 return (PrefixedResourceBundle) bundle;
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 public static PrefixedResourceBundle getPrefixedResourceBundle(final String baseFileName, final Locale locale,
302 final String defaultPrefix) throws IOException {
303 ResourceBundle bundle = ResourceBundle.getBundle(baseFileName, locale, new PrefixedControl(defaultPrefix));
304 while (bundle != null && !(bundle instanceof PrefixedResourceBundle)) {
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323 ResourceBundle.clearCache();
324 bundle = ResourceBundle.getBundle(baseFileName, locale, new PrefixedControl(defaultPrefix));
325 }
326 return (PrefixedResourceBundle) bundle;
327 }
328
329 private final PrefixedProperties properties;
330
331
332
333
334
335
336
337 public PrefixedResourceBundle(final PrefixedProperties properties) {
338 this.properties = properties;
339 }
340
341
342
343
344
345
346 public String getConfiguredPrefix() {
347 return properties.getEffectivePrefix();
348 }
349
350
351
352
353
354
355 @SuppressWarnings("unchecked")
356 @Override
357 public Enumeration<String> getKeys() {
358 return new ResouceBundleEnumeration(properties.stringPropertyNames().iterator());
359 }
360
361
362
363
364
365
366 public PrefixedProperties getPrefixedProperties() {
367 return properties;
368 }
369
370
371
372
373
374
375 @Override
376 protected Object handleGetObject(final String key) {
377 if (key == null) {
378 throw new NullPointerException("The given key is null.");
379 }
380 return properties.get(key);
381 }
382
383 public void setConfiguredPrefix(final String configuredPrefix) {
384 properties.setLocalPrefix(configuredPrefix);
385 }
386
387
388
389
390
391
392
393 public void setDefaultPrefix(final String prefix) {
394 properties.setDefaultPrefix(prefix);
395 }
396 }