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 }