1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.castor.core.util;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.URL;
25 import java.text.MessageFormat;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Properties;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34
35
36
37
38
39
40
41
42 public abstract class AbstractProperties {
43
44
45
46
47
48 private static final String USER_PROPERTIES_SYSTEM_PROPERTY =
49 "org.castor.user.properties.location";
50
51
52
53
54
55 private static final Log LOG = LogFactory.getLog(AbstractProperties.class);
56
57
58
59
60
61 private final ClassLoader _applicationClassLoader;
62
63
64
65
66
67 private final ClassLoader _domainClassLoader;
68
69
70
71
72 private final AbstractProperties _parent;
73
74 private final Map _map = new HashMap();
75
76
77
78
79
80 protected AbstractProperties() {
81 this(null, null);
82 }
83
84
85
86
87
88
89
90 protected AbstractProperties(final ClassLoader app, final ClassLoader domain) {
91 _applicationClassLoader = (app != null) ? app : getClass().getClassLoader();
92 _domainClassLoader = (domain != null) ? domain : getClass().getClassLoader();
93
94 _parent = null;
95 }
96
97
98
99
100
101
102
103 protected AbstractProperties(final AbstractProperties parent) {
104 _applicationClassLoader = parent.getApplicationClassLoader();
105 _domainClassLoader = parent.getDomainClassLoader();
106
107 _parent = parent;
108 }
109
110
111
112
113
114
115 public final ClassLoader getApplicationClassLoader() {
116 return _applicationClassLoader;
117 }
118
119
120
121
122
123
124
125 public final ClassLoader getDomainClassLoader() {
126 return _domainClassLoader;
127 }
128
129
130
131
132
133
134
135
136
137
138
139 protected void loadDefaultProperties(final String path, final String filename) {
140 Properties properties = new Properties();
141
142
143 boolean inCastorJar = loadFromClassPath(properties, path + filename);
144
145
146
147 boolean inJavaLibDir = loadFromJavaHome(properties, filename);
148
149
150 if (!inCastorJar && !inJavaLibDir) {
151 throw new PropertiesException("Failed to load properties: " + filename);
152 }
153
154 _map.putAll(properties);
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168 protected void loadUserProperties(final String filename) {
169 Properties properties = new Properties();
170
171
172 boolean userPropertiesLoaded = loadFromClassPath(properties, "/" + filename);
173
174
175
176 if (!userPropertiesLoaded) {
177 userPropertiesLoaded = loadFromWorkingDirectory(properties, filename);
178 }
179
180 if (!userPropertiesLoaded) {
181 String property = System.getProperty(USER_PROPERTIES_SYSTEM_PROPERTY);
182 if (property != null && property.length() > 0) {
183 File file = new File(property);
184 if (file.exists()) {
185 LOG.info("Loading custom Castor properties from " + file.getAbsolutePath());
186 userPropertiesLoaded = loadFromFile(properties, file);
187 } else {
188 LOG.warn(file.getAbsolutePath() + " is not a valid file.");
189 }
190 }
191 }
192
193 _map.putAll(properties);
194 }
195
196
197
198
199
200
201
202
203 private boolean loadFromClassPath(final Properties properties, final String filename) {
204 InputStream classPathStream = null;
205 try {
206 URL url = getClass().getResource(filename);
207 if (url != null) {
208 classPathStream = url.openStream();
209 properties.load(classPathStream);
210
211 if (LOG.isDebugEnabled()) {
212 LOG.debug("Properties loaded from classpath: " + filename);
213 }
214
215 return true;
216 }
217 return false;
218 } catch (Exception ex) {
219 LOG.warn("Failed to load properties from classpath: " + filename, ex);
220 return false;
221 } finally {
222 if (classPathStream != null) {
223 try {
224 classPathStream.close();
225 } catch (IOException e) {
226 LOG.warn("Failed to close properties from classpath: " + filename);
227 }
228 }
229 }
230 }
231
232
233
234
235
236
237
238
239
240 private boolean loadFromJavaHome(final Properties properties, final String filename) {
241 try {
242 String javaHome = System.getProperty("java.home");
243 if (javaHome == null) { return false; }
244 return loadFromFile(properties, new File(new File(javaHome, "lib"), filename));
245 } catch (SecurityException ex) {
246 LOG.warn("Security policy prevented access to system property 'java.home'.", ex);
247 return false;
248 }
249 }
250
251
252
253
254
255
256
257
258
259 private boolean loadFromWorkingDirectory(final Properties properties, final String filename) {
260 return loadFromFile(properties, new File(filename));
261 }
262
263
264
265
266
267
268
269
270 private boolean loadFromFile(final Properties properties, final File file) {
271 InputStream fileStream = null;
272 try {
273 if (file.exists() && file.canRead()) {
274 fileStream = new FileInputStream(file);
275 properties.load(fileStream);
276
277 if (LOG.isDebugEnabled()) {
278 LOG.debug("Properties file loaded: " + file);
279 }
280
281 return true;
282 }
283 return false;
284 } catch (SecurityException ex) {
285 LOG.warn("Security policy prevented access to properties file: " + file, ex);
286 return false;
287 } catch (Exception ex) {
288 LOG.warn("Failed to load properties file: " + file, ex);
289 return false;
290 } finally {
291 if (fileStream != null) {
292 try {
293 fileStream.close();
294 } catch (IOException e) {
295 LOG.warn("Failed to close properties file: " + file);
296 }
297 }
298 }
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 public final synchronized Object put(final String key, final Object value) {
319 if (value == null) { throw new NullPointerException(); }
320 return _map.put(key, value);
321 }
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337 public final synchronized Object remove(final String key) {
338 return _map.remove(key);
339 }
340
341
342
343
344
345
346
347
348
349
350
351
352 protected synchronized Object get(final String key) {
353 Object value = _map.get(key);
354 if ((value == null) && (_parent != null)) {
355 value = _parent.get(key);
356 }
357 return value;
358 }
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 public final Boolean getBoolean(final String key) {
376 Object objectValue = get(key);
377
378 if (objectValue == null) {
379 return null;
380 } else if (objectValue instanceof Boolean) {
381 return (Boolean) objectValue;
382 } else if (objectValue instanceof String) {
383 String stringValue = (String) objectValue;
384 if ("true".equalsIgnoreCase(stringValue)) {
385 return Boolean.TRUE;
386 } else if ("false".equalsIgnoreCase(stringValue)) {
387 return Boolean.FALSE;
388 }
389 }
390
391 Object[] args = new Object[] {key, objectValue};
392 String msg = "Properties value can not be converted to boolean: {0}={1}";
393 throw new PropertiesException(MessageFormat.format(msg, args));
394 }
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 public final boolean getBoolean(final String key, final boolean defaultValue) {
410 Object objectValue = get(key);
411
412 if (objectValue instanceof Boolean) {
413 return ((Boolean) objectValue).booleanValue();
414 } else if (objectValue instanceof String) {
415 String stringValue = (String) objectValue;
416 if ("true".equalsIgnoreCase(stringValue)) {
417 return true;
418 } else if ("false".equalsIgnoreCase(stringValue)) {
419 return false;
420 }
421 }
422
423 return defaultValue;
424 }
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 public final Integer getInteger(final String key) {
442 Object objectValue = get(key);
443
444 if (objectValue == null) {
445 return null;
446 } else if (objectValue instanceof Integer) {
447 return (Integer) objectValue;
448 } else if (objectValue instanceof String) {
449 try {
450 return Integer.valueOf((String) objectValue);
451 } catch (NumberFormatException ex) {
452 Object[] args = new Object[] {key, objectValue};
453 String msg = "Properties value can not be converted to int: {0}={1}";
454 throw new PropertiesException(MessageFormat.format(msg, args), ex);
455 }
456 }
457
458 Object[] args = new Object[] {key, objectValue};
459 String msg = "Properties value can not be converted to int: {0}={1}";
460 throw new PropertiesException(MessageFormat.format(msg, args));
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476 public final int getInteger(final String key, final int defaultValue) {
477 Object objectValue = get(key);
478
479 if (objectValue instanceof Integer) {
480 return ((Integer) objectValue).intValue();
481 } else if (objectValue instanceof String) {
482 String stringValue = (String) objectValue;
483 try {
484 return Integer.parseInt(stringValue);
485 } catch (NumberFormatException ex) {
486 return defaultValue;
487 }
488 }
489
490 return defaultValue;
491 }
492
493
494
495
496
497
498
499
500
501
502
503
504
505 public final String getString(final String key) {
506 Object objectValue = get(key);
507
508 if (objectValue == null) {
509 return null;
510 } else if (objectValue instanceof String) {
511 return (String) objectValue;
512 }
513
514 Object[] args = new Object[] {key, objectValue};
515 String msg = "Properties value is not a string: {0}={1}";
516 throw new PropertiesException(MessageFormat.format(msg, args));
517 }
518
519
520
521
522
523
524
525
526
527
528
529
530
531 public final String getString(final String key, final String defaultValue) {
532 Object objectValue = get(key);
533
534 if ((objectValue instanceof String) && !"".equals(objectValue)) {
535 return (String) objectValue;
536 }
537
538 return defaultValue;
539 }
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554 public final String[] getStringArray(final String key) {
555 Object objectValue = get(key);
556
557 if (objectValue == null) {
558 return null;
559 } else if (objectValue instanceof String[]) {
560 return (String[]) objectValue;
561 } else if (objectValue instanceof String) {
562 return ((String) objectValue).split(",");
563 }
564
565 Object[] args = new Object[] {key, objectValue};
566 String msg = "Properties value is not a String[]: {0}={1}";
567 throw new PropertiesException(MessageFormat.format(msg, args));
568 }
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584 public final Class getClass(final String key, final ClassLoader loader) {
585 Object objectValue = get(key);
586
587 if (objectValue == null) {
588 return null;
589 } else if (objectValue instanceof Class) {
590 return (Class) objectValue;
591 } else if (objectValue instanceof String) {
592 String classname = (String) objectValue;
593 try {
594 return loader.loadClass(classname);
595 } catch (ClassNotFoundException ex) {
596 Object[] args = new Object[] {key, classname};
597 String msg = "Could not find class of properties value: {0}={1}";
598 throw new PropertiesException(MessageFormat.format(msg, args), ex);
599 }
600 }
601
602 Object[] args = new Object[] {key, objectValue};
603 String msg = "Properties value is not a Class: {0}={1}";
604 throw new PropertiesException(MessageFormat.format(msg, args));
605 }
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622 public final Class[] getClassArray(final String key, final ClassLoader loader) {
623 Object objectValue = get(key);
624
625 if (objectValue == null) {
626 return null;
627 } else if (objectValue instanceof Class[]) {
628 return (Class[]) objectValue;
629 } else if (objectValue instanceof String) {
630 String[] classnames = ((String) objectValue).split(",");
631 Class[] classes = new Class[classnames.length];
632 for (int i = 0; i < classnames.length; i++) {
633 try {
634 classes[i] = loader.loadClass(classnames[i]);
635 } catch (ClassNotFoundException ex) {
636 Object[] args = new Object[] {key, new Integer(i), classnames[i]};
637 String msg = "Could not find class of properties value: {0}[{1}]={2}";
638 throw new PropertiesException(MessageFormat.format(msg, args), ex);
639 }
640 }
641 return classes;
642 }
643
644 Object[] args = new Object[] {key, objectValue};
645 String msg = "Properties value is not a Class[]: {0}={1}";
646 throw new PropertiesException(MessageFormat.format(msg, args));
647 }
648
649
650
651
652
653
654
655
656
657
658
659
660 public final Object getObject(final String key) {
661 return get(key);
662 }
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680 public final Object[] getObjectArray(final String key, final ClassLoader loader) {
681 Object objectValue = get(key);
682
683 if (objectValue == null) {
684 return null;
685 } else if (objectValue instanceof Object[]) {
686 return (Object[]) objectValue;
687 } else if (objectValue instanceof String) {
688 List objects = new ArrayList();
689 String[] classnames = ((String) objectValue).split(",");
690 for (int i = 0; i < classnames.length; i++) {
691 String classname = classnames[i];
692 try {
693 if ((classname != null) && !"".equals(classname.trim())) {
694 classname = classname.trim();
695 objects.add(loader.loadClass(classname).newInstance());
696 }
697 } catch (ClassNotFoundException ex) {
698 Object[] args = new Object[] {key, new Integer(i), classname};
699 String msg = "Could not find configured class: {0}[{1}]={2}";
700 throw new PropertiesException(MessageFormat.format(msg, args), ex);
701 } catch (IllegalAccessException ex) {
702 Object[] args = new Object[] {key, new Integer(i), classname};
703 String msg = "Could not instantiate configured class: {0}[{1}]={2}";
704 throw new PropertiesException(MessageFormat.format(msg, args), ex);
705 } catch (InstantiationException ex) {
706 Object[] args = new Object[] {key, new Integer(i), classname};
707 String msg = "Could not instantiate configured class: {0}[{1}]={2}";
708 throw new PropertiesException(MessageFormat.format(msg, args), ex);
709 } catch (ExceptionInInitializerError ex) {
710 Object[] args = new Object[] {key, new Integer(i), classname};
711 String msg = "Could not instantiate configured class: {0}[{1}]={2}";
712 throw new PropertiesException(MessageFormat.format(msg, args), ex);
713 } catch (SecurityException ex) {
714 Object[] args = new Object[] {key, new Integer(i), classname};
715 String msg = "Could not instantiate configured class: {0}[{1}]={2}";
716 throw new PropertiesException(MessageFormat.format(msg, args), ex);
717 }
718 }
719 return objects.toArray();
720 }
721
722 Object[] args = new Object[] {key, objectValue};
723 String msg = "Properties value is not an Object[]: {0}={1}";
724 throw new PropertiesException(MessageFormat.format(msg, args));
725 }
726
727 }