org.apache.commons.configuration.AbstractHierarchicalFileConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.commons.configuration.AbstractHierarchicalFileConfiguration.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.configuration;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.configuration.event.ConfigurationEvent;
import org.apache.commons.configuration.event.ConfigurationListener;
import org.apache.commons.configuration.reloading.ReloadingStrategy;

/**
 * <p>Base class for implementing file based hierarchical configurations.</p>
 * <p>This class serves an analogous purpose as the
 * <code>{@link AbstractFileConfiguration}</code> class for non hierarchical
 * configurations. It behaves in exactly the same way, so please refer to the
 * documentation of <code>AbstractFileConfiguration</code> for further details.</p>
 *
 * @since 1.2
 *
 * @author Emmanuel Bourg
 * @version $Revision: 712405 $, $Date: 2008-11-08 17:37:48 +0100 (Sa, 08 Nov 2008) $
 */
public abstract class AbstractHierarchicalFileConfiguration extends HierarchicalConfiguration
        implements FileConfiguration, ConfigurationListener {
    /** Stores the delegate used for implementing functionality related to the
     * <code>FileConfiguration</code> interface.
     */
    private FileConfigurationDelegate delegate;

    /**
     * Creates a new instance of
     * <code>AbstractHierarchicalFileConfiguration</code>.
     */
    protected AbstractHierarchicalFileConfiguration() {
        initialize();
    }

    /**
     * Creates a new instance of
     * <code>AbstractHierarchicalFileConfiguration</code> and copies the
     * content of the specified configuration into this object.
     *
     * @param c the configuration to copy
     * @since 1.4
     */
    protected AbstractHierarchicalFileConfiguration(HierarchicalConfiguration c) {
        super(c);
        initialize();
    }

    /**
     * Creates and loads the configuration from the specified file.
     *
     * @param fileName The name of the plist file to load.
     * @throws ConfigurationException Error while loading the file
     */
    public AbstractHierarchicalFileConfiguration(String fileName) throws ConfigurationException {
        this();
        // store the file name
        delegate.setFileName(fileName);

        // load the file
        load();
    }

    /**
     * Creates and loads the configuration from the specified file.
     *
     * @param file The configuration file to load.
     * @throws ConfigurationException Error while loading the file
     */
    public AbstractHierarchicalFileConfiguration(File file) throws ConfigurationException {
        this();
        // set the file and update the url, the base path and the file name
        setFile(file);

        // load the file
        if (file.exists()) {
            load();
        }
    }

    /**
     * Creates and loads the configuration from the specified URL.
     *
     * @param url The location of the configuration file to load.
     * @throws ConfigurationException Error while loading the file
     */
    public AbstractHierarchicalFileConfiguration(URL url) throws ConfigurationException {
        this();
        // set the URL and update the base path and the file name
        setURL(url);

        // load the file
        load();
    }

    /**
     * Initializes this instance, mainly the internally used delegate object.
     */
    private void initialize() {
        delegate = createDelegate();
        initDelegate(delegate);
    }

    protected void addPropertyDirect(String key, Object obj) {
        super.addPropertyDirect(key, obj);
        delegate.possiblySave();
    }

    public void clearProperty(String key) {
        super.clearProperty(key);
        delegate.possiblySave();
    }

    public void clearTree(String key) {
        super.clearTree(key);
        delegate.possiblySave();
    }

    public void setProperty(String key, Object value) {
        super.setProperty(key, value);
        delegate.possiblySave();
    }

    public void load() throws ConfigurationException {
        delegate.load();
    }

    public void load(String fileName) throws ConfigurationException {
        delegate.load(fileName);
    }

    public void load(File file) throws ConfigurationException {
        delegate.load(file);
    }

    public void load(URL url) throws ConfigurationException {
        delegate.load(url);
    }

    public void load(InputStream in) throws ConfigurationException {
        delegate.load(in);
    }

    public void load(InputStream in, String encoding) throws ConfigurationException {
        delegate.load(in, encoding);
    }

    public void save() throws ConfigurationException {
        delegate.save();
    }

    public void save(String fileName) throws ConfigurationException {
        delegate.save(fileName);
    }

    public void save(File file) throws ConfigurationException {
        delegate.save(file);
    }

    public void save(URL url) throws ConfigurationException {
        delegate.save(url);
    }

    public void save(OutputStream out) throws ConfigurationException {
        delegate.save(out);
    }

    public void save(OutputStream out, String encoding) throws ConfigurationException {
        delegate.save(out, encoding);
    }

    public String getFileName() {
        return delegate.getFileName();
    }

    public void setFileName(String fileName) {
        delegate.setFileName(fileName);
    }

    public String getBasePath() {
        return delegate.getBasePath();
    }

    public void setBasePath(String basePath) {
        delegate.setBasePath(basePath);
    }

    public File getFile() {
        return delegate.getFile();
    }

    public void setFile(File file) {
        delegate.setFile(file);
    }

    public URL getURL() {
        return delegate.getURL();
    }

    public void setURL(URL url) {
        delegate.setURL(url);
    }

    public void setAutoSave(boolean autoSave) {
        delegate.setAutoSave(autoSave);
    }

    public boolean isAutoSave() {
        return delegate.isAutoSave();
    }

    public ReloadingStrategy getReloadingStrategy() {
        return delegate.getReloadingStrategy();
    }

    public void setReloadingStrategy(ReloadingStrategy strategy) {
        delegate.setReloadingStrategy(strategy);
    }

    public void reload() {
        setDetailEvents(false);
        try {
            delegate.reload();
        } finally {
            setDetailEvents(true);
        }
    }

    public String getEncoding() {
        return delegate.getEncoding();
    }

    public void setEncoding(String encoding) {
        delegate.setEncoding(encoding);
    }

    public boolean containsKey(String key) {
        reload();
        return super.containsKey(key);
    }

    public Iterator getKeys() {
        reload();
        return super.getKeys();
    }

    public Iterator getKeys(String prefix) {
        reload();
        return super.getKeys(prefix);
    }

    public Object getProperty(String key) {
        reload();
        return super.getProperty(key);
    }

    public boolean isEmpty() {
        reload();
        return super.isEmpty();
    }

    /**
     * Directly adds sub nodes to this configuration. This implementation checks
     * whether auto save is necessary after executing the operation.
     *
     * @param key the key where the nodes are to be added
     * @param nodes a collection with the nodes to be added
     * @since 1.5
     */
    public void addNodes(String key, Collection nodes) {
        super.addNodes(key, nodes);
        delegate.possiblySave();
    }

    /**
     * Fetches a list of nodes, which are selected by the specified key. This
     * implementation will perform a reload if necessary.
     *
     * @param key the key
     * @return a list with the selected nodes
     */
    protected List fetchNodeList(String key) {
        reload();
        return super.fetchNodeList(key);
    }

    /**
     * Reacts on changes of an associated subnode configuration. If the auto
     * save mechanism is active, the configuration must be saved.
     *
     * @param event the event describing the change
     * @since 1.5
     */
    protected void subnodeConfigurationChanged(ConfigurationEvent event) {
        delegate.possiblySave();
        super.subnodeConfigurationChanged(event);
    }

    /**
     * Creates the file configuration delegate, i.e. the object that implements
     * functionality required by the <code>FileConfiguration</code> interface.
     * This base implementation will return an instance of the
     * <code>FileConfigurationDelegate</code> class. Derived classes may
     * override it to create a different delegate object.
     *
     * @return the file configuration delegate
     */
    protected FileConfigurationDelegate createDelegate() {
        return new FileConfigurationDelegate();
    }

    /**
     * Helper method for initializing the file configuration delegate.
     *
     * @param del the delegate
     */
    private void initDelegate(FileConfigurationDelegate del) {
        del.addConfigurationListener(this);
    }

    /**
     * Reacts on configuration change events triggered by the delegate. These
     * events are passed to the registered configuration listeners.
     *
     * @param event the triggered event
     * @since 1.3
     */
    public void configurationChanged(ConfigurationEvent event) {
        // deliver reload events to registered listeners
        setDetailEvents(true);
        try {
            fireEvent(event.getType(), event.getPropertyName(), event.getPropertyValue(), event.isBeforeUpdate());
        } finally {
            setDetailEvents(false);
        }
    }

    /**
     * Returns the file configuration delegate.
     *
     * @return the delegate
     */
    protected FileConfigurationDelegate getDelegate() {
        return delegate;
    }

    /**
     * Allows to set the file configuration delegate.
     * @param delegate the new delegate
     */
    protected void setDelegate(FileConfigurationDelegate delegate) {
        this.delegate = delegate;
    }

    /**
     * A special implementation of the <code>FileConfiguration</code> interface that is
     * used internally to implement the <code>FileConfiguration</code> methods
     * for hierarchical configurations.
     */
    protected class FileConfigurationDelegate extends AbstractFileConfiguration {
        public void load(Reader in) throws ConfigurationException {
            AbstractHierarchicalFileConfiguration.this.load(in);
        }

        public void save(Writer out) throws ConfigurationException {
            AbstractHierarchicalFileConfiguration.this.save(out);
        }

        public void clear() {
            AbstractHierarchicalFileConfiguration.this.clear();
        }
    }
}