001/*
002 * Configurate
003 * Copyright (C) zml and Configurate contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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.spongepowered.configurate;
018
019import java.util.Collection;
020import java.util.Iterator;
021
022/**
023 * Represents the path to a given node.
024 *
025 * @since 4.0.0
026 */
027public interface NodePath extends Iterable<Object> {
028
029    /**
030     * Create a node path reference.
031     *
032     * @param path the path to reference. The provided array will be copied.
033     * @return the path instance
034     * @since 4.0.0
035     */
036    static NodePath of(Object[] path) {
037        if (path.length == 0) {
038            return NodePathImpl.EMPTY;
039        } else {
040            return new NodePathImpl(path, true);
041        }
042    }
043
044    /**
045     * Create a node path reference.
046     *
047     * @param path a collection containing elements of the path to reference
048     * @return the path instance
049     * @since 4.0.0
050     */
051    static NodePath of(Collection<?> path) {
052        if (path.isEmpty()) {
053            return NodePathImpl.EMPTY;
054        } else {
055            return new NodePathImpl(path.toArray(), false);
056        }
057    }
058
059    /**
060     * Create a node path reference.
061     *
062     * <p>This overload takes varargs, and is designed to be imported statically
063     * to create paths.
064     *
065     * @param elements the path to reference. The provided array will be copied.
066     * @return the path instance
067     * @since 4.0.0
068     */
069    static NodePath path(Object... elements) {
070        return of(elements);
071    }
072
073    /**
074     * Get an empty node path. This refers to the root node.
075     *
076     * @return the empty path
077     * @since 4.0.0
078     */
079    static NodePath path() {
080        return NodePathImpl.EMPTY;
081    }
082
083    /**
084     * Gets a specific element from the path array.
085     *
086     * @param i the index to get
087     * @return object at the index
088     * @since 4.0.0
089     */
090    Object get(int i);
091
092    /**
093     * Gets the length of the path.
094     *
095     * @return length of the path array
096     * @since 4.0.0
097     */
098    int size();
099
100    /**
101     * Returns a copy of the original path array.
102     *
103     * @return the copied array
104     * @since 4.0.0
105     */
106    Object[] array();
107
108    /**
109     * Create a new path with the provided element appended to the end.
110     *
111     * @param childKey the new key to append
112     * @return a new path object reflecting the extended path
113     * @since 4.0.0
114     */
115    NodePath withAppendedChild(Object childKey);
116
117    /**
118     * Create a new path with the value at {@code index} replaced
119     * with {@code value}.
120     *
121     * @param index position to change
122     * @param value value to insert
123     * @return new path object with changed value
124     * @throws IndexOutOfBoundsException if index &lt; 0 or &ge; {@linkplain #size()}
125     * @since 4.0.0
126     */
127    NodePath with(int index, Object value) throws IndexOutOfBoundsException;
128
129    /**
130     * Create a new path from the combination of {@code this} and {@code other}.
131     *
132     * @param other the path to append
133     * @return a new path, containing the elements of this path followed by the
134     *      elements of {@code other}.
135     * @since 4.1.0
136     */
137    NodePath plus(NodePath other);
138
139    /**
140     * Returns an iterator over the path.
141     *
142     * @return an iterator of the path elements
143     * @since 4.0.0
144     */
145    @Override
146    Iterator<Object> iterator();
147
148    /**
149     * Create a new node path with the same data as this path.
150     *
151     * @return a new path
152     * @since 4.0.0
153     */
154    NodePath copy();
155
156}