~ubuntu-branches/ubuntu/saucy/commons-configuration/saucy

« back to all changes in this revision

Viewing changes to src/main/java/org/apache/commons/configuration/AbstractHierarchicalFileConfiguration.java

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2013-07-01 16:29:44 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130701162944-98waq5gogha5gpn1
Tags: 1.9-1
* New upstream release
* debian/control:
  - Updated Standards-Version to 3.9.4 (no changes)
  - Use canonical URLs for the Vcs-* fields
  - Added new build dependencies (libjavacc-maven-plugin-java, junit4)
  - Upgraded the dependency on the Servlet API (2.5 -> 3.0)
  - Removed the dependency on the Activation Framework (glassfish-activation)
  - Replaced the dependency on glassfish-mail with libgnumail-java
  - Removed the unused dependencies:
    liblog4j1.2-java-doc, libmaven-assembly-plugin-java
  - Replaced the dependency on libcommons-jexl-java by libcommons-jexl2-java
* debian/watch: Changed to point the official Apache distribution server
* Removed the obsolete file debian/ant.properties
* Installed the upstream changelog in the binary packages
* Added the report plugins to maven.ignoreRules
* Added the classpath attribute to the jar manifest

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements.  See the NOTICE file distributed with
 
4
 * this work for additional information regarding copyright ownership.
 
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
6
 * (the "License"); you may not use this file except in compliance with
 
7
 * the License.  You may obtain a copy of the License at
 
8
 *
 
9
 *     http://www.apache.org/licenses/LICENSE-2.0
 
10
 *
 
11
 * Unless required by applicable law or agreed to in writing, software
 
12
 * distributed under the License is distributed on an "AS IS" BASIS,
 
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
 * See the License for the specific language governing permissions and
 
15
 * limitations under the License.
 
16
 */
 
17
 
 
18
package org.apache.commons.configuration;
 
19
 
 
20
import java.io.File;
 
21
import java.io.InputStream;
 
22
import java.io.OutputStream;
 
23
import java.io.Reader;
 
24
import java.io.Writer;
 
25
import java.net.URL;
 
26
import java.util.Collection;
 
27
import java.util.Iterator;
 
28
import java.util.List;
 
29
 
 
30
import org.apache.commons.configuration.event.ConfigurationErrorEvent;
 
31
import org.apache.commons.configuration.event.ConfigurationErrorListener;
 
32
import org.apache.commons.configuration.event.ConfigurationEvent;
 
33
import org.apache.commons.configuration.event.ConfigurationListener;
 
34
import org.apache.commons.configuration.reloading.Reloadable;
 
35
import org.apache.commons.configuration.reloading.ReloadingStrategy;
 
36
import org.apache.commons.configuration.tree.ConfigurationNode;
 
37
 
 
38
/**
 
39
 * <p>Base class for implementing file based hierarchical configurations.</p>
 
40
 * <p>This class serves an analogous purpose as the
 
41
 * {@link AbstractFileConfiguration} class for non hierarchical
 
42
 * configurations. It behaves in exactly the same way, so please refer to the
 
43
 * documentation of {@code AbstractFileConfiguration} for further details.</p>
 
44
 *
 
45
 * @since 1.2
 
46
 *
 
47
 * @author Emmanuel Bourg
 
48
 * @version $Id: AbstractHierarchicalFileConfiguration.java 1206575 2011-11-26 20:07:52Z oheger $
 
49
 */
 
50
public abstract class AbstractHierarchicalFileConfiguration
 
51
extends HierarchicalConfiguration
 
52
implements FileConfiguration, ConfigurationListener, ConfigurationErrorListener, FileSystemBased,
 
53
        Reloadable
 
54
{
 
55
    /** Stores the delegate used for implementing functionality related to the
 
56
     * {@code FileConfiguration} interface.
 
57
     */
 
58
    private FileConfigurationDelegate delegate;
 
59
 
 
60
    /**
 
61
     * Creates a new instance of {@code AbstractHierarchicalFileConfiguration}.
 
62
     */
 
63
    protected AbstractHierarchicalFileConfiguration()
 
64
    {
 
65
        initialize();
 
66
    }
 
67
 
 
68
    /**
 
69
     * Creates a new instance of
 
70
     * {@code AbstractHierarchicalFileConfiguration} and copies the
 
71
     * content of the specified configuration into this object.
 
72
     *
 
73
     * @param c the configuration to copy
 
74
     * @since 1.4
 
75
     */
 
76
    protected AbstractHierarchicalFileConfiguration(HierarchicalConfiguration c)
 
77
    {
 
78
        super(c);
 
79
        initialize();
 
80
    }
 
81
 
 
82
    /**
 
83
     * Creates and loads the configuration from the specified file.
 
84
     *
 
85
     * @param fileName The name of the plist file to load.
 
86
     * @throws ConfigurationException Error while loading the file
 
87
     */
 
88
    public AbstractHierarchicalFileConfiguration(String fileName) throws ConfigurationException
 
89
    {
 
90
        this();
 
91
        // store the file name
 
92
        delegate.setFileName(fileName);
 
93
 
 
94
        // load the file
 
95
        load();
 
96
    }
 
97
 
 
98
    /**
 
99
     * Creates and loads the configuration from the specified file.
 
100
     *
 
101
     * @param file The configuration file to load.
 
102
     * @throws ConfigurationException Error while loading the file
 
103
     */
 
104
    public AbstractHierarchicalFileConfiguration(File file) throws ConfigurationException
 
105
    {
 
106
        this();
 
107
        // set the file and update the url, the base path and the file name
 
108
        setFile(file);
 
109
 
 
110
        // load the file
 
111
        if (file.exists())
 
112
        {
 
113
            load();
 
114
        }
 
115
    }
 
116
 
 
117
    /**
 
118
     * Creates and loads the configuration from the specified URL.
 
119
     *
 
120
     * @param url The location of the configuration file to load.
 
121
     * @throws ConfigurationException Error while loading the file
 
122
     */
 
123
    public AbstractHierarchicalFileConfiguration(URL url) throws ConfigurationException
 
124
    {
 
125
        this();
 
126
        // set the URL and update the base path and the file name
 
127
        setURL(url);
 
128
 
 
129
        // load the file
 
130
        load();
 
131
    }
 
132
 
 
133
    /**
 
134
     * Initializes this instance, mainly the internally used delegate object.
 
135
     */
 
136
    private void initialize()
 
137
    {
 
138
        delegate = createDelegate();
 
139
        initDelegate(delegate);
 
140
    }
 
141
 
 
142
    @Override
 
143
    protected void addPropertyDirect(String key, Object obj)
 
144
    {
 
145
        synchronized (delegate.getReloadLock())
 
146
        {
 
147
            super.addPropertyDirect(key, obj);
 
148
            delegate.possiblySave();
 
149
        }
 
150
    }
 
151
 
 
152
    @Override
 
153
    public void clearProperty(String key)
 
154
    {
 
155
        synchronized (delegate.getReloadLock())
 
156
        {
 
157
            super.clearProperty(key);
 
158
            delegate.possiblySave();
 
159
        }
 
160
    }
 
161
 
 
162
    @Override
 
163
    public void clearTree(String key)
 
164
    {
 
165
        synchronized (delegate.getReloadLock())
 
166
        {
 
167
            super.clearTree(key);
 
168
            delegate.possiblySave();
 
169
        }
 
170
    }
 
171
 
 
172
    @Override
 
173
    public void setProperty(String key, Object value)
 
174
    {
 
175
        synchronized (delegate.getReloadLock())
 
176
        {
 
177
            super.setProperty(key, value);
 
178
            delegate.possiblySave();
 
179
        }
 
180
    }
 
181
 
 
182
    public void load() throws ConfigurationException
 
183
    {
 
184
        delegate.load();
 
185
    }
 
186
 
 
187
    public void load(String fileName) throws ConfigurationException
 
188
    {
 
189
        delegate.load(fileName);
 
190
    }
 
191
 
 
192
    public void load(File file) throws ConfigurationException
 
193
    {
 
194
        delegate.load(file);
 
195
    }
 
196
 
 
197
    public void load(URL url) throws ConfigurationException
 
198
    {
 
199
        delegate.load(url);
 
200
    }
 
201
 
 
202
    public void load(InputStream in) throws ConfigurationException
 
203
    {
 
204
        delegate.load(in);
 
205
    }
 
206
 
 
207
    public void load(InputStream in, String encoding) throws ConfigurationException
 
208
    {
 
209
        delegate.load(in, encoding);
 
210
    }
 
211
 
 
212
    public void save() throws ConfigurationException
 
213
    {
 
214
        delegate.save();
 
215
    }
 
216
 
 
217
    public void save(String fileName) throws ConfigurationException
 
218
    {
 
219
        delegate.save(fileName);
 
220
    }
 
221
 
 
222
    public void save(File file) throws ConfigurationException
 
223
    {
 
224
        delegate.save(file);
 
225
    }
 
226
 
 
227
    public void save(URL url) throws ConfigurationException
 
228
    {
 
229
        delegate.save(url);
 
230
    }
 
231
 
 
232
    public void save(OutputStream out) throws ConfigurationException
 
233
    {
 
234
        delegate.save(out);
 
235
    }
 
236
 
 
237
    public void save(OutputStream out, String encoding) throws ConfigurationException
 
238
    {
 
239
        delegate.save(out, encoding);
 
240
    }
 
241
 
 
242
    public String getFileName()
 
243
    {
 
244
        return delegate.getFileName();
 
245
    }
 
246
 
 
247
    public void setFileName(String fileName)
 
248
    {
 
249
        delegate.setFileName(fileName);
 
250
    }
 
251
 
 
252
    public String getBasePath()
 
253
    {
 
254
        return delegate.getBasePath();
 
255
    }
 
256
 
 
257
    public void setBasePath(String basePath)
 
258
    {
 
259
        delegate.setBasePath(basePath);
 
260
    }
 
261
 
 
262
    public File getFile()
 
263
    {
 
264
        return delegate.getFile();
 
265
    }
 
266
 
 
267
    public void setFile(File file)
 
268
    {
 
269
        delegate.setFile(file);
 
270
    }
 
271
 
 
272
    public URL getURL()
 
273
    {
 
274
        return delegate.getURL();
 
275
    }
 
276
 
 
277
    public void setURL(URL url)
 
278
    {
 
279
        delegate.setURL(url);
 
280
    }
 
281
 
 
282
    public void setAutoSave(boolean autoSave)
 
283
    {
 
284
        delegate.setAutoSave(autoSave);
 
285
    }
 
286
 
 
287
    public boolean isAutoSave()
 
288
    {
 
289
        return delegate.isAutoSave();
 
290
    }
 
291
 
 
292
    public ReloadingStrategy getReloadingStrategy()
 
293
    {
 
294
        return delegate.getReloadingStrategy();
 
295
    }
 
296
 
 
297
    public void setReloadingStrategy(ReloadingStrategy strategy)
 
298
    {
 
299
        delegate.setReloadingStrategy(strategy);
 
300
    }
 
301
 
 
302
    public void reload()
 
303
    {
 
304
        reload(false);
 
305
    }
 
306
 
 
307
    private boolean reload(boolean checkReload)
 
308
    {
 
309
        synchronized (delegate.getReloadLock())
 
310
        {
 
311
            setDetailEvents(false);
 
312
            try
 
313
            {
 
314
                return delegate.reload(checkReload);
 
315
            }
 
316
            finally
 
317
            {
 
318
                setDetailEvents(true);
 
319
            }
 
320
        }
 
321
    }
 
322
 
 
323
    /**
 
324
     * Reloads the associated configuration file. This method first clears the
 
325
     * content of this configuration, then the associated configuration file is
 
326
     * loaded again. Updates on this configuration which have not yet been saved
 
327
     * are lost. Calling this method is like invoking {@code reload()}
 
328
     * without checking the reloading strategy.
 
329
     *
 
330
     * @throws ConfigurationException if an error occurs
 
331
     * @since 1.7
 
332
     */
 
333
    public void refresh() throws ConfigurationException
 
334
    {
 
335
        delegate.refresh();
 
336
    }
 
337
 
 
338
    public String getEncoding()
 
339
    {
 
340
        return delegate.getEncoding();
 
341
    }
 
342
 
 
343
    public void setEncoding(String encoding)
 
344
    {
 
345
        delegate.setEncoding(encoding);
 
346
    }
 
347
 
 
348
    @Override
 
349
    public Object getReloadLock()
 
350
    {
 
351
        return delegate.getReloadLock();
 
352
    }
 
353
 
 
354
    @Override
 
355
    public boolean containsKey(String key)
 
356
    {
 
357
        reload();
 
358
        synchronized (delegate.getReloadLock())
 
359
        {
 
360
            return super.containsKey(key);
 
361
        }
 
362
    }
 
363
 
 
364
    @Override
 
365
    public Iterator<String> getKeys()
 
366
    {
 
367
        reload();
 
368
        synchronized (delegate.getReloadLock())
 
369
        {
 
370
            return super.getKeys();
 
371
        }
 
372
    }
 
373
 
 
374
    @Override
 
375
    public Iterator<String> getKeys(String prefix)
 
376
    {
 
377
        reload();
 
378
        synchronized (delegate.getReloadLock())
 
379
        {
 
380
            return super.getKeys(prefix);
 
381
        }
 
382
    }
 
383
 
 
384
    @Override
 
385
    public Object getProperty(String key)
 
386
    {
 
387
        if (reload(true))
 
388
        {
 
389
            // Avoid reloading again and getting the same error.
 
390
            synchronized (delegate.getReloadLock())
 
391
            {
 
392
                return super.getProperty(key);
 
393
            }
 
394
        }
 
395
        return null;
 
396
    }
 
397
 
 
398
    @Override
 
399
    public boolean isEmpty()
 
400
    {
 
401
        reload();
 
402
        synchronized (delegate.getReloadLock())
 
403
        {
 
404
            return super.isEmpty();
 
405
        }
 
406
    }
 
407
 
 
408
    /**
 
409
     * Directly adds sub nodes to this configuration. This implementation checks
 
410
     * whether auto save is necessary after executing the operation.
 
411
     *
 
412
     * @param key the key where the nodes are to be added
 
413
     * @param nodes a collection with the nodes to be added
 
414
     * @since 1.5
 
415
     */
 
416
    @Override
 
417
    public void addNodes(String key, Collection<? extends ConfigurationNode> nodes)
 
418
    {
 
419
        synchronized (delegate.getReloadLock())
 
420
        {
 
421
            super.addNodes(key, nodes);
 
422
            delegate.possiblySave();
 
423
        }
 
424
    }
 
425
 
 
426
    /**
 
427
     * Fetches a list of nodes, which are selected by the specified key. This
 
428
     * implementation will perform a reload if necessary.
 
429
     *
 
430
     * @param key the key
 
431
     * @return a list with the selected nodes
 
432
     */
 
433
    @Override
 
434
    protected List<ConfigurationNode> fetchNodeList(String key)
 
435
    {
 
436
        reload();
 
437
        synchronized (delegate.getReloadLock())
 
438
        {
 
439
            return super.fetchNodeList(key);
 
440
        }
 
441
    }
 
442
 
 
443
    /**
 
444
     * Reacts on changes of an associated subnode configuration. If the auto
 
445
     * save mechanism is active, the configuration must be saved.
 
446
     *
 
447
     * @param event the event describing the change
 
448
     * @since 1.5
 
449
     */
 
450
    @Override
 
451
    protected void subnodeConfigurationChanged(ConfigurationEvent event)
 
452
    {
 
453
        delegate.possiblySave();
 
454
        super.subnodeConfigurationChanged(event);
 
455
    }
 
456
 
 
457
    /**
 
458
     * Creates the file configuration delegate, i.e. the object that implements
 
459
     * functionality required by the {@code FileConfiguration} interface.
 
460
     * This base implementation will return an instance of the
 
461
     * {@code FileConfigurationDelegate} class. Derived classes may
 
462
     * override it to create a different delegate object.
 
463
     *
 
464
     * @return the file configuration delegate
 
465
     */
 
466
    protected FileConfigurationDelegate createDelegate()
 
467
    {
 
468
        return new FileConfigurationDelegate();
 
469
    }
 
470
 
 
471
    /**
 
472
     * Helper method for initializing the file configuration delegate.
 
473
     *
 
474
     * @param del the delegate
 
475
     */
 
476
    private void initDelegate(FileConfigurationDelegate del)
 
477
    {
 
478
        del.addConfigurationListener(this);
 
479
        del.addErrorListener(this);
 
480
        del.setLogger(getLogger());
 
481
    }
 
482
 
 
483
    /**
 
484
     * Reacts on configuration change events triggered by the delegate. These
 
485
     * events are passed to the registered configuration listeners.
 
486
     *
 
487
     * @param event the triggered event
 
488
     * @since 1.3
 
489
     */
 
490
    public void configurationChanged(ConfigurationEvent event)
 
491
    {
 
492
        // deliver reload events to registered listeners
 
493
        setDetailEvents(true);
 
494
        try
 
495
        {
 
496
            fireEvent(event.getType(), event.getPropertyName(), event
 
497
                    .getPropertyValue(), event.isBeforeUpdate());
 
498
        }
 
499
        finally
 
500
        {
 
501
            setDetailEvents(false);
 
502
        }
 
503
    }
 
504
 
 
505
    public void configurationError(ConfigurationErrorEvent event)
 
506
    {
 
507
        fireError(event.getType(), event.getPropertyName(), event.getPropertyValue(),
 
508
                event.getCause());
 
509
    }
 
510
 
 
511
    /**
 
512
     * Returns the file configuration delegate.
 
513
     *
 
514
     * @return the delegate
 
515
     */
 
516
    protected FileConfigurationDelegate getDelegate()
 
517
    {
 
518
        return delegate;
 
519
    }
 
520
 
 
521
    /**
 
522
     * Allows to set the file configuration delegate.
 
523
     * @param delegate the new delegate
 
524
     */
 
525
    protected void setDelegate(FileConfigurationDelegate delegate)
 
526
    {
 
527
        this.delegate = delegate;
 
528
    }
 
529
 
 
530
    /**
 
531
     * Set the FileSystem to be used for this Configuration.
 
532
     * @param fileSystem The FileSystem to use.
 
533
     */
 
534
    public void setFileSystem(FileSystem fileSystem)
 
535
    {
 
536
        delegate.setFileSystem(fileSystem);
 
537
    }
 
538
 
 
539
    /**
 
540
     * Reset the FileSystem to the default;
 
541
     */
 
542
    public void resetFileSystem()
 
543
    {
 
544
        delegate.resetFileSystem();
 
545
    }
 
546
 
 
547
    /**
 
548
     * Retrieve the FileSystem being used.
 
549
     * @return The FileSystem.
 
550
     */
 
551
    public FileSystem getFileSystem()
 
552
    {
 
553
        return delegate.getFileSystem();
 
554
    }
 
555
 
 
556
    /**
 
557
     * A special implementation of the {@code FileConfiguration} interface that is
 
558
     * used internally to implement the {@code FileConfiguration} methods
 
559
     * for hierarchical configurations.
 
560
     */
 
561
    protected class FileConfigurationDelegate extends AbstractFileConfiguration
 
562
    {
 
563
        public void load(Reader in) throws ConfigurationException
 
564
        {
 
565
            AbstractHierarchicalFileConfiguration.this.load(in);
 
566
        }
 
567
 
 
568
        public void save(Writer out) throws ConfigurationException
 
569
        {
 
570
            AbstractHierarchicalFileConfiguration.this.save(out);
 
571
        }
 
572
 
 
573
        @Override
 
574
        public void clear()
 
575
        {
 
576
            AbstractHierarchicalFileConfiguration.this.clear();
 
577
        }
 
578
    }
 
579
}