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 package org.jrobin.core;
27
28 import org.w3c.dom.Element;
29 import org.w3c.dom.Node;
30 import org.xml.sax.InputSource;
31
32 import java.awt.*;
33 import java.io.File;
34 import java.io.IOException;
35 import java.util.*;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38
39
40
41
42
43
44
45
46
47 public abstract class XmlTemplate {
48 private static final String PATTERN_STRING = "\\$\\{(\\w+)\\}";
49 private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING);
50
51 protected Element root;
52 private HashMap<String, Object> valueMap = new HashMap<String, Object>();
53 private HashSet<Node> validatedNodes = new HashSet<Node>();
54
55 protected XmlTemplate(InputSource xmlSource) throws IOException, RrdException {
56 root = Util.Xml.getRootElement(xmlSource);
57 }
58
59 protected XmlTemplate(String xmlString) throws IOException, RrdException {
60 root = Util.Xml.getRootElement(xmlString);
61 }
62
63 protected XmlTemplate(File xmlFile) throws IOException, RrdException {
64 root = Util.Xml.getRootElement(xmlFile);
65 }
66
67
68
69
70 public void clearValues() {
71 valueMap.clear();
72 }
73
74
75
76
77
78
79
80
81
82 public void setVariable(String name, String value) {
83 valueMap.put(name, value);
84 }
85
86
87
88
89
90
91
92
93
94 public void setVariable(String name, int value) {
95 valueMap.put(name, value);
96 }
97
98
99
100
101
102
103
104
105
106 public void setVariable(String name, long value) {
107 valueMap.put(name, value);
108 }
109
110
111
112
113
114
115
116
117
118 public void setVariable(String name, double value) {
119 valueMap.put(name, value);
120 }
121
122
123
124
125
126
127
128
129
130 public void setVariable(String name, Color value) {
131 String r = byteToHex(value.getRed());
132 String g = byteToHex(value.getGreen());
133 String b = byteToHex(value.getBlue());
134 String a = byteToHex(value.getAlpha());
135 valueMap.put(name, "#" + r + g + b + a);
136 }
137
138 private String byteToHex(int i) {
139 String s = Integer.toHexString(i);
140 while (s.length() < 2) {
141 s = "0" + s;
142 }
143 return s;
144 }
145
146
147
148
149
150
151
152
153
154 public void setVariable(String name, Date value) {
155 setVariable(name, Util.getTimestamp(value));
156 }
157
158
159
160
161
162
163
164
165
166 public void setVariable(String name, Calendar value) {
167 setVariable(name, Util.getTimestamp(value));
168 }
169
170
171
172
173
174
175
176
177
178 public void setVariable(String name, boolean value) {
179 valueMap.put(name, "" + value);
180 }
181
182
183
184
185
186
187
188 public boolean hasVariables() {
189 return PATTERN.matcher(root.toString()).find();
190 }
191
192
193
194
195
196
197 public String[] getVariables() {
198 ArrayList<String> list = new ArrayList<String>();
199 Matcher m = PATTERN.matcher(root.toString());
200
201 while (m.find()) {
202 String var = m.group(1);
203 if (!list.contains(var)) {
204 list.add(var);
205 }
206 }
207
208 return list.toArray(new String[list.size()]);
209 }
210
211 protected static Node[] getChildNodes(Node parentNode, String childName) {
212 return Util.Xml.getChildNodes(parentNode, childName);
213 }
214
215 protected static Node[] getChildNodes(Node parentNode) {
216 return Util.Xml.getChildNodes(parentNode, null);
217 }
218
219 protected static Node getFirstChildNode(Node parentNode, String childName) throws RrdException {
220 return Util.Xml.getFirstChildNode(parentNode, childName);
221 }
222
223 protected boolean hasChildNode(Node parentNode, String childName) {
224 return Util.Xml.hasChildNode(parentNode, childName);
225 }
226
227 protected String getChildValue(Node parentNode, String childName) throws RrdException {
228 return getChildValue(parentNode, childName, true);
229 }
230
231 protected String getChildValue(Node parentNode, String childName, boolean trim) throws RrdException {
232 String value = Util.Xml.getChildValue(parentNode, childName, trim);
233 return resolveMappings(value);
234 }
235
236 protected String getValue(Node parentNode) {
237 return getValue(parentNode, true);
238 }
239
240 protected String getValue(Node parentNode, boolean trim) {
241 String value = Util.Xml.getValue(parentNode, trim);
242 return resolveMappings(value);
243 }
244
245 private String resolveMappings(String templateValue) {
246 if (templateValue == null) {
247 return null;
248 }
249 Matcher matcher = PATTERN.matcher(templateValue);
250 StringBuffer result = new StringBuffer();
251 int lastMatchEnd = 0;
252 while (matcher.find()) {
253 String var = matcher.group(1);
254 if (valueMap.containsKey(var)) {
255
256 result.append(templateValue.substring(lastMatchEnd, matcher.start()));
257 result.append(valueMap.get(var).toString());
258 lastMatchEnd = matcher.end();
259 }
260 else {
261
262
263 throw new IllegalArgumentException("No mapping found for template variable ${" + var + "}");
264 }
265 }
266 result.append(templateValue.substring(lastMatchEnd));
267 return result.toString();
268 }
269
270 protected int getChildValueAsInt(Node parentNode, String childName) throws RrdException {
271 String valueStr = getChildValue(parentNode, childName);
272 return Integer.parseInt(valueStr);
273 }
274
275 protected int getValueAsInt(Node parentNode) {
276 String valueStr = getValue(parentNode);
277 return Integer.parseInt(valueStr);
278 }
279
280 protected long getChildValueAsLong(Node parentNode, String childName) throws RrdException {
281 String valueStr = getChildValue(parentNode, childName);
282 return Long.parseLong(valueStr);
283 }
284
285 protected long getValueAsLong(Node parentNode) {
286 String valueStr = getValue(parentNode);
287 return Long.parseLong(valueStr);
288 }
289
290 protected double getChildValueAsDouble(Node parentNode, String childName) throws RrdException {
291 String valueStr = getChildValue(parentNode, childName);
292 return Util.parseDouble(valueStr);
293 }
294
295 protected double getValueAsDouble(Node parentNode) {
296 String valueStr = getValue(parentNode);
297 return Util.parseDouble(valueStr);
298 }
299
300 protected boolean getChildValueAsBoolean(Node parentNode, String childName) throws RrdException {
301 String valueStr = getChildValue(parentNode, childName);
302 return Util.parseBoolean(valueStr);
303 }
304
305 protected boolean getValueAsBoolean(Node parentNode) {
306 String valueStr = getValue(parentNode);
307 return Util.parseBoolean(valueStr);
308 }
309
310 protected Paint getValueAsColor(Node parentNode) throws RrdException {
311 String rgbStr = getValue(parentNode);
312 return Util.parseColor(rgbStr);
313 }
314
315 protected boolean isEmptyNode(Node node) {
316
317 return node.getNodeName().equals("#comment") ||
318 (node.getNodeName().equals("#text") && node.getNodeValue().trim().length() == 0);
319 }
320
321 protected void validateTagsOnlyOnce(Node parentNode, String[] allowedChildNames) throws RrdException {
322
323 if (validatedNodes.contains(parentNode)) {
324 return;
325 }
326 Node[] childs = getChildNodes(parentNode);
327 main:
328 for (Node child : childs) {
329 String childName = child.getNodeName();
330 for (int j = 0; j < allowedChildNames.length; j++) {
331 if (allowedChildNames[j].equals(childName)) {
332
333 allowedChildNames[j] = "<--removed-->";
334 continue main;
335 }
336 else if (allowedChildNames[j].equals(childName + "*")) {
337
338 continue main;
339 }
340 }
341 if (!isEmptyNode(child)) {
342 throw new RrdException("Unexpected tag encountered: <" + childName + ">");
343 }
344 }
345
346 validatedNodes.add(parentNode);
347 }
348 }