2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.binding;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
14 import org.opendaylight.yangtools.concepts.Builder;
15 import org.opendaylight.yangtools.concepts.Immutable;
16 import org.opendaylight.yangtools.concepts.Path;
19 * Uniquely identifies data location in the overall of data tree
24 public final class InstanceIdentifier<T extends DataObject> implements Path<InstanceIdentifier<?>>,Immutable {
26 private final List<PathArgument> path;
27 private final Class<T> targetType;
29 public InstanceIdentifier(Class<T> type) {
30 path = Collections.<PathArgument> singletonList(new Item<>(type));
31 this.targetType = type;
34 public InstanceIdentifier(List<PathArgument> path, Class<T> type) {
35 this.path = Collections.<PathArgument> unmodifiableList(new ArrayList<>(path));
36 this.targetType = type;
43 public List<PathArgument> getPath() {
47 public Class<T> getTargetType() {
48 return this.targetType;
52 public String toString() {
53 return "InstanceIdentifier [path=" + path + "]";
57 * Path argument of {@link InstanceIdentifier}.
59 * Interface which implementations are used as path components of the
60 * path in overall data tree.
63 public interface PathArgument {
65 Class<? extends DataObject> getType();
69 public static final class Item<T extends DataObject> implements PathArgument {
70 private final Class<T> type;
72 public Item(Class<T> type) {
76 public Class<T> getType() {
81 public int hashCode() {
84 result = prime * result + ((type == null) ? 0 : type.hashCode());
89 public boolean equals(Object obj) {
94 if (getClass() != obj.getClass())
96 Item<?> other = (Item<?>) obj;
98 if (other.type != null)
100 } else if (!type.equals(other.type))
106 public String toString() {
107 return type.getName();
111 public static final class IdentifiableItem<I extends Identifiable<T> & DataObject, T extends Identifier<I>> implements
115 private final Class<I> type;
117 public IdentifiableItem(Class<I> type, T key) {
119 throw new IllegalArgumentException("Type must not be null.");
121 throw new IllegalArgumentException("Key must not be null.");
131 public Class<I> getType() {
136 public boolean equals(Object obj) {
140 if (obj.hashCode() != hashCode()) {
143 if (!(obj instanceof IdentifiableItem<?, ?>)) {
146 IdentifiableItem<?, ?> foreign = (IdentifiableItem<?, ?>) obj;
147 return key.equals(foreign.getKey());
151 public int hashCode() {
152 return key.hashCode();
156 public String toString() {
157 return type.getName() + "[key=" + key + "]";
161 public interface InstanceIdentifierBuilder<T extends DataObject> extends Builder<InstanceIdentifier<T>> {
163 <N extends DataObject> InstanceIdentifierBuilder<N> node(Class<N> container);
165 <N extends Identifiable<K> & DataObject, K extends Identifier<N>> InstanceIdentifierBuilder<N> node(
166 Class<N> listItem, K listKey);
168 <N extends ChildOf<? super T>> InstanceIdentifierBuilder<N> child(Class<N> container);
170 <N extends Identifiable<K> & ChildOf<? super T>, K extends Identifier<N>> InstanceIdentifierBuilder<N> child(
171 Class<N> listItem, K listKey);
175 @SuppressWarnings("rawtypes")
176 public static InstanceIdentifierBuilder<?> builder() {
177 return new BuilderImpl();
180 @SuppressWarnings({ "rawtypes", "unchecked" })
181 public static InstanceIdentifierBuilder<?> builder(InstanceIdentifier<?> basePath) {
182 return new BuilderImpl(basePath.path,basePath.targetType);
185 private static final class BuilderImpl<T extends DataObject> implements InstanceIdentifierBuilder<T> {
187 private List<PathArgument> path;
188 private Class<? extends DataObject> target = null;
190 public BuilderImpl() {
191 this.path = new ArrayList<>();
195 public BuilderImpl(List<? extends PathArgument> prefix,Class<? extends DataObject> target) {
196 this.path = new ArrayList<>(prefix);
197 this.target = target;
200 @SuppressWarnings({ "unchecked", "rawtypes" })
202 public InstanceIdentifier<T> toInstance() {
203 List<PathArgument> immutablePath = Collections.unmodifiableList(new ArrayList<PathArgument>(path));
204 return new InstanceIdentifier(immutablePath, target);
208 @SuppressWarnings("unchecked")
209 public <N extends DataObject> InstanceIdentifierBuilder<N> node(Class<N> container) {
211 path.add(new Item<N>(container));
212 return (InstanceIdentifierBuilder<N>) this;
216 @SuppressWarnings("unchecked")
217 public <N extends DataObject & Identifiable<K> , K extends Identifier<N>> InstanceIdentifierBuilder<N> node(
218 Class<N> listItem, K listKey) {
220 path.add(new IdentifiableItem<N, K>(listItem, listKey));
221 return (InstanceIdentifierBuilder<N>) this;
225 public <N extends ChildOf<? super T>> InstanceIdentifierBuilder<N> child(Class<N> container) {
226 return node(container);
230 public <N extends Identifiable<K> & ChildOf<? super T>, K extends Identifier<N>> InstanceIdentifierBuilder<N> child(
231 Class<N> listItem, K listKey) {
232 return node(listItem,listKey);
237 public int hashCode() {
238 final int prime = 31;
240 result = prime * result + ((path == null) ? 0 : path.hashCode());
245 public boolean equals(Object obj) {
252 if (getClass() != obj.getClass()) {
255 InstanceIdentifier<?> other = (InstanceIdentifier<?>) obj;
257 if (other.path != null) {
260 } else if (!path.equals(other.path)) {
267 public boolean contains(final InstanceIdentifier<?> other) {
269 throw new IllegalArgumentException("other should not be null");
271 final int localSize = this.path.size();
272 final List<PathArgument> otherPath = other.getPath();
273 if(localSize > other.path.size()) {
276 for(int i = 0;i<localSize;i++ ) {
277 if(!path.get(i).equals(otherPath.get(i))) {