/*
 * 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.configuration2;

import org.apache.commons.configuration2.tree.ImmutableNode;
import org.apache.commons.configuration2.tree.InMemoryNodeModel;
import org.apache.commons.configuration2.tree.NodeModel;
import org.apache.commons.configuration2.tree.NodeSelector;
import org.apache.commons.configuration2.tree.TrackedNodeModel;

/**
 * <p>
 * A specialized hierarchical configuration class with a node model that uses a
 * tracked node of another node model as its root node.
 * </p>
 * <p>
 * Configurations of this type are initialized with a special {@link NodeModel}
 * operating on a specific tracked node of the parent configuration and the
 * corresponding {@link NodeSelector}. All property accessor methods are
 * evaluated relative to this root node. A good use case for a
 * {@code SubnodeConfiguration} is when multiple properties from a specific sub
 * tree of the whole configuration need to be accessed. Then a
 * {@code SubnodeConfiguration} can be created with the parent node of the
 * affected sub tree as root node. This allows for simpler property keys and is
 * also more efficient.
 * </p>
 * <p>
 * By making use of a tracked node as root node, a {@code SubnodeConfiguration}
 * and its parent configuration initially operate on the same hierarchy of
 * configuration nodes. So if modifications are performed at the subnode
 * configuration, these changes are immediately visible in the parent
 * configuration. Analogously will updates of the parent configuration affect
 * the {@code SubnodeConfiguration} if the sub tree spanned by the
 * {@code SubnodeConfiguration}'s root node is involved.
 * </p>
 * <p>
 * Note that by making use of a {@code NodeSelector} the
 * {@code SubnodeConfiguration} is not associated with a physical node instance,
 * but the selection criteria stored in the selector are evaluated after each
 * change of the nodes structure. As an example consider that the selector uses
 * a key with an index into a list element, say index 2. Now if an update occurs
 * on the underlying nodes structure which removes the first element in this
 * list structure, the {@code SubnodeConfiguration} still references the element
 * with index 2 which is now another one.
 * </p>
 * <p>
 * There are also possible changes of the underlying nodes structure which
 * completely detach the {@code SubnodeConfiguration} from its parent
 * configuration. For instance, the key referenced by the
 * {@code SubnodeConfiguration} could be removed in the parent configuration. If
 * this happens, the {@code SubnodeConfiguration} stays functional; however, it
 * now operates on a separate node model than its parent configuration. Changes
 * made by one configuration are no longer visible for the other one (as the
 * node models have no longer overlapping nodes, there is no way to have a
 * synchronization here).
 * </p>
 * <p>
 * When a subnode configuration is created, it inherits the settings of its
 * parent configuration, e.g. some flags like the
 * {@code throwExceptionOnMissing} flag or the settings for handling list
 * delimiters) or the expression engine. If these settings are changed later in
 * either the subnode or the parent configuration, the changes are not visible
 * for each other. So you could create a subnode configuration, and change its
 * expression engine without affecting the parent configuration.
 * </p>
 * <p>
 * Because the {@code SubnodeConfiguration} operates on the same nodes structure
 * as its parent it uses the same {@code Synchronizer} instance per default.
 * This means that locks held on one {@code SubnodeConfiguration} also impact
 * the parent configuration and all of its other {@code SubnodeConfiguration}
 * objects. You should not change this without a good reason! Otherwise, there
 * is the risk of data corruption when multiple threads access these
 * configuration concurrently.
 * </p>
 * <p>
 * From its purpose this class is quite similar to {@link SubsetConfiguration}.
 * The difference is that a subset configuration of a hierarchical configuration
 * may combine multiple configuration nodes from different sub trees of the
 * configuration, while all nodes in a subnode configuration belong to the same
 * sub tree. If an application can live with this limitation, it is recommended
 * to use this class instead of {@code SubsetConfiguration} because creating a
 * subset configuration is more expensive than creating a subnode configuration.
 * </p>
 * <p>
 * It is strongly recommended to create {@code SubnodeConfiguration} instances
 * only through the {@code configurationAt()} methods of a hierarchical
 * configuration. These methods ensure that all necessary initializations are
 * done. Creating instances manually without doing proper initialization may
 * break some of the functionality provided by this class.
 * </p>
 *
 * @since 1.3
 * @version $Id$
 */
public class SubnodeConfiguration extends BaseHierarchicalConfiguration
{
    /** Stores the parent configuration. */
    private final BaseHierarchicalConfiguration parent;

    /** The node selector selecting the root node of this configuration. */
    private final NodeSelector rootSelector;

    /**
     * Creates a new instance of {@code SubnodeConfiguration} and initializes it
     * with all relevant properties.
     *
     * @param parent the parent configuration
     * @param model the {@code TrackedNodeModel} to be used for this configuration
     * @throws IllegalArgumentException if a required argument is missing
     */
    public SubnodeConfiguration(BaseHierarchicalConfiguration parent,
                                TrackedNodeModel model)
    {
        super(model);
        if (parent == null)
        {
            throw new IllegalArgumentException(
                    "Parent configuration must not be null!");
        }
        if (model == null)
        {
            throw new IllegalArgumentException("Node model must not be null!");
        }

        this.parent = parent;
        rootSelector = model.getSelector();
    }

    /**
     * Returns the parent configuration of this subnode configuration.
     *
     * @return the parent configuration
     */
    public BaseHierarchicalConfiguration getParent()
    {
        return parent;
    }

    /**
     * Returns the selector to the root node of this configuration.
     *
     * @return the {@code NodeSelector} to the root node
     */
    public NodeSelector getRootSelector()
    {
        return rootSelector;
    }

    /**
     * Closes this sub configuration. This method closes the underlying
     * {@link TrackedNodeModel}, thus causing the tracked node acting as root
     * node to be released. Per default, this happens automatically when the
     * model is claimed by the garbage collector. By calling this method
     * explicitly, it can be indicated that this configuration is no longer used
     * and that resources used by it can be freed immediately.
     */
    public void close()
    {
        (getTrackedModel()).close();
    }

    /**
     * {@inheritDoc} This implementation returns the node model of the parent
     * configuration. This is necessary because this sub configuration does not
     * have an {@code InMemoryNodeModel} object.
     */
    @Override
    public InMemoryNodeModel getNodeModel()
    {
        return getParent().getNodeModel();
    }

    /**
     * {@inheritDoc} This implementation returns a copy of the current node
     * model with the same settings. However, it has to be ensured that the
     * track count for the node selector is increased.
     *
     * @return the node model for the clone
     */
    @Override
    protected NodeModel<ImmutableNode> cloneNodeModel()
    {
        InMemoryNodeModel parentModel =
                (InMemoryNodeModel) getParent().getModel();
        parentModel.trackNode(getRootSelector(), getParent());
        return new TrackedNodeModel(getParent(), getRootSelector(), true);
    }

    /**
     * {@inheritDoc} This implementation returns a sub selector of the selector
     * of this configuration.
     */
    @Override
    protected NodeSelector getSubConfigurationNodeSelector(String key)
    {
        return getRootSelector().subSelector(key);
    }

    /**
     * {@inheritDoc} This implementation returns the parent model of the
     * {@link TrackedNodeModel} used by this configuration.
     */
    @Override
    protected InMemoryNodeModel getSubConfigurationParentModel()
    {
        return getTrackedModel().getParentModel();
    }

    /**
     * Convenience method that returns the tracked model used by this sub
     * configuration.
     *
     * @return the {@code TrackedNodeModel}
     */
    private TrackedNodeModel getTrackedModel()
    {
        return (TrackedNodeModel) getModel();
    }
}
