KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > core > XmlTemplate


1 /* ============================================================
2  * JRobin : Pure java implementation of RRDTool's functionality
3  * ============================================================
4  *
5  * Project Info: http://www.jrobin.org
6  * Project Lead: Sasa Markovic (saxon@jrobin.org);
7  *
8  * (C) Copyright 2003, by Sasa Markovic.
9  *
10  * Developers: Sasa Markovic (saxon@jrobin.org)
11  * Arne Vandamme (cobralord@jrobin.org)
12  *
13  * This library is free software; you can redistribute it and/or modify it under the terms
14  * of the GNU Lesser General Public License as published by the Free Software Foundation;
15  * either version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License along with this
22  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */

25
26 package org.jrobin.core;
27
28 import org.w3c.dom.Node JavaDoc;
29 import org.w3c.dom.Element JavaDoc;
30 import org.xml.sax.InputSource JavaDoc;
31
32 import java.io.IOException JavaDoc;
33 import java.io.File JavaDoc;
34 import java.util.*;
35 import java.util.regex.Pattern JavaDoc;
36 import java.util.regex.Matcher JavaDoc;
37 import java.awt.*;
38
39 /**
40  * Class used as a base class for various XML template related classes. Class provides
41  * methods for XML source parsing and XML tree traversing. XML source may have unlimited
42  * number of placeholders (variables) in the format <code>${variable_name}</code>.
43  * Methods are provided to specify variable values at runtime.
44  * Note that this class has limited functionality: XML source gets parsed, and variable
45  * values are collected. You have to extend this class to do something more useful.<p>
46  */

47 public abstract class XmlTemplate {
48     private static final String JavaDoc PATTERN_STRING = "\\$\\{(\\w+)\\}";
49     private static final Pattern JavaDoc PATTERN = Pattern.compile(PATTERN_STRING);
50
51     protected Element JavaDoc root;
52     private HashMap valueMap = new HashMap();
53     private HashSet validatedNodes = new HashSet();
54
55     protected XmlTemplate(InputSource JavaDoc xmlSource) throws IOException JavaDoc, RrdException {
56         root = Util.Xml.getRootElement(xmlSource);
57     }
58
59     protected XmlTemplate(String JavaDoc xmlString) throws IOException JavaDoc, RrdException {
60         root = Util.Xml.getRootElement(xmlString);
61     }
62
63     protected XmlTemplate(File JavaDoc xmlFile) throws IOException JavaDoc, RrdException {
64         root = Util.Xml.getRootElement(xmlFile);
65     }
66
67     /**
68      * Removes all placeholder-value mappings.
69      */

70     public void clearValues() {
71         valueMap.clear();
72     }
73
74     /**
75      * Sets value for a single XML template variable. Variable name should be specified
76      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
77      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
78      * @param name variable name
79      * @param value value to be set in the XML template
80      */

81     public void setVariable(String JavaDoc name, String JavaDoc value) {
82         valueMap.put(name, value);
83     }
84
85     /**
86      * Sets value for a single XML template variable. Variable name should be specified
87      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
88      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
89      * @param name variable name
90      * @param value value to be set in the XML template
91      */

92     public void setVariable(String JavaDoc name, int value) {
93         valueMap.put(name, new Integer JavaDoc(value));
94     }
95
96     /**
97      * Sets value for a single XML template variable. Variable name should be specified
98      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
99      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
100      * @param name variable name
101      * @param value value to be set in the XML template
102      */

103     public void setVariable(String JavaDoc name, long value) {
104         valueMap.put(name, new Long JavaDoc(value));
105     }
106
107     /**
108      * Sets value for a single XML template variable. Variable name should be specified
109      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
110      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
111      * @param name variable name
112      * @param value value to be set in the XML template
113      */

114     public void setVariable(String JavaDoc name, double value) {
115         valueMap.put(name, new Double JavaDoc(value));
116     }
117
118     /**
119      * Sets value for a single XML template variable. Variable name should be specified
120      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
121      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
122      * @param name variable name
123      * @param value value to be set in the XML template
124      */

125     public void setVariable(String JavaDoc name, Color value) {
126         valueMap.put(name, "#" + Integer.toHexString(value.getRGB() & 0xFFFFFF));
127     }
128
129     /**
130      * Sets value for a single XML template variable. Variable name should be specified
131      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
132      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
133      * @param name variable name
134      * @param value value to be set in the XML template
135      */

136     public void setVariable(String JavaDoc name, Date value) {
137         setVariable(name, Util.getTimestamp(value));
138     }
139
140     /**
141      * Sets value for a single XML template variable. Variable name should be specified
142      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
143      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
144      * @param name variable name
145      * @param value value to be set in the XML template
146      */

147     public void setVariable(String JavaDoc name, GregorianCalendar value) {
148         setVariable(name, Util.getTimestamp(value));
149     }
150
151     /**
152      * Sets value for a single XML template variable. Variable name should be specified
153      * without leading '${' and ending '}' placeholder markers. For example, for a placeholder
154      * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter.
155      * @param name variable name
156      * @param value value to be set in the XML template
157      */

158     public void setVariable(String JavaDoc name, boolean value) {
159         valueMap.put(name, "" + value);
160     }
161
162     /**
163      * Searches the XML template to see if there are variables in there that
164      * will need to be set.
165      *
166      * @return True if variables were detected, false if not.
167      */

168     public boolean hasVariables() {
169         return PATTERN.matcher( root.toString() ).find();
170     }
171
172     /**
173      * Returns the list of variables that should be set in this template.
174      *
175      * @return List of variable names as an array of strings.
176      */

177     public String JavaDoc[] getVariables()
178     {
179         ArrayList list = new ArrayList();
180         Matcher JavaDoc m = PATTERN.matcher( root.toString() );
181
182         while ( m.find() )
183         {
184             String JavaDoc var = m.group(1);
185             if ( !list.contains( var ) )
186                 list.add( var );
187         }
188
189         return (String JavaDoc[]) list.toArray( new String JavaDoc[list.size()] );
190     }
191
192     protected static Node JavaDoc[] getChildNodes(Node JavaDoc parentNode, String JavaDoc childName) {
193         return Util.Xml.getChildNodes(parentNode, childName);
194     }
195
196     protected static Node JavaDoc[] getChildNodes(Node JavaDoc parentNode) {
197         return Util.Xml.getChildNodes(parentNode, null);
198     }
199
200     protected static Node JavaDoc getFirstChildNode(Node JavaDoc parentNode, String JavaDoc childName) throws RrdException {
201         return Util.Xml.getFirstChildNode(parentNode, childName);
202     }
203
204     protected boolean hasChildNode(Node JavaDoc parentNode, String JavaDoc childName) {
205         return Util.Xml.hasChildNode(parentNode, childName);
206     }
207
208     protected String JavaDoc getChildValue( Node JavaDoc parentNode, String JavaDoc childName ) throws RrdException {
209         return getChildValue( parentNode, childName, true );
210     }
211     
212     protected String JavaDoc getChildValue(Node JavaDoc parentNode, String JavaDoc childName, boolean trim) throws RrdException {
213         String JavaDoc value = Util.Xml.getChildValue(parentNode, childName, trim);
214         return resolveMappings(value);
215     }
216
217     protected String JavaDoc getValue( Node JavaDoc parentNode ) {
218         return getValue( parentNode, true );
219     }
220     
221     protected String JavaDoc getValue(Node JavaDoc parentNode, boolean trim ) {
222         String JavaDoc value = Util.Xml.getValue(parentNode, trim);
223         return resolveMappings(value);
224     }
225
226     private String JavaDoc resolveMappings(String JavaDoc templateValue) {
227         if(templateValue == null) {
228             return null;
229         }
230         Matcher JavaDoc matcher = PATTERN.matcher(templateValue);
231         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
232         int lastMatchEnd = 0;
233         while(matcher.find()) {
234             String JavaDoc var = matcher.group(1);
235             if(valueMap.containsKey(var)) {
236                 // mapping found
237
result.append(templateValue.substring(lastMatchEnd, matcher.start()));
238                 result.append(valueMap.get(var).toString());
239                 lastMatchEnd = matcher.end();
240             }
241             else {
242                 // no mapping found - this is illegal
243
// throw runtime exception
244
throw new IllegalArgumentException JavaDoc(
245                     "No mapping found for template variable ${" + var + "}");
246             }
247         }
248         result.append(templateValue.substring(lastMatchEnd));
249         return result.toString();
250     }
251
252     protected int getChildValueAsInt(Node JavaDoc parentNode, String JavaDoc childName) throws RrdException {
253         String JavaDoc valueStr = getChildValue(parentNode, childName);
254         return Integer.parseInt(valueStr);
255     }
256
257     protected int getValueAsInt(Node JavaDoc parentNode) {
258         String JavaDoc valueStr = getValue(parentNode);
259         return Integer.parseInt(valueStr);
260     }
261
262     protected long getChildValueAsLong(Node JavaDoc parentNode, String JavaDoc childName) throws RrdException {
263         String JavaDoc valueStr = getChildValue(parentNode, childName);
264         return Long.parseLong(valueStr);
265     }
266
267     protected long getValueAsLong(Node JavaDoc parentNode) {
268         String JavaDoc valueStr = getValue(parentNode);
269         return Long.parseLong(valueStr);
270     }
271
272     protected double getChildValueAsDouble(Node JavaDoc parentNode, String JavaDoc childName) throws RrdException {
273         String JavaDoc valueStr = getChildValue(parentNode, childName);
274         return Util.parseDouble(valueStr);
275     }
276
277     protected double getValueAsDouble(Node JavaDoc parentNode) {
278         String JavaDoc valueStr = getValue(parentNode);
279         return Util.parseDouble(valueStr);
280     }
281
282     protected boolean getChildValueAsBoolean(Node JavaDoc parentNode, String JavaDoc childName) throws RrdException {
283         String JavaDoc valueStr = getChildValue(parentNode, childName);
284         return Util.parseBoolean(valueStr);
285     }
286
287     protected boolean getValueAsBoolean(Node JavaDoc parentNode) {
288         String JavaDoc valueStr = getValue(parentNode);
289         return Util.parseBoolean(valueStr);
290     }
291
292     protected boolean isEmptyNode(Node JavaDoc node) {
293         // comment node or empty text node
294
return node.getNodeName().equals("#comment") ||
295             (node.getNodeName().equals("#text") && node.getNodeValue().trim().length() == 0);
296     }
297
298     protected void validateTagsOnlyOnce(Node JavaDoc parentNode, String JavaDoc[] allowedChildNames) throws RrdException {
299         // validate node only once
300
if(validatedNodes.contains(parentNode)) {
301             return;
302         }
303         Node JavaDoc[] childs = getChildNodes(parentNode);
304         main:
305         for(int i = 0; i < childs.length; i++) {
306             String JavaDoc childName = childs[i].getNodeName();
307             for(int j = 0; j < allowedChildNames.length; j++) {
308                 if(allowedChildNames[j].equals(childName)) {
309                     // only one such tag is allowed
310
allowedChildNames[j] = "<--removed-->";
311                     continue main;
312                 }
313                 else if(allowedChildNames[j].equals(childName + "*")) {
314                     // several tags allowed
315
continue main;
316                 }
317             }
318             if(!isEmptyNode(childs[i])) {
319                 throw new RrdException("Unexpected tag encountered: <" + childName + ">");
320             }
321         }
322         // everything is OK
323
validatedNodes.add(parentNode);
324     }
325 }
326
Popular Tags