1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.germinus.easyconf;
17
18 import org.apache.commons.configuration.AbstractFileConfiguration;
19 import org.apache.commons.configuration.CompositeConfiguration;
20 import org.apache.commons.configuration.Configuration;
21 import org.apache.commons.configuration.FileConfiguration;
22 import org.apache.commons.configuration.JNDIConfiguration;
23 import org.apache.commons.configuration.PropertiesConfiguration;
24 import org.apache.commons.configuration.SubsetConfiguration;
25 import org.apache.commons.configuration.SystemConfiguration;
26 import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 import java.net.URL;
31 import java.util.*;
32
33 /***
34 * Provides configuration properties from several sources making distintion from:
35 * <ul>
36 * <li>Base properties specific to the current component
37 * <li>Global properties which may be prefixed
38 * <li>System properties (so that they are available as variables to the
39 * other property files)
40 * </ul>
41 * It also knows the source the a property to offer user information.
42 *
43 * @author jferrer
44 */
45 public class AggregatedProperties extends CompositeConfiguration {
46 private static final Log log = LogFactory.getLog(AggregatedProperties.class);
47
48 private CompositeConfiguration baseConf = new CompositeConfiguration();
49 private CompositeConfiguration globalConf = new CompositeConfiguration();
50 private SystemConfiguration systemConfiguration = new SystemConfiguration();
51 private Configuration prefixedSystemConfiguration = new SubsetConfiguration
52 (systemConfiguration, getPrefix(), null);
53 private String componentName;
54 private String companyId;
55 private List loadedSources = new ArrayList();
56 private boolean baseConfigurationLoaded = false;
57
58 public AggregatedProperties(String companyId, String componentName) {
59 this.componentName = componentName;
60 this.companyId = companyId;
61 }
62
63 /***
64 * Look for the property in environment, global and base configuration,
65 * in this order
66 * @param key
67 * @return
68 */
69 public Object getProperty(String key) {
70 Object value = null;
71 if (value == null) {
72
73 value = System.getProperty(getPrefix() + key);
74 }
75 if (value == null) {
76 value = globalConf.getProperty(getPrefix() + key);
77 }
78 if (value == null) {
79 value = globalConf.getProperty(key);
80 }
81 if (value == null) {
82 value = baseConf.getProperty(key);
83 }
84 if (value == null) {
85 value = super.getProperty(key);
86 }
87 if (value == null) {
88
89 value = System.getProperty(key);
90 }
91 if ((value == null) && (key.equals(Conventions.COMPANY_ID_PROPERTY))) {
92 value = companyId;
93 }
94 if ((value == null) && (key.equals(Conventions.COMPONENT_NAME_PROPERTY))) {
95 value = componentName;
96 }
97 return value;
98 }
99
100 private String getPrefix() {
101 return componentName + Conventions.PREFIX_SEPARATOR;
102 }
103
104
105 public void addBaseFileName(String fileName) {
106 Configuration conf = addPropertiesSource(fileName, baseConf);
107 if ((conf != null) && (!conf.isEmpty())) {
108 baseConfigurationLoaded = true;
109 }
110 }
111
112 public void addGlobalFileName(String fileName) {
113 addPropertiesSource(fileName, globalConf);
114 }
115
116 /***
117 * Read the given source of properties and add it to the composite
118 * configuration.
119 * The added configuration will be returned. If it is not found
120 * null will be returned.
121 */
122 private Configuration addPropertiesSource(String sourceName,
123 CompositeConfiguration loadedConf) {
124 try {
125 Configuration newConf;
126 if (DatasourceURL.isDatasource(sourceName)) {
127 newConf = addDatasourceProperties(sourceName);
128 } else if (JndiURL.isJndi(sourceName)) {
129 newConf = addJndiProperties(sourceName);
130 } else {
131 newConf = addFileProperties(sourceName, loadedConf);
132 }
133 if (newConf != null) {
134 loadedConf.addConfiguration(newConf);
135 super.addConfiguration(newConf);
136 if (newConf instanceof AbstractFileConfiguration) {
137 loadedSources.add(((AbstractFileConfiguration) newConf).
138 getURL().toString());
139 } else {
140 loadedSources.add(sourceName);
141 }
142 }
143 return newConf;
144 } catch (Exception ignore) {
145 if (log.isDebugEnabled()) {
146 log.debug("Configuration source " + sourceName + " ignored");
147 }
148 return null;
149 }
150 }
151
152 private Configuration addFileProperties(String fileName,
153 CompositeConfiguration loadedConf)
154 throws ConfigurationException {
155 try {
156 FileConfiguration newConf = new PropertiesConfiguration(fileName);
157 URL fileURL = newConf.getURL();
158 log.debug("Adding file: " + fileURL);
159
160 Long delay = getReloadDelay(loadedConf, newConf);
161 if (delay != null) {
162 FileChangedReloadingStrategy reloadingStrategy =
163 new FileConfigurationChangedReloadingStrategy();
164 if (log.isDebugEnabled()) {
165 log.debug("File " + fileURL + " will be reloaded every "
166 + delay + " seconds");
167 }
168 long milliseconds = delay.longValue() * 1000;
169 reloadingStrategy.setRefreshDelay(milliseconds);
170 newConf.setReloadingStrategy(reloadingStrategy);
171 }
172
173 addIncludedPropertiesSources(newConf, loadedConf);
174 return newConf;
175 } catch (org.apache.commons.configuration.ConfigurationException e) {
176 if (log.isDebugEnabled()) {
177 log.debug("Configuration source " + fileName + " ignored");
178 }
179 return null;
180 }
181 }
182
183 private Long getReloadDelay(CompositeConfiguration loadedConf, FileConfiguration newConf) {
184 Long delay = newConf.getLong(Conventions.RELOAD_DELAY_PROPERTY, null);
185 if (delay == null) {
186 delay = loadedConf.getLong(Conventions.RELOAD_DELAY_PROPERTY, null);
187 }
188 return delay;
189 }
190
191 private Configuration addDatasourceProperties(String datasourcePath) {
192 DatasourceURL dsUrl = new DatasourceURL(datasourcePath, companyId, componentName);
193 return dsUrl.getConfiguration();
194 }
195
196
197 private Configuration addJndiProperties(String sourcePath) {
198 JNDIConfiguration conf = null;
199 JndiURL jndiUrl = new JndiURL(sourcePath, companyId, componentName);
200 return jndiUrl.getConfiguration();
201 }
202
203 private void addIncludedPropertiesSources(Configuration newConf,
204 CompositeConfiguration loadedConf) {
205 CompositeConfiguration tempConf = new CompositeConfiguration();
206 tempConf.addConfiguration(prefixedSystemConfiguration);
207 tempConf.addConfiguration(newConf);
208 tempConf.addConfiguration(systemConfiguration);
209 tempConf.addProperty(Conventions.COMPANY_ID_PROPERTY, companyId);
210 tempConf.addProperty(Conventions.COMPONENT_NAME_PROPERTY, componentName);
211 String[] fileNames = tempConf.getStringArray(Conventions.INCLUDE_PROPERTY);
212 for (int i = fileNames.length - 1; i >= 0; i--) {
213 String iteratedFileName = fileNames[i];
214 addPropertiesSource(iteratedFileName, loadedConf);
215 }
216 }
217
218 public List loadedSources() {
219 return loadedSources;
220 }
221
222 public boolean hasBaseConfiguration() {
223 return baseConfigurationLoaded;
224 }
225
226 public String getComponentName() {
227 return componentName;
228 }
229 }