Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: hk/hku/cecid/phoenix/common/util/Property.java


1   /*
2    * Academic Free License
3    * Version 1.0
4    *
5    * This Academic Free License applies to any software and associated 
6    * documentation (the "Software") whose owner (the "Licensor") has placed the 
7    * statement "Licensed under the Academic Free License Version 1.0" immediately 
8    * after the copyright notice that applies to the Software. 
9    *
10   * Permission is hereby granted, free of charge, to any person obtaining a copy 
11   * of the Software (1) to use, copy, modify, merge, publish, perform, 
12   * distribute, sublicense, and/or sell copies of the Software, and to permit 
13   * persons to whom the Software is furnished to do so, and (2) under patent 
14   * claims owned or controlled by the Licensor that are embodied in the Software 
15   * as furnished by the Licensor, to make, use, sell and offer for sale the 
16   * Software and derivative works thereof, subject to the following conditions: 
17   *
18   * - Redistributions of the Software in source code form must retain all 
19   *   copyright notices in the Software as furnished by the Licensor, this list 
20   *   of conditions, and the following disclaimers. 
21   * - Redistributions of the Software in executable form must reproduce all 
22   *   copyright notices in the Software as furnished by the Licensor, this list 
23   *   of conditions, and the following disclaimers in the documentation and/or 
24   *   other materials provided with the distribution. 
25   * - Neither the names of Licensor, nor the names of any contributors to the 
26   *   Software, nor any of their trademarks or service marks, may be used to 
27   *   endorse or promote products derived from this Software without express 
28   *   prior written permission of the Licensor. 
29   *
30   * DISCLAIMERS: LICENSOR WARRANTS THAT THE COPYRIGHT IN AND TO THE SOFTWARE IS 
31   * OWNED BY THE LICENSOR OR THAT THE SOFTWARE IS DISTRIBUTED BY LICENSOR UNDER 
32   * A VALID CURRENT LICENSE. EXCEPT AS EXPRESSLY STATED IN THE IMMEDIATELY 
33   * PRECEDING SENTENCE, THE SOFTWARE IS PROVIDED BY THE LICENSOR, CONTRIBUTORS 
34   * AND COPYRIGHT OWNERS "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
35   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
36   * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 
37   * LICENSOR, CONTRIBUTORS OR COPYRIGHT OWNERS BE LIABLE FOR ANY CLAIM, DAMAGES 
38   * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
39   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE. 
40   *
41   * This license is Copyright (C) 2002 Lawrence E. Rosen. All rights reserved. 
42   * Permission is hereby granted to copy and distribute this license without 
43   * modification. This license may not be modified without the express written 
44   * permission of its copyright owner. 
45   */
46  
47  /* ===== 
48   *
49   * $Header: /ebxml/staff/cecid/cvs_repository/common/src/hk/hku/cecid/phoenix/common/util/Property.java,v 1.14 2002/12/13 03:59:03 kcyee Exp $
50   *
51   * Code authored by:
52   *
53   * kcyee [2002-05-27]
54   *
55   * Code reviewed by:
56   *
57   * username [YYYY-MM-DD]
58   *
59   * Remarks:
60   *
61   * =====
62   */
63  
64  package hk.hku.cecid.phoenix.common.util;
65  
66  import java.io.File;
67  import java.io.IOException;
68  import java.net.URL;
69  import java.util.Hashtable;
70  import java.util.Vector;
71  
72  /**
73   * This is an abstract class for property file reader. We may implement 
74   * XML based, or plain text based, or encrypted property file reader out 
75   * of this abstract class. This interface is defining some common methods
76   * needed by all kinds of property readers.
77   *
78   * @author kcyee
79   * @version $Revision: 1.14 $
80   */
81  public abstract class Property {
82  
83      /**
84       * Singleton instance of text property object for each location
85       */
86      private static Hashtable loadedProps = new Hashtable();
87  
88      /**
89       * Cache of property values
90       */
91      protected Hashtable cache;
92  
93      /**
94       * System property name for location property file
95       */
96      protected final static String PROP_HOME = "prop.home";
97  
98      /** 
99       * Default constructor
100      */
101     Property() {
102         cache = new Hashtable();
103     }
104 
105     /**
106      * Gets the property value from cache. Try to see if the property value
107      * has been retrieved previously.
108      *
109      * @param path the path (key) of the property
110      * @return the property value given the path (key), null if not found
111      */
112     protected String getFromCache(String path) {
113         if (path == null) {
114             return null;
115         }
116         return (String) cache.get(path);
117     }
118 
119     /**
120      * Saves the property value to cache.
121      *
122      * @param path the path (key) of the property
123      * @param value the property value of the specified property key
124      */
125     protected void saveToCache(String path, String value) {
126         if (path == null) {
127             return;
128         }
129 
130         if (value == null) {
131             cache.remove(path);
132         }
133         else {
134             cache.put(path, value);
135         }
136     }
137 
138     /**
139      * Removes the property value from cache.
140      *
141      * @param path the path (key) of the property
142      */
143     protected void removeFromCache(String path) {
144         saveToCache(path, null);
145     }
146 
147     /**
148      * Reloads the property file.
149      */
150     public void reload() {
151         cache.clear();
152     }
153 
154     /**
155      * Gets the property value given the path (key). Multiple values are
156      * referenced by the same path will be returned using a String array.
157      *
158      * @param path the path (key) of the property
159      * @return the property values given the path (key)
160      */
161     public abstract String[] getMultiple(String path);
162 
163     /**
164      * Gets the property value given the path (key).
165      *
166      * @param path the path (key) of the property
167      * @return the property value given the path (key)
168      */
169     public abstract String get(String path);
170 
171     /**
172      * Gets the property value given the path (key). If the property value
173      * is not found, the default value passed in is returned.
174      *
175      * @param path the path (key) of the property
176      * @param defaultValue the value to be returned if the property value
177      *                     is not found
178      * @return the property value given the path (key)
179      */
180     public abstract String get(String path, String defaultValue);
181 
182     /**
183      * Sets the property value of the given path (key).
184      *
185      * @param path the path (key) of the property to be set
186      * @param value the property value to be set
187      */
188     public abstract void set(String path, String value);
189 
190     /**
191      * Saves the property object to the same location when loading.
192      *
193      * @throws IOException when error occurs when saving the property object
194      */
195     public abstract void save() throws IOException;
196 
197     /**
198      * Saves the property object to the specified location.
199      *
200      * @param location the location for saving the property object
201      * @throws IOException when error occurs when saving the property object
202      */
203     public abstract void save(String location) throws IOException;
204 
205     /**
206      * Default file name of property file
207      */
208     protected static final String DEFAULT_FILENAME = "phoenix.properties.xml";
209 
210     /**
211      * Loads the default property object out of the default location. 
212      * The default filename is phoenix.properties.xml. We search for the 
213      * default properties file in the following locations in that order:
214      * 1. The directory pointed by the system property prop.home
215      * 2. The directories in classpath
216      * 3. The current working directory
217      * 4. The current user's home directory
218      *
219      * @return the property object loaded
220      * @throws IOException when error occurs when loading the property object
221      */
222     public static synchronized Property load() throws IOException {
223         return load(DEFAULT_FILENAME);
224     }
225 
226     /**
227      * Reloads the property object out of a given location. The property
228      * object will be reloaded even if it has been cached before. Currently
229      * only 2 types of property objects are supported: text-based and
230      * XML-based. The location is interpreted as file path in both
231      * cases. We search for the properties file in the following locations 
232      * in that order:
233      * 1. The directory pointed by the system property prop.home
234      * 2. The directories in classpath
235      * 3. The current working directory
236      * 4. See if the location is a full path
237      * 5. The current user's home directory
238      *
239      * @param location the location for loading the property object
240      * @return the property object loaded
241      * @throws IOException when error occurs when loading the property object
242      */
243     public static synchronized Property reload(String location)
244         throws IOException {
245         loadedProps.remove(location);
246         return load(location);
247     }
248 
249     /**
250      * Loads the property object out of a given location. Currently
251      * only 2 types of property objects are supported: text-based and
252      * XML-based. The location is interpreted as file path in both
253      * cases. We search for the properties file in the following locations 
254      * in that order:
255      * 1. The directory pointed by the system property prop.home
256      * 2. The directories in classpath
257      * 3. The current working directory
258      * 4. See if the location is a full path
259      * 5. The current user's home directory
260      *
261      * @param location the location for loading the property object
262      * @return the property object loaded
263      * @throws IOException when error occurs when loading the property object
264      */
265     public static synchronized Property load(String location)
266         throws IOException {
267         if (location == null) {
268             throw new IOException("Cannot load <null>!");
269         }
270 
271         if (loadedProps.get(location) != null) {
272             return (Property) loadedProps.get(location);
273         }
274 
275         Vector locationTried = new Vector();
276 
277         String fileSep = System.getProperty("file.separator");
278         String propDir = System.getProperty(PROP_HOME);
279         String curDir = (new File(".")).getCanonicalPath();
280         String homeDir = System.getProperty("user.home");
281 
282         // try user-defined system property "prop.home"
283         try {
284             if (propDir != null) {
285                 Property prop = loadFromFullPath(
286                     propDir + fileSep + location);
287                 loadedProps.put(location, prop);
288                 System.err.println("Info: using property file in " 
289                     + propDir + fileSep + location);
290                 return prop;
291             }
292             else {
293                 locationTried.add("<prop.home> environment variable");
294             }
295         }
296         catch (IOException e) {
297             System.err.println(e.getMessage());
298         }
299         // try classpath...
300         try {
301             URL url = Property.class.getClassLoader()
302                         .getResource(location);
303             if (url != null) {
304                 Property prop = loadFromFullPath(url.getFile());
305                 loadedProps.put(location, prop);
306                 System.err.println("Info: using property file in "
307                     + url.getFile());
308                 return prop;
309             }
310             else {
311                 locationTried.add("Classpath");
312             }
313         }
314         catch (IOException e) {
315             System.err.println(e.getMessage());
316         }
317         // try current directory...
318         try {
319             File file = new File(curDir + fileSep + location);
320             if (!locationTried.contains(file.getCanonicalPath())) {
321                 if (file.exists()) {
322                     Property prop = loadFromFullPath(file.getCanonicalPath());
323                     loadedProps.put(location, prop);
324                     System.err.println("Info: using property file in "
325                         + file.getCanonicalPath());
326                     return prop;
327                 }
328                 else {
329                     locationTried.add(file.getCanonicalPath());
330                 }
331             }
332         }
333         catch (IOException e) {
334             System.err.println(e.getMessage());
335         }
336         // try if the location is full path...
337         try {
338             File file = new File(location);
339             if (!locationTried.contains(file.getCanonicalPath())) {
340                 if (file.exists()) {
341                     Property prop = loadFromFullPath(file.getCanonicalPath());
342                     loadedProps.put(location, prop);
343                     System.err.println("Info: using property file in "
344                         + file.getCanonicalPath());
345                     return prop;
346                 }
347                 else {
348                     locationTried.add(file.getCanonicalPath());
349                 }
350             }
351         }
352         catch (IOException e) {
353             System.err.println(e.getMessage());
354         }
355         // try user's home directory...
356         try {
357             File file = new File(homeDir + fileSep + location);
358             if (!locationTried.contains(file.getCanonicalPath())) {
359                 if (file.exists()) {
360                     Property prop = loadFromFullPath(file.getCanonicalPath());
361                     loadedProps.put(location, prop);
362                     System.err.println("Info: using property file in "
363                         + file.getCanonicalPath());
364                     return prop;
365                 }
366                 else {
367                     locationTried.add(file.getCanonicalPath());
368                 }
369             }
370         }
371         catch (IOException e) {
372             System.err.println(e.getMessage());
373         }
374 
375         String message = 
376             "Cannot find property file in the following locations:";
377         for (int i=0 ; i<locationTried.size() ; i++) {
378             message = message + "\n    " + (i+1) + ". " + locationTried.get(i);
379         }
380         message = message + "\n\n";
381         throw new IOException(message);
382     }
383 
384     /**
385      * Loads the property file based on a full path. This function will
386      * dispatch the Property file type by the extension of the specified
387      * path.
388      *
389      * @param location the full path of the location of the file
390      * @return the property object loaded
391      * @throws IOException when error occurs when loading the property object
392      */
393     protected static synchronized Property loadFromFullPath(String location) 
394         throws IOException {
395         if (location.toUpperCase().endsWith(".XML")) {
396             return new XMLProperty(location);
397         }
398         else {
399             return new TextProperty(location);
400         }
401     }
402 }