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