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 public ConfigurationImpl(
082 ClassLoader classLoader, String name, long companyId, String webId) {
083
084 _componentConfiguration = new ClassLoaderComponentConfiguration(
085 classLoader, webId, name);
086
087 printSources(companyId, webId);
088 }
089
090 @Override
091 public void addProperties(Properties properties) {
092 try {
093 ComponentProperties componentProperties =
094 _componentConfiguration.getProperties();
095
096 ClassLoaderAggregateProperties classLoaderAggregateProperties =
097 (ClassLoaderAggregateProperties)
098 componentProperties.toConfiguration();
099
100 Field field1 = CompositeConfiguration.class.getDeclaredField(
101 "configList");
102
103 field1.setAccessible(true);
104
105
106
107 List<Configuration> configurations =
108 (List<Configuration>)field1.get(classLoaderAggregateProperties);
109
110 MapConfiguration newConfiguration = new MapConfiguration(
111 properties);
112
113 configurations.add(0, newConfiguration);
114
115
116
117 CompositeConfiguration compositeConfiguration =
118 classLoaderAggregateProperties.getBaseConfiguration();
119
120 configurations = (List<Configuration>)field1.get(
121 compositeConfiguration);
122
123 configurations.add(0, newConfiguration);
124
125 clearCache();
126 }
127 catch (Exception e) {
128 _log.error("The properties could not be added", e);
129 }
130 }
131
132 @Override
133 public void clearCache() {
134 _values.clear();
135 }
136
137 @Override
138 public boolean contains(String key) {
139 Object value = _values.get(key);
140
141 if (value == null) {
142 ComponentProperties componentProperties = getComponentProperties();
143
144 value = componentProperties.getProperty(key);
145
146 if (value == null) {
147 value = _nullValue;
148 }
149
150 _values.put(key, value);
151 }
152
153 if (value == _nullValue) {
154 return false;
155 }
156
157 return true;
158 }
159
160 @Override
161 public String get(String key) {
162 Object value = _values.get(key);
163
164 if (value == null) {
165 ComponentProperties componentProperties = getComponentProperties();
166
167 value = componentProperties.getString(key);
168
169 if (value == null) {
170 value = _nullValue;
171 }
172
173 _values.put(key, value);
174 }
175 else if (_PRINT_DUPLICATE_CALLS_TO_GET) {
176 System.out.println("Duplicate call to get " + key);
177 }
178
179 if (value instanceof String) {
180 return (String)value;
181 }
182
183 return null;
184 }
185
186 @Override
187 public String get(String key, Filter filter) {
188 String filterCacheKey = buildFilterCacheKey(key, filter, false);
189
190 Object value = null;
191
192 if (filterCacheKey != null) {
193 value = _values.get(filterCacheKey);
194 }
195
196 if (value == null) {
197 ComponentProperties componentProperties = getComponentProperties();
198
199 value = componentProperties.getString(
200 key, getEasyConfFilter(filter));
201
202 if (filterCacheKey != null) {
203 if (value == null) {
204 value = _nullValue;
205 }
206
207 _values.put(filterCacheKey, value);
208 }
209 }
210
211 if (value instanceof String) {
212 return (String)value;
213 }
214
215 return null;
216 }
217
218 @Override
219 public String[] getArray(String key) {
220 String cacheKey = _ARRAY_KEY_PREFIX.concat(key);
221
222 Object value = _values.get(cacheKey);
223
224 if (value == null) {
225 ComponentProperties componentProperties = getComponentProperties();
226
227 String[] array = componentProperties.getStringArray(key);
228
229 value = fixArrayValue(cacheKey, array);
230 }
231
232 if (value instanceof String[]) {
233 return (String[])value;
234 }
235
236 return _emptyArray;
237 }
238
239 @Override
240 public String[] getArray(String key, Filter filter) {
241 String filterCacheKey = buildFilterCacheKey(key, filter, true);
242
243 Object value = null;
244
245 if (filterCacheKey != null) {
246 value = _values.get(filterCacheKey);
247 }
248
249 if (value == null) {
250 ComponentProperties componentProperties = getComponentProperties();
251
252 String[] array = componentProperties.getStringArray(
253 key, getEasyConfFilter(filter));
254
255 value = fixArrayValue(filterCacheKey, array);
256 }
257
258 if (value instanceof String[]) {
259 return (String[])value;
260 }
261
262 return _emptyArray;
263 }
264
265 @Override
266 public Properties getProperties() {
267
268
269
270
271
272
273
274
275
276 Properties properties = new Properties();
277
278 ComponentProperties componentProperties = getComponentProperties();
279
280 Properties componentPropertiesProperties =
281 componentProperties.getProperties();
282
283 for (String key : componentPropertiesProperties.stringPropertyNames()) {
284 properties.setProperty(key, componentProperties.getString(key));
285 }
286
287 return properties;
288 }
289
290 @Override
291 public Properties getProperties(String prefix, boolean removePrefix) {
292 Properties properties = getProperties();
293
294 return PropertiesUtil.getProperties(properties, prefix, removePrefix);
295 }
296
297 @Override
298 public void removeProperties(Properties properties) {
299 try {
300 ComponentProperties componentProperties =
301 _componentConfiguration.getProperties();
302
303 ClassLoaderAggregateProperties classLoaderAggregateProperties =
304 (ClassLoaderAggregateProperties)
305 componentProperties.toConfiguration();
306
307 CompositeConfiguration compositeConfiguration =
308 classLoaderAggregateProperties.getBaseConfiguration();
309
310 Field field2 = CompositeConfiguration.class.getDeclaredField(
311 "configList");
312
313 field2.setAccessible(true);
314
315 @SuppressWarnings("unchecked")
316 List<Configuration> configurations =
317 (List<Configuration>)field2.get(compositeConfiguration);
318
319 Iterator<Configuration> itr = configurations.iterator();
320
321 while (itr.hasNext()) {
322 Configuration configuration = itr.next();
323
324 if (!(configuration instanceof MapConfiguration)) {
325 break;
326 }
327
328 MapConfiguration mapConfiguration =
329 (MapConfiguration)configuration;
330
331 if (mapConfiguration.getMap() == properties) {
332 itr.remove();
333
334 classLoaderAggregateProperties.removeConfiguration(
335 configuration);
336 }
337 }
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 Log _log = LogFactoryUtil.getLog(ConfigurationImpl.class);
462
463 private static String[] _emptyArray = new String[0];
464 private static Object _nullValue = new Object();
465
466 private ComponentConfiguration _componentConfiguration;
467 private Set<String> _printedSources = new HashSet<String>();
468 private Map<String, Object> _values =
469 new ConcurrentHashMap<String, Object>();
470
471 }