~ubuntu-branches/ubuntu/lucid/libjcommon-java/lucid

« back to all changes in this revision

Viewing changes to source/org/jfree/base/config/HierarchicalConfiguration.java

  • Committer: Bazaar Package Importer
  • Author(s): Wolfgang Baer
  • Date: 2006-02-09 15:58:13 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060209155813-fzi9zwh2rzedbllq
Tags: 1.0.0-1
* New stable upstream release (closes: #328574)
* Move to main - build with kaffe
* Use cdbs build system - added cdbs build-dependency
* Move package to pkg-java-maintainers for comaintenance, 
  added Christian Bayle and myself as uploaders
* Removed unneeded README.Debian
* Added README.Debian-source how the upstream tarball was cleaned
* Move big documentation in an own -doc package
* Register javadoc api with doc-base
* Standards-Version 3.6.2 (no changes)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.6 2005/10/18 13:14:12 mungady 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;
 
47
import java.io.ObjectInputStream;
 
48
import java.io.ObjectOutputStream;
 
49
import java.util.Collections;
 
50
import java.util.Enumeration;
 
51
import java.util.Iterator;
 
52
import java.util.Properties;
 
53
import java.util.TreeSet;
 
54
 
 
55
import org.jfree.util.Configuration;
 
56
 
 
57
/**
 
58
 * A hierarchical configuration. Such a configuration can have one or more
 
59
 * parent configurations providing usefull default values.
 
60
 *
 
61
 * @author Thomas Morgner
 
62
 */
 
63
public class HierarchicalConfiguration
 
64
    implements ModifiableConfiguration {
 
65
 
 
66
    /**
 
67
     * The instance configuration properties.
 
68
     */
 
69
    private Properties configuration;
 
70
 
 
71
    /**
 
72
     * The parent configuration (null if this is the root configuration).
 
73
     */
 
74
    private transient Configuration parentConfiguration;
 
75
 
 
76
    /**
 
77
     * Creates a new configuration.
 
78
     */
 
79
    public HierarchicalConfiguration() {
 
80
        this.configuration = new Properties();
 
81
    }
 
82
 
 
83
    /**
 
84
     * Creates a new configuration.
 
85
     *
 
86
     * @param parentConfiguration the parent configuration.
 
87
     */
 
88
    public HierarchicalConfiguration(final Configuration parentConfiguration) {
 
89
        this();
 
90
        this.parentConfiguration = parentConfiguration;
 
91
    }
 
92
 
 
93
    /**
 
94
     * Returns the configuration property with the specified key.
 
95
     *
 
96
     * @param key the property key.
 
97
     * @return the property value.
 
98
     */
 
99
    public String getConfigProperty(final String key) {
 
100
        return getConfigProperty(key, null);
 
101
    }
 
102
 
 
103
    /**
 
104
     * Returns the configuration property with the specified key
 
105
     * (or the specified default value if there is no such property).
 
106
     * <p/>
 
107
     * If the property is not defined in this configuration, the code
 
108
     * will lookup the property in the parent configuration.
 
109
     *
 
110
     * @param key          the property key.
 
111
     * @param defaultValue the default value.
 
112
     * @return the property value.
 
113
     */
 
114
    public String getConfigProperty(final String key, final String defaultValue) {
 
115
        String value = this.configuration.getProperty(key);
 
116
        if (value == null) {
 
117
            if (isRootConfig()) {
 
118
                value = defaultValue;
 
119
            }
 
120
            else {
 
121
                value = this.parentConfiguration.getConfigProperty(key, defaultValue);
 
122
            }
 
123
        }
 
124
        return value;
 
125
    }
 
126
 
 
127
    /**
 
128
     * Sets a configuration property.
 
129
     *
 
130
     * @param key   the property key.
 
131
     * @param value the property value.
 
132
     */
 
133
    public void setConfigProperty(final String key, final String value) {
 
134
        if (key == null) {
 
135
            throw new NullPointerException();
 
136
        }
 
137
 
 
138
        if (value == null) {
 
139
            this.configuration.remove(key);
 
140
        }
 
141
        else {
 
142
            this.configuration.setProperty(key, value);
 
143
        }
 
144
    }
 
145
 
 
146
    /**
 
147
     * Returns true if this object has no parent.
 
148
     *
 
149
     * @return true, if this report is the root configuration, false otherwise.
 
150
     */
 
151
    private boolean isRootConfig() {
 
152
        return this.parentConfiguration == null;
 
153
    }
 
154
 
 
155
    /**
 
156
     * Checks, whether the given key is localy defined in this instance or
 
157
     * whether the key's value is inherited.
 
158
     *
 
159
     * @param key the key that should be checked.
 
160
     * @return true, if the key is defined locally, false otherwise.
 
161
     */
 
162
    public boolean isLocallyDefined(final String key) {
 
163
        return this.configuration.containsKey(key);
 
164
    }
 
165
 
 
166
    /**
 
167
     * Returns the collection of properties for the configuration.
 
168
     *
 
169
     * @return the properties.
 
170
     */
 
171
    protected Properties getConfiguration() {
 
172
        return this.configuration;
 
173
    }
 
174
 
 
175
    /**
 
176
     * The new configuartion will be inserted into the list of report configuration,
 
177
     * so that this configuration has the given report configuration instance as parent.
 
178
     *
 
179
     * @param config the new report configuration.
 
180
     */
 
181
    public void insertConfiguration(final HierarchicalConfiguration config) {
 
182
        config.setParentConfig(getParentConfig());
 
183
        setParentConfig(config);
 
184
    }
 
185
 
 
186
    /**
 
187
     * Set the parent configuration. The parent configuration is queried, if the
 
188
     * requested configuration values was not found in this report configuration.
 
189
     *
 
190
     * @param config the parent configuration.
 
191
     */
 
192
    protected void setParentConfig(final Configuration config) {
 
193
        if (this.parentConfiguration == this) {
 
194
            throw new IllegalArgumentException("Cannot add myself as parent configuration.");
 
195
        }
 
196
        this.parentConfiguration = config;
 
197
    }
 
198
 
 
199
    /**
 
200
     * Returns the parent configuration. The parent configuration is queried, if the
 
201
     * requested configuration values was not found in this report configuration.
 
202
     *
 
203
     * @return the parent configuration.
 
204
     */
 
205
    protected Configuration getParentConfig() {
 
206
        return this.parentConfiguration;
 
207
    }
 
208
 
 
209
    /**
 
210
     * Returns all defined configuration properties for the report. The enumeration
 
211
     * contains all keys of the changed properties, properties set from files or
 
212
     * the system properties are not included.
 
213
     *
 
214
     * @return all defined configuration properties for the report.
 
215
     */
 
216
    public Enumeration getConfigProperties() {
 
217
        return this.configuration.keys();
 
218
    }
 
219
 
 
220
    /**
 
221
     * Searches all property keys that start with a given prefix.
 
222
     *
 
223
     * @param prefix the prefix that all selected property keys should share
 
224
     * @return the properties as iterator.
 
225
     */
 
226
    public Iterator findPropertyKeys(final String prefix) {
 
227
        final TreeSet keys = new TreeSet();
 
228
        collectPropertyKeys(prefix, this, keys);
 
229
        return Collections.unmodifiableSet(keys).iterator();
 
230
    }
 
231
 
 
232
    /**
 
233
     * Collects property keys from this and all parent report configurations, which
 
234
     * start with the given prefix.
 
235
     *
 
236
     * @param prefix    the prefix, that selects the property keys.
 
237
     * @param config    the currently processed report configuration.
 
238
     * @param collector the target list, that should receive all valid keys.
 
239
     */
 
240
    private void collectPropertyKeys(final String prefix, final Configuration config,
 
241
                                     final TreeSet collector) {
 
242
        final Enumeration enum1 = config.getConfigProperties();
 
243
        while (enum1.hasMoreElements()) {
 
244
            final String key = (String) enum1.nextElement();
 
245
            if (key.startsWith(prefix)) {
 
246
                if (collector.contains(key) == false) {
 
247
                    collector.add(key);
 
248
                }
 
249
            }
 
250
        }
 
251
 
 
252
        if (config instanceof HierarchicalConfiguration) {
 
253
            final HierarchicalConfiguration hconfig = (HierarchicalConfiguration) config;
 
254
            if (hconfig.parentConfiguration != null) {
 
255
                collectPropertyKeys(prefix, hconfig.parentConfiguration, collector);
 
256
            }
 
257
        }
 
258
    }
 
259
 
 
260
    /**
 
261
     * Checks, whether the parent configuration can be serialized. Usually the
 
262
     * global configuration is not serialized and should return false here.
 
263
     *
 
264
     * @return true, if the parent config can be serialized, false otherwise.
 
265
     */
 
266
    protected boolean isParentSaved() {
 
267
        return true;
 
268
    }
 
269
 
 
270
    /**
 
271
     * A callback method to reconnect this configuration with the global configuration
 
272
     * after deserialization.
 
273
     */
 
274
    protected void configurationLoaded() {
 
275
    }
 
276
 
 
277
    /**
 
278
     * Helper method for serialization.
 
279
     *
 
280
     * @param out the output stream where to write the object.
 
281
     * @throws java.io.IOException if errors occur while writing the stream.
 
282
     */
 
283
    private void writeObject(final ObjectOutputStream out)
 
284
        throws IOException {
 
285
        out.defaultWriteObject();
 
286
        if (isParentSaved() == false) {
 
287
            out.writeBoolean(false);
 
288
        }
 
289
        else {
 
290
            out.writeBoolean(true);
 
291
            out.writeObject(parentConfiguration);
 
292
        }
 
293
    }
 
294
 
 
295
    /**
 
296
     * Helper method for serialization.
 
297
     *
 
298
     * @param in the input stream from where to read the serialized object.
 
299
     * @throws IOException            when reading the stream fails.
 
300
     * @throws ClassNotFoundException if a class definition for a serialized object
 
301
     *                                could not be found.
 
302
     */
 
303
    private void readObject(final ObjectInputStream in)
 
304
        throws IOException, ClassNotFoundException {
 
305
        in.defaultReadObject();
 
306
        final boolean readParent = in.readBoolean();
 
307
        if (readParent) {
 
308
            parentConfiguration = (ModifiableConfiguration) in.readObject();
 
309
        }
 
310
        else {
 
311
            parentConfiguration = null;
 
312
        }
 
313
        configurationLoaded();
 
314
    }
 
315
 
 
316
}