001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013:
014: package org.wings.util;
015:
016: import org.apache.commons.logging.Log;
017: import org.apache.commons.logging.LogFactory;
018: import org.wings.session.SessionManager;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.net.URL;
023: import java.util.Enumeration;
024: import java.util.Properties;
025:
026: /**
027: * Utility class to discover all properties that can be found in retrievable files either via Classpath loader or as file in the
028: * <code>WEB-INF</code> directory.
029: */
030: public final class PropertyDiscovery {
031: private final static Log log = LogFactory
032: .getLog(PropertyDiscovery.class);
033: private static final String WEB_INF = "WEB-INF/";
034:
035: /**
036: * Loads all properties from either the class path or with modified name in the WEB-INF directory. Requires something to be found.
037: * <p/>
038: * First looks in the classPath for the file. Then replace all path-separators with . and look for a named file in the WEB-INF
039: * directory. Throws an exception if nothings was found and required is true! <p>Example: <code>org/wings/myprops.properties</code>
040: * first checks for that file on the classpath and then for a file <code>WEB-INF/org.wings.myprops.properties</code>.
041: *
042: * @param propertyPath the name of the properties file i.e. <code>org/wings/myprops.properties</code>
043: * @return The Properties loaded
044: * @throws java.io.IOException if something fails or nothing was found
045: */
046: public static Properties loadRequiredProperties(String propertyPath)
047: throws IOException {
048: return loadProperties(propertyPath, true);
049: }
050:
051: /**
052: * Loads all properties from either the class path or with modified name in the WEB-INF directory.
053: * <p/>
054: * First looks in the classPath for the file. Then replace all path-separators with . and look for a named file in the WEB-INF
055: * directory. Throws an exception if nothings was found and required is true! <p>Example: <code>org/wings/myprops.properties</code>
056: * first checks for that file on the classpath and then for a file <code>WEB-INF/org.wings.myprops.properties</code>.
057: *
058: * @param propertyPath the name of the properties file i.e. <code>org/wings/myprops.properties</code>
059: * @return The Properties loaded
060: */
061: public static Properties loadOptionalProperties(String propertyPath) {
062: try {
063: return loadProperties(propertyPath, false);
064: } catch (IOException e) {
065: log.info("Error", e);
066: return new Properties();
067: }
068: }
069:
070: private static Properties loadProperties(String propertyPath,
071: boolean required) throws IOException {
072: final Properties properties = new Properties();
073: // first load defaults from classpath, and if it fails, throw Exception
074: boolean somethingFound = loadPropertiesFromClasspath(
075: properties, propertyPath);
076: // now load from webapp folder, log if fails.
077: String webappUrl = WEB_INF + propertyPath.replace('/', '.');
078: somethingFound |= (loadPropertiesFromContainer(properties,
079: webappUrl));
080: if (required && !somethingFound) {
081: throw new IOException("No properties found under: "
082: + propertyPath);
083: }
084:
085: return properties;
086: }
087:
088: /**
089: * Loads a file from the webapp's dir into a properties file.
090: *
091: * @param webappUrl the file's url
092: * @return true if something was found
093: */
094: private static boolean loadPropertiesFromContainer(
095: final Properties properties, final String webappUrl) {
096: InputStream in;
097: try {
098: in = SessionManager.getSession().getServletContext()
099: .getResourceAsStream(webappUrl);
100: properties.load(in);
101: in.close();
102: if (log.isDebugEnabled()) {
103: log
104: .debug("Loaded properties from servlet container file '"
105: + webappUrl + "'");
106: }
107: } catch (Exception e) {
108: log.debug("No custom " + webappUrl
109: + "found. Using defaults.");
110: return false;
111: }
112: return true;
113: }
114:
115: /**
116: * Loads a file from the webapp's classpath into a properties file.
117: *
118: * @param propertyFileClasspath the file's classpath
119: * @return <code>true</code> if something was found and loaded
120: */
121: private static boolean loadPropertiesFromClasspath(
122: final Properties properties,
123: final String propertyFileClasspath) throws IOException {
124: final ClassLoader classLoader = Thread.currentThread()
125: .getContextClassLoader();
126: final Enumeration<URL> filesFound = classLoader
127: .getResources(propertyFileClasspath);
128: boolean somethingLoaded = false;
129: while (filesFound.hasMoreElements()) {
130: final URL propertyFile = filesFound.nextElement();
131: try {
132: InputStream content = propertyFile.openStream();
133: properties.load(content);
134: content.close();
135: somethingLoaded = true;
136: if (log.isDebugEnabled()) {
137: log.debug("Loaded properties from classpath file '"
138: + propertyFileClasspath + "'");
139: }
140: } catch (Exception e) {
141: final String error = "Unable to open "
142: + propertyFile.toExternalForm()
143: + " from classpath due " + e
144: + ". Please check deployment!";
145: throw new IOException(error);
146: }
147: }
148: return somethingLoaded;
149: }
150: }
|