KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > proactive > core > xml > XMLPropertiesStore


1 /*
2 * ################################################################
3 *
4 * ProActive: The Java(TM) library for Parallel, Distributed,
5 * Concurrent computing with Security and Mobility
6 *
7 * Copyright (C) 1997-2002 INRIA/University of Nice-Sophia Antipolis
8 * Contact: proactive-support@inria.fr
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
24 *
25 * Initial developer(s): The ProActive Team
26 * http://www.inria.fr/oasis/ProActive/contacts.html
27 * Contributor(s):
28 *
29 * ################################################################
30 */

31 package org.objectweb.proactive.core.xml;
32
33
34 /**
35  * This class implements a XML based preferences store. Constructor expect a URI pointing to an XML file containing
36  * the values.
37  * The URI can point to a file using the file protocol :
38  * file:///D:/doc/xml/properties.xml
39  *
40  * The data are loaded and parsed in memory.
41  *
42  * In order to query the values, the class uses a stripped down version of XPath expressions.
43  * The only supported expressions are combination of /, . and @ for the attributes.
44  *
45  * Here some examples of supported expressions :
46  *
47  * /a/b/c : returns the value of the node or the node c
48  * /a/b/c/ : returns the value of the node or the node c
49  * /a/b/c/. : returns the value of the node or the node c
50  * e/. : returns the value of the node e which should be a child of the given current node
51  * /a/b/c/@t : returns the value of the attribute node or the attribute node t
52  * &t : returns the value of the attribute node or the attribute node t which should be a child of the given current node
53  *
54  *
55  * @author Lionel Mestre
56  * @version 1.0
57  */

58 public class XMLPropertiesStore {
59
60   //
61
// ----- STATIC MEMBERS -----------------------------------------------------------------------------------
62
//
63

64   //
65
// ----- PRIVATE MEMBERS -----------------------------------------------------------------------------------
66
//
67

68   /** the URI pointing to the XML data to read the properties from */
69   private String JavaDoc targetURI;
70
71   /** the DOM Document resulting of the parsing of the XML Data */
72   private org.w3c.dom.Document JavaDoc targetDocument;
73
74   /** the DOM Element root of the Document resulting from the parsing */
75   private org.w3c.dom.Element JavaDoc rootElement;
76
77
78
79   //
80
// ----- CONSTRUCTORS -----------------------------------------------------------------------------------
81
//
82

83  /**
84   * Contructs a new intance of XMLPropertiesStore based on th given URI pointing to
85   * XML data. The data are loaded and parsed into a DOM.
86   * @param uri the URI of the XML data containing the properties to read
87   * @exception java.io.IOException if the XML data cannot be loaded
88   */

89   public XMLPropertiesStore(String JavaDoc uri) throws java.io.IOException JavaDoc {
90     this.targetURI = uri;
91     this.targetDocument = parseFromURI(uri);
92     this.rootElement = targetDocument.getDocumentElement();
93   }
94
95
96
97
98   //
99
// ----- STATIC METHODS -----------------------------------------------------------------------------------
100
//
101

102  /**
103   * Parses the XML data the given URI points to and returns the DOM Document
104   * representing that XML.
105   * @param uri the URI of the XML data containing the data to read
106   * @exception java.io.IOException if the XML data cannot be read or parsed
107   */

108   public static org.w3c.dom.Document JavaDoc parseFromURI(String JavaDoc uri) throws java.io.IOException JavaDoc {
109     try {
110             javax.xml.parsers.DocumentBuilderFactory JavaDoc factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
111             javax.xml.parsers.DocumentBuilder JavaDoc documentBuilder = factory.newDocumentBuilder();
112             return documentBuilder.parse(uri);
113     } catch (org.xml.sax.SAXException JavaDoc e) {
114       throw new java.io.IOException JavaDoc(e.toString());
115     } catch (javax.xml.parsers.ParserConfigurationException JavaDoc e) {
116       throw new java.io.IOException JavaDoc(e.toString());
117     }
118   }
119   
120
121
122
123   //
124
// ----- PUBLIC METHODS -----------------------------------------------------------------------------------
125
//
126

127  /**
128   * Returns the value defined by the given path as a string. If the XPath
129   * is not found null is returned
130   * @param path represents the XPath expression leading to the value.
131   * (see restrictions in the class description)
132   * @return the value identified by path or null
133   */

134   public String JavaDoc getValueAsString(String JavaDoc path) {
135     return getValueAsString(path, rootElement);
136   }
137
138
139  /**
140   * Returns the value defined by the given path as an int. If the XPath
141   * is not found null is returned
142   * @param path represents the XPath expression leading to the value.
143   * (see restrictions in the class description)
144   * @param defaultValue the defaultValue to return if the value cannot be found
145   * @return the value identified by path or the defaultValue
146   */

147   public int getValueAsInt(String JavaDoc path, int defaultValue) {
148     return getValueAsInt(path, rootElement, defaultValue);
149   }
150
151
152  /**
153   * Returns the value defined by the given path as an int. If the XPath
154   * is not found null is returned
155   * @param path represents the XPath expression leading to the value.
156   * (see restrictions in the class description)
157   * @return the node identified by path or null
158   */

159   public org.w3c.dom.Node JavaDoc getValueAsNode(String JavaDoc path) {
160     return getValueAsNode(path, rootElement);
161   }
162
163
164  /**
165   * Returns all child nodes defined by the given path. If the XPath
166   * is not found null is returned.
167   * @param path represents the XPath expression leading to the nodes.
168   * (see restrictions in the class description)
169   * @return all nodes identified by path or null
170   */

171   public org.w3c.dom.Node JavaDoc[] getAllNodes(String JavaDoc path) {
172     return getAllNodes(path, rootElement);
173   }
174   
175   
176  /**
177   * Returns the value defined by the given path as a string. If the XPath
178   * is not found null is returned
179   * @param path represents the XPath expression leading to the value.
180   * It is relative to the given context.
181   * @param context the node from which to interprete the XPath expression.
182   * @return the value identified by path or null
183   */

184   public String JavaDoc getValueAsString(String JavaDoc path, org.w3c.dom.Node JavaDoc context) {
185    if (context.getOwnerDocument() != targetDocument) return null;
186    org.w3c.dom.Node JavaDoc node = findNodeFromXPath(path,context);
187    if (node == null) return null;
188    int type = node.getNodeType();
189    if (type == org.w3c.dom.Node.ELEMENT_NODE) {
190      org.w3c.dom.Node JavaDoc child = node.getFirstChild();
191      if (child == null) return null;
192      return child.getNodeValue();
193    } else {
194      return node.getNodeValue();
195    }
196   }
197
198
199  /**
200   * Returns the value defined by the given path as a string. If the XPath
201   * is not found null is returned
202   * @param path represents the XPath expression leading to the value.
203   * It is relative to the given context.
204   * @param context the node from which to interprete the XPath expression.
205   * @param defaultValue the defaultValue to return if the value cannot be found
206   * @return the value identified by path or the defaultValue
207   */

208   public int getValueAsInt(String JavaDoc path, org.w3c.dom.Node JavaDoc context, int defaultValue) {
209     String JavaDoc s = getValueAsString(path,context);
210     if (s == null) return defaultValue;
211     try {
212       return Integer.parseInt(s);
213     } catch (NumberFormatException JavaDoc e) {
214       return defaultValue;
215     }
216   }
217
218
219  /**
220   * Returns the node defined by the given path. If the XPath
221   * is not found null is returned. The XPath is interpreted from the given node.
222   * @param path represents the XPath expression leading to the property.
223   * (see restrictions in the class description)
224   * @param context the node from which to interprete the XPath expression.
225   * @return the node of the property identified by path or null
226   */

227   public org.w3c.dom.Node JavaDoc getValueAsNode(String JavaDoc path, org.w3c.dom.Node JavaDoc context) {
228    if (context.getOwnerDocument() != targetDocument) return null;
229    return findNodeFromXPath(path, context);
230   }
231
232
233  /**
234   * Returns all child nodes defined by the given path. If the XPath
235   * is not found null is returned. The XPath is interpreted from the given node.
236   * @param path represents the XPath expression leading to the nodes.
237   * (see restrictions in the class description)
238   * @param context the node from which to interprete the XPath expression.
239   * @return all nodes identified by path or null
240   */

241   public org.w3c.dom.Node JavaDoc[] getAllNodes(String JavaDoc path, org.w3c.dom.Node JavaDoc context) {
242     if (context.getOwnerDocument() != targetDocument) return null;
243     return findNodesFromXPath(path, context);
244   }
245
246
247 /*
248   // for testing purpose
249
250   public static void main(String[] args) {
251     String uri = null;
252     if (args.length > 0) {
253       uri = args[0];
254     } else {
255       uri = "file:///D:/cygwin/home/lmestre/ProActive/ProActiveDescriptor2.xml";
256       System.out.println("uri="+uri);
257     }
258     try {
259       XMLPropertiesStore p = new XMLPropertiesStore(uri);
260       System.out.println("p="+p.toString());
261       System.out.println(" ==== ");
262     } catch (java.io.IOException e) {
263       e.printStackTrace();
264     }
265
266   }
267
268   // for testing purpose
269
270   public String toString() {
271     try {
272       return serializeDocumentToString(targetDocument);
273     } catch (java.io.IOException e) {
274       e.printStackTrace();
275       return null;
276     }
277   }
278
279   public static String serializeDocumentToString(org.w3c.dom.Document doc) throws java.io.IOException {
280     org.apache.xml.serialize.OutputFormat of = new org.apache.xml.serialize.OutputFormat(
281         org.apache.xml.serialize.Method.XML,
282         org.apache.xml.serialize.OutputFormat.Defaults.Encoding,true);
283     of.setIndent(2);
284     org.apache.xml.serialize.XMLSerializer ts = new org.apache.xml.serialize.XMLSerializer(of);
285     java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
286     java.io.Writer writer = new java.io.PrintWriter(baos,false);
287     ts.setOutputCharStream(writer);
288     ts.serialize(doc);
289     writer.flush();
290     writer.close();
291     return baos.toString();
292   }
293 */

294
295
296   //
297
// ----- PRIVATE METHODS -----------------------------------------------------------------------------------
298
//
299

300  /**
301   * Returns the node of the current DOM defined by the given xpath and starting from
302   * the given context node. If the xpath expression does not lead to a node null is returned.
303   * @param path is the XPath expression leading to the node.
304   * @param node is the context node from where to start processing the xpath
305   * @return the node targeted by the xpath expression or null
306   */

307   private org.w3c.dom.Node JavaDoc findNodeFromXPath(String JavaDoc path, org.w3c.dom.Node JavaDoc node) {
308     // deals with special cases if path is empty or point to the current node
309
if (path == null || path.length() == 0 || path.equals(".")) return node;
310
311     // find the possible attribute in the XPath expression
312
int n = path.indexOf('@');
313     String JavaDoc attributeName = null;
314     if (n > -1 && n < (path.length()-1)) {
315       attributeName = path.substring(n+1);
316       path = path.substring(0,n);
317     }
318
319     // deal with case where the XPath was just an attribute
320
if (path.length() == 0)
321       return findNamedAttribute(attributeName,node);
322
323     java.util.StringTokenizer JavaDoc st = new java.util.StringTokenizer JavaDoc(path,"/");
324     if (path.charAt(0) == '/') {
325       // case of an absolute path (starting from the root node)
326
// in this case we process the current node
327
node = rootElement;
328       if (st.hasMoreTokens()) {
329         String JavaDoc t = st.nextToken();
330         if (! t.equals(node.getNodeName())) return null;
331       }
332     }
333
334     // iterates through the /
335
while (st.hasMoreTokens() && node != null) {
336       String JavaDoc t = st.nextToken();
337       if (t.equals(".")) break;
338       node = findNamedChild(t,node);
339     }
340     return findNamedAttribute(attributeName,node);
341   }
342
343
344  /**
345   * Returns the nodes of the current DOM defined by the given xpath and starting from
346   * the given context node. If the xpath expression does not lead to a node null is returned.
347   * @param path is the XPath expression leading to the node.
348   * @param node is the context node from where to start processing the xpath
349   * @return the node targeted by the xpath expression or null
350   */

351   private org.w3c.dom.Node JavaDoc[] findNodesFromXPath(String JavaDoc path, org.w3c.dom.Node JavaDoc node) {
352     // deals with special cases if path is empty or point to the current node
353
if (path == null || path.length() == 0 || path.equals(".")) return null;
354
355     // remove possible attribute in the XPath expression
356
int n = path.indexOf('@');
357     if (n > -1 && n < (path.length()-1)) {
358       path = path.substring(0,n);
359     }
360     // deal with case where the XPath was just an attribute
361
if (path.length() == 0) return null;
362
363     java.util.StringTokenizer JavaDoc st = new java.util.StringTokenizer JavaDoc(path,"/");
364     if (path.charAt(0) == '/') {
365       // case of an absolute path (starting from the root node)
366
// in this case we process the current node
367
node = rootElement;
368       if (st.hasMoreTokens()) {
369         String JavaDoc t = st.nextToken();
370         if (! t.equals(node.getNodeName())) return null;
371       }
372     }
373
374     // iterates through the /
375
if (! st.hasMoreTokens()) return null;
376     while (node != null) {
377       String JavaDoc t = st.nextToken();
378       if (t.equals(".")) return null;
379       if (st.hasMoreTokens()) {
380         node = findNamedChild(t,node);
381       } else {
382         return findNamedChilds(t, node);
383       }
384     }
385     return null;
386   }
387
388
389  /**
390   * Returns the attribute node of the given node and of name attributeName. If there is
391   * no attribute of such a name null is returned.
392   * @param attributeName the name of the attribute to look for
393   * @param node the node where to look for the attribute (the node can be null
394   * and in such a case null is returned)
395   * @return the attribute node of name attributeName or null
396   */

397   private org.w3c.dom.Node JavaDoc findNamedAttribute(String JavaDoc attributeName, org.w3c.dom.Node JavaDoc node) {
398     if (attributeName == null || attributeName.length() == 0) return node;
399     org.w3c.dom.NamedNodeMap JavaDoc attributes = node.getAttributes();
400     if (attributes == null) return null;
401     return attributes.getNamedItem(attributeName);
402   }
403
404  /**
405   * Returns the child node of the given node and of given name. If there is
406   * no child of such a name null is returned. If there is more than one child
407   * only the first one is returned
408   * @param name the name of the child to look for
409   * @param node the non null node where to look for the childs
410   * @return the matching child node or null
411   */

412   private org.w3c.dom.Node JavaDoc findNamedChild(String JavaDoc name, org.w3c.dom.Node JavaDoc node) {
413     org.w3c.dom.Node JavaDoc child = node.getFirstChild();
414     while (child != null) {
415       if (name.equals(child.getNodeName())) {
416         return child;
417       }
418       child = child.getNextSibling();
419     }
420     return child;
421   }
422
423  /**
424   * Returns the child nodes of the given node and of given name. If there is
425   * no child of such a name null is returned. All childs of that name are returned.
426   * @param name the name of the child to look for
427   * @param node the non null node where to look for the childs
428   * @return the matching child nodes or null
429   */

430   private org.w3c.dom.Node JavaDoc[] findNamedChilds(String JavaDoc name, org.w3c.dom.Node JavaDoc node) {
431     org.w3c.dom.Node JavaDoc child = node.getFirstChild();
432     java.util.ArrayList JavaDoc result = new java.util.ArrayList JavaDoc();
433     while (child != null) {
434       if (name.equals(child.getNodeName())) {
435         result.add(child);
436       }
437       child = child.getNextSibling();
438     }
439     int n = result.size();
440     if (n == 0) return null;
441     org.w3c.dom.Node JavaDoc[] resultArray = new org.w3c.dom.Node JavaDoc[n];
442     return (org.w3c.dom.Node JavaDoc[]) result.toArray(resultArray);
443   }
444 }
Popular Tags