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