001
014
015 package com.liferay.portal.configuration;
016
017 import com.germinus.easyconf.ComponentConfiguration;
018 import com.germinus.easyconf.ComponentProperties;
019
020 import com.liferay.portal.configuration.easyconf.ClassLoaderAggregateProperties;
021 import com.liferay.portal.configuration.easyconf.ClassLoaderComponentConfiguration;
022 import com.liferay.portal.kernel.configuration.Filter;
023 import com.liferay.portal.kernel.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.util.ArrayUtil;
026 import com.liferay.portal.kernel.util.PropertiesUtil;
027 import com.liferay.portal.kernel.util.StringBundler;
028 import com.liferay.portal.kernel.util.Validator;
029 import com.liferay.portal.model.Company;
030 import com.liferay.portal.model.CompanyConstants;
031 import com.liferay.portal.service.CompanyLocalServiceUtil;
032
033 import java.lang.reflect.Field;
034
035 import java.util.HashSet;
036 import java.util.Iterator;
037 import java.util.List;
038 import java.util.Map;
039 import java.util.Properties;
040 import java.util.Set;
041 import java.util.concurrent.ConcurrentHashMap;
042
043 import org.apache.commons.configuration.CompositeConfiguration;
044 import org.apache.commons.configuration.Configuration;
045 import org.apache.commons.configuration.MapConfiguration;
046
047
051 public class ConfigurationImpl
052 implements com.liferay.portal.kernel.configuration.Configuration {
053
054 public ConfigurationImpl(ClassLoader classLoader, String name) {
055 this(classLoader, name, CompanyConstants.SYSTEM);
056 }
057
058 public ConfigurationImpl(
059 ClassLoader classLoader, String name, long companyId) {
060
061 String webId = null;
062
063 if (companyId > CompanyConstants.SYSTEM) {
064 try {
065 Company company = CompanyLocalServiceUtil.getCompanyById(
066 companyId);
067
068 webId = company.getWebId();
069 }
070 catch (Exception e) {
071 _log.error(e, e);
072 }
073 }
074
075 _componentConfiguration = new ClassLoaderComponentConfiguration(
076 classLoader, webId, name);
077
078 printSources(companyId, webId);
079 }
080
081 @Override
082 public void addProperties(Properties properties) {
083 try {
084 ComponentProperties componentProperties = getComponentProperties();
085
086 ClassLoaderAggregateProperties classLoaderAggregateProperties =
087 (ClassLoaderAggregateProperties)
088 componentProperties.toConfiguration();
089
090 Field field1 = CompositeConfiguration.class.getDeclaredField(
091 "configList");
092
093 field1.setAccessible(true);
094
095
096
097 List<Configuration> configurations =
098 (List<Configuration>)field1.get(classLoaderAggregateProperties);
099
100 MapConfiguration newConfiguration = new MapConfiguration(
101 properties);
102
103 newConfiguration.setTrimmingDisabled(true);
104
105 configurations.add(0, newConfiguration);
106
107
108
109 CompositeConfiguration compositeConfiguration =
110 classLoaderAggregateProperties.getBaseConfiguration();
111
112 configurations = (List<Configuration>)field1.get(
113 compositeConfiguration);
114
115 configurations.add(0, newConfiguration);
116
117 _properties = null;
118
119 clearCache();
120 }
121 catch (Exception e) {
122 _log.error("The properties could not be added", e);
123 }
124 }
125
126 @Override
127 public void clearCache() {
128 _values.clear();
129
130 _properties = null;
131 }
132
133 @Override
134 public boolean contains(String key) {
135 Object value = _values.get(key);
136
137 if (value == null) {
138 ComponentProperties componentProperties = getComponentProperties();
139
140 value = componentProperties.getProperty(key);
141
142 if (value == null) {
143 value = _nullValue;
144 }
145
146 _values.put(key, value);
147 }
148
149 if (value == _nullValue) {
150 return false;
151 }
152
153 return true;
154 }
155
156 @Override
157 public String get(String key) {
158 Object value = _values.get(key);
159
160 if (value == null) {
161 ComponentProperties componentProperties = getComponentProperties();
162
163 value = componentProperties.getString(key);
164
165 if (value == null) {
166 value = _nullValue;
167 }
168
169 _values.put(key, value);
170 }
171 else if (_PRINT_DUPLICATE_CALLS_TO_GET) {
172 System.out.println("Duplicate call to get " + key);
173 }
174
175 if (value instanceof String) {
176 return (String)value;
177 }
178
179 return null;
180 }
181
182 @Override
183 public String get(String key, Filter filter) {
184 String filterCacheKey = buildFilterCacheKey(key, filter, false);
185
186 Object value = null;
187
188 if (filterCacheKey != null) {
189 value = _values.get(filterCacheKey);
190 }
191
192 if (value == null) {
193 ComponentProperties componentProperties = getComponentProperties();
194
195 value = componentProperties.getString(
196 key, getEasyConfFilter(filter));
197
198 if (filterCacheKey != null) {
199 if (value == null) {
200 value = _nullValue;
201 }
202
203 _values.put(filterCacheKey, value);
204 }
205 }
206
207 if (value instanceof String) {
208 return (String)value;
209 }
210
211 return null;
212 }
213
214 @Override
215 public String[] getArray(String key) {
216 String cacheKey = _ARRAY_KEY_PREFIX.concat(key);
217
218 Object value = _values.get(cacheKey);
219
220 if (value == null) {
221 ComponentProperties componentProperties = getComponentProperties();
222
223 String[] array = componentProperties.getStringArray(key);
224
225 value = fixArrayValue(cacheKey, array);
226 }
227
228 if (value instanceof String[]) {
229 return (String[])value;
230 }
231
232 return _emptyArray;
233 }
234
235 @Override
236 public String[] getArray(String key, Filter filter) {
237 String filterCacheKey = buildFilterCacheKey(key, filter, true);
238
239 Object value = null;
240
241 if (filterCacheKey != null) {
242 value = _values.get(filterCacheKey);
243 }
244
245 if (value == null) {
246 ComponentProperties componentProperties = getComponentProperties();
247
248 String[] array = componentProperties.getStringArray(
249 key, getEasyConfFilter(filter));
250
251 value = fixArrayValue(filterCacheKey, array);
252 }
253
254 if (value instanceof String[]) {
255 return (String[])value;
256 }
257
258 return _emptyArray;
259 }
260
261 @Override
262 public Properties getProperties() {
263 if (_properties != null) {
264 return _properties;
265 }
266
267
268
269
270
271
272
273
274
275 _properties = new Properties();
276
277 ComponentProperties componentProperties = getComponentProperties();
278
279 Properties componentPropertiesProperties =
280 componentProperties.getProperties();
281
282 for (String key : componentPropertiesProperties.stringPropertyNames()) {
283 _properties.setProperty(key, componentProperties.getString(key));
284 }
285
286 return _properties;
287 }
288
289 @Override
290 public Properties getProperties(String prefix, boolean removePrefix) {
291 Properties properties = getProperties();
292
293 return PropertiesUtil.getProperties(properties, prefix, removePrefix);
294 }
295
296 @Override
297 public void removeProperties(Properties properties) {
298 try {
299 ComponentProperties componentProperties = getComponentProperties();
300
301 ClassLoaderAggregateProperties classLoaderAggregateProperties =
302 (ClassLoaderAggregateProperties)
303 componentProperties.toConfiguration();
304
305 CompositeConfiguration compositeConfiguration =
306 classLoaderAggregateProperties.getBaseConfiguration();
307
308 Field field2 = CompositeConfiguration.class.getDeclaredField(
309 "configList");
310
311 field2.setAccessible(true);
312
313 @SuppressWarnings("unchecked")
314 List<Configuration> configurations =
315 (List<Configuration>)field2.get(compositeConfiguration);
316
317 Iterator<Configuration> itr = configurations.iterator();
318
319 while (itr.hasNext()) {
320 Configuration configuration = itr.next();
321
322 if (!(configuration instanceof MapConfiguration)) {
323 break;
324 }
325
326 MapConfiguration mapConfiguration =
327 (MapConfiguration)configuration;
328
329 if (mapConfiguration.getMap() == (Map<?, ?>)properties) {
330 itr.remove();
331
332 classLoaderAggregateProperties.removeConfiguration(
333 configuration);
334 }
335 }
336
337 _properties = null;
338
339 clearCache();
340 }
341 catch (Exception e) {
342 _log.error("The properties could not be removed", e);
343 }
344 }
345
346 @Override
347 public void set(String key, String value) {
348 ComponentProperties componentProperties = getComponentProperties();
349
350 componentProperties.setProperty(key, value);
351
352 _values.put(key, value);
353 }
354
355 protected String buildFilterCacheKey(
356 String key, Filter filter, boolean arrayValue) {
357
358 if (filter.getVariables() != null) {
359 return null;
360 }
361
362 String[] selectors = filter.getSelectors();
363
364 int length = 0;
365
366 if (arrayValue) {
367 length = selectors.length + 2;
368 }
369 else {
370 length = selectors.length + 1;
371 }
372
373 StringBundler sb = new StringBundler(length);
374
375 if (arrayValue) {
376 sb.append(_ARRAY_KEY_PREFIX);
377 }
378
379 sb.append(key);
380 sb.append(selectors);
381
382 return sb.toString();
383 }
384
385 protected Object fixArrayValue(String cacheKey, String[] array) {
386 if (cacheKey == null) {
387 return array;
388 }
389
390 Object value = _nullValue;
391
392 if (ArrayUtil.isNotEmpty(array)) {
393
394
395
396
397
398
399 if (Validator.isNull(array[array.length - 1])) {
400 String[] subArray = new String[array.length - 1];
401
402 System.arraycopy(array, 0, subArray, 0, subArray.length);
403
404 array = subArray;
405 }
406
407 if (array.length > 0) {
408 value = array;
409 }
410 }
411
412 _values.put(cacheKey, value);
413
414 return value;
415 }
416
417 protected ComponentProperties getComponentProperties() {
418 return _componentConfiguration.getProperties();
419 }
420
421 protected com.germinus.easyconf.Filter getEasyConfFilter(Filter filter) {
422 com.germinus.easyconf.Filter easyConfFilter =
423 com.germinus.easyconf.Filter.by(filter.getSelectors());
424
425 if (filter.getVariables() != null) {
426 easyConfFilter.setVariables(filter.getVariables());
427 }
428
429 return easyConfFilter;
430 }
431
432 protected void printSources(long companyId, String webId) {
433 ComponentProperties componentProperties = getComponentProperties();
434
435 List<String> sources = componentProperties.getLoadedSources();
436
437 for (int i = sources.size() - 1; i >= 0; i--) {
438 String source = sources.get(i);
439
440 if (_printedSources.contains(source)) {
441 continue;
442 }
443
444 _printedSources.add(source);
445
446 String info = "Loading " + source;
447
448 if (companyId > CompanyConstants.SYSTEM) {
449 info +=
450 " for {companyId=" + companyId + ", webId=" + webId + "}";
451 }
452
453 System.out.println(info);
454 }
455 }
456
457 private static final String _ARRAY_KEY_PREFIX = "ARRAY_";
458
459 private static final boolean _PRINT_DUPLICATE_CALLS_TO_GET = false;
460
461 private static final Log _log = LogFactoryUtil.getLog(
462 ConfigurationImpl.class);
463
464 private static final String[] _emptyArray = new String[0];
465 private static final Object _nullValue = new Object();
466
467 private final ComponentConfiguration _componentConfiguration;
468 private final Set<String> _printedSources = new HashSet<>();
469 private Properties _properties;
470 private final Map<String, Object> _values = new ConcurrentHashMap<>();
471
472 }