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.cms.beans.config;
35
36 import info.magnolia.cms.core.SystemProperty;
37 import info.magnolia.module.ModuleRegistry;
38 import info.magnolia.module.model.ModuleDefinition;
39 import info.magnolia.module.model.PropertyDefinition;
40 import info.magnolia.objectfactory.Components;
41
42 import java.io.File;
43 import java.io.FileInputStream;
44 import java.io.FileNotFoundException;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.nio.file.Paths;
48 import java.text.MessageFormat;
49 import java.util.HashSet;
50 import java.util.Iterator;
51 import java.util.List;
52 import java.util.Properties;
53 import java.util.Set;
54
55 import javax.inject.Inject;
56 import javax.servlet.ServletContext;
57
58 import org.apache.commons.io.IOUtils;
59 import org.apache.commons.lang3.ArrayUtils;
60 import org.apache.commons.lang3.StringUtils;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64
65
66
67
68
69
70 @Deprecated
71 public class PropertiesInitializer {
72 private static final Logger log = LoggerFactory.getLogger(PropertiesInitializer.class);
73
74
75
76
77 private static final String MGNL_BEANS_PROPERTIES = "/mgnl-beans.properties";
78
79
80
81
82 public static final String PLACEHOLDER_PREFIX = "${";
83
84
85
86
87 public static final String PLACEHOLDER_SUFFIX = "}";
88
89
90
91
92
93 public static final String CONTEXT_ATTRIBUTE_PLACEHOLDER_PREFIX = "contextAttribute/";
94
95
96
97
98
99 public static final String CONTEXT_PARAM_PLACEHOLDER_PREFIX = "contextParam/";
100
101
102
103
104
105 public static final String SYSTEM_PROPERTY_PLACEHOLDER_PREFIX = "systemProperty/";
106
107
108
109
110
111 public static final String ENV_PROPERTY_PLACEHOLDER_PREFIX = "env/";
112
113
114
115
116 public static PropertiesInitializer getInstance() {
117 return Components.getSingleton(PropertiesInitializer.class);
118 }
119
120
121
122
123 public static final String DEFAULT_INITIALIZATION_PARAMETER =
124 "WEB-INF/config/${servername}/${webapp}/magnolia.properties,"
125 + "WEB-INF/config/${servername}/magnolia.properties,"
126 + "WEB-INF/config/${webapp}/magnolia.properties,"
127 + "WEB-INF/config/default/magnolia.properties,"
128 + "WEB-INF/config/magnolia.properties";
129
130 private final ModuleRegistry moduleRegistry;
131
132 @Inject
133 public PropertiesInitializer(ModuleRegistry moduleRegistry) {
134 this.moduleRegistry = moduleRegistry;
135 }
136
137 public void loadAllProperties(String propertiesFilesString, String rootPath) {
138
139 loadBeanProperties();
140
141 loadAllModuleProperties();
142
143
144 loadPropertiesFiles(propertiesFilesString, rootPath);
145
146
147 overloadWithSystemProperties();
148
149
150 resolveNestedProperties();
151 }
152
153 private void resolveNestedProperties() {
154
155 Properties sysProps = SystemProperty.getProperties();
156
157 for (Iterator<Object> it = sysProps.keySet().iterator(); it.hasNext(); ) {
158 String key = (String) it.next();
159 String oldValue = (String) sysProps.get(key);
160 String value = parseStringValue(oldValue, new HashSet<String>());
161 SystemProperty.getProperties().put(key, value.trim());
162 }
163
164 }
165
166 public void loadAllModuleProperties() {
167
168 final List<ModuleDefinition> moduleDefinitions = moduleRegistry.getModuleDefinitions();
169 loadModuleProperties(moduleDefinitions);
170 }
171
172
173
174
175
176 protected void loadModuleProperties(List<ModuleDefinition> moduleDefinitions) {
177 for (ModuleDefinition module : moduleDefinitions) {
178 for (PropertyDefinition property : module.getProperties()) {
179 SystemProperty.setProperty(property.getName(), property.getValue());
180 }
181 }
182 }
183
184 public void loadPropertiesFiles(String propertiesLocationString, String rootPath) {
185
186 String[] propertiesLocation = StringUtils.split(propertiesLocationString, ',');
187
188 boolean found = false;
189
190
191 for (int j = propertiesLocation.length - 1; j >= 0; j--) {
192 String location = StringUtils.trim(propertiesLocation[j]);
193
194 if (loadPropertiesFile(rootPath, location)) {
195 found = true;
196 }
197 }
198
199 if (!found) {
200 final String msg = MessageFormat.format("No configuration found using location list {0}. Base path is [{1}]", ArrayUtils.toString(propertiesLocation), rootPath);
201 log.error(msg);
202 throw new ConfigurationException(msg);
203 }
204 }
205
206
207
208
209
210 @Deprecated
211 public void loadBeanProperties() {
212 InputStream mgnlbeansStream = getClass().getResourceAsStream(MGNL_BEANS_PROPERTIES);
213
214 if (mgnlbeansStream != null) {
215 Properties mgnlbeans = new Properties();
216 try {
217 mgnlbeans.load(mgnlbeansStream);
218 } catch (IOException e) {
219 log.error("Unable to load {} due to an IOException: {}", MGNL_BEANS_PROPERTIES, e.getMessage());
220 } finally {
221 IOUtils.closeQuietly(mgnlbeansStream);
222 }
223
224 for (Iterator<Object> iter = mgnlbeans.keySet().iterator(); iter.hasNext(); ) {
225 String key = (String) iter.next();
226 SystemProperty.setProperty(key, mgnlbeans.getProperty(key));
227 }
228
229 } else {
230 log.warn("{} not found in the classpath. Check that all the needed implementation classes are defined in your custom magnolia.properties file.", MGNL_BEANS_PROPERTIES);
231 }
232 }
233
234
235
236
237 public boolean loadPropertiesFile(String rootPath, String location) {
238 final File initFile;
239 if (Paths.get(location).isAbsolute()) {
240 initFile = new File(location);
241 } else {
242 initFile = new File(rootPath, location);
243 }
244
245 if (!initFile.exists() || initFile.isDirectory()) {
246 log.debug("Configuration file not found with path [{}]", initFile.getAbsolutePath());
247 return false;
248 }
249
250 InputStream fileStream = null;
251 try {
252 fileStream = new FileInputStream(initFile);
253 } catch (FileNotFoundException e1) {
254 log.debug("Configuration file not found with path [{}]", initFile.getAbsolutePath());
255 return false;
256 }
257
258 try {
259 SystemProperty.getProperties().load(fileStream);
260 log.info("Loading configuration at {}", initFile.getAbsolutePath());
261 } catch (Exception e) {
262 log.error(e.getMessage(), e);
263 return false;
264 } finally {
265 IOUtils.closeQuietly(fileStream);
266 }
267 return true;
268 }
269
270
271
272
273 public void overloadWithSystemProperties() {
274 Iterator<Object> it = SystemProperty.getProperties().keySet().iterator();
275 while (it.hasNext()) {
276 String key = (String) it.next();
277 if (System.getProperties().containsKey(key)) {
278 log.info("system property found: {}", key);
279 String value = System.getProperty(key);
280 SystemProperty.setProperty(key, value);
281 }
282 }
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303 public static String processPropertyFilesString(ServletContext context, String servername, String webapp, String propertiesFilesString, String contextPath) {
304
305 propertiesFilesString = StringUtils.replace(propertiesFilesString, "${servername}", servername);
306 propertiesFilesString = StringUtils.replace(propertiesFilesString, "${webapp}", webapp);
307 propertiesFilesString = StringUtils.replace(propertiesFilesString, "${contextPath}", contextPath);
308
309
310 String[] contextAttributeNames = getNamesBetweenPlaceholders(propertiesFilesString, CONTEXT_ATTRIBUTE_PLACEHOLDER_PREFIX);
311 if (contextAttributeNames != null) {
312 for (String ctxAttrName : contextAttributeNames) {
313 if (ctxAttrName != null) {
314
315
316 final String originalPlaceHolder = PLACEHOLDER_PREFIX + CONTEXT_ATTRIBUTE_PLACEHOLDER_PREFIX + ctxAttrName + PLACEHOLDER_SUFFIX;
317 final Object attrValue = context.getAttribute(ctxAttrName);
318 if (attrValue != null) {
319 propertiesFilesString = propertiesFilesString.replace(originalPlaceHolder, attrValue.toString());
320 }
321 }
322 }
323 }
324
325
326 String[] contextParamNames = getNamesBetweenPlaceholders(propertiesFilesString, CONTEXT_PARAM_PLACEHOLDER_PREFIX);
327 if (contextParamNames != null) {
328 for (String ctxParamName : contextParamNames) {
329 if (ctxParamName != null) {
330
331 final String originalPlaceHolder = PLACEHOLDER_PREFIX + CONTEXT_PARAM_PLACEHOLDER_PREFIX + ctxParamName + PLACEHOLDER_SUFFIX;
332 final String paramValue = context.getInitParameter(ctxParamName);
333 if (paramValue != null) {
334 propertiesFilesString = propertiesFilesString.replace(originalPlaceHolder, paramValue);
335 }
336 }
337 }
338 }
339
340
341 String[] systemPropertiesNames = getNamesBetweenPlaceholders(propertiesFilesString, SYSTEM_PROPERTY_PLACEHOLDER_PREFIX);
342 if (systemPropertiesNames != null) {
343 for (String sysPropName : systemPropertiesNames) {
344 if (StringUtils.isNotBlank(sysPropName)) {
345 final String originalPlaceHolder = PLACEHOLDER_PREFIX + SYSTEM_PROPERTY_PLACEHOLDER_PREFIX + sysPropName + PLACEHOLDER_SUFFIX;
346 final String paramValue = System.getProperty(sysPropName);
347 if (paramValue != null) {
348 propertiesFilesString = propertiesFilesString.replace(originalPlaceHolder, paramValue);
349 }
350 }
351 }
352 }
353
354
355 String[] envPropertiesNames = getNamesBetweenPlaceholders(propertiesFilesString, ENV_PROPERTY_PLACEHOLDER_PREFIX);
356 if (envPropertiesNames != null) {
357 for (String envPropName : envPropertiesNames) {
358 if (StringUtils.isNotBlank(envPropName)) {
359 final String originalPlaceHolder = PLACEHOLDER_PREFIX + ENV_PROPERTY_PLACEHOLDER_PREFIX + envPropName + PLACEHOLDER_SUFFIX;
360 final String paramValue = System.getenv(envPropName);
361 if (paramValue != null) {
362 propertiesFilesString = propertiesFilesString.replace(originalPlaceHolder, paramValue);
363 }
364 }
365 }
366 }
367
368 return propertiesFilesString;
369 }
370
371 private static String[] getNamesBetweenPlaceholders(String propertiesFilesString, String contextNamePlaceHolder) {
372 final String[] names = StringUtils.substringsBetween(
373 propertiesFilesString,
374 PLACEHOLDER_PREFIX + contextNamePlaceHolder,
375 PLACEHOLDER_SUFFIX);
376 return StringUtils.stripAll(names);
377 }
378
379
380
381
382
383
384
385 protected String parseStringValue(String strVal, Set<String> visitedPlaceholders) {
386
387 StringBuffer buf = new StringBuffer(strVal);
388
389 int startIndex = strVal.indexOf(PLACEHOLDER_PREFIX);
390 while (startIndex != -1) {
391 int endIndex = -1;
392
393 int index = startIndex + PLACEHOLDER_PREFIX.length();
394 int withinNestedPlaceholder = 0;
395 while (index < buf.length()) {
396 if (PLACEHOLDER_SUFFIX.equals(buf.subSequence(index, index + PLACEHOLDER_SUFFIX.length()))) {
397 if (withinNestedPlaceholder > 0) {
398 withinNestedPlaceholder--;
399 index = index + PLACEHOLDER_SUFFIX.length();
400 } else {
401 endIndex = index;
402 break;
403 }
404 } else if (PLACEHOLDER_PREFIX.equals(buf.subSequence(index, index + PLACEHOLDER_PREFIX.length()))) {
405 withinNestedPlaceholder++;
406 index = index + PLACEHOLDER_PREFIX.length();
407 } else {
408 index++;
409 }
410 }
411
412 if (endIndex != -1) {
413 String placeholder = buf.substring(startIndex + PLACEHOLDER_PREFIX.length(), endIndex);
414 if (!visitedPlaceholders.add(placeholder)) {
415
416 log.warn("Circular reference detected in properties, \"{}\" is not resolvable", strVal);
417 return strVal;
418 }
419
420 placeholder = parseStringValue(placeholder, visitedPlaceholders);
421
422 String propVal = SystemProperty.getProperty(placeholder);
423 if (propVal != null) {
424
425
426 propVal = parseStringValue(propVal, visitedPlaceholders);
427 buf.replace(startIndex, endIndex + PLACEHOLDER_SUFFIX.length(), propVal);
428 startIndex = buf.indexOf(PLACEHOLDER_PREFIX, startIndex + propVal.length());
429 } else {
430
431 startIndex = buf.indexOf(PLACEHOLDER_PREFIX, endIndex + PLACEHOLDER_SUFFIX.length());
432 }
433 visitedPlaceholders.remove(placeholder);
434 } else {
435 startIndex = -1;
436 }
437 }
438
439 return buf.toString();
440 }
441
442 }