1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.util.properties;
17
18 import java.util.List;
19 import java.util.Properties;
20
21 import org.kuali.common.util.Assert;
22 import org.kuali.common.util.PropertyUtils;
23 import org.kuali.common.util.cache.Cache;
24 import org.kuali.common.util.cache.SimpleCache;
25 import org.kuali.common.util.property.processor.NoOpProcessor;
26 import org.kuali.common.util.property.processor.OverridingProcessor;
27 import org.kuali.common.util.property.processor.PropertyProcessor;
28 import org.kuali.common.util.resolver.PropertiesValueResolver;
29 import org.kuali.common.util.resolver.ValueResolver;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 public class DefaultPropertiesService implements PropertiesService {
34
35 private static final Logger logger = LoggerFactory.getLogger(DefaultPropertiesService.class);
36
37 private static final Cache<String, Properties> CACHE = new SimpleCache<String, Properties>();
38 private static final PropertyProcessor DEFAULT_POST_PROCESSOR = NoOpProcessor.INSTANCE;
39
40 private final Properties overrides;
41 private final PropertyProcessor postProcessor;
42
43 public DefaultPropertiesService(Properties overrides) {
44 this(overrides, DEFAULT_POST_PROCESSOR);
45 }
46
47 public DefaultPropertiesService(Properties overrides, PropertyProcessor postProcessor) {
48 Assert.noNulls(overrides, postProcessor);
49 this.overrides = PropertyUtils.toImmutable(overrides);
50 this.postProcessor = postProcessor;
51 }
52
53 protected PropertiesLoader getLoader(Location location, Cache<String, Properties> cache, Properties combined) {
54 return new CachingLoader(location, CACHE);
55 }
56
57 @Override
58 public Properties getProperties(List<Location> locations) {
59
60
61 Properties properties = new Properties();
62
63
64 for (Location location : locations) {
65
66
67 Properties combined = PropertyUtils.combine(properties, overrides);
68
69
70 ValueResolver resolver = new PropertiesValueResolver(combined);
71
72
73 String resolvedLocation = resolver.resolve(location.getValue());
74
75
76 Location actualLocation = getLocation(location, location.getValue(), resolvedLocation);
77
78
79
80
81
82 PropertiesLoader loader = getLoader(actualLocation, CACHE, combined);
83
84
85 Properties loaded = loader.load();
86
87
88 new OverridingProcessor(loaded).process(properties);
89 }
90
91
92 postProcessor.process(properties);
93
94
95 if (logger.isDebugEnabled()) {
96 logger.debug("Displaying {} property values:\n\n{}", properties.size(), PropertyUtils.toString(properties));
97 }
98
99
100 return properties;
101 }
102
103 private Location getLocation(Location location, String originalLocation, String resolvedLocation) {
104 if (originalLocation.equals(resolvedLocation)) {
105 return location;
106 } else {
107 return Location.builder(location, resolvedLocation).build();
108 }
109 }
110
111 public void clearCache() {
112 CACHE.clear();
113 }
114
115 public Properties getOverrides() {
116 return overrides;
117 }
118
119 public PropertyProcessor getPostProcessor() {
120 return postProcessor;
121 }
122
123 }