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 package org.polago.deployconf.task.filter;
26
27 import java.io.BufferedReader;
28 import java.io.BufferedWriter;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.io.OutputStream;
33 import java.io.OutputStreamWriter;
34 import java.util.LinkedHashSet;
35 import java.util.Set;
36 import java.util.regex.Matcher;
37
38 import org.jdom2.Element;
39 import org.polago.deployconf.InteractiveConfigurer;
40 import org.polago.deployconf.group.ConfigGroup;
41 import org.polago.deployconf.group.ConfigGroupManager;
42 import org.polago.deployconf.task.AbstractTask;
43 import org.polago.deployconf.task.Task;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49
50 public class FilterTask extends AbstractTask {
51
52 private static Logger logger = LoggerFactory.getLogger(FilterTask.class);
53
54
55
56
57 public static final String DOM_ELEMENT_TASK = "filter";
58
59 private static final String DOM_ELEMENT_NAME = "name";
60
61 private static final String DOM_ELEMENT_REGEX = "regex";
62
63 private static final String DOM_ELEMENT_TOKEN = "token";
64
65 private static final String ATTRIBUTE_ENCODING = "encoding";
66
67 private Set<FilterToken> tokens;
68
69 private String encoding = "UTF-8";
70
71
72
73
74
75
76 public FilterTask(ConfigGroupManager groupManager) {
77 super(groupManager);
78 tokens = new LinkedHashSet<FilterToken>();
79 }
80
81
82
83
84 @Override
85 public void deserialize(Element root) throws IOException {
86 super.deserialize(root);
87 String enc = root.getAttributeValue(ATTRIBUTE_ENCODING);
88 if (enc != null) {
89 encoding = enc;
90 }
91 for (Element e : root.getChildren()) {
92 String name = e.getChildTextTrim(DOM_ELEMENT_NAME);
93 if (name.length() == 0) {
94 throw new IllegalStateException("Filter name element does not exists");
95 }
96 String regex = e.getChildTextTrim(DOM_ELEMENT_REGEX);
97 if (regex.length() == 0) {
98 throw new IllegalStateException("Filter regex element does not exists");
99 }
100 String description = e.getChildTextTrim(DOM_ELEMENT_DESCRIPTION);
101 if (description.length() == 0) {
102 throw new IllegalStateException("Filter description element does not exists");
103 }
104 String defaultValue = e.getChildTextTrim(DOM_ELEMENT_DEFAULT);
105
106 String group = e.getAttributeValue(DOM_ATTRIBUTE_GROUP);
107 String value = null;
108
109 if (group != null) {
110 value = getGroupManager().lookupGroup(group).getProperty(name);
111 }
112
113 if (value == null) {
114 value = e.getChildTextTrim(DOM_ELEMENT_VALUE);
115 if (group != null && value != null) {
116 logger.debug("Populating group {} with value of name {}: {}", group, name, value);
117 getGroupManager().lookupGroup(group).setProperty(name, value);
118 }
119 }
120
121 FilterToken t = new FilterToken(name, regex, description, defaultValue, value);
122
123 if (group != null) {
124 t.setGroup(group);
125 }
126
127 t.setCondition(e.getChildTextTrim(DOM_ELEMENT_CONDITION));
128
129 logger.debug("Deserializing FilterToken: {}", t);
130
131 tokens.add(t);
132 }
133 }
134
135
136
137
138 @Override
139 public void serialize(Element node) throws IOException {
140 super.serialize(node);
141 node.setAttribute(ATTRIBUTE_ENCODING, getEncoding());
142 for (FilterToken t : tokens) {
143 logger.debug("Serializing FilterToken: {}", t);
144 Element e = createJDOMElement(DOM_ELEMENT_TOKEN);
145 e.addContent(createJDOMTextElement(DOM_ELEMENT_NAME, t.getName()));
146 e.addContent(createJDOMTextElement(DOM_ELEMENT_REGEX, t.getRegex().toString()));
147 e.addContent(createJDOMCDATAElement(DOM_ELEMENT_DESCRIPTION, t.getDescription()));
148 e.addContent(createJDOMTextElement(DOM_ELEMENT_DEFAULT, t.getDefaultValue()));
149 e.addContent(createJDOMTextElement(DOM_ELEMENT_CONDITION, t.getCondition()));
150
151 String group = t.getGroup();
152 if (group != null) {
153 e.setAttribute(DOM_ATTRIBUTE_GROUP, group);
154 } else {
155 e.addContent(createJDOMTextElement(DOM_ELEMENT_VALUE, t.getValue()));
156 }
157
158 node.addContent(e);
159 }
160 }
161
162
163
164
165
166
167 public Set<FilterToken> getTokens() {
168 return tokens;
169 }
170
171
172
173
174
175
176 void setTokens(Set<FilterToken> tokens) {
177 this.tokens = tokens;
178 }
179
180
181
182
183
184
185 private String getEncoding() {
186 return encoding;
187 }
188
189
190
191
192 @Override
193 public void merge(Task other) {
194 if (other instanceof FilterTask) {
195 FilterTask oft = (FilterTask) other;
196 tokens.retainAll(oft.getTokens());
197
198 for (FilterToken ot : oft.getTokens()) {
199 boolean exists = false;
200 for (FilterToken t : tokens) {
201 if (t.equals(ot)) {
202 exists = true;
203 t.setRegex(ot.getRegex());
204 t.setDescription(ot.getDescription());
205 t.setDefaultValue(ot.getDefaultValue());
206 t.setGroup(ot.getGroup());
207 t.setCondition(ot.getCondition());
208 logger.debug("Merging existing FilterToken: {}", t);
209 break;
210 }
211 }
212 if (!exists) {
213 logger.debug("Adding new FilterToken: {}", ot);
214 tokens.add(ot);
215 }
216 }
217 }
218 }
219
220
221
222
223 @Override
224 public boolean isConfigured() throws IOException {
225 for (FilterToken t : tokens) {
226 if (evaluateCondition(t.getCondition(), getGroupManager().lookupGroup(t.getGroup()))) {
227 if (t.getValue() == null || t.getValue().length() == 0) {
228 logger.debug("FilterToken is not configured: {}", t);
229 return false;
230 }
231 }
232 }
233
234 return true;
235 }
236
237
238
239
240 @Override
241 public boolean configureInteractively(InteractiveConfigurer configurer, boolean force) throws Exception {
242
243 boolean configured = true;
244
245 for (FilterToken t : tokens) {
246 ConfigGroup group = getGroupManager().lookupGroup(t.getGroup());
247 if (evaluateCondition(t.getCondition(), group)
248 && (force || t.getValue() == null || t.getValue().length() == 0)) {
249 configured = configureTokenInteractively(t, configurer);
250 if (configured) {
251 group.setProperty(t.getName(), t.getValue());
252 } else {
253 return configured;
254 }
255 }
256 }
257
258 return configured;
259 }
260
261
262
263
264 @Override
265 public String getSerializedName() {
266 return DOM_ELEMENT_TASK;
267 }
268
269
270
271
272 @Override
273 public void apply(InputStream source, OutputStream destination) throws Exception {
274
275 InputStreamReader in = new InputStreamReader(source, getEncoding());
276 BufferedReader reader = new BufferedReader(in);
277
278 OutputStreamWriter out = new OutputStreamWriter(destination, getEncoding());
279 BufferedWriter writer = new BufferedWriter(out);
280
281 String line = reader.readLine();
282 while (line != null) {
283 line = filterLine(line);
284 writer.write(line);
285 line = reader.readLine();
286 writer.newLine();
287 }
288 writer.flush();
289 }
290
291
292
293
294
295
296
297
298 private String filterLine(String line) throws IOException {
299 for (FilterToken t : getTokens()) {
300 ConfigGroup group = getGroupManager().lookupGroup(t.getGroup());
301 if (evaluateCondition(t.getCondition(), group)) {
302 Matcher matcher = t.getRegex().matcher(line);
303 String value = expandPropertyExpression(t.getValue(), group);
304 line = matcher.replaceAll(value);
305 }
306 }
307
308 return line;
309
310 }
311
312
313
314
315
316
317
318
319
320 private boolean configureTokenInteractively(FilterToken t, InteractiveConfigurer configurer) throws IOException {
321
322 boolean result = false;
323
324 logger.debug("Configure interactively: {}", t.getRegex().toString());
325
326 String defaultValue = t.getValue();
327 if (defaultValue == null || defaultValue.length() == 0) {
328 defaultValue = t.getDefaultValue();
329 }
330
331 String value = configurer.configure(t.getName(), t.getDescription(), defaultValue);
332 logger.debug("Configure interactively result for '{}({})': {}", t.getName(), t.getRegex().toString(), value);
333 if (value != null) {
334 t.setValue(value);
335 result = true;
336 }
337
338 return result;
339 }
340
341
342
343
344 @Override
345 public String toString() {
346 return "FilterTask [path=" + getPath() + ", tokens=" + tokens + ", encoding=" + encoding + "]";
347 }
348
349 }