001    /**
002     * Copyright (c) 2000-present 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) {
068                            _baseConfigurationLoaded = true;
069    
070                            if (configuration.isEmpty() && _log.isDebugEnabled()) {
071                                    _log.debug("Empty configuration " + fileName);
072                            }
073                    }
074            }
075    
076            @Override
077            public void addGlobalFileName(String fileName) {
078                    URL url = _classLoader.getResource(fileName);
079    
080                    _addPropertiesSource(fileName, url, _globalCompositeConfiguration);
081            }
082    
083            public CompositeConfiguration getBaseConfiguration() {
084                    return _baseCompositeConfiguration;
085            }
086    
087            @Override
088            public String getComponentName() {
089                    return _componentName;
090            }
091    
092            @Override
093            public Object getProperty(String key) {
094                    Object value = null;
095    
096                    if (value == null) {
097                            value = System.getProperty(_getPrefix().concat(key));
098                    }
099    
100                    if (value == null) {
101                            value = _globalCompositeConfiguration.getProperty(
102                                    _getPrefix().concat(key));
103                    }
104    
105                    if (value == null) {
106                            value = _globalCompositeConfiguration.getProperty(key);
107                    }
108    
109                    if (value == null) {
110                            value = _baseCompositeConfiguration.getProperty(key);
111                    }
112    
113                    if (value == null) {
114                            value = super.getProperty(key);
115                    }
116    
117                    if (value == null) {
118                            value = System.getProperty(key);
119                    }
120    
121                    if ((value == null) && key.equals(Conventions.COMPANY_ID_PROPERTY)) {
122                            value = _companyId;
123                    }
124    
125                    if ((value == null) &&
126                            key.equals(Conventions.COMPONENT_NAME_PROPERTY)) {
127    
128                            value = _componentName;
129                    }
130    
131                    return value;
132            }
133    
134            @Override
135            public boolean hasBaseConfiguration() {
136                    return _baseConfigurationLoaded;
137            }
138    
139            @Override
140            public List<String> loadedSources() {
141                    return _loadedSources;
142            }
143    
144            private Configuration _addDatasourceProperties(String datasourcePath) {
145                    DatasourceURL datasourceURL = new DatasourceURL(
146                            datasourcePath, _companyId, _componentName,
147                            DatasourceURL.PROPERTIES_TABLE);
148    
149                    return datasourceURL.getConfiguration();
150            }
151    
152            private Configuration _addFileProperties(
153                            String fileName,
154                            CompositeConfiguration loadedCompositeConfiguration)
155                    throws ConfigurationException {
156    
157                    try {
158                            FileConfiguration newFileConfiguration =
159                                    new PropertiesConfiguration(fileName);
160    
161                            URL url = newFileConfiguration.getURL();
162    
163                            if (_log.isDebugEnabled()) {
164                                    _log.debug("Adding file " + url);
165                            }
166    
167                            Long delay = _getReloadDelay(
168                                    loadedCompositeConfiguration, newFileConfiguration);
169    
170                            if (delay != null) {
171                                    FileChangedReloadingStrategy fileChangedReloadingStrategy =
172                                            new FileConfigurationChangedReloadingStrategy();
173    
174                                    if (_log.isDebugEnabled()) {
175                                            _log.debug(
176                                                    "File " + url + " will be reloaded every " +
177                                                            delay + " seconds");
178                                    }
179    
180                                    long milliseconds = delay.longValue() * 1000;
181    
182                                    fileChangedReloadingStrategy.setRefreshDelay(milliseconds);
183    
184                                    newFileConfiguration.setReloadingStrategy(
185                                            fileChangedReloadingStrategy);
186                            }
187    
188                            _addIncludedPropertiesSources(
189                                    newFileConfiguration, loadedCompositeConfiguration);
190    
191                            return newFileConfiguration;
192                    }
193                    catch (org.apache.commons.configuration.ConfigurationException ce) {
194                            if (_log.isDebugEnabled()) {
195                                    _log.debug("Configuration source " + fileName + " ignored");
196                            }
197    
198                            return null;
199                    }
200            }
201    
202            private void _addIncludedPropertiesSources(
203                    Configuration newConfiguration,
204                    CompositeConfiguration loadedCompositeConfiguration) {
205    
206                    CompositeConfiguration tempCompositeConfiguration =
207                            new CompositeConfiguration();
208    
209                    tempCompositeConfiguration.addConfiguration(
210                            _prefixedSystemConfiguration);
211                    tempCompositeConfiguration.addConfiguration(newConfiguration);
212                    tempCompositeConfiguration.addConfiguration(_systemConfiguration);
213                    tempCompositeConfiguration.addProperty(
214                            Conventions.COMPANY_ID_PROPERTY, _companyId);
215                    tempCompositeConfiguration.addProperty(
216                            Conventions.COMPONENT_NAME_PROPERTY, _componentName);
217    
218                    String[] fileNames = tempCompositeConfiguration.getStringArray(
219                            Conventions.INCLUDE_PROPERTY);
220    
221                    ArrayUtil.reverse(fileNames);
222    
223                    for (String fileName : fileNames) {
224                            URL url = null;
225    
226                            try {
227                                    url = _classLoader.getResource(fileName);
228                            }
229                            catch (RuntimeException re) {
230                                    if (fileName.startsWith("file:/")) {
231                                            throw re;
232                                    }
233    
234                                    fileName = "file:/".concat(fileName);
235    
236                                    url = _classLoader.getResource(fileName);
237                            }
238    
239                            _addPropertiesSource(fileName, url, loadedCompositeConfiguration);
240                    }
241            }
242    
243            private Configuration _addJNDIProperties(String sourcePath) {
244                    JndiURL jndiURL = new JndiURL(sourcePath, _companyId, _componentName);
245    
246                    return jndiURL.getConfiguration();
247            }
248    
249            private Configuration _addPropertiesSource(
250                    String sourceName, URL url,
251                    CompositeConfiguration loadedCompositeConfiguration) {
252    
253                    try {
254                            Configuration newConfiguration = null;
255    
256                            if (DatasourceURL.isDatasource(sourceName)) {
257                                    newConfiguration = _addDatasourceProperties(sourceName);
258                            }
259                            else if (JndiURL.isJndi(sourceName)) {
260                                    newConfiguration = _addJNDIProperties(sourceName);
261                            }
262                            else if (url != null) {
263                                    newConfiguration = _addURLProperties(
264                                            url, loadedCompositeConfiguration);
265                            }
266                            else {
267                                    newConfiguration = _addFileProperties(
268                                            sourceName, loadedCompositeConfiguration);
269                            }
270    
271                            if (newConfiguration == null) {
272                                    return newConfiguration;
273                            }
274    
275                            loadedCompositeConfiguration.addConfiguration(newConfiguration);
276    
277                            super.addConfiguration(newConfiguration);
278    
279                            if (newConfiguration instanceof AbstractFileConfiguration) {
280                                    AbstractFileConfiguration abstractFileConfiguration =
281                                            (AbstractFileConfiguration)newConfiguration;
282    
283                                    URL abstractFileConfigurationURL =
284                                            abstractFileConfiguration.getURL();
285    
286                                    _loadedSources.add(abstractFileConfigurationURL.toString());
287                            }
288                            else {
289                                    _loadedSources.add(sourceName);
290                            }
291    
292                            return newConfiguration;
293                    }
294                    catch (Exception e) {
295                            if (_log.isDebugEnabled()) {
296                                    _log.debug(
297                                            "Configuration source " + sourceName + " ignored: " +
298                                                    e.getMessage());
299                            }
300    
301                            return null;
302                    }
303            }
304    
305            private Configuration _addURLProperties(
306                            URL url, CompositeConfiguration loadedCompositeConfiguration)
307                    throws ConfigurationException {
308    
309                    try {
310                            FileConfiguration newFileConfiguration =
311                                    new PropertiesConfiguration(url);
312    
313                            if (_log.isDebugEnabled()) {
314                                    _log.debug("Adding resource " + url);
315                            }
316    
317                            Long delay = _getReloadDelay(
318                                    loadedCompositeConfiguration, newFileConfiguration);
319    
320                            if (delay != null) {
321                                    FileChangedReloadingStrategy fileChangedReloadingStrategy =
322                                            new FileConfigurationChangedReloadingStrategy();
323    
324                                    if (_log.isDebugEnabled()) {
325                                            _log.debug(
326                                                    "Resource " + url + " will be reloaded every " +
327                                                            delay + " seconds");
328                                    }
329    
330                                    long milliseconds = delay.longValue() * 1000;
331    
332                                    fileChangedReloadingStrategy.setRefreshDelay(milliseconds);
333    
334                                    newFileConfiguration.setReloadingStrategy(
335                                            fileChangedReloadingStrategy);
336                            }
337    
338                            _addIncludedPropertiesSources(
339                                    newFileConfiguration, loadedCompositeConfiguration);
340    
341                            return newFileConfiguration;
342                    }
343                    catch (org.apache.commons.configuration.ConfigurationException ce) {
344                            if (_log.isDebugEnabled()) {
345                                    _log.debug("Configuration source " + url + " ignored");
346                            }
347    
348                            return null;
349                    }
350            }
351    
352            private String _getPrefix() {
353                    return _componentName.concat(Conventions.PREFIX_SEPARATOR);
354            }
355    
356            private Long _getReloadDelay(
357                    CompositeConfiguration loadedCompositeConfiguration,
358                    FileConfiguration newFileConfiguration) {
359    
360                    Long delay = newFileConfiguration.getLong(
361                            Conventions.RELOAD_DELAY_PROPERTY, null);
362    
363                    if (delay == null) {
364                            delay = loadedCompositeConfiguration.getLong(
365                                    Conventions.RELOAD_DELAY_PROPERTY, null);
366                    }
367    
368                    return delay;
369            }
370    
371            private static final Log _log = LogFactoryUtil.getLog(
372                    ClassLoaderAggregateProperties.class);
373    
374            private final CompositeConfiguration _baseCompositeConfiguration =
375                    new CompositeConfiguration();
376            private boolean _baseConfigurationLoaded;
377            private final ClassLoader _classLoader;
378            private final String _companyId;
379            private final String _componentName;
380            private final CompositeConfiguration _globalCompositeConfiguration =
381                    new CompositeConfiguration();
382            private final List<String> _loadedSources = new ArrayList<>();
383            private final Configuration _prefixedSystemConfiguration;
384            private final SystemConfiguration _systemConfiguration =
385                    new SystemConfiguration();
386    
387    }