View Javadoc
1   /*
2    * $Source$
3    * $Revision$
4    *
5    * Copyright (C) 2000 William Chesters
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     William Chesters <williamc AT paneris.org>
42   *     http://paneris.org/~williamc
43   *     Obrechtstraat 114, 2517VX Den Haag, The Netherlands
44   */
45  
46  package org.melati.util;
47  
48  import java.util.Hashtable;
49  import java.util.Properties;
50  import java.io.File;
51  import java.io.InputStream;
52  import java.io.FileInputStream;
53  import java.io.IOException;
54  import java.io.FileNotFoundException;
55  
56  /**
57   * Useful things to do with properties files.
58   */
59  public final class PropertiesUtils {
60  
61    private PropertiesUtils() {}
62  
63    /**
64     * Get a {@link Properties} object from a file.
65     * 
66     * @param path a {@link File} path name
67     * @return a {@link Properties} object
68     * @throws IOException if there is a problem loading the file
69     */
70    public static Properties fromFile(File path) throws IOException {
71      InputStream data = new FileInputStream(path);
72      Properties them = new Properties();
73      try {
74        them.load(data);
75      } catch (IOException e) {
76        throw new IOException("Corrupt properties file `" + path + "': " +
77        e.getMessage());
78      }
79  
80      return them;
81    }
82    
83    public static Properties fromResource(Class<?> clazz)
84          throws IOException {
85      String name = clazz.getCanonicalName() + ".properties";
86      return fromResource(clazz, name);
87    }
88  
89    /**
90     * Get a {@link Properties} object from a {@link Class}.
91     * 
92     * 
93     * @param clazz the {@link Class} to look up
94     * @param name the property file name
95     * @return a {@link Properties} object
96     * @throws IOException if the file cannot load or is not found
97     */
98    public static Properties fromResource(Class<?> clazz, String name)
99        throws IOException {
100     InputStream is = clazz.getResourceAsStream(name);
101 
102     if (is == null)
103       throw new FileNotFoundException(name + ": is it in CLASSPATH?");
104 
105     Properties them = new Properties();
106     try {
107       them.load(is);
108     } catch (IOException e) {
109       throw new IOException("Corrupt properties file `" + name + "': " +
110       e.getMessage());
111     }
112 
113     return them;
114   }
115 
116   /**
117    * Return a property.
118    * 
119    * @param properties the {@link Properties} object to look in 
120    * @param propertyName the property to get 
121    * @return the property value
122    * @throws NoSuchPropertyException if the property is not set
123    */
124   public static String getOrDie(Properties properties, String propertyName)
125       throws NoSuchPropertyException {
126     String value = properties.getProperty(propertyName);
127     if (value == null)
128       throw new NoSuchPropertyException(properties, propertyName);
129     return value;
130   }
131 
132   /**
133    * Get a property or return the supplied default.
134    * 
135    * @param properties the {@link Properties} object to look in 
136    * @param propertyName the property to get 
137    * @param def the default to return if not found
138    * @return the property value
139    */
140   public static String getOrDefault(Properties properties, 
141                                     String propertyName, String def) {
142     String value = properties.getProperty(propertyName);
143     if (value == null) return def;
144     return value;
145   }
146 
147   /**
148    * Get an Integer property.
149    * 
150    * @param properties the {@link Properties} object to look in 
151    * @param propertyName the property to get 
152    * @return the int property value 
153    * @throws NoSuchPropertyException if it is not found
154    * @throws FormatPropertyException if it is not an Integer 
155    */
156   public static int getOrDie_int(Properties properties, String propertyName)
157       throws NoSuchPropertyException, FormatPropertyException {
158     String string = getOrDie(properties, propertyName);
159     try {
160       return Integer.parseInt(string);
161     }
162     catch (NumberFormatException e) {
163       throw new FormatPropertyException(properties, propertyName, string,
164       "an integer", e);
165     }
166   }
167 
168   /**
169    * Get an Integer property from a {@link Properties} object or make a fuss. 
170    * 
171    * @param properties a {@link Properties} 
172    * @param propertyName the name of the property
173    * @param def cater for multiple definitions, with increment numbers
174    * @return the property as an int 
175    * @throws FormatPropertyException if it is not an Integer 
176    */
177   public static int getOrDefault_int(Properties properties, 
178                                      String propertyName, int def)
179       throws FormatPropertyException {
180     String string = getOrDefault(properties, propertyName, ""+def);
181     try {
182       return Integer.parseInt(string);
183     }
184     catch (NumberFormatException e) {
185       throw new FormatPropertyException(properties, propertyName, string,
186       "an integer", e);
187     }
188   }
189 
190   private static Hashtable<String, Object> instantiatedClassesCache = new Hashtable<String, Object>();
191   /**
192    * Instantiate an interface.
193    * 
194    * @param className the name of the class
195    * @param interfaceClassName the interface Class name
196    * @return a new object
197    * @throws InstantiationPropertyException 
198    *   if the named class does not descend from the interface
199    */
200   public static Object instanceOfNamedClass(String className, String interfaceClassName)
201       throws InstantiationPropertyException {
202     Object cached = instantiatedClassesCache.get(className);
203     if (cached != null)
204       return cached;
205     try {
206       Class<?> clazz = Class.forName(className);
207       if (interfaceClassName != null) {
208         Class<?> interfaceClass = Class.forName(interfaceClassName);
209         if (!interfaceClass.isAssignableFrom(clazz))
210           throw new ClassCastException(
211                 clazz + " is not descended from " + interfaceClass);
212       }
213       Object it = clazz.newInstance();
214       instantiatedClassesCache.put(className, it);
215       return it;
216     } catch (Exception e) {
217       throw new InstantiationPropertyException(className, e);
218     }
219   }
220 
221   /**
222    * Instantiate a Class.
223    * 
224    * @param properties a {@link Properties} 
225    * @param propertyName the name of the property
226    * @param interfaceClassName     the interface name
227    * @param defaultName  a default concrete class if the property is undefined
228    * @return a new Object
229    * @throws InstantiationPropertyException if there is a problem
230    */
231   public static Object instanceOfNamedClass(Properties properties, 
232                                             String propertyName,
233                                             String interfaceClassName, 
234                                             String defaultName)
235   throws InstantiationPropertyException {
236     String className =  (String)properties.get(propertyName);
237     return instanceOfNamedClass(className == null ? defaultName : className, interfaceClassName);
238   }
239 }