KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.myvietnam.mvncore.configuration;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 1999-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.util.ArrayList JavaDoc;
58 import java.util.Collection JavaDoc;
59 import java.util.Collections JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.List JavaDoc;
62
63 /**
64  * <p>A base class for converters that transform a normal configuration
65  * object into a hierarchical configuration.</p>
66  * <p>This class provides a default mechanism for iterating over the keys in a
67  * configuration and to throw corresponding element start and end events. By
68  * handling these events a hierarchy can be constructed that is equivalent to
69  * the keys in the original configuration.</p>
70  * <p>Concrete sub classes will implement event handlers that generate SAX
71  * events for XML processing or construct a
72  * <code>HierarchicalConfiguration</code> root node. All in all with this class
73  * it is possible to treat a default configuration as if it was a hierarchical
74  * configuration, which can be sometimes useful.</p>
75  * @see HierarchicalConfiguration
76  *
77  * @author <a HREF="mailto:oliver.heger@t-online.de">Oliver Heger</a>
78  * @version $Id: HierarchicalConfigurationConverter.java,v 1.1 2003/12/09 08:25:30 huumai Exp $
79  */

80 abstract class HierarchicalConfigurationConverter
81 {
82     /**
83      * Processes the specified configuration object. This method implements
84      * the iteration over the configuration's keys. All defined keys are
85      * translated into a set of element start and end events represented by
86      * calls to the <code>elementStart()</code> and
87      * <code>elementEnd()</code> methods.
88      * @param config the configuration to be processed
89      */

90     public void process(Configuration config)
91     {
92         if (config != null)
93         {
94             ConfigurationKey keyEmpty = new ConfigurationKey();
95             ConfigurationKey keyLast = keyEmpty;
96
97             for (Iterator JavaDoc it = config.getKeys(); it.hasNext();)
98             {
99                 String JavaDoc key = (String JavaDoc) it.next();
100                 ConfigurationKey keyAct = new ConfigurationKey(key);
101                 closeElements(keyLast, keyAct);
102                 String JavaDoc elem = openElements(keyLast, keyAct);
103                 fireValue(elem, config.getProperty(key));
104                 keyLast = keyAct;
105             } /* for */
106
107             closeElements(keyLast, keyEmpty); // close all open
108
}
109     }
110
111     /**
112      * An event handler method that is called when an element starts.
113      * Concrete sub classes must implement it to perform a proper event
114      * handling.
115      * @param name the name of the new element
116      * @param value the element's value; can be <b>null</b> if the element
117      * does not have any value
118      */

119     protected abstract void elementStart(String JavaDoc name, Object JavaDoc value);
120
121     /**
122      * An event handler method that is called when an element ends. For each
123      * call of <code>elementStart()</code> there will be a corresponding call
124      * of this method. Concrete sub classes must implement it to perform a
125      * proper event handling.
126      * @param name the name of the ending element
127      */

128     protected abstract void elementEnd(String JavaDoc name);
129
130     /**
131      * Fires all necessary element end events for the specified keys. This
132      * method is called for each key obtained from the configuration to be
133      * converted. It calculates the common part of the actual and the last
134      * processed key and thus determines how many elements must be
135      * closed.
136      * @param keyLast the last processed key
137      * @param keyAct the actual key
138      */

139     protected void closeElements(
140         ConfigurationKey keyLast,
141         ConfigurationKey keyAct)
142     {
143         ConfigurationKey keyDiff = keyAct.differenceKey(keyLast);
144         Iterator JavaDoc it = reverseIterator(keyDiff);
145         if (it.hasNext())
146         {
147             // Skip first because it has already been closed by fireValue()
148
it.next();
149         } /* if */
150
151         while (it.hasNext())
152         {
153             elementEnd((String JavaDoc) it.next());
154         } /* while */
155     }
156
157     /**
158      * Helper method for determining a reverse iterator for the specified key.
159      * This implementation returns an iterator that returns the parts of the
160      * given key in reverse order, ignoring indices.
161      * @param key the key
162      * @return a reverse iterator for the parts of this key
163      */

164     protected Iterator JavaDoc reverseIterator(ConfigurationKey key)
165     {
166         List JavaDoc list = new ArrayList JavaDoc();
167         for (ConfigurationKey.KeyIterator it = key.iterator(); it.hasNext();)
168         {
169             list.add(it.nextKey());
170         } /* for */
171
172         Collections.reverse(list);
173         return list.iterator();
174     }
175
176     /**
177      * Fires all necessary element start events for the specified key. This
178      * method is called for each key obtained from the configuration to be
179      * converted. It ensures that all elements "between" the last key and the
180      * actual key are opened.
181      * @param keyLast the last processed key
182      * @param keyAct the actual key
183      * @return the name of the last element on the path
184      */

185     protected String JavaDoc openElements(
186         ConfigurationKey keyLast,
187         ConfigurationKey keyAct)
188     {
189         ConfigurationKey.KeyIterator it =
190             keyLast.differenceKey(keyAct).iterator();
191
192         for (it.nextKey(); it.hasNext(); it.nextKey())
193         {
194             elementStart(it.currentKey(), null);
195         } /* for */
196
197         return it.currentKey();
198     }
199
200     /**
201      * Fires all necessary element start events with the actual element values.
202      * This method is called for each key obtained from the configuration to be
203      * processed with the last part of the key as argument. The value can be
204      * either a single value or a collection.
205      * @param name the name of the actual element
206      * @param value the element's value
207      */

208     protected void fireValue(String JavaDoc name, Object JavaDoc value)
209     {
210         if (value != null && value instanceof Collection JavaDoc)
211         {
212             for (Iterator JavaDoc it = ((Collection JavaDoc) value).iterator(); it.hasNext();)
213             {
214                 fireValue(name, it.next());
215             } /* for */
216         } /* if */
217
218         else
219         {
220             elementStart(name, value);
221             elementEnd(name);
222         } /* else */
223     }
224 }
225
Popular Tags