1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.init;
35
36 import java.util.ArrayList;
37 import java.util.HashSet;
38 import java.util.List;
39 import java.util.Set;
40
41
42
43
44
45
46 public abstract class AbstractMagnoliaConfigurationProperties implements MagnoliaConfigurationProperties {
47 protected static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractMagnoliaConfigurationProperties.class);
48
49 protected List<PropertySource> sources;
50
51 protected AbstractMagnoliaConfigurationProperties(List<PropertySource> propertySources) {
52 this.sources = propertySources;
53 }
54
55 protected AbstractMagnoliaConfigurationProperties() {
56 this(new ArrayList<PropertySource>());
57 }
58
59 @Override
60 public void init() throws Exception {
61 }
62
63 @Override
64 public Set<String> getKeys() {
65 final Set<String> allKeys = new HashSet<String>();
66 for (PropertySource source : sources) {
67 allKeys.addAll(source.getKeys());
68 }
69 return allKeys;
70 }
71
72 @Override
73 public PropertySource getPropertySource(String key) {
74 for (PropertySource source : sources) {
75 if (source.hasProperty(key)) {
76 return source;
77 }
78 }
79 return null;
80 }
81
82 @Override
83 public String getProperty(String key) {
84 final PropertySource propertySource = getPropertySource(key);
85 if (propertySource != null) {
86 final String value = propertySource.getProperty(key);
87 return parseStringValue(value, new HashSet<String>());
88 }
89 return null;
90 }
91
92 @Override
93 public boolean getBooleanProperty(String property) {
94 return Boolean.parseBoolean(getProperty(property));
95 }
96
97 @Override
98 public boolean hasProperty(String key) {
99 return getPropertySource(key) != null;
100 }
101
102 @Override
103 public String describe() {
104 final StringBuilder s = new StringBuilder()
105 .append("[")
106 .append(getClass().getSimpleName())
107 .append(" with sources: ");
108 for (PropertySource source : sources) {
109 s.append(source.describe());
110 }
111 s.append("]");
112 return s.toString();
113 }
114
115 @Override
116 public String toString() {
117 return describe() + " with properties: " + sources;
118 }
119
120
121
122
123
124 protected String parseStringValue(String strVal, Set<String> visitedPlaceholders) {
125 final StringBuffer buf = new StringBuffer(strVal.trim());
126
127 int startIndex = strVal.indexOf(PLACEHOLDER_PREFIX);
128 while (startIndex != -1) {
129 int endIndex = -1;
130
131 int index = startIndex + PLACEHOLDER_PREFIX.length();
132 int withinNestedPlaceholder = 0;
133 while (index < buf.length()) {
134 if (PLACEHOLDER_SUFFIX.equals(buf.subSequence(index, index + PLACEHOLDER_SUFFIX.length()))) {
135 if (withinNestedPlaceholder > 0) {
136 withinNestedPlaceholder--;
137 index = index + PLACEHOLDER_SUFFIX.length();
138 } else {
139 endIndex = index;
140 break;
141 }
142 } else if (PLACEHOLDER_PREFIX.equals(buf.subSequence(index, index + PLACEHOLDER_PREFIX.length()))) {
143 withinNestedPlaceholder++;
144 index = index + PLACEHOLDER_PREFIX.length();
145 } else {
146 index++;
147 }
148 }
149
150 if (endIndex != -1) {
151 String placeholder = buf.substring(startIndex + PLACEHOLDER_PREFIX.length(), endIndex);
152 if (!visitedPlaceholders.add(placeholder)) {
153 log.warn("Circular reference detected in properties, \"{}\" is not resolvable", strVal);
154 return strVal;
155 }
156
157 placeholder = parseStringValue(placeholder, visitedPlaceholders);
158
159
160 final PropertySource propertySource = getPropertySource(placeholder);
161 String propVal = propertySource != null ? propertySource.getProperty(placeholder) : null;
162 if (propVal != null) {
163
164
165 propVal = parseStringValue(propVal, visitedPlaceholders);
166 buf.replace(startIndex, endIndex + PLACEHOLDER_SUFFIX.length(), propVal);
167 startIndex = buf.indexOf(PLACEHOLDER_PREFIX, startIndex + propVal.length());
168 } else {
169
170 startIndex = buf.indexOf(PLACEHOLDER_PREFIX, endIndex + PLACEHOLDER_SUFFIX.length());
171 }
172 visitedPlaceholders.remove(placeholder);
173 } else {
174 startIndex = -1;
175 }
176 }
177
178 return buf.toString();
179 }
180
181 protected static final String PLACEHOLDER_PREFIX = "${";
182 protected static final String PLACEHOLDER_SUFFIX = "}";
183
184
185 }