View Javadoc

1   /*
2    * Copyright 2004-2005 Germinus XXI
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License")
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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              //value = prefixedSystemConfiguration.getProperty(key);
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              //value = systemConfiguration.getProperty(key);
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 }