KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > util > Property


1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: Property.java,v 1.1.1.1.2.4 2004/07/16 23:32:04 vlad_r Exp $
8  */

9 package com.vladium.util;
10
11 import java.io.BufferedInputStream JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.FileInputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.util.Enumeration JavaDoc;
17 import java.util.Hashtable JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Properties JavaDoc;
21
22 /*
23  * NOTE: to avoid certain build problems, this class should use only
24  * core Java APIs and not any app infrastructure.
25  */

26
27 // ----------------------------------------------------------------------------
28
/**
29  * @author Vlad Roubtsov, (C) 2003
30  */

31 public
32 abstract class Property
33 {
34     // public: ................................................................
35

36
37     public static boolean toBoolean (final String JavaDoc value)
38     {
39         if (value == null)
40             return false;
41         else
42             return value.startsWith ("t") || value.startsWith ("y");
43     }
44
45     
46     /**
47      * NOTE: this does not guarantee that the result will be mutatable
48      * independently from 'overrides' or 'base', so this method
49      * should be used for read-only property only
50      *
51      * @param overrides [null is equivalent to empty]
52      * @param base [null is equivalent to empty]
53      *
54      * @return [never null, could be empty]
55      */

56     public static Properties JavaDoc combine (final Properties JavaDoc overrides, final Properties JavaDoc base)
57     {
58         // note: no defensive copies here
59

60         if (base == null)
61         {
62             if (overrides == null)
63                 return new XProperties ();
64             else
65                 return overrides;
66         }
67         
68         // [assertion: base != null]
69

70         if (overrides == null) return base;
71         
72         // [assertion: both 'overrides' and 'base' are not null]
73

74         final Properties JavaDoc result = new XProperties (base);
75         
76         // note: must use propertyNames() because that is the only method that recurses
77
// into possible bases inside 'overrides'
78

79         for (Enumeration JavaDoc overrideNames = overrides.propertyNames (); overrideNames.hasMoreElements (); )
80         {
81             final String JavaDoc n = (String JavaDoc) overrideNames.nextElement ();
82             final String JavaDoc v = overrides.getProperty (n);
83             
84             result.setProperty (n, v);
85         }
86         
87         return result;
88     }
89     
90     /**
91      * Creates a set of properties for an application with a given namespace.
92      * This method is not property aliasing-aware.
93      *
94      * @param namespace application namespace [may not be null]
95      * @param loader classloader to use for any classloader resource lookups
96      * [null is equivalent to the applicaton classloader]
97      * @return application properties [never null, a new instance is created
98      * on each invocation]
99      */

100     public static Properties JavaDoc getAppProperties (final String JavaDoc namespace, final ClassLoader JavaDoc loader)
101     {
102         if (namespace == null)
103             throw new IllegalArgumentException JavaDoc ("null properties: appNameLC");
104         
105         final Properties JavaDoc appDefaults = Property.getProperties (namespace + "_default.properties", loader);
106         final Properties JavaDoc systemFileOverrides;
107         {
108             final String JavaDoc fileName = Property.getSystemProperty (namespace + ".properties");
109             final File JavaDoc file = fileName != null
110                 ? new File JavaDoc (fileName)
111                 : null;
112
113             systemFileOverrides = Property.getLazyPropertiesFromFile (file);
114         }
115         final Properties JavaDoc systemOverrides = Property.getSystemProperties (namespace);
116         final Properties JavaDoc resOverrides = Property.getProperties (namespace + ".properties", loader);
117         
118         return combine (resOverrides,
119                combine (systemOverrides,
120                combine (systemFileOverrides,
121                         appDefaults)));
122     }
123     
124     public static Properties JavaDoc getSystemProperties (final String JavaDoc systemPrefix)
125     {
126         // note: this method is not synchronized on purpose
127

128         Properties JavaDoc result = s_systemProperties;
129         if (result == null)
130         {
131             result = new SystemPropertyLookup (systemPrefix);
132             
133             s_systemProperties = result;
134             return result;
135         }
136         
137         return result;
138     }
139     
140     public static Properties JavaDoc getSystemPropertyRedirects (final Map JavaDoc systemRedirects)
141     {
142         // note: this method is not synchronized on purpose
143

144         Properties JavaDoc result = s_systemRedirects;
145         if (result == null)
146         {
147             result = new SystemRedirectsLookup (systemRedirects);
148             
149             s_systemRedirects = result;
150             return result;
151         }
152         
153         return result;
154     }
155
156
157     public static String JavaDoc getSystemFingerprint ()
158     {
159         // [not synchronized intentionally]
160

161         if (s_systemFingerprint != null)
162             return s_systemFingerprint;
163         else
164         {
165             final StringBuffer JavaDoc s = new StringBuffer JavaDoc ();
166             final char delimiter = ':';
167             
168             s.append (getSystemProperty ("java.vm.name", ""));
169             s.append (delimiter);
170             s.append (getSystemProperty ("java.vm.version", ""));
171             s.append (delimiter);
172             s.append (getSystemProperty ("java.vm.vendor", ""));
173             s.append (delimiter);
174             s.append (getSystemProperty ("os.name", ""));
175             s.append (delimiter);
176             s.append (getSystemProperty ("os.version", ""));
177             s.append (delimiter);
178             s.append (getSystemProperty ("os.arch", ""));
179             
180             s_systemFingerprint = s.toString ();
181             return s_systemFingerprint;
182         }
183     }
184     
185     public static String JavaDoc getSystemProperty (final String JavaDoc key)
186     {
187         try
188         {
189             return System.getProperty (key);
190         }
191         catch (SecurityException JavaDoc se)
192         {
193             return null;
194         }
195     }
196     
197     public static String JavaDoc getSystemProperty (final String JavaDoc key, final String JavaDoc def)
198     {
199         try
200         {
201             return System.getProperty (key, def);
202         }
203         catch (SecurityException JavaDoc se)
204         {
205             return def;
206         }
207     }
208     
209     /**
210      * does not throw
211      *
212      * @param name
213      * @return
214      */

215     public static Properties JavaDoc getProperties (final String JavaDoc name)
216     {
217         Properties JavaDoc result = null;
218         
219         InputStream JavaDoc in = null;
220         try
221         {
222             in = ResourceLoader.getResourceAsStream (name);
223             if (in != null)
224             {
225                 result = new XProperties ();
226                 result.load (in);
227             }
228         }
229         catch (Throwable JavaDoc t)
230         {
231             result = null;
232         }
233         finally
234         {
235             if (in != null) try { in.close (); } catch (Throwable JavaDoc ignore) {}
236             in = null;
237         }
238         
239         return result;
240     }
241     
242     /**
243      * does not throw
244      *
245      * @param name
246      * @param loader
247      * @return
248      */

249     public static Properties JavaDoc getProperties (final String JavaDoc name, final ClassLoader JavaDoc loader)
250     {
251         Properties JavaDoc result = null;
252         
253         InputStream JavaDoc in = null;
254         try
255         {
256             in = ResourceLoader.getResourceAsStream (name, loader);
257             if (in != null)
258             {
259                 result = new XProperties ();
260                 result.load (in);
261             }
262         }
263         catch (Throwable JavaDoc t)
264         {
265             result = null;
266         }
267         finally
268         {
269             if (in != null) try { in.close (); } catch (Throwable JavaDoc ignore) {}
270             in = null;
271         }
272         
273         return result;
274     }
275
276     /**
277      * Loads 'file' as a .properties file.
278      *
279      * @param file [may not be null]
280      * @return read properties [never null]
281      * @throws IOException on any file I/O errors
282      */

283     public static Properties JavaDoc getPropertiesFromFile (final File JavaDoc file)
284         throws IOException JavaDoc
285     {
286         if (file == null)
287             throw new IllegalArgumentException JavaDoc ("null input: file");
288         
289         Properties JavaDoc result = null;
290         
291         InputStream JavaDoc in = null;
292         try
293         {
294             in = new BufferedInputStream JavaDoc (new FileInputStream JavaDoc (file), 8 * 1024);
295
296             result = new XProperties ();
297             result.load (in);
298         }
299         finally
300         {
301             if (in != null) try { in.close (); } catch (Throwable JavaDoc ignore) {}
302             in = null;
303         }
304         
305         return result;
306     }
307
308     /**
309      * Returns a lazy property implementation that will read 'load' as a .properties
310      * file on first use. If there are any file I/O errors when reading the file,
311      * they will be thrown as runtime exceptions (also on first use).
312      *
313      * @param file [can be null, which results in an empty property set returned]
314      * @return [never null]
315      */

316     public static Properties JavaDoc getLazyPropertiesFromFile (final File JavaDoc file)
317     {
318         return new FilePropertyLookup (file);
319     }
320     
321     // protected: .............................................................
322

323     // package: ...............................................................
324

325     // private: ...............................................................
326

327     
328     private static final class FilePropertyLookup extends XProperties
329     {
330         // note: due to incredibly stupid coding in java.util.Properties
331
// (getProperty() uses a non-virtual call to get(), while propertyNames()
332
// uses a virtual call to the same instead of delegating to getProperty())
333
// I must override both methods below
334

335         public String JavaDoc getProperty (final String JavaDoc key)
336         {
337             faultContents ();
338             
339             return m_contents.getProperty (key);
340         }
341             
342         public Object JavaDoc get (final Object JavaDoc key)
343         {
344             faultContents ();
345             
346             return m_contents.get (key);
347         }
348         
349         /*
350          * Overrides Properties.keys () [this is used for debug logging only]
351          */

352         public Enumeration JavaDoc keys ()
353         {
354             faultContents ();
355             
356             return m_contents.keys ();
357         }
358
359
360         /**
361          * Creates a lazy property lookup based on 'src' contents.
362          *
363          * @param src [null will result in empty property set created]
364          */

365         FilePropertyLookup (final File JavaDoc src)
366         {
367             m_src = src;
368         }
369         
370         /*
371          * @throws RuntimeException on file I/O failures.
372          */

373         private synchronized void faultContents ()
374         {
375             Properties JavaDoc contents = m_contents;
376             if ((contents == null) && (m_src != null))
377             {
378                 try
379                 {
380                     contents = getPropertiesFromFile (m_src);
381                 }
382                 catch (RuntimeException JavaDoc re)
383                 {
384                     throw re; // re-throw;
385
}
386                 catch (Exception JavaDoc e)
387                 {
388                     throw new RuntimeException JavaDoc ("exception while processing properties file [" + m_src.getAbsolutePath () + "]: " + e);
389                 }
390             }
391             
392             if (contents == null)
393             {
394                 contents = new XProperties (); // non-null marker
395
}
396             
397             m_contents = contents;
398         }
399         
400
401         private final File JavaDoc m_src; // can be null
402
private Properties JavaDoc m_contents; // non-null after faultContents()
403

404     } // end of nested class
405

406
407     private static final class SystemPropertyLookup extends XProperties
408     {
409         // note: due to incredibly stupid coding in java.util.Properties
410
// (getProperty() uses a non-virtual call to get(), while propertyNames()
411
// uses a virtual call to the same instead of delegating to getProperty())
412
// I must override both methods below
413

414         public String JavaDoc getProperty (final String JavaDoc key)
415         {
416             return (String JavaDoc) get (key);
417         }
418             
419         public Object JavaDoc get (final Object JavaDoc key)
420         {
421             if (! (key instanceof String JavaDoc)) return null;
422             
423             String JavaDoc result = (String JavaDoc) super.get (key);
424             if (result != null) return result;
425             
426             if (m_systemPrefix != null)
427             {
428                 result = getSystemProperty (m_systemPrefix.concat ((String JavaDoc) key), null);
429                 
430                 if (result != null) return result;
431             }
432             
433             return result;
434         }
435         
436         /*
437          * Overrides Properties.keys () [this is used for debug logging only]
438          */

439         public synchronized Enumeration JavaDoc keys ()
440         {
441             final Hashtable JavaDoc _propertyNames = new Hashtable JavaDoc ();
442             
443             if (m_systemPrefix != null)
444             {
445                 try
446                 {
447                     final int systemPrefixLength = m_systemPrefix.length ();
448                     
449                     for (Enumeration JavaDoc e = System.getProperties ().propertyNames ();
450                          e.hasMoreElements (); )
451                     {
452                         final String JavaDoc n = (String JavaDoc) e.nextElement ();
453                         
454                         if (n.startsWith (m_systemPrefix))
455                         {
456                             final String JavaDoc yn = n.substring (systemPrefixLength);
457                             
458                             _propertyNames.put (yn, yn);
459                         }
460                     }
461                 }
462                 catch (SecurityException JavaDoc ignore)
463                 {
464                     ignore.printStackTrace (System.out);
465                     
466                     // continue
467
}
468             }
469             
470             return _propertyNames.keys ();
471         }
472
473                 
474         SystemPropertyLookup (String JavaDoc systemPrefix)
475         {
476             if ((systemPrefix != null) && ! systemPrefix.endsWith ("."))
477                 systemPrefix = systemPrefix.concat (".");
478                 
479             m_systemPrefix = systemPrefix;
480         }
481         
482         
483         private final String JavaDoc m_systemPrefix; // can be null [if not null, normalized to end with "."]
484

485     } // end of nested class
486

487     
488     private static final class SystemRedirectsLookup extends XProperties
489     {
490         // note: due to incredibly stupid coding in java.util.Properties
491
// (getProperty() uses a non-virtual call to get(), while propertyNames()
492
// uses a virtual call to the same instead of delegating to getProperty())
493
// I must override both methods below
494

495         public String JavaDoc getProperty (final String JavaDoc key)
496         {
497             return (String JavaDoc) get (key);
498         }
499             
500         public Object JavaDoc get (final Object JavaDoc key)
501         {
502             if (! (key instanceof String JavaDoc)) return null;
503             
504             String JavaDoc result = (String JavaDoc) super.get (key);
505             if (result != null) return result;
506             
507             if (m_systemRedirects != null)
508             {
509                 final String JavaDoc redirect = (String JavaDoc) m_systemRedirects.get (key);
510                 
511                 if (redirect != null)
512                 {
513                     result = getSystemProperty (redirect, null);
514                     if (result != null) return result;
515                 }
516             }
517             
518             return result;
519         }
520         
521         /*
522          * Overrides Properties.keys () [this is used for debug logging only]
523          */

524         public synchronized Enumeration JavaDoc keys ()
525         {
526             final Hashtable JavaDoc _propertyNames = new Hashtable JavaDoc ();
527             
528             if (m_systemRedirects != null)
529             {
530                 for (Iterator JavaDoc i = m_systemRedirects.keySet ().iterator ();
531                      i.hasNext (); )
532                 {
533                     final Object JavaDoc key = i.next ();
534                     if (key != null) _propertyNames.put (key , key);
535                 }
536             }
537             
538             return _propertyNames.keys ();
539         }
540
541                 
542         SystemRedirectsLookup (final Map JavaDoc systemRedirects)
543         {
544             m_systemRedirects = systemRedirects; // note: no defensive copy
545
}
546         
547         
548         private final Map JavaDoc m_systemRedirects; // can be null
549

550     } // end of nested class
551

552     
553     private static String JavaDoc s_systemFingerprint;
554     private static Properties JavaDoc s_systemProperties, s_systemRedirects;
555     
556 } // end of class
557
// ----------------------------------------------------------------------------
Popular Tags