001: package org.obe.util;
002:
003: import org.apache.commons.logging.Log;
004: import org.apache.commons.logging.LogFactory;
005: import org.obe.OBERuntimeException;
006: import org.xml.sax.InputSource;
007:
008: import java.io.*;
009: import java.net.URL;
010: import java.util.Properties;
011:
012: /**
013: * Provides common configuration-related functionality.
014: *
015: * @author Adrian Price
016: */
017: public class CommonConfig {
018: protected static final Log _logger = LogFactory
019: .getLog(CommonConfig.class);
020: private static final String SERVICES_DIR = "META-INF/services/";
021: protected static final String CONFIG_FILE = "obe.properties";
022: /**
023: * Property key for the default client protocol type.
024: *
025: * @see #getProtocol()
026: */
027: public static final String PROTOCOL_PROP = "obe.client.protocol";
028: /**
029: * Property key for the default JAAS principal name.
030: *
031: * @see #getPrincipal()
032: */
033: public static final String PRINCIPAL_PROP = "obe.client.principal";
034: /**
035: * Property key for the default JAAS credentials.
036: *
037: * @see #getCredentials()
038: */
039: public static final String CREDENTIALS_PROP = "obe.client.credentials";
040: /**
041: * Property key for the configuration directory.
042: *
043: * @see #getConfigDir()
044: */
045: public static final String CONFIG_DIR_PROP = "obe.config.dir";
046: /**
047: * Property key for the default date format.
048: *
049: * @see #getDefaultDateFormat()
050: */
051: public static final String DATE_FORMAT_PROP = "obe.xpdl.date.format";
052: /**
053: * Property key for the default duration unit.
054: *
055: * @see #getDefaultDurationUnit()
056: */
057: public static final String DURATION_UNIT_PROP = "obe.xpdl.duration.unit";
058: protected static final Properties _props = new Properties(System
059: .getProperties());
060: private static final File _configDir;
061:
062: static {
063: _configDir = new File(System.getProperty(CONFIG_DIR_PROP, "."));
064: InputStream in = openInputStream(CONFIG_FILE);
065: if (in != null) {
066: try {
067: _props.load(in);
068: } catch (IOException e) {
069: throw new OBERuntimeException(e);
070: } finally {
071: try {
072: in.close();
073: } catch (IOException e) {
074: throw new OBERuntimeException(e);
075: }
076: }
077: }
078: }
079:
080: protected static boolean getBooleanProperty(String propertyName,
081: boolean defaultValue) {
082:
083: String property = _props.getProperty(propertyName);
084: return property == null ? defaultValue : Boolean.valueOf(
085: property).booleanValue();
086: }
087:
088: protected static int getIntProperty(String propertyName,
089: int defaultValue) {
090: String property = _props.getProperty(propertyName);
091: return property == null ? defaultValue : Integer
092: .parseInt(property);
093: }
094:
095: protected static String getStringProperty(String propertyName,
096: String defaultValue) {
097:
098: return _props.getProperty(propertyName, defaultValue);
099: }
100:
101: /**
102: * Returns the configuration directory. Loose files in this directory
103: * override their counterparts in the obeconfig.jar archive.
104: * <p/>
105: * The setting reflects the string value of the system property
106: * <code>obe.config.dir</code>.
107: *
108: * @return The configuration directory, defaulting to the current directory.
109: * @see #CONFIG_DIR_PROP
110: */
111: public static File getConfigDir() {
112: return _configDir;
113: }
114:
115: /**
116: * Returns the default client protocol type.
117: * <p/>
118: * The setting reflects the string value of the configuration property
119: * <code>obe.client.protocol</code>.
120: *
121: * @return Client protocol type, defaulting to <code>"local"</code>.
122: * @see #PROTOCOL_PROP
123: */
124: public static String getProtocol() {
125: return getStringProperty(PROTOCOL_PROP, "local");
126: }
127:
128: /**
129: * Returns the default client principal name.
130: * <p/>
131: * The setting reflects the string value of the configuration property
132: * <code>obe.client.principal</code>.
133: *
134: * @return Client principal name, defaulting to <code>"system"</code>.
135: * @see #PRINCIPAL_PROP
136: */
137: public static String getPrincipal() {
138: return getStringProperty(PRINCIPAL_PROP, "system");
139: }
140:
141: /**
142: * Returns the credentials with which the client should authenticate.
143: * <p/>
144: * The setting reflects the string value of the configuration property
145: * <code>obe.client.credentials</code>.
146: *
147: * @return Client credentials, defaulting to <code>"password"</code>.
148: * @see #CREDENTIALS_PROP
149: */
150: public static String getCredentials() {
151: return getStringProperty(CREDENTIALS_PROP, "password");
152: }
153:
154: /**
155: * Returns the date format to be used when rendering dates.
156: * <p/>
157: * The setting reflects the value of the configuration property
158: * <code>obe.xpdl.date.format</code>.
159: *
160: * @return Date format, defaulting to <code>yyyy-MM-dd'T'HH:mm:ssZ</code>.
161: * @see #DATE_FORMAT_PROP
162: */
163: public static String getDefaultDateFormat() {
164: return getStringProperty(DATE_FORMAT_PROP,
165: "yyyy-MM-dd'T'HH:mm:ssZ");
166: }
167:
168: /**
169: * Returns the default duration unit to use if an XPDL file does not specify
170: * a default.
171: * <p/>
172: * The setting reflects the value of the configuration property
173: * <code>obe.xpdl.duration.unit</code>.
174: *
175: * @return Default duration unit, defaulting to <code>"D"</code> (day).
176: * @see #DURATION_UNIT_PROP
177: */
178: public static String getDefaultDurationUnit() {
179: return getStringProperty(DURATION_UNIT_PROP, "D");
180: }
181:
182: /**
183: * Locates a configuration resource. The resource can either be in
184: * the configuration directory, or it can be packaged in obeconfig.jar.
185: *
186: * @param resource The resource name.
187: * @return The URL of the resource, or <code>null</code> if it could not be
188: * located.
189: */
190: public static URL findResource(String resource) {
191: URL url;
192: File file = new File(_configDir, resource);
193: if (file.exists()) {
194: try {
195: file = file.getCanonicalFile();
196: url = file.toURL();
197: } catch (IOException e) {
198: throw new OBERuntimeException(e);
199: }
200: } else {
201: ClassLoader cl = CommonConfig.class.getClassLoader();
202: url = cl.getResource(SERVICES_DIR + resource);
203: // Last ditch attempt in case we're running under the debugger.
204: if (url == null)
205: url = cl.getResource(resource);
206: }
207: if (url != null) {
208: _logger.info("Located resource at " + url);
209: } else {
210: // No configuration - we'll just use the defaults.
211: _logger.info("Resource '" + resource
212: + "' not found - using defaults");
213: }
214: return url;
215: }
216:
217: /**
218: * Opens an input stream for the specified resource. The caller is
219: * responsible for closing the input stream after reading from it. The
220: * implementation checks first whether the resource is present as a file in
221: * the configuration directory, and if this is not the case it checks for
222: * the presence of the resource inside the obeconfig.jar file.
223: *
224: * @param resource The partially qualified resource name, <em>relative to
225: * the configuration directory or the root of obeconfig.jar</em>.
226: * @return The input stream, or <code>null</code> if the resource could not
227: * be located.
228: */
229: public static InputStream openInputStream(String resource) {
230: InputStream in = null;
231: URL url = findResource(resource);
232: if (url != null) {
233: try {
234: in = url.openStream();
235: } catch (IOException e) {
236: // We'll return null if we can't open a stream.
237: }
238: }
239: return in;
240: }
241:
242: /**
243: * Opens an output stream for the specified resource. The caller is
244: * responsible for closing the output stream after writing to it. The
245: * implementation attempts to open the specified file in the configuration
246: * directory (or a subdirectory thereof if the resource name contains a
247: * path).
248: *
249: * @param resource The partially qualified resource name, <em>relative to
250: * the configuration directory</em>.
251: * @return The output stream, or <code>null</code> if the resource could not
252: * be located.
253: */
254: public static OutputStream openOutputStream(String resource) {
255: OutputStream out = null;
256: File file = new File(_configDir, resource);
257: try {
258: out = new FileOutputStream(file);
259: } catch (FileNotFoundException e) {
260: _logger.error("Unable to open file for writing: " + file);
261: }
262: return out;
263: }
264:
265: /**
266: * Opens a SAX input source for a resource. The caller is responsible for
267: * closing the associated byte stream afterwards.
268: *
269: * @param resource The resource name.
270: * @return The input source, or <code>null</code> if the resource could not
271: * be located.
272: */
273: public static InputSource openInputSource(String resource) {
274: InputSource src = null;
275: URL url = findResource(resource);
276: if (url != null) {
277: try {
278: InputStream in = url.openStream();
279: src = new InputSource(in);
280: src.setSystemId(url.toExternalForm());
281: } catch (IOException e) {
282: // We'll return null if we can't open a stream.
283: }
284: }
285: return src;
286: }
287:
288: /**
289: * Opens a character stream for a resource. The caller is responsible for
290: * closing the reader afterwards.
291: *
292: * @param resource The resource name.
293: * @return The character stream, or <code>null</code> if the resource could
294: * not be located.
295: */
296: public static Reader openReader(String resource) {
297: Reader reader = null;
298: InputStream in = openInputStream(resource);
299: if (in != null)
300: reader = new InputStreamReader(in);
301: return reader;
302: }
303:
304: protected CommonConfig() {
305: }
306: }
|