Merge "BUG-981: remove deprecated elements"
[yangtools.git] / yang / yang-model-api / src / main / java / org / opendaylight / yangtools / yang / model / api / SchemaPath.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.model.api;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableList;
12 import com.google.common.collect.Iterables;
13 import java.util.Arrays;
14 import java.util.List;
15 import org.opendaylight.yangtools.yang.common.QName;
16
17 /**
18  *
19  * Represents unique path to the every node inside the module.
20  *
21  */
22 public class SchemaPath {
23     /**
24      * Shared instance of the conceptual root schema node.
25      */
26     public static final SchemaPath ROOT = new SchemaPath(ImmutableList.<QName> of(), true, null);
27
28     /**
29      * Shared instance of the "same" relative schema node.
30      */
31     public static final SchemaPath SAME = new SchemaPath(ImmutableList.<QName> of(), false, null);
32
33     /**
34      * List of QName instances which represents complete path to the node.
35      */
36     private final ImmutableList<QName> path;
37
38     /**
39      * Boolean value which represents type of schema path (relative or
40      * absolute).
41      */
42     private final Boolean absolute;
43
44     /**
45      * Constructs new instance of this class with the concrete path.
46      *
47      * @param path
48      *            list of QName instances which specifies exact path to the
49      *            module node
50      * @param absolute
51      *            boolean value which specifies if the path is absolute or
52      *            relative
53      *
54      * @deprecated Use {@link #create(Iterable, boolean)} instead.
55      */
56     @Deprecated
57     public SchemaPath(final List<QName> path, final boolean absolute) {
58         this(ImmutableList.copyOf(path), absolute, null);
59     }
60
61     /**
62      * Returns the complete path to schema node.
63      *
64      * @return list of <code>QName</code> instances which represents complete
65      *         path to schema node
66      *
67      * @deprecated Use {@link #getPathFromRoot()} instead.
68      */
69     @Deprecated
70     public List<QName> getPath() {
71         return path;
72     }
73
74     private SchemaPath(final ImmutableList<QName> path, final boolean absolute, final Void dummy) {
75         this.path = Preconditions.checkNotNull(path);
76         this.absolute = absolute;
77     }
78
79     /**
80      * Constructs new instance of this class with the concrete path.
81      *
82      * @param path
83      *            list of QName instances which specifies exact path to the
84      *            module node
85      * @param absolute
86      *            boolean value which specifies if the path is absolute or
87      *            relative
88      *
89      * @return A SchemaPath instance.
90      */
91     public static SchemaPath create(final Iterable<QName> path, final boolean absolute) {
92         if (Iterables.isEmpty(path)) {
93             return absolute ? ROOT : SAME;
94         } else {
95             return new SchemaPath(ImmutableList.copyOf(path), absolute, null);
96         }
97     }
98
99     /**
100      * Constructs new instance of this class with the concrete path.
101      *
102      * @param absolute
103      *            boolean value which specifies if the path is absolute or
104      *            relative
105      * @param path
106      *            one or more QName instances which specifies exact path to the
107      *            module node
108      *
109      * @return A SchemaPath instance.
110      */
111     public static SchemaPath create(final boolean absolute, final QName... path) {
112         return create(Arrays.asList(path), absolute);
113     }
114
115     /**
116      * Create a child path based on concatenation of this path and a relative path.
117      *
118      * @param relative Relative path
119      * @return A new child path
120      */
121     public SchemaPath createChild(final Iterable<QName> relative) {
122         if (Iterables.isEmpty(relative)) {
123             return this;
124         }
125         return create(Iterables.concat(path, relative), absolute);
126     }
127
128     /**
129      * Create a child path based on concatenation of this path and a relative path.
130      *
131      * @param relative Relative SchemaPath
132      * @return A new child path
133      */
134     public SchemaPath createChild(final SchemaPath relative) {
135         Preconditions.checkArgument(!relative.isAbsolute(), "Child creation requires relative path");
136         return createChild(relative.path);
137     }
138
139     /**
140      * Create a child path based on concatenation of this path and additional
141      * path elements.
142      *
143      * @param elements Relative SchemaPath elements
144      * @return A new child path
145      */
146     public SchemaPath createChild(final QName... elements) {
147         return createChild(Arrays.asList(elements));
148     }
149
150     /**
151      * Returns the list of nodes which need to be traversed to get from the
152      * starting point (root for absolute SchemaPaths) to the node represented
153      * by this object.
154      *
155      * @return list of <code>qname</code> instances which represents
156      *         path from the root to the schema node.
157      */
158     public Iterable<QName> getPathFromRoot() {
159         return path;
160     }
161
162     /**
163      * Returns the list of nodes which need to be traversed to get from this
164      * node to the starting point (root for absolute SchemaPaths).
165      *
166      * @return list of <code>qname</code> instances which represents
167      *         path from the schema node towards the root.
168      */
169     public Iterable<QName> getPathTowardsRoot() {
170         return path.reverse();
171     }
172
173     /**
174      * Describes whether schema path is|isn't absolute.
175      *
176      * @return boolean value which is <code>true</code> if schema path is
177      *         absolute.
178      */
179     public boolean isAbsolute() {
180         return absolute;
181     }
182
183     @Override
184     public int hashCode() {
185         final int prime = 31;
186         int result = 1;
187         result = prime * result + absolute.hashCode();
188
189         // TODO: Temporary fix for Bug 1076 - hash computation
190         // Which adds same behaviour as using List.hashCode().
191         int pathHash = 1;
192         for (Object o : path) {
193             pathHash = prime * pathHash + o.hashCode();
194         }
195         result = prime * result + pathHash;
196         return result;
197     }
198
199     @Override
200     public boolean equals(final Object obj) {
201         if (this == obj) {
202             return true;
203         }
204         if (obj == null) {
205             return false;
206         }
207         if (getClass() != obj.getClass()) {
208             return false;
209         }
210         SchemaPath other = (SchemaPath) obj;
211         if (absolute != other.absolute) {
212             return false;
213         }
214
215         return Iterables.elementsEqual(path, other.path);
216     }
217
218     @Override
219     public String toString() {
220         StringBuilder builder = new StringBuilder();
221         builder.append("SchemaPath [path=");
222         builder.append(path);
223         builder.append(", absolute=");
224         builder.append(absolute);
225         builder.append("]");
226         return builder.toString();
227     }
228 }