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 static com.google.common.base.Preconditions.checkArgument;
19 import static com.google.common.base.Preconditions.checkNotNull;
20
21 import java.util.Set;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
24
25 import org.apache.commons.lang3.StringUtils;
26 import org.kuali.common.util.log.LoggerUtils;
27 import org.slf4j.Logger;
28 import org.springframework.util.PropertyPlaceholderHelper;
29
30 import com.google.common.collect.Sets;
31
32 public final class RicePropertyPlaceholderHelper extends PropertyPlaceholderHelper {
33
34 private static final Logger logger = LoggerUtils.make();
35
36 private final boolean convertUnresolvablePlaceholdersToEmpty;
37 private final String placeholderRegex;
38 private final Pattern pattern;
39
40 private RicePropertyPlaceholderHelper(Builder builder) {
41 super(builder.placeholderPrefix, builder.placeholderSuffix, builder.valueSeparator, builder.allowUnresolvablePlaceholders);
42 this.convertUnresolvablePlaceholdersToEmpty = builder.convertUnresolvablePlaceholdersToEmpty;
43 this.placeholderRegex = builder.placeholderRegex;
44 this.pattern = builder.pattern;
45 }
46
47 public static RicePropertyPlaceholderHelper create() {
48 return builder().build();
49 }
50
51 public static Builder builder() {
52 return new Builder();
53 }
54
55 public static class Builder {
56
57 private boolean allowUnresolvablePlaceholders = true;
58 private boolean convertUnresolvablePlaceholdersToEmpty = true;
59 private String placeholderPrefix = "${";
60 private String placeholderSuffix = "}";
61 private String valueSeparator = ":";
62 private String placeholderRegex = "\\$\\{([^{}]+)\\}";
63
64
65 private Pattern pattern;
66
67 public Builder placeholderRegex(String placeholderRegex) {
68 this.placeholderRegex = placeholderRegex;
69 return this;
70 }
71
72 public Builder convertUnresolvablePlaceholdersToEmpty(boolean convertUnresolvablePlaceholdersToEmpty) {
73 this.convertUnresolvablePlaceholdersToEmpty = convertUnresolvablePlaceholdersToEmpty;
74 return this;
75 }
76
77 public Builder placeholderPrefix(String placeholderPrefix) {
78 this.placeholderPrefix = placeholderPrefix;
79 return this;
80 }
81
82 public Builder placeholderSuffix(String placeholderSuffix) {
83 this.placeholderSuffix = placeholderSuffix;
84 return this;
85 }
86
87 public Builder valueSeparator(String valueSeparator) {
88 this.valueSeparator = valueSeparator;
89 return this;
90 }
91
92 public Builder allowUnresolvablePlaceholders(boolean allowUnresolvablePlaceholders) {
93 this.allowUnresolvablePlaceholders = allowUnresolvablePlaceholders;
94 return this;
95 }
96
97 public RicePropertyPlaceholderHelper build() {
98 this.pattern = Pattern.compile(placeholderRegex);
99 RicePropertyPlaceholderHelper instance = new RicePropertyPlaceholderHelper(this);
100 validate(instance);
101 return instance;
102 }
103
104 private static void validate(RicePropertyPlaceholderHelper instance) {
105 checkArgument(!StringUtils.isBlank(instance.placeholderRegex), "'placeholderRegex' cannot be blank");
106 checkNotNull(instance.pattern, "'pattern' cannot be null");
107 }
108
109 public boolean isAllowUnresolvablePlaceholders() {
110 return allowUnresolvablePlaceholders;
111 }
112
113 public void setAllowUnresolvablePlaceholders(boolean allowUnresolvablePlaceholders) {
114 this.allowUnresolvablePlaceholders = allowUnresolvablePlaceholders;
115 }
116
117 public boolean isConvertUnresolvablePlaceholdersToEmpty() {
118 return convertUnresolvablePlaceholdersToEmpty;
119 }
120
121 public void setConvertUnresolvablePlaceholdersToEmpty(boolean convertUnresolvablePlaceholdersToEmpty) {
122 this.convertUnresolvablePlaceholdersToEmpty = convertUnresolvablePlaceholdersToEmpty;
123 }
124
125 public String getPlaceholderPrefix() {
126 return placeholderPrefix;
127 }
128
129 public void setPlaceholderPrefix(String placeholderPrefix) {
130 this.placeholderPrefix = placeholderPrefix;
131 }
132
133 public String getPlaceholderSuffix() {
134 return placeholderSuffix;
135 }
136
137 public void setPlaceholderSuffix(String placeholderSuffix) {
138 this.placeholderSuffix = placeholderSuffix;
139 }
140
141 public String getValueSeparator() {
142 return valueSeparator;
143 }
144
145 public void setValueSeparator(String valueSeparator) {
146 this.valueSeparator = valueSeparator;
147 }
148 }
149
150 public boolean isConvertUnresolvablePlaceholdersToEmpty() {
151 return convertUnresolvablePlaceholdersToEmpty;
152 }
153
154 protected Conversion convertToEmpty(String value) {
155 return convert(value, "");
156 }
157
158 public static class Conversion {
159
160 public Conversion(String original, String converted, Set<String> keys) {
161 checkNotNull(original, "original cannot be null");
162 checkNotNull(converted, "converted cannot be null");
163 checkNotNull(keys, "keys cannot be null");
164 this.original = original;
165 this.converted = converted;
166 this.keys = keys;
167 }
168
169 private final String original;
170 private final String converted;
171 private final Set<String> keys;
172
173 public String getOriginal() {
174 return original;
175 }
176
177 public String getConverted() {
178 return converted;
179 }
180
181 public Set<String> getKeys() {
182 return keys;
183 }
184 }
185
186 protected Conversion convert(String value, String token) {
187 String result = value;
188 Matcher matcher = pattern.matcher(value);
189 Set<String> keys = Sets.newTreeSet();
190 while (matcher.find()) {
191
192
193 keys.add(matcher.group(1));
194
195
196 result = matcher.replaceFirst(token);
197
198
199 matcher = matcher.reset(result);
200 }
201
202
203 return new Conversion(value, result, keys);
204 }
205
206 protected String convert(String string) {
207 if (convertUnresolvablePlaceholdersToEmpty) {
208 Conversion result = convert(string, "");
209 for (String key : result.getKeys()) {
210 logger.info("? unknown - [{}] - converted to \"\"", key);
211 }
212 return result.getConverted();
213 } else {
214 return string;
215 }
216 }
217
218 @Override
219 public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
220 String replaced = super.replacePlaceholders(value, placeholderResolver);
221 if (convertUnresolvablePlaceholdersToEmpty) {
222 Conversion result = convert(replaced, "");
223 for (String key : result.getKeys()) {
224 logger.info("? unknown - [{}] - converted to \"\"", key);
225 }
226 return result.getConverted();
227 } else {
228 return replaced;
229 }
230 }
231
232 public String getPlaceholderRegex() {
233 return placeholderRegex;
234 }
235
236 public Pattern getPattern() {
237 return pattern;
238 }
239 }