001
014
015 package com.liferay.portal.configuration;
016
017 import com.germinus.easyconf.AggregatedProperties;
018 import com.germinus.easyconf.ComponentConfiguration;
019 import com.germinus.easyconf.ComponentProperties;
020 import com.germinus.easyconf.Conventions;
021 import com.germinus.easyconf.EasyConf;
022
023 import com.liferay.portal.kernel.configuration.Filter;
024 import com.liferay.portal.kernel.log.Log;
025 import com.liferay.portal.kernel.log.LogFactoryUtil;
026 import com.liferay.portal.kernel.util.PropertiesUtil;
027 import com.liferay.portal.kernel.util.StreamUtil;
028 import com.liferay.portal.kernel.util.StringBundler;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.StringUtil;
031 import com.liferay.portal.kernel.util.Validator;
032 import com.liferay.portal.model.Company;
033 import com.liferay.portal.model.CompanyConstants;
034 import com.liferay.portal.service.CompanyLocalServiceUtil;
035
036 import java.io.File;
037 import java.io.FileWriter;
038 import java.io.InputStream;
039 import java.io.Writer;
040
041 import java.lang.reflect.Field;
042
043 import java.net.URI;
044 import java.net.URISyntaxException;
045 import java.net.URL;
046
047 import java.util.HashSet;
048 import java.util.Iterator;
049 import java.util.List;
050 import java.util.Map;
051 import java.util.Properties;
052 import java.util.Set;
053 import java.util.concurrent.ConcurrentHashMap;
054
055 import org.apache.commons.configuration.CompositeConfiguration;
056 import org.apache.commons.configuration.Configuration;
057 import org.apache.commons.configuration.MapConfiguration;
058
059
063 public class ConfigurationImpl
064 implements com.liferay.portal.kernel.configuration.Configuration {
065
066 public ConfigurationImpl(ClassLoader classLoader, String name) {
067 this(classLoader, name, CompanyConstants.SYSTEM);
068 }
069
070 public ConfigurationImpl(
071 ClassLoader classLoader, String name, long companyId) {
072
073 updateBasePath(classLoader, name);
074
075 String webId = null;
076
077 if (companyId > CompanyConstants.SYSTEM) {
078 try {
079 Company company = CompanyLocalServiceUtil.getCompanyById(
080 companyId);
081
082 webId = company.getWebId();
083 }
084 catch (Exception e) {
085 _log.error(e, e);
086 }
087 }
088
089 EasyConf.refreshAll();
090
091 if (webId != null) {
092 _componentConfiguration = EasyConf.getConfiguration(
093 webId, getFileName(classLoader, name));
094 }
095 else {
096 _componentConfiguration = EasyConf.getConfiguration(
097 getFileName(classLoader, name));
098 }
099
100 printSources(companyId, webId);
101 }
102
103 public void addProperties(Properties properties) {
104 try {
105 ComponentProperties componentProperties =
106 _componentConfiguration.getProperties();
107
108 AggregatedProperties aggregatedProperties =
109 (AggregatedProperties)componentProperties.toConfiguration();
110
111 Field field1 = CompositeConfiguration.class.getDeclaredField(
112 "configList");
113
114 field1.setAccessible(true);
115
116
117
118 List<Configuration> configurations =
119 (List<Configuration>)field1.get(aggregatedProperties);
120
121 MapConfiguration newConfiguration = new MapConfiguration(
122 properties);
123
124 configurations.add(0, newConfiguration);
125
126
127
128 Class<?> clazz = aggregatedProperties.getClass();
129
130 Field field2 = clazz.getDeclaredField("baseConf");
131
132 field2.setAccessible(true);
133
134 CompositeConfiguration compositeConfiguration =
135 (CompositeConfiguration)field2.get(aggregatedProperties);
136
137 configurations = (List<Configuration>)field1.get(
138 compositeConfiguration);
139
140 configurations.add(0, newConfiguration);
141
142 clearCache();
143 }
144 catch (Exception e) {
145 _log.error("The properties could not be added", e);
146 }
147 }
148
149 public void clearCache() {
150 _values.clear();
151 }
152
153 public boolean contains(String key) {
154 Object value = _values.get(key);
155
156 if (value == null) {
157 ComponentProperties componentProperties = getComponentProperties();
158
159 value = componentProperties.getProperty(key);
160
161 if (value == null) {
162 value = _nullValue;
163 }
164
165 _values.put(key, value);
166 }
167
168 if (value == _nullValue) {
169 return false;
170 }
171 else {
172 return true;
173 }
174 }
175
176 public String get(String key) {
177 Object value = _values.get(key);
178
179 if (value == null) {
180 ComponentProperties componentProperties = getComponentProperties();
181
182 value = componentProperties.getString(key);
183
184 if (value == null) {
185 value = _nullValue;
186 }
187
188 _values.put(key, value);
189 }
190 else if (_PRINT_DUPLICATE_CALLS_TO_GET) {
191 System.out.println("Duplicate call to get " + key);
192 }
193
194 if (value instanceof String) {
195 return (String)value;
196 }
197 else {
198 return null;
199 }
200 }
201
202 public String get(String key, Filter filter) {
203 String filterCacheKey = buildFilterCacheKey(key, filter, false);
204
205 Object value = null;
206
207 if (filterCacheKey != null) {
208 value = _values.get(filterCacheKey);
209 }
210
211 if (value == null) {
212 ComponentProperties componentProperties = getComponentProperties();
213
214 value = componentProperties.getString(
215 key, getEasyConfFilter(filter));
216
217 if (filterCacheKey != null) {
218 if (value == null) {
219 value = _nullValue;
220 }
221
222 _values.put(filterCacheKey, value);
223 }
224 }
225
226 if (value instanceof String) {
227 return (String)value;
228 }
229 else {
230 return null;
231 }
232
233 }
234
235 public String[] getArray(String key) {
236 String cacheKey = _ARRAY_KEY_PREFIX.concat(key);
237
238 Object value = _values.get(cacheKey);
239
240 if (value == null) {
241 ComponentProperties componentProperties = getComponentProperties();
242
243 String[] array = componentProperties.getStringArray(key);
244
245 value = fixArrayValue(cacheKey, array);
246 }
247
248 if (value instanceof String[]) {
249 return (String[])value;
250 }
251 else {
252 return _emptyArray;
253 }
254 }
255
256 public String[] getArray(String key, Filter filter) {
257 String filterCacheKey = buildFilterCacheKey(key, filter, true);
258
259 Object value = null;
260
261 if (filterCacheKey != null) {
262 value = _values.get(filterCacheKey);
263 }
264
265 if (value == null) {
266 ComponentProperties componentProperties = getComponentProperties();
267
268 String[] array = componentProperties.getStringArray(
269 key, getEasyConfFilter(filter));
270
271 value = fixArrayValue(filterCacheKey, array);
272 }
273
274 if (value instanceof String[]) {
275 return (String[])value;
276 }
277 else {
278 return _emptyArray;
279 }
280 }
281
282 public Properties getProperties() {
283
284
285
286
287
288
289
290
291
292 Properties properties = new Properties();
293
294 ComponentProperties componentProperties = getComponentProperties();
295
296 Properties componentPropertiesProperties =
297 componentProperties.getProperties();
298
299 for (Map.Entry<Object, Object> entry :
300 componentPropertiesProperties.entrySet()) {
301
302 String key = (String)entry.getKey();
303 String value = (String)entry.getValue();
304
305 properties.setProperty(key, value);
306 }
307
308 return properties;
309 }
310
311 public Properties getProperties(String prefix, boolean removePrefix) {
312 Properties properties = getProperties();
313
314 return PropertiesUtil.getProperties(properties, prefix, removePrefix);
315 }
316
317 public void removeProperties(Properties properties) {
318 try {
319 ComponentProperties componentProperties =
320 _componentConfiguration.getProperties();
321
322 AggregatedProperties aggregatedProperties =
323 (AggregatedProperties)componentProperties.toConfiguration();
324
325 Class<?> clazz = aggregatedProperties.getClass();
326
327 Field field1 = clazz.getDeclaredField("baseConf");
328
329 field1.setAccessible(true);
330
331 CompositeConfiguration compositeConfiguration =
332 (CompositeConfiguration)field1.get(aggregatedProperties);
333
334 Field field2 = CompositeConfiguration.class.getDeclaredField(
335 "configList");
336
337 field2.setAccessible(true);
338
339 List<Configuration> configurations =
340 (List<Configuration>)field2.get(compositeConfiguration);
341
342 Iterator<Configuration> itr = configurations.iterator();
343
344 while (itr.hasNext()) {
345 Configuration configuration = itr.next();
346
347 if (!(configuration instanceof MapConfiguration)) {
348 return;
349 }
350
351 MapConfiguration mapConfiguration =
352 (MapConfiguration)configuration;
353
354 if (mapConfiguration.getMap() == properties) {
355 itr.remove();
356
357 aggregatedProperties.removeConfiguration(configuration);
358 }
359 }
360
361 clearCache();
362 }
363 catch (Exception e) {
364 _log.error("The properties could not be removed", e);
365 }
366 }
367
368 public void set(String key, String value) {
369 ComponentProperties componentProperties = getComponentProperties();
370
371 componentProperties.setProperty(key, value);
372
373 _values.put(key, value);
374 }
375
376 protected String buildFilterCacheKey(
377 String key, Filter filter, boolean arrayValue) {
378
379 if (filter.getVariables() != null) {
380 return null;
381 }
382
383 String[] selectors = filter.getSelectors();
384
385 int length = 0;
386
387 if (arrayValue) {
388 length = selectors.length + 2;
389 }
390 else {
391 length = selectors.length + 1;
392 }
393
394 StringBundler sb = new StringBundler(length);
395
396 if (arrayValue) {
397 sb.append(_ARRAY_KEY_PREFIX);
398 }
399
400 sb.append(key);
401 sb.append(selectors);
402
403 return sb.toString();
404 }
405
406 protected Object fixArrayValue(String cacheKey, String[] array) {
407 if (cacheKey == null) {
408 return array;
409 }
410
411 Object value = _nullValue;
412
413 if ((array != null) && (array.length > 0)) {
414
415
416
417
418
419
420 if (Validator.isNull(array[array.length - 1])) {
421 String[] subArray = new String[array.length - 1];
422
423 System.arraycopy(array, 0, subArray, 0, subArray.length);
424
425 array = subArray;
426 }
427
428 if (array.length > 0) {
429 value = array;
430 }
431 }
432
433 _values.put(cacheKey, value);
434
435 return value;
436 }
437
438 protected ComponentProperties getComponentProperties() {
439 return _componentConfiguration.getProperties();
440 }
441
442 protected com.germinus.easyconf.Filter getEasyConfFilter(Filter filter) {
443 com.germinus.easyconf.Filter easyConfFilter =
444 com.germinus.easyconf.Filter.by(filter.getSelectors());
445
446 if (filter.getVariables() != null) {
447 easyConfFilter.setVariables(filter.getVariables());
448 }
449
450 return easyConfFilter;
451 }
452
453 protected String getFileName(ClassLoader classLoader, String name) {
454 URL url = classLoader.getResource(name + ".properties");
455
456
457
458
459
460
461
462
463
464 String protocol = url.getProtocol();
465
466 if (protocol.equals("code-source") || protocol.equals("jar") ||
467 protocol.equals("vfs") || protocol.equals("vfsfile") ||
468 protocol.equals("vfszip") || protocol.equals("wsjar") ||
469 protocol.equals("zip")) {
470
471 name = url.toExternalForm();
472 }
473 else {
474 try {
475 name = new URI(url.getPath()).getPath();
476 }
477 catch (URISyntaxException urise) {
478 name = url.getFile();
479 }
480 }
481
482 int pos = name.lastIndexOf(".properties");
483
484 if (pos != -1) {
485 name = name.substring(0, pos);
486 }
487
488 return name;
489 }
490
491 protected void printSources(long companyId, String webId) {
492 ComponentProperties componentProperties = getComponentProperties();
493
494 List<String> sources = componentProperties.getLoadedSources();
495
496 for (int i = sources.size() - 1; i >= 0; i--) {
497 String source = sources.get(i);
498
499 if (_printedSources.contains(source)) {
500 continue;
501 }
502
503 _printedSources.add(source);
504
505 String info = "Loading " + source;
506
507 if (companyId > CompanyConstants.SYSTEM) {
508 info +=
509 " for {companyId=" + companyId + ", webId=" + webId + "}";
510 }
511
512 System.out.println(info);
513 }
514 }
515
516 protected void updateBasePath(ClassLoader classLoader, String name) {
517 InputStream inputStream = null;
518
519 try {
520 URL url = classLoader.getResource(
521 name + Conventions.PROPERTIES_EXTENSION);
522
523 if (url == null) {
524 return;
525 }
526
527 String protocol = url.getProtocol();
528
529 if (!protocol.equals("file")) {
530 return;
531 }
532
533 Properties properties = new Properties();
534
535 inputStream = url.openStream();
536
537 properties.load(inputStream);
538
539 if (properties.containsKey("base.path")) {
540 return;
541 }
542
543 String fileName = StringUtil.replace(
544 url.getFile(), "%20", StringPool.SPACE);
545
546 File file = new File(fileName);
547
548 if (!file.exists() || !file.canWrite()) {
549 if (_log.isWarnEnabled()) {
550 _log.warn("Unable to write " + file);
551 }
552
553 return;
554 }
555
556 Writer writer = new FileWriter(file, true);
557
558 StringBundler sb = new StringBundler(4);
559
560 sb.append(StringPool.OS_EOL);
561 sb.append(StringPool.OS_EOL);
562 sb.append("base.path=");
563
564 String basePath = url.getPath();
565
566 int pos = basePath.lastIndexOf(
567 StringPool.SLASH + name + Conventions.PROPERTIES_EXTENSION);
568
569 if (pos != -1) {
570 basePath = basePath.substring(0, pos);
571 }
572
573 sb.append(basePath);
574
575 writer.write(sb.toString());
576
577 writer.close();
578 }
579 catch (Exception e) {
580 _log.error(e, e);
581 }
582 finally {
583 StreamUtil.cleanUp(inputStream);
584 }
585 }
586
587 private static final String _ARRAY_KEY_PREFIX = "ARRAY_";
588
589 private static final boolean _PRINT_DUPLICATE_CALLS_TO_GET = false;
590
591 private static Log _log = LogFactoryUtil.getLog(ConfigurationImpl.class);
592
593 private static String[] _emptyArray = new String[0];
594 private static Object _nullValue = new Object();
595
596 private ComponentConfiguration _componentConfiguration;
597 private Set<String> _printedSources = new HashSet<String>();
598 private Map<String, Object> _values =
599 new ConcurrentHashMap<String, Object>();
600
601 }