001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.configuration.easyconf;
016    
017    import com.germinus.easyconf.AggregatedProperties;
018    import com.germinus.easyconf.ConfigurationException;
019    import com.germinus.easyconf.Conventions;
020    import com.germinus.easyconf.DatasourceURL;
021    import com.germinus.easyconf.FileConfigurationChangedReloadingStrategy;
022    import com.germinus.easyconf.JndiURL;
023    
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
027    
028    import java.net.URL;
029    
030    import java.util.ArrayList;
031    import java.util.List;
032    
033    import org.apache.commons.configuration.AbstractFileConfiguration;
034    import org.apache.commons.configuration.CompositeConfiguration;
035    import org.apache.commons.configuration.Configuration;
036    import org.apache.commons.configuration.FileConfiguration;
037    import org.apache.commons.configuration.PropertiesConfiguration;
038    import org.apache.commons.configuration.SubsetConfiguration;
039    import org.apache.commons.configuration.SystemConfiguration;
040    import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
041    
042    /**
043     * @author Raymond Augé
044     */
045    public class ClassLoaderAggregateProperties extends AggregatedProperties {
046    
047            public ClassLoaderAggregateProperties(
048                    ClassLoader classLoader, String companyId, String componentName) {
049    
050                    super(companyId, componentName);
051    
052                    _classLoader = classLoader;
053                    _companyId = companyId;
054                    _componentName = componentName;
055    
056                    _prefixedSystemConfiguration = new SubsetConfiguration(
057                            _systemConfiguration, _getPrefix(), null);
058            }
059    
060            @Override
061            public void addBaseFileName(String fileName) {
062                    URL url = _classLoader.getResource(fileName);
063    
064                    Configuration configuration = _addPropertiesSource(
065                            fileName, url, _baseCompositeConfiguration);
066    
067                    if ((configuration != null) && !configuration.isEmpty()) {
068                            _baseConfigurationLoaded = true;
069                    }
070            }
071    
072            @Override
073            public void addGlobalFileName(String fileName) {
074                    URL url = _classLoader.getResource(fileName);
075    
076                    _addPropertiesSource(fileName, url, _globalCompositeConfiguration);
077            }
078    
079            public CompositeConfiguration getBaseConfiguration() {
080                    return _baseCompositeConfiguration;
081            }
082    
083            @Override
084            public String getComponentName() {
085                    return _componentName;
086            }
087    
088            @Override
089            public Object getProperty(String key) {
090                    Object value = null;
091    
092                    if (value == null) {
093                            value = System.getProperty(_getPrefix().concat(key));
094                    }
095    
096                    if (value == null) {
097                            value = _globalCompositeConfiguration.getProperty(
098                                    _getPrefix().concat(key));
099                    }
100    
101                    if (value == null) {
102                            value = _globalCompositeConfiguration.getProperty(key);
103                    }
104    
105                    if (value == null) {
106                            value = _baseCompositeConfiguration.getProperty(key);
107                    }
108    
109                    if (value == null) {
110                            value = super.getProperty(key);
111                    }
112    
113                    if (value == null) {
114                            value = System.getProperty(key);
115                    }
116    
117                    if ((value == null) && key.equals(Conventions.COMPANY_ID_PROPERTY)) {
118                            value = _companyId;
119                    }
120    
121                    if ((value == null) &&
122                            key.equals(Conventions.COMPONENT_NAME_PROPERTY)) {
123    
124                            value = _componentName;
125                    }
126    
127                    return value;
128            }
129    
130            @Override
131            public boolean hasBaseConfiguration() {
132                    return _baseConfigurationLoaded;
133            }
134    
135            @Override
136            public List<String> loadedSources() {
137                    return _loadedSources;
138            }
139    
140            private Configuration _addDatasourceProperties(String datasourcePath) {
141                    DatasourceURL datasourceURL = new DatasourceURL(
142                            datasourcePath, _companyId, _componentName,
143                            DatasourceURL.PROPERTIES_TABLE);
144    
145                    return datasourceURL.getConfiguration();
146            }
147    
148            private Configuration _addFileProperties(
149                            String fileName,
150                            CompositeConfiguration loadedCompositeConfiguration)
151                    throws ConfigurationException {
152    
153                    try {
154                            FileConfiguration newFileConfiguration =
155                                    new PropertiesConfiguration(fileName);
156    
157                            URL url = newFileConfiguration.getURL();
158    
159                            if (_log.isDebugEnabled()) {
160                                    _log.debug("Adding file " + url);
161                            }
162    
163                            Long delay = _getReloadDelay(
164                                    loadedCompositeConfiguration, newFileConfiguration);
165    
166                            if (delay != null) {
167                                    FileChangedReloadingStrategy fileChangedReloadingStrategy =
168                                            new FileConfigurationChangedReloadingStrategy();
169    
170                                    if (_log.isDebugEnabled()) {
171                                            _log.debug(
172                                                    "File " + url + " will be reloaded every " +
173                                                            delay + " seconds");
174                                    }
175    
176                                    long milliseconds = delay.longValue() * 1000;
177    
178                                    fileChangedReloadingStrategy.setRefreshDelay(milliseconds);
179    
180                                    newFileConfiguration.setReloadingStrategy(
181                                            fileChangedReloadingStrategy);
182                            }
183    
184                            _addIncludedPropertiesSources(
185                                    newFileConfiguration, loadedCompositeConfiguration);
186    
187                            return newFileConfiguration;
188                    }
189                    catch (org.apache.commons.configuration.ConfigurationException ce) {
190                            if (_log.isDebugEnabled()) {
191                                    _log.debug("Configuration source " + fileName + " ignored");
192                            }
193    
194                            return null;
195                    }
196            }
197    
198            private void _addIncludedPropertiesSources(
199                    Configuration newConfiguration,
200                    CompositeConfiguration loadedCompositeConfiguration) {
201    
202                    CompositeConfiguration tempCompositeConfiguration =
203                            new CompositeConfiguration();
204    
205                    tempCompositeConfiguration.addConfiguration(
206                            _prefixedSystemConfiguration);
207                    tempCompositeConfiguration.addConfiguration(newConfiguration);
208                    tempCompositeConfiguration.addConfiguration(_systemConfiguration);
209                    tempCompositeConfiguration.addProperty(
210                            Conventions.COMPANY_ID_PROPERTY, _companyId);
211                    tempCompositeConfiguration.addProperty(
212                            Conventions.COMPONENT_NAME_PROPERTY, _componentName);
213    
214                    String[] fileNames = tempCompositeConfiguration.getStringArray(
215                            Conventions.INCLUDE_PROPERTY);
216    
217                    for (String fileName : fileNames) {
218                            URL url = null;
219    
220                            try {
221                                    url = _classLoader.getResource(fileName);
222                            }
223                            catch (RuntimeException re) {
224                                    if (fileName.startsWith("file:/")) {
225                                            throw re;
226                                    }
227    
228                                    fileName = "file:/".concat(fileName);
229    
230                                    url = _classLoader.getResource(fileName);
231                            }
232    
233                            _addPropertiesSource(fileName, url, loadedCompositeConfiguration);
234                    }
235            }
236    
237            private Configuration _addJNDIProperties(String sourcePath) {
238                    JndiURL jndiURL = new JndiURL(sourcePath, _companyId, _componentName);
239    
240                    return jndiURL.getConfiguration();
241            }
242    
243            private Configuration _addPropertiesSource(
244                    String sourceName, URL url,
245                    CompositeConfiguration loadedCompositeConfiguration) {
246    
247                    boolean checkGetClassLoader =
248                            PortalSecurityManagerThreadLocal.isCheckGetClassLoader();
249    
250                    try {
251                            PortalSecurityManagerThreadLocal.setCheckGetClassLoader(false);
252    
253                            Configuration newConfiguration = null;
254    
255                            if (DatasourceURL.isDatasource(sourceName)) {
256                                    newConfiguration = _addDatasourceProperties(sourceName);
257                            }
258                            else if (JndiURL.isJndi(sourceName)) {
259                                    newConfiguration = _addJNDIProperties(sourceName);
260                            }
261                            else if (url != null) {
262                                    newConfiguration = _addURLProperties(
263                                            url, loadedCompositeConfiguration);
264                            }
265                            else {
266                                    newConfiguration = _addFileProperties(
267                                            sourceName, loadedCompositeConfiguration);
268                            }
269    
270                            if (newConfiguration == null) {
271                                    return newConfiguration;
272                            }
273    
274                            loadedCompositeConfiguration.addConfiguration(newConfiguration);
275    
276                            super.addConfiguration(newConfiguration);
277    
278                            if (newConfiguration instanceof AbstractFileConfiguration) {
279                                    AbstractFileConfiguration abstractFileConfiguration =
280                                            (AbstractFileConfiguration)newConfiguration;
281    
282                                    URL abstractFileConfigurationURL =
283                                            abstractFileConfiguration.getURL();
284    
285                                    _loadedSources.add(abstractFileConfigurationURL.toString());
286                            }
287                            else {
288                                    _loadedSources.add(sourceName);
289                            }
290    
291                            return newConfiguration;
292                    }
293                    catch (Exception e) {
294                            if (_log.isDebugEnabled()) {
295                                    _log.debug(
296                                            "Configuration source " + sourceName + " ignored: "
297                                                    + e.getMessage());
298                            }
299    
300                            return null;
301                    }
302                    finally {
303                            PortalSecurityManagerThreadLocal.setCheckGetClassLoader(
304                                    checkGetClassLoader);
305                    }
306            }
307    
308            private Configuration _addURLProperties(
309                            URL url, CompositeConfiguration loadedCompositeConfiguration)
310                    throws ConfigurationException {
311    
312                    try {
313                            FileConfiguration newFileConfiguration =
314                                    new PropertiesConfiguration(url);
315    
316                            if (_log.isDebugEnabled()) {
317                                    _log.debug("Adding resource " + url);
318                            }
319    
320                            Long delay = _getReloadDelay(
321                                    loadedCompositeConfiguration, newFileConfiguration);
322    
323                            if (delay != null) {
324                                    FileChangedReloadingStrategy fileChangedReloadingStrategy =
325                                            new FileConfigurationChangedReloadingStrategy();
326    
327                                    if (_log.isDebugEnabled()) {
328                                            _log.debug(
329                                                    "Resource " + url + " will be reloaded every " +
330                                                            delay + " seconds");
331                                    }
332    
333                                    long milliseconds = delay.longValue() * 1000;
334    
335                                    fileChangedReloadingStrategy.setRefreshDelay(milliseconds);
336    
337                                    newFileConfiguration.setReloadingStrategy(
338                                            fileChangedReloadingStrategy);
339                            }
340    
341                            _addIncludedPropertiesSources(
342                                    newFileConfiguration, loadedCompositeConfiguration);
343    
344                            return newFileConfiguration;
345                    }
346                    catch (org.apache.commons.configuration.ConfigurationException ce) {
347                            if (_log.isDebugEnabled()) {
348                                    _log.debug("Configuration source " + url + " ignored");
349                            }
350    
351                            return null;
352                    }
353            }
354    
355            private String _getPrefix() {
356                    return _componentName.concat(Conventions.PREFIX_SEPARATOR);
357            }
358    
359            private Long _getReloadDelay(
360                    CompositeConfiguration loadedCompositeConfiguration,
361                    FileConfiguration newFileConfiguration) {
362    
363                    Long delay = newFileConfiguration.getLong(
364                            Conventions.RELOAD_DELAY_PROPERTY, null);
365    
366                    if (delay == null) {
367                            delay = loadedCompositeConfiguration.getLong(
368                                    Conventions.RELOAD_DELAY_PROPERTY, null);
369                    }
370    
371                    return delay;
372            }
373    
374            private static final Log _log = LogFactoryUtil.getLog(
375                    AggregatedProperties.class);
376    
377            private CompositeConfiguration _baseCompositeConfiguration =
378                    new CompositeConfiguration();
379            private boolean _baseConfigurationLoaded;
380            private ClassLoader _classLoader;
381            private String _companyId;
382            private String _componentName;
383            private CompositeConfiguration _globalCompositeConfiguration =
384                    new CompositeConfiguration();
385            private List<String> _loadedSources = new ArrayList<String>();
386            private Configuration _prefixedSystemConfiguration;
387            private SystemConfiguration _systemConfiguration =
388                    new SystemConfiguration();
389    
390    }