KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > base > config > HierarchicalConfiguration


1 /* ========================================================================
2  * JCommon : a free general purpose class library for the Java(tm) platform
3  * ========================================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jcommon/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ------------------------------
28  * HierarchicalConfiguration.java
29  * ------------------------------
30  * (C) Copyright 2004, by Object Refinery Limited.
31  *
32  * Original Author: Thomas Morgner;
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  *
35  * $Id: HierarchicalConfiguration.java,v 1.7 2006/11/20 21:36:30 taqua Exp $
36  *
37  * Changes
38  * -------
39  * 07-Jun-2004 : Added JCommon header (DG);
40  * 29-Jul-2004 : Replaced 'enum' variable name (reserved word in JDK 1.5) (DG);
41  *
42  */

43
44 package org.jfree.base.config;
45
46 import java.io.IOException JavaDoc;
47 import java.io.ObjectInputStream JavaDoc;
48 import java.io.ObjectOutputStream JavaDoc;
49 import java.util.Collections JavaDoc;
50 import java.util.Enumeration JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.Properties JavaDoc;
53 import java.util.TreeSet JavaDoc;
54
55 import org.jfree.util.Configuration;
56 import org.jfree.util.PublicCloneable;
57
58 /**
59  * A hierarchical configuration. Such a configuration can have one or more
60  * parent configurations providing usefull default values.
61  *
62  * @author Thomas Morgner
63  */

64 public class HierarchicalConfiguration
65     implements ModifiableConfiguration, PublicCloneable
66 {
67
68   /**
69    * The instance configuration properties.
70    */

71   private Properties JavaDoc configuration;
72
73   /**
74    * The parent configuration (null if this is the root configuration).
75    */

76   private transient Configuration parentConfiguration;
77
78   /**
79    * Creates a new configuration.
80    */

81   public HierarchicalConfiguration()
82   {
83     this.configuration = new Properties JavaDoc();
84   }
85
86   /**
87    * Creates a new configuration.
88    *
89    * @param parentConfiguration the parent configuration.
90    */

91   public HierarchicalConfiguration(final Configuration parentConfiguration)
92   {
93     this();
94     this.parentConfiguration = parentConfiguration;
95   }
96
97   /**
98    * Returns the configuration property with the specified key.
99    *
100    * @param key the property key.
101    * @return the property value.
102    */

103   public String JavaDoc getConfigProperty(final String JavaDoc key)
104   {
105     return getConfigProperty(key, null);
106   }
107
108   /**
109    * Returns the configuration property with the specified key (or the
110    * specified default value if there is no such property).
111    * <p/>
112    * If the property is not defined in this configuration, the code will
113    * lookup the property in the parent configuration.
114    *
115    * @param key the property key.
116    * @param defaultValue the default value.
117    * @return the property value.
118    */

119   public String JavaDoc getConfigProperty(final String JavaDoc key, final String JavaDoc defaultValue)
120   {
121     String JavaDoc value = this.configuration.getProperty(key);
122     if (value == null)
123     {
124       if (isRootConfig())
125       {
126         value = defaultValue;
127       }
128       else
129       {
130         value = this.parentConfiguration.getConfigProperty(key, defaultValue);
131       }
132     }
133     return value;
134   }
135
136   /**
137    * Sets a configuration property.
138    *
139    * @param key the property key.
140    * @param value the property value.
141    */

142   public void setConfigProperty(final String JavaDoc key, final String JavaDoc value)
143   {
144     if (key == null)
145     {
146       throw new NullPointerException JavaDoc();
147     }
148
149     if (value == null)
150     {
151       this.configuration.remove(key);
152     }
153     else
154     {
155       this.configuration.setProperty(key, value);
156     }
157   }
158
159   /**
160    * Returns true if this object has no parent.
161    *
162    * @return true, if this report is the root configuration, false otherwise.
163    */

164   private boolean isRootConfig()
165   {
166     return this.parentConfiguration == null;
167   }
168
169   /**
170    * Checks, whether the given key is localy defined in this instance or
171    * whether the key's value is inherited.
172    *
173    * @param key the key that should be checked.
174    * @return true, if the key is defined locally, false otherwise.
175    */

176   public boolean isLocallyDefined(final String JavaDoc key)
177   {
178     return this.configuration.containsKey(key);
179   }
180
181   /**
182    * Returns the collection of properties for the configuration.
183    *
184    * @return the properties.
185    */

186   protected Properties JavaDoc getConfiguration()
187   {
188     return this.configuration;
189   }
190
191   /**
192    * The new configuartion will be inserted into the list of report
193    * configuration, so that this configuration has the given report
194    * configuration instance as parent.
195    *
196    * @param config the new report configuration.
197    */

198   public void insertConfiguration(final HierarchicalConfiguration config)
199   {
200     config.setParentConfig(getParentConfig());
201     setParentConfig(config);
202   }
203
204   /**
205    * Set the parent configuration. The parent configuration is queried, if the
206    * requested configuration values was not found in this report
207    * configuration.
208    *
209    * @param config the parent configuration.
210    */

211   protected void setParentConfig(final Configuration config)
212   {
213     if (this.parentConfiguration == this)
214     {
215       throw new IllegalArgumentException JavaDoc("Cannot add myself as parent configuration.");
216     }
217     this.parentConfiguration = config;
218   }
219
220   /**
221    * Returns the parent configuration. The parent configuration is queried, if
222    * the requested configuration values was not found in this report
223    * configuration.
224    *
225    * @return the parent configuration.
226    */

227   protected Configuration getParentConfig()
228   {
229     return this.parentConfiguration;
230   }
231
232   /**
233    * Returns all defined configuration properties for the report. The
234    * enumeration contains all keys of the changed properties, properties set
235    * from files or the system properties are not included.
236    *
237    * @return all defined configuration properties for the report.
238    */

239   public Enumeration JavaDoc getConfigProperties()
240   {
241     return this.configuration.keys();
242   }
243
244   /**
245    * Searches all property keys that start with a given prefix.
246    *
247    * @param prefix the prefix that all selected property keys should share
248    * @return the properties as iterator.
249    */

250   public Iterator JavaDoc findPropertyKeys(final String JavaDoc prefix)
251   {
252     final TreeSet JavaDoc keys = new TreeSet JavaDoc();
253     collectPropertyKeys(prefix, this, keys);
254     return Collections.unmodifiableSet(keys).iterator();
255   }
256
257   /**
258    * Collects property keys from this and all parent report configurations,
259    * which start with the given prefix.
260    *
261    * @param prefix the prefix, that selects the property keys.
262    * @param config the currently processed report configuration.
263    * @param collector the target list, that should receive all valid keys.
264    */

265   private void collectPropertyKeys(final String JavaDoc prefix,
266                                    final Configuration config,
267                                    final TreeSet JavaDoc collector)
268   {
269     final Enumeration JavaDoc enum1 = config.getConfigProperties();
270     while (enum1.hasMoreElements())
271     {
272       final String JavaDoc key = (String JavaDoc) enum1.nextElement();
273       if (key.startsWith(prefix))
274       {
275         if (collector.contains(key) == false)
276         {
277           collector.add(key);
278         }
279       }
280     }
281
282     if (config instanceof HierarchicalConfiguration)
283     {
284       final HierarchicalConfiguration hconfig = (HierarchicalConfiguration) config;
285       if (hconfig.parentConfiguration != null)
286       {
287         collectPropertyKeys(prefix, hconfig.parentConfiguration, collector);
288       }
289     }
290   }
291
292   /**
293    * Checks, whether the parent configuration can be serialized. Usually the
294    * global configuration is not serialized and should return false here.
295    *
296    * @return true, if the parent config can be serialized, false otherwise.
297    */

298   protected boolean isParentSaved()
299   {
300     return true;
301   }
302
303   /**
304    * A callback method to reconnect this configuration with the global
305    * configuration after deserialization.
306    */

307   protected void configurationLoaded()
308   {
309   }
310
311   /**
312    * Helper method for serialization.
313    *
314    * @param out the output stream where to write the object.
315    * @throws java.io.IOException if errors occur while writing the stream.
316    */

317   private void writeObject(final ObjectOutputStream JavaDoc out)
318       throws IOException JavaDoc
319   {
320     out.defaultWriteObject();
321     if (isParentSaved() == false)
322     {
323       out.writeBoolean(false);
324     }
325     else
326     {
327       out.writeBoolean(true);
328       out.writeObject(parentConfiguration);
329     }
330   }
331
332   /**
333    * Helper method for serialization.
334    *
335    * @param in the input stream from where to read the serialized object.
336    * @throws IOException when reading the stream fails.
337    * @throws ClassNotFoundException if a class definition for a serialized
338    * object could not be found.
339    */

340   private void readObject(final ObjectInputStream JavaDoc in)
341       throws IOException JavaDoc, ClassNotFoundException JavaDoc
342   {
343     in.defaultReadObject();
344     final boolean readParent = in.readBoolean();
345     if (readParent)
346     {
347       parentConfiguration = (ModifiableConfiguration) in.readObject();
348     }
349     else
350     {
351       parentConfiguration = null;
352     }
353     configurationLoaded();
354   }
355
356   public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc
357   {
358     HierarchicalConfiguration config = (HierarchicalConfiguration) super.clone();
359     config.configuration = (Properties JavaDoc) configuration.clone();
360     return config;
361   }
362 }
363
Popular Tags