001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.configuration.tree;
018
019import java.util.Collections;
020import java.util.LinkedList;
021import java.util.List;
022
023/**
024 * <p>
025 * A simple data class used by {@link ExpressionEngine} to store
026 * the results of the {@code prepareAdd()} operation.
027 * </p>
028 * <p>
029 * If a new property is to be added to a configuration, the affected
030 * {@code Configuration} object must know, where in its hierarchy of
031 * configuration nodes new elements have to be added. This information is
032 * obtained by an {@code ExpressionEngine} object that interprets the key
033 * of the new property. This expression engine will pack all information
034 * necessary for the configuration to perform the add operation in an instance
035 * of this class.
036 * </p>
037 * <p>
038 * Information managed by this class contains:
039 * <ul>
040 * <li>the configuration node, to which new elements must be added</li>
041 * <li>the name of the new node</li>
042 * <li>whether the new node is a child node or an attribute node</li>
043 * <li>if a whole branch is to be added at once, the names of all nodes between
044 * the parent node (the target of the add operation) and the new node</li>
045 * </ul>
046 * </p>
047 *
048 * @since 1.3
049 * @author <a
050 * href="http://commons.apache.org/configuration/team-list.html">Commons
051 * Configuration team</a>
052 * @version $Id: NodeAddData.java 1234988 2012-01-23 21:12:15Z oheger $
053 */
054public class NodeAddData
055{
056    /** Stores the parent node of the add operation. */
057    private ConfigurationNode parent;
058
059    /**
060     * Stores a list with nodes that are on the path between the parent node and
061     * the new node.
062     */
063    private List<String> pathNodes;
064
065    /** Stores the name of the new node. */
066    private String newNodeName;
067
068    /** Stores the attribute flag. */
069    private boolean attribute;
070
071    /**
072     * Creates a new, uninitialized instance of {@code NodeAddData}.
073     */
074    public NodeAddData()
075    {
076        this(null, null);
077    }
078
079    /**
080     * Creates a new instance of {@code NodeAddData} and sets the most
081     * important data fields.
082     *
083     * @param parent the parent node
084     * @param nodeName the name of the new node
085     */
086    public NodeAddData(ConfigurationNode parent, String nodeName)
087    {
088        setParent(parent);
089        setNewNodeName(nodeName);
090    }
091
092    /**
093     * Returns a flag if the new node to be added is an attribute.
094     *
095     * @return <b>true</b> for an attribute node, <b>false</b> for a child
096     * node
097     */
098    public boolean isAttribute()
099    {
100        return attribute;
101    }
102
103    /**
104     * Sets the attribute flag. This flag determines whether an attribute or a
105     * child node will be added.
106     *
107     * @param attribute the attribute flag
108     */
109    public void setAttribute(boolean attribute)
110    {
111        this.attribute = attribute;
112    }
113
114    /**
115     * Returns the name of the new node.
116     *
117     * @return the new node's name
118     */
119    public String getNewNodeName()
120    {
121        return newNodeName;
122    }
123
124    /**
125     * Sets the name of the new node. A node with this name will be added to the
126     * configuration's node hierarchy.
127     *
128     * @param newNodeName the name of the new node
129     */
130    public void setNewNodeName(String newNodeName)
131    {
132        this.newNodeName = newNodeName;
133    }
134
135    /**
136     * Returns the parent node.
137     *
138     * @return the parent node
139     */
140    public ConfigurationNode getParent()
141    {
142        return parent;
143    }
144
145    /**
146     * Sets the parent node. New nodes will be added to this node.
147     *
148     * @param parent the parent node
149     */
150    public void setParent(ConfigurationNode parent)
151    {
152        this.parent = parent;
153    }
154
155    /**
156     * Returns a list with further nodes that must be added. This is needed if a
157     * complete branch is to be added at once. For instance imagine that there
158     * exists only a node {@code database}. Now the key
159     * {@code database.connection.settings.username} (assuming the syntax
160     * of the default expression engine) is to be added. Then
161     * {@code username} is the name of the new node, but the nodes
162     * {@code connection} and {@code settings} must be added to
163     * the parent node first. In this example these names would be returned by
164     * this method.
165     *
166     * @return a list with the names of nodes that must be added as parents of
167     * the new node (never <b>null</b>)
168     */
169    public List<String> getPathNodes()
170    {
171        if (pathNodes != null)
172        {
173            return Collections.unmodifiableList(pathNodes);
174        }
175        else
176        {
177            return Collections.emptyList();
178        }
179    }
180
181    /**
182     * Adds the name of a path node. With this method an additional node to be
183     * added can be defined.
184     *
185     * @param nodeName the name of the node
186     * @see #getPathNodes()
187     */
188    public void addPathNode(String nodeName)
189    {
190        if (pathNodes == null)
191        {
192            pathNodes = new LinkedList<String>();
193        }
194        pathNodes.add(nodeName);
195    }
196}