001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
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.kernel.util.ArrayUtil;
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                    ArrayUtil.reverse(fileNames);
218    
219                    for (String fileName : fileNames) {
220                            URL url = null;
221    
222                            try {
223                                    url = _classLoader.getResource(fileName);
224                            }
225                            catch (RuntimeException re) {
226                                    if (fileName.startsWith("file:/")) {
227                                            throw re;
228                                    }
229    
230                                    fileName = "file:/".concat(fileName);
231    
232                                    url = _classLoader.getResource(fileName);
233                            }
234    
235                            _addPropertiesSource(fileName, url, loadedCompositeConfiguration);
236                    }
237            }
238    
239            private Configuration _addJNDIProperties(String sourcePath) {
240                    JndiURL jndiURL = new JndiURL(sourcePath, _companyId, _componentName);
241    
242                    return jndiURL.getConfiguration();
243            }
244    
245            private Configuration _addPropertiesSource(
246                    String sourceName, URL url,
247                    CompositeConfiguration loadedCompositeConfiguration) {
248    
249                    try {
250                            Configuration newConfiguration = null;
251    
252                            if (DatasourceURL.isDatasource(sourceName)) {
253                                    newConfiguration = _addDatasourceProperties(sourceName);
254                            }
255                            else if (JndiURL.isJndi(sourceName)) {
256                                    newConfiguration = _addJNDIProperties(sourceName);
257                            }
258                            else if (url != null) {
259                                    newConfiguration = _addURLProperties(
260                                            url, loadedCompositeConfiguration);
261                            }
262                            else {
263                                    newConfiguration = _addFileProperties(
264                                            sourceName, loadedCompositeConfiguration);
265                            }
266    
267                            if (newConfiguration == null) {
268                                    return newConfiguration;
269                            }
270    
271                            loadedCompositeConfiguration.addConfiguration(newConfiguration);
272    
273                            super.addConfiguration(newConfiguration);
274    
275                            if (newConfiguration instanceof AbstractFileConfiguration) {
276                                    AbstractFileConfiguration abstractFileConfiguration =
277                                            (AbstractFileConfiguration)newConfiguration;
278    
279                                    URL abstractFileConfigurationURL =
280                                            abstractFileConfiguration.getURL();
281    
282                                    _loadedSources.add(abstractFileConfigurationURL.toString());
283                            }
284                            else {
285                                    _loadedSources.add(sourceName);
286                            }
287    
288                            return newConfiguration;
289                    }
290                    catch (Exception e) {
291                            if (_log.isDebugEnabled()) {
292                                    _log.debug(
293                                            "Configuration source " + sourceName + " ignored: " +
294                                                    e.getMessage());
295                            }
296    
297                            return null;
298                    }
299            }
300    
301            private Configuration _addURLProperties(
302                            URL url, CompositeConfiguration loadedCompositeConfiguration)
303                    throws ConfigurationException {
304    
305                    try {
306                            FileConfiguration newFileConfiguration =
307                                    new PropertiesConfiguration(url);
308    
309                            if (_log.isDebugEnabled()) {
310                                    _log.debug("Adding resource " + url);
311                            }
312    
313                            Long delay = _getReloadDelay(
314                                    loadedCompositeConfiguration, newFileConfiguration);
315    
316                            if (delay != null) {
317                                    FileChangedReloadingStrategy fileChangedReloadingStrategy =
318                                            new FileConfigurationChangedReloadingStrategy();
319    
320                                    if (_log.isDebugEnabled()) {
321                                            _log.debug(
322                                                    "Resource " + url + " will be reloaded every " +
323                                                            delay + " seconds");
324                                    }
325    
326                                    long milliseconds = delay.longValue() * 1000;
327    
328                                    fileChangedReloadingStrategy.setRefreshDelay(milliseconds);
329    
330                                    newFileConfiguration.setReloadingStrategy(
331                                            fileChangedReloadingStrategy);
332                            }
333    
334                            _addIncludedPropertiesSources(
335                                    newFileConfiguration, loadedCompositeConfiguration);
336    
337                            return newFileConfiguration;
338                    }
339                    catch (org.apache.commons.configuration.ConfigurationException ce) {
340                            if (_log.isDebugEnabled()) {
341                                    _log.debug("Configuration source " + url + " ignored");
342                            }
343    
344                            return null;
345                    }
346            }
347    
348            private String _getPrefix() {
349                    return _componentName.concat(Conventions.PREFIX_SEPARATOR);
350            }
351    
352            private Long _getReloadDelay(
353                    CompositeConfiguration loadedCompositeConfiguration,
354                    FileConfiguration newFileConfiguration) {
355    
356                    Long delay = newFileConfiguration.getLong(
357                            Conventions.RELOAD_DELAY_PROPERTY, null);
358    
359                    if (delay == null) {
360                            delay = loadedCompositeConfiguration.getLong(
361                                    Conventions.RELOAD_DELAY_PROPERTY, null);
362                    }
363    
364                    return delay;
365            }
366    
367            private static Log _log = LogFactoryUtil.getLog(
368                    ClassLoaderAggregateProperties.class);
369    
370            private CompositeConfiguration _baseCompositeConfiguration =
371                    new CompositeConfiguration();
372            private boolean _baseConfigurationLoaded;
373            private ClassLoader _classLoader;
374            private String _companyId;
375            private String _componentName;
376            private CompositeConfiguration _globalCompositeConfiguration =
377                    new CompositeConfiguration();
378            private List<String> _loadedSources = new ArrayList<String>();
379            private Configuration _prefixedSystemConfiguration;
380            private SystemConfiguration _systemConfiguration =
381                    new SystemConfiguration();
382    
383    }