001: /**
002: *
003: */package org.drools.util;
004:
005: import java.io.File;
006: import java.io.IOException;
007: import java.io.Serializable;
008: import java.net.MalformedURLException;
009: import java.net.URL;
010: import java.util.ArrayList;
011: import java.util.Enumeration;
012: import java.util.Iterator;
013: import java.util.List;
014: import java.util.Map;
015: import java.util.Properties;
016:
017: public class ChainedProperties implements Serializable {
018: private final List props;
019: private final List defaultProps;
020:
021: public ChainedProperties(String confFileName) {
022: this (null, confFileName);
023: }
024:
025: public ChainedProperties(ClassLoader classLoader,
026: String confFileName) {
027: this (classLoader, confFileName, true);
028: }
029:
030: public ChainedProperties(ClassLoader classLoader,
031: String confFileName, boolean populateDefaults) {
032: if (classLoader == null) {
033: classLoader = Thread.currentThread()
034: .getContextClassLoader();
035: if (classLoader == null) {
036: classLoader = this .getClass().getClassLoader();
037: }
038: }
039:
040: this .props = new ArrayList();
041: this .defaultProps = new ArrayList();
042:
043: // Properties added in precedence order
044:
045: // System defined properties always get precedence
046: addProperties(System.getProperties());
047:
048: // System property defined properties file
049: loadProperties(System.getProperty("drools." + confFileName),
050: this .props);
051:
052: // User home properties file
053: loadProperties(System.getProperty("user.home") + "/drools."
054: + confFileName, this .props);
055:
056: // Working directory properties file
057: loadProperties("drools." + confFileName, this .props);
058:
059: // check META-INF directories for all known ClassLoaders
060: ClassLoader confClassLoader = classLoader;
061: if (confClassLoader != null) {
062: loadProperties(getResources("META-INF/drools."
063: + confFileName, confClassLoader), this .props);
064: }
065:
066: confClassLoader = getClass().getClassLoader();
067: if (confClassLoader != null && confClassLoader != classLoader) {
068: loadProperties(getResources("META-INF/drools."
069: + confFileName, confClassLoader), this .props);
070: }
071:
072: confClassLoader = Thread.currentThread()
073: .getContextClassLoader();
074: if (confClassLoader != null && confClassLoader != classLoader) {
075: loadProperties(getResources("META-INF/drools."
076: + confFileName, confClassLoader), this .props);
077: }
078:
079: confClassLoader = ClassLoader.getSystemClassLoader();
080: if (confClassLoader != null && confClassLoader != classLoader) {
081: loadProperties(getResources("META-INF/drools."
082: + confFileName, confClassLoader), this .props);
083: }
084:
085: if (!populateDefaults) {
086: return;
087: }
088:
089: // load defaults
090: confClassLoader = classLoader;
091: if (confClassLoader != null) {
092: loadProperties(getResources("META-INF/drools.default."
093: + confFileName, confClassLoader), this .defaultProps);
094: }
095:
096: confClassLoader = getClass().getClassLoader();
097: if (confClassLoader != null && confClassLoader != classLoader) {
098: loadProperties(getResources("META-INF/drools.default."
099: + confFileName, confClassLoader), this .defaultProps);
100: }
101:
102: confClassLoader = Thread.currentThread()
103: .getContextClassLoader();
104: if (confClassLoader != null && confClassLoader != classLoader) {
105: loadProperties(getResources("META-INF/drools.default."
106: + confFileName, confClassLoader), this .defaultProps);
107: }
108:
109: confClassLoader = ClassLoader.getSystemClassLoader();
110: if (confClassLoader != null && confClassLoader != classLoader) {
111: loadProperties(getResources("META-INF/drools.default."
112: + confFileName, confClassLoader), this .defaultProps);
113: }
114: }
115:
116: private Enumeration getResources(String name,
117: ClassLoader classLoader) {
118: Enumeration enumeration = null;
119: try {
120: enumeration = classLoader.getResources(name);
121: } catch (IOException e) {
122: e.printStackTrace();
123: }
124: return enumeration;
125: }
126:
127: public void addProperties(Properties properties) {
128: this .props.add(properties);
129: }
130:
131: public String getProperty(String key, String defaultValue) {
132: String value = null;
133: for (Iterator it = this .props.iterator(); it.hasNext();) {
134: Properties props = (Properties) it.next();
135: value = props.getProperty(key);
136: if (value != null) {
137: break;
138: }
139: }
140: if (value == null) {
141: for (Iterator it = this .defaultProps.iterator(); it
142: .hasNext();) {
143: Properties props = (Properties) it.next();
144: value = props.getProperty(key);
145: if (value != null) {
146: break;
147: }
148: }
149: }
150: return (value != null) ? value : defaultValue;
151: }
152:
153: public void mapStartsWith(Map map, String startsWith,
154: boolean includeSubProperties) {
155: for (Iterator it = this .props.iterator(); it.hasNext();) {
156: Properties props = (Properties) it.next();
157: mapStartsWith(map, props, startsWith, includeSubProperties);
158: }
159:
160: for (Iterator it = this .defaultProps.iterator(); it.hasNext();) {
161: Properties props = (Properties) it.next();
162: mapStartsWith(map, props, startsWith, includeSubProperties);
163: }
164: }
165:
166: private void mapStartsWith(Map map, Properties properties,
167: String startsWith, boolean includeSubProperties) {
168: Enumeration enumeration = properties.propertyNames();
169: while (enumeration.hasMoreElements()) {
170: String key = (String) enumeration.nextElement();
171: if (key.startsWith(startsWith)) {
172: if (!includeSubProperties
173: && key.substring(startsWith.length() + 1)
174: .indexOf('.') > 0) {
175: // +1 to the length, as we do allow the direct property, just not ones below it
176: // This key has sub properties beyond the given startsWith, so skip
177: continue;
178: }
179: if (!map.containsKey(key)) {
180: map.put(key, properties.getProperty(key));
181: }
182:
183: }
184: }
185: }
186:
187: private void loadProperties(Enumeration enumeration, List chain) {
188: if (enumeration == null) {
189: return;
190: }
191:
192: while (enumeration.hasMoreElements()) {
193: URL url = (URL) enumeration.nextElement();
194: loadProperties(url, chain);
195: }
196: }
197:
198: private void loadProperties(String fileName, List chain) {
199: if (fileName != null) {
200: File file = new File(fileName);
201: if (file != null && file.exists()) {
202: try {
203: loadProperties(file.toURL(), chain);
204: } catch (MalformedURLException e) {
205: throw new IllegalArgumentException(
206: "file.toURL() failed for drools.packagebuilder.conf properties value '"
207: + file + "'");
208: }
209: } else {
210: //throw new IllegalArgumentException( "drools.packagebuilder.conf is specified but cannot be found '" + file + "'" );
211: }
212: }
213: }
214:
215: private void loadProperties(URL confURL, List chain) {
216: if (confURL == null) {
217: return;
218: }
219: Properties properties = new Properties();
220: try {
221: properties.load(confURL.openStream());
222: chain.add(properties);
223: } catch (IOException e) {
224: //throw new IllegalArgumentException( "Invalid URL to properties file '" + confURL.toExternalForm() + "'" );
225: }
226: }
227: }
|