1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.utils;
21
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Properties;
26 import java.util.Set;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29
30 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
31
32
33
34
35 public final class ChainedPropertyUtil {
36
37
38
39
40 public static final String UNDEFINED_PROPERTY_MESSAGE = "Undefined property: ";
41
42
43
44
45 private static final Pattern PROPERTY_VARIABLE_PATTERN = Pattern.compile("\\$\\{([^\\s}]+)}");
46
47
48
49
50 private ChainedPropertyUtil() {
51 }
52
53
54
55
56
57
58
59
60
61
62 public static Properties getResolvedProperties(Properties properties)
63 throws CheckstyleException {
64 final Set<String> unresolvedPropertyNames =
65 new HashSet<>(properties.stringPropertyNames());
66 Iterator<String> unresolvedPropertyIterator = unresolvedPropertyNames.iterator();
67 final Map<Object, Object> comparisonProperties = new Properties();
68
69 while (unresolvedPropertyIterator.hasNext()) {
70 final String propertyName = unresolvedPropertyIterator.next();
71 String propertyValue = properties.getProperty(propertyName);
72 final Matcher matcher = PROPERTY_VARIABLE_PATTERN.matcher(propertyValue);
73
74 while (matcher.find()) {
75 final String propertyVariableExpression = matcher.group();
76 final String unresolvedPropertyName =
77 getPropertyNameFromExpression(propertyVariableExpression);
78
79 final String resolvedPropertyValue =
80 properties.getProperty(unresolvedPropertyName);
81
82 if (resolvedPropertyValue != null) {
83 propertyValue = propertyValue.replace(propertyVariableExpression,
84 resolvedPropertyValue);
85 properties.setProperty(propertyName, propertyValue);
86 }
87 }
88
89 if (allChainedPropertiesAreResolved(propertyValue)) {
90 unresolvedPropertyIterator.remove();
91 }
92
93 if (!unresolvedPropertyIterator.hasNext()) {
94
95 if (comparisonProperties.equals(properties)) {
96
97
98 throw new CheckstyleException(UNDEFINED_PROPERTY_MESSAGE
99 + unresolvedPropertyNames);
100 }
101 comparisonProperties.putAll(properties);
102 unresolvedPropertyIterator = unresolvedPropertyNames.iterator();
103 }
104
105 }
106 return properties;
107 }
108
109
110
111
112
113
114
115
116 private static String getPropertyNameFromExpression(String variableExpression) {
117 final int propertyStartIndex = variableExpression.lastIndexOf('{') + 1;
118 final int propertyEndIndex = variableExpression.lastIndexOf('}');
119 return variableExpression.substring(propertyStartIndex, propertyEndIndex);
120 }
121
122
123
124
125
126
127
128
129
130 private static boolean allChainedPropertiesAreResolved(String propertyValue) {
131 return !PROPERTY_VARIABLE_PATTERN.matcher(propertyValue).find();
132 }
133 }