X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-binding%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fbinding%2FInstanceIdentifier.java;h=16a06e139f70c89c4daa361b9e0a5c47af3cd5b8;hb=d8fd3315a670972425a89e5984e71678839c9749;hp=42cc11a5540bfb855f37b951b399567ac991667c;hpb=5c1f875f69e35248aa4115c429bd962160beeef4;p=yangtools.git diff --git a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java index 42cc11a554..16a06e139f 100644 --- a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java +++ b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java @@ -7,13 +7,409 @@ */ package org.opendaylight.yangtools.yang.binding; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.concepts.Immutable; +import org.opendaylight.yangtools.concepts.Path; + +import com.google.common.collect.Iterables; + /** - * Created with IntelliJ IDEA. - * User: lsedlak - * Date: 27.6.2013 - * Time: 11:44 - * To change this template use File | Settings | File Templates. + * Uniquely identifies data location in the overall of data tree + * modeled by YANG. + * + * */ -public class InstanceIdentifier { +public final class InstanceIdentifier implements Path>,Immutable { + + private final List path; + private final Class targetType; + + public InstanceIdentifier(Class type) { + path = Collections. singletonList(new Item<>(type)); + this.targetType = type; + } + + public InstanceIdentifier(List path, Class type) { + this.path = Collections. unmodifiableList(new ArrayList<>(path)); + this.targetType = type; + } + + /** + * + * @return path + */ + public List getPath() { + return getPathArguments(); + } + + public List getPathArguments() { + return this.path; + } + + public Class getTargetType() { + return this.targetType; + } + + @Override + public String toString() { + return "InstanceIdentifier [path=" + path + "]"; + } + + /** + * Return an instance identifier trimmed at the first occurrence of a + * specific component type. + * + * @param type component type + * @return trimmed instance identifier, or null if the component type + * is not present. + */ + public InstanceIdentifier firstIdentifierOf(final Class type) { + int i = 1; + for (final PathArgument a : path) { + if (type.equals(a.getType())) { + return new InstanceIdentifier<>(path.subList(0, i), type); + } + + ++i; + } + + return null; + } + + /** + * Return the key associated with the first component of specified type in + * an identifier. + * + * @param listItem component type + * @param listKey component key type + * @return key associated with the component, or null if the component type + * is not present. + */ + public & DataObject, K extends Identifier> K firstKeyOf(final Class listItem, final Class listKey) { + for (PathArgument i : path) { + if (listItem.equals(i.getType())) { + @SuppressWarnings("unchecked") + final K ret = ((IdentifiableItem)i).getKey(); + return ret; + } + } + + return null; + } + + /** + * Return the key associated with the last component of the specified identifier. + * + * @param id instance identifier + * @return key associated with the last component + */ + public static & DataObject, K extends Identifier> K keyOf(final InstanceIdentifier id) { + @SuppressWarnings("unchecked") + final K ret = ((IdentifiableItem)Iterables.getLast(id.getPath())).getKey(); + return ret; + } + + /** + * Path argument of {@link InstanceIdentifier}. + *

+ * Interface which implementations are used as path components of the + * path in overall data tree. + * + */ + public interface PathArgument { + + Class getType(); + + } + + public static final class Item implements PathArgument { + private final Class type; + + public Item(Class type) { + this.type = type; + } + + public Class getType() { + return type; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Item other = (Item) obj; + if (type == null) { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + return true; + } + + @Override + public String toString() { + return type.getName(); + } + } + + public static final class IdentifiableItem & DataObject, T extends Identifier> implements + PathArgument { + + private final T key; + private final Class type; + + public IdentifiableItem(Class type, T key) { + if (type == null) + throw new IllegalArgumentException("Type must not be null."); + if (key == null) + throw new IllegalArgumentException("Key must not be null."); + this.type = type; + this.key = key; + } + + public T getKey() { + return this.key; + } + + @Override + public Class getType() { + return this.type; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj.hashCode() != hashCode()) { + return false; + } + if (!(obj instanceof IdentifiableItem)) { + return false; + } + IdentifiableItem foreign = (IdentifiableItem) obj; + return key.equals(foreign.getKey()); + } + + @Override + public int hashCode() { + return key.hashCode(); + } + + @Override + public String toString() { + return type.getName() + "[key=" + key + "]"; + } + } + + public interface InstanceIdentifierBuilder extends Builder> { + /** + * @deprecated use {@link child(Class)} or {@link augmentation(Class)} instead. + */ + @Deprecated + InstanceIdentifierBuilder node(Class container); + + /** + * @deprecated use {@link child(Class,Identifier)} or {@link augmentation(Class,Identifier)} instead. + */ + @Deprecated + & DataObject, K extends Identifier> InstanceIdentifierBuilder node( + Class listItem, K listKey); + + > InstanceIdentifierBuilder child(Class container); + + & ChildOf, K extends Identifier> InstanceIdentifierBuilder child( + Class listItem, K listKey); + + > InstanceIdentifierBuilder augmentation(Class container); + + InstanceIdentifier build(); + + } + + /** + * @deprecated use {@link builder(Class)} or {@link builder(Class,Identifier)} instead. + */ + @Deprecated + @SuppressWarnings("rawtypes") + public static InstanceIdentifierBuilder builder() { + return new BuilderImpl(); + } + + public static > InstanceIdentifierBuilder builder(Class container) { + return new BuilderImpl().addNode(container); + } + + public static & ChildOf, K extends Identifier> InstanceIdentifierBuilder builder( + Class listItem, K listKey) { + return new BuilderImpl().addNode(listItem, listKey); + } + + public static InstanceIdentifierBuilder builder(InstanceIdentifier basePath) { + return new BuilderImpl(basePath.path,basePath.targetType); + } + + private static final class BuilderImpl implements InstanceIdentifierBuilder { + + private List path; + private Class target = null; + + public BuilderImpl() { + this.path = new ArrayList<>(); + } + + public BuilderImpl(List prefix,Class target) { + this.path = new ArrayList<>(prefix); + this.target = target; + } + + @SuppressWarnings("unchecked") + private InstanceIdentifierBuilder addNode(Class container) { + target = container; + path.add(new Item(container)); + return (InstanceIdentifierBuilder) this; + } + + @SuppressWarnings("unchecked") + private , K extends Identifier> InstanceIdentifierBuilder addNode( + Class listItem, K listKey) { + target = listItem; + path.add(new IdentifiableItem(listItem, listKey)); + return (InstanceIdentifierBuilder) this; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public InstanceIdentifier toInstance() { + List immutablePath = Collections.unmodifiableList(new ArrayList(path)); + return new InstanceIdentifier(immutablePath, target); + } + + @Override + public InstanceIdentifier build() { + return toInstance(); + } + + @Override + public InstanceIdentifierBuilder node(Class container) { + return addNode(container); + } + + @Override + public , K extends Identifier> InstanceIdentifierBuilder node( + Class listItem, K listKey) { + return addNode(listItem, listKey); + } + + @Override + public > InstanceIdentifierBuilder child(Class container) { + return addNode(container); + } + + @Override + public & ChildOf, K extends Identifier> InstanceIdentifierBuilder child( + Class listItem, K listKey) { + return addNode(listItem,listKey); + } + + @Override + public > InstanceIdentifierBuilder augmentation( + Class container) { + return addNode(container); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((path == null) ? 0 : path.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + InstanceIdentifier other = (InstanceIdentifier) obj; + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + return true; + } + + @Override + public boolean contains(final InstanceIdentifier other) { + if(other == null) { + throw new IllegalArgumentException("other should not be null"); + } + final int localSize = this.path.size(); + final List otherPath = other.getPath(); + if(localSize > other.path.size()) { + return false; + } + for(int i = 0;i other) { + if(other == null) { + throw new IllegalArgumentException("other should not be null"); + } + final int localSize = this.path.size(); + final List otherPath = other.getPath(); + if(localSize > other.path.size()) { + return false; + } + for(int i = 0;i && !localArgument.equals(otherPath.get(i))) { + return false; + } + } + return true; + } + public boolean isWildcarded() { + for(PathArgument pathArgument : path) { + if(Identifiable.class.isAssignableFrom(pathArgument.getType()) && !(pathArgument instanceof IdentifiableItem)) { + return true; + } + } + return false; + } }