KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > myvietnam > mvncore > configuration > ConfigurationXMLDocument


1 package net.myvietnam.mvncore.configuration;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if
22  * any, must include the following acknowledgement:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgement may appear in the software itself,
26  * if and wherever such third-party acknowledgements normally appear.
27  *
28  * 4. The names "The Jakarta Project", "Commons", and "Apache Software
29  * Foundation" must not be used to endorse or promote products derived
30  * from this software without prior written permission. For written
31  * permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache"
34  * nor may "Apache" appear in their names without prior written
35  * permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 import java.io.IOException JavaDoc;
58 import java.io.Writer JavaDoc;
59 import java.util.NoSuchElementException JavaDoc;
60
61 import org.apache.commons.digester.Digester;
62 import org.dom4j.Document;
63 import org.dom4j.DocumentException;
64 import org.dom4j.io.DOMWriter;
65 import org.dom4j.io.OutputFormat;
66 import org.dom4j.io.SAXReader;
67 import org.dom4j.io.XMLWriter;
68 import org.xml.sax.SAXException JavaDoc;
69
70 /**
71  * <p>A helper class that supports XML-like processing for configuration
72  * objects.</p>
73  * <p>This class provides a set of methods that all have something to do with
74  * treating a <code>Configuration</code> object as a XML document. So a
75  * configuration can be transformed into a <code>Document</code> (either
76  * dom4j or w3c), saved as an XML file or passed to Digester.</p>
77  * <p><strong>Implementation note:</strong> This class is not thread safe.</p>
78  *
79  * @author <a HREF="mailto:oliver.heger@t-online.de">Oliver Heger</a>
80  * @version $Id: ConfigurationXMLDocument.java,v 1.1 2003/12/09 08:25:30 huumai Exp $
81  */

82 public class ConfigurationXMLDocument
83 {
84     /** Constant for the class element.*/
85     protected static final String JavaDoc ELEM_CLASS = "config/class";
86
87     /** Constant for the property element.*/
88     protected static final String JavaDoc ELEM_PROPERTY = "config/class/property";
89
90     /** Constant for the name attribute.*/
91     protected static final String JavaDoc ATTR_NAME = "name";
92
93     /** Constant for the value attribute.*/
94     protected static final String JavaDoc ATTR_VALUE = "value";
95
96     /** Stores the configuration object this object operates on.*/
97     private Configuration configuration;
98
99     /**
100      * Creates a new instance of <code>ConfigurationXMLDocument</code>
101      * and sets the configuration object to be processed.
102      * @param config the configuration object
103      */

104     public ConfigurationXMLDocument(Configuration config)
105     {
106         setConfiguration(config);
107     }
108
109     /**
110      * Returns the <code>Configuration</code> object for this document.
111      * @return the <code>Configuration</code> object
112      */

113     public Configuration getConfiguration()
114     {
115         return configuration;
116     }
117
118     /**
119      * Sets the <code>Configuration</code> object this document operates on.
120      * @param configuration the <code>Configuration</code> object
121      */

122     public void setConfiguration(Configuration configuration)
123     {
124         this.configuration = configuration;
125     }
126
127     /**
128      * Returns a <code>XMLReader</code> object for the specified configuration
129      * object. This reader can then be used to perform XML-like processing on
130      * the configuration.
131      * @param config the configuration object
132      * @return a XMLReader for this configuration
133      */

134     public static ConfigurationXMLReader createXMLReader(Configuration config)
135     {
136         if (config instanceof HierarchicalConfiguration)
137         {
138             return new HierarchicalConfigurationXMLReader(
139                 (HierarchicalConfiguration) config);
140         } /* if */
141         else
142         {
143             return new BaseConfigurationXMLReader(config);
144         } /* else */
145     }
146
147     /**
148      * Returns a <code>XMLReader</code> object for the actual configuration
149      * object.
150      * @return a XMLReader for the actual configuration
151      */

152     public ConfigurationXMLReader createXMLReader()
153     {
154         return createXMLReader((String JavaDoc) null);
155     }
156
157     /**
158      * Returns a <code>ConfigurationXMLReader</code> object for the subset
159      * configuration specified by the given prefix. If no properties are found
160      * under this prefix, a <code>NoSuchElementException</code>
161      * exception will be thrown.
162      * @param prefix the prefix of the configuration keys that belong to the
163      * subset; can be <b>null</b>, then the whole configuration is affected
164      * @return a XMLReader for the specified subset configuration
165      */

166     public ConfigurationXMLReader createXMLReader(String JavaDoc prefix)
167     {
168         return createXMLReader(configForKey(prefix));
169     }
170
171     /**
172      * Transforms the wrapped configuration into a dom4j document.
173      * @param prefix a prefix for the keys to process; can be <b>null</b>,
174      * then all keys in the configuration will be added to the document
175      * @param rootName the name of the root element in the document; can be
176      * <b>null</b>, then a default name will be used
177      * @return the document
178      * @throws DocumentException if an error occurs
179      */

180     public Document getDocument(String JavaDoc prefix, String JavaDoc rootName)
181         throws DocumentException
182     {
183         ConfigurationXMLReader xmlReader = createXMLReader(prefix);
184         if (rootName != null)
185         {
186             xmlReader.setRootName(rootName);
187         } /* if */
188
189         SAXReader reader = new SAXReader(xmlReader);
190         return reader.read(getClass().getName());
191     }
192
193     /**
194      * Transforms the wrapped configuration into a dom4j document. The root
195      * element will be given a default name.
196      * @param prefix a prefix for the keys to process; can be <b>null</b>,
197      * then all keys in the configuration will be added to the document
198      * @return the document
199      * @throws DocumentException if an error occurs
200      */

201     public Document getDocument(String JavaDoc prefix) throws DocumentException
202     {
203         return getDocument(prefix, null);
204     }
205
206     /**
207      * Transforms the wrapped configuration into a dom4j document. The root
208      * element will be given a default name.
209      * @return the document
210      * @throws DocumentException if an error occurs
211      */

212     public Document getDocument() throws DocumentException
213     {
214         return getDocument(null, null);
215     }
216
217     /**
218      * Transforms the wrapped configuration into a w3c document.
219      * @param prefix a prefix for the keys to process; can be <b>null</b>,
220      * then all keys in the configuration will be added to the document
221      * @param rootName the name of the root element in the document; can be
222      * <b>null</b>, then a default name will be used
223      * @return the document
224      * @throws DocumentException if an error occurs
225      */

226     public org.w3c.dom.Document JavaDoc getW3cDocument(String JavaDoc prefix, String JavaDoc rootName)
227         throws DocumentException
228     {
229         return toW3cDocument(getDocument(prefix, rootName));
230     }
231
232     /**
233      * Transforms the wrapped configuration into a w3c document. The root
234      * element will be given a default name.
235      * @param prefix a prefix for the keys to process; can be <b>null</b>,
236      * then all keys in the configuration will be added to the document
237      * @return the document
238      * @throws DocumentException if an error occurs
239      */

240     public org.w3c.dom.Document JavaDoc getW3cDocument(String JavaDoc prefix)
241         throws DocumentException
242     {
243         return getW3cDocument(prefix, null);
244     }
245
246     /**
247      * Transforms the wrapped configuration into a w3c document. The root
248      * element will be given a default name.
249      * @return the document
250      * @throws DocumentException if an error occurs
251      */

252     public org.w3c.dom.Document JavaDoc getW3cDocument() throws DocumentException
253     {
254         return getW3cDocument(null, null);
255     }
256
257     /**
258      * Converts a dom4j document into a w3c document.
259      * @param doc the dom4j document
260      * @return the w3c document
261      * @throws DocumentException if an error occurs
262      */

263     static org.w3c.dom.Document JavaDoc toW3cDocument(Document doc)
264         throws DocumentException
265     {
266         return new DOMWriter().write(doc);
267     }
268
269     /**
270      * Helper method for constructing a subset if necessary. Depending on
271      * the passed in key this method either returns the wrapped configuration
272      * or the specified subset of it.
273      * @param key the key
274      * @return the configuration for that key
275      */

276     private Configuration configForKey(String JavaDoc key)
277     {
278         Configuration conf = (key == null)
279             ? getConfiguration()
280             : getConfiguration().subset(key);
281
282         // undefined?
283
if(conf == null || (conf instanceof CompositeConfiguration
284         && ((CompositeConfiguration) conf).getNumberOfConfigurations() < 2))
285         {
286             throw new NoSuchElementException JavaDoc("No subset with key " + key);
287         } /* if */
288
289         return conf;
290     }
291
292     /**
293      * <p>Creates and initializes an object specified in the configuration
294      * using Digester.</p>
295      * <p>This method first constructs a subset configuration with the keys
296      * starting with the given prefix. It then transforms this subset into a
297      * XML document and let that be processed by Digester. The result of this
298      * processing is returned.</p>
299      * <p>The method is intended to be used for creating simple objects that
300      * are specified somewhere in the configuration in a standard way. The
301      * following fragment shows how a configuration file must look like to be
302      * understood by the default Digester rule set used by this method:</p>
303      * <p><pre>
304      * ...
305      * &lt;class name="mypackage.MyClass"/&gt;
306      * &lt;args&gt;
307      * &lt;property name="myFirstProperty" value="myFirstValue"/&gt;
308      * &lt;property name="MySecondProperty" value="mySecondValue"/&gt;
309      * ...
310      * &lt;/args&gt;
311      * ...
312      * </pre></p>
313      * @param prefix the prefix of the keys that are passed to Digester; can
314      * be <b>null</b>, then the whole configuration will be processed
315      * @return the result of the Digester processing
316      * @throws IOException if an IOException occurs
317      * @throws SAXException if a SAXException occurs
318      */

319     public Object JavaDoc callDigester(String JavaDoc prefix) throws IOException JavaDoc, SAXException JavaDoc
320     {
321         Digester digester = getDefaultDigester(prefix);
322         return digester.parse(getClass().getName());
323     }
324
325     /**
326      * Returns a default Digester instance. This instance is used for the
327      * simple object creation feature.
328      * @param prefix the prefix of the keys to be processed; can be
329      * <b>null</b>, then the whole configuration is meant
330      * @return the default Digester instance
331      */

332     protected Digester getDefaultDigester(String JavaDoc prefix)
333     {
334         Digester digester = createDefaultDigester(prefix);
335         setupDefaultDigester(digester);
336
337         return digester;
338     }
339
340     /**
341      * Creates the default Digester instance for the given prefix. This method
342      * is called by <code>getDefaultDigester()</code>.
343      * @param prefix the prefix of the keys to be processed; can be
344      * <b>null</b>, then the whole configuration is meant
345      * @return the default Digester instance
346      */

347     protected Digester createDefaultDigester(String JavaDoc prefix)
348     {
349         return new Digester(createXMLReader(prefix));
350     }
351
352     /**
353      * Initializes the default digester instance used for simple object
354      * creation. Here all needed properties and rules can be set. This base
355      * implementation sets default rules for object creation as explained in
356      * the comment for the <code>callDigester()</code> methods.
357      * @param digester the digester instance to be initialized
358      */

359     protected void setupDefaultDigester(Digester digester)
360     {
361         digester.addObjectCreate(ELEM_CLASS, ATTR_NAME, Object JavaDoc.class);
362         digester.addSetProperty(ELEM_PROPERTY, ATTR_NAME, ATTR_VALUE);
363     }
364
365     /**
366      * Writes a configuration (or parts of it) to the given writer.
367      * @param out the output writer
368      * @param prefix the prefix of the subset to write; if <b>null</b>, the
369      * whole configuration is written
370      * @param root the name of the root element of the resulting document;
371      * <b>null</b> for a default name
372      * @param pretty flag for the pretty print mode
373      * @throws IOException if an IO error occurs
374      * @throws DocumentException if there is an error during processing
375      */

376     public void write(Writer JavaDoc out, String JavaDoc prefix, String JavaDoc root, boolean pretty)
377         throws IOException JavaDoc, DocumentException
378     {
379         OutputFormat format =
380             (pretty)
381                 ? OutputFormat.createPrettyPrint()
382                 : OutputFormat.createCompactFormat();
383
384         XMLWriter writer = new XMLWriter(out, format);
385         writer.write(getDocument(prefix, root));
386     }
387
388     /**
389      * Writes a configuration (or parts of it) to the given writer.
390      * This overloaded version always uses pretty print mode.
391      * @param out the output writer
392      * @param prefix the prefix of the subset to write; if <b>null</b>, the
393      * whole configuration is written
394      * @param root the name of the root element of the resulting document;
395      * <b>null</b> for a default name
396      * @throws IOException if an IO error occurs
397      * @throws DocumentException if there is an error during processing
398      */

399     public void write(Writer JavaDoc out, String JavaDoc prefix, String JavaDoc root)
400         throws IOException JavaDoc, DocumentException
401     {
402         write(out, prefix, root, true);
403     }
404
405     /**
406      * Writes a configuration (or parts of it) to the given writer.
407      * The resulting document's root element will be given a default name.
408      * @param out the output writer
409      * @param prefix the prefix of the subset to write; if <b>null</b>, the
410      * whole configuration is written
411      * @param pretty flag for the pretty print mode
412      * @throws IOException if an IO error occurs
413      * @throws DocumentException if there is an error during processing
414      */

415     public void write(Writer JavaDoc out, String JavaDoc prefix, boolean pretty)
416         throws IOException JavaDoc, DocumentException
417     {
418         write(out, prefix, null, pretty);
419     }
420
421     /**
422      * Writes a configuration (or parts of it) to the given writer.
423      * The resulting document's root element will be given a default name.
424      * This overloaded version always uses pretty print mode.
425      * @param out the output writer
426      * @param prefix the prefix of the subset to write; if <b>null</b>, the
427      * whole configuration is written
428      * @throws IOException if an IO error occurs
429      * @throws DocumentException if there is an error during processing
430      */

431     public void write(Writer JavaDoc out, String JavaDoc prefix)
432         throws IOException JavaDoc, DocumentException
433     {
434         write(out, prefix, true);
435     }
436
437     /**
438      * Writes the wrapped configuration to the given writer.
439      * The resulting document's root element will be given a default name.
440      * @param out the output writer
441      * @param pretty flag for the pretty print mode
442      * @throws IOException if an IO error occurs
443      * @throws DocumentException if there is an error during processing
444      */

445     public void write(Writer JavaDoc out, boolean pretty)
446         throws IOException JavaDoc, DocumentException
447     {
448         write(out, null, null, pretty);
449     }
450
451     /**
452      * Writes the wrapped configuration to the given writer.
453      * The resulting document's root element will be given a default name.
454      * This overloaded version always uses pretty print mode.
455      * @param out the output writer
456      * @throws IOException if an IO error occurs
457      * @throws DocumentException if there is an error during processing
458      */

459     public void write(Writer JavaDoc out) throws IOException JavaDoc, DocumentException
460     {
461         write(out, true);
462     }
463 }
464
Popular Tags