X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-api%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fapi%2FYangInstanceIdentifier.java;h=a582e5c32a3e1f0855bfbaad0a9685172ff42464;hb=0d55e5ea183d9fc7ff8e7acc72e9172e90836662;hp=e9f940a4555bad2af63797018916240a4209d3a3;hpb=153362f50d57c7e3b39e07b626d8acf238aa88ed;p=yangtools.git diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java index e9f940a455..a582e5c32a 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java @@ -8,24 +8,22 @@ package org.opendaylight.yangtools.yang.data.api; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - import java.io.Serializable; import java.lang.reflect.Array; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; - +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.concepts.Path; @@ -64,32 +62,47 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; * * * - * @see http://tools.ietf.org/html/rfc6020#section-9.13 + * @see RFC6020 */ -public final class YangInstanceIdentifier implements Path, Immutable, Serializable { - private static final YangInstanceIdentifier EMPTY = trustedCreate(Collections.emptyList()); +public abstract class YangInstanceIdentifier extends IterablePathArguments implements Path, Immutable, Serializable { + /** + * An empty {@link YangInstanceIdentifier}. It corresponds to the path of the conceptual + * root of the YANG namespace. + */ + public static final YangInstanceIdentifier EMPTY = FixedYangInstanceIdentifier.EMPTY_INSTANCE; - private static final long serialVersionUID = 2L; - private final Iterable pathArguments; - private final int hash; + private static final AtomicReferenceFieldUpdater TOSTRINGCACHE_UPDATER = + AtomicReferenceFieldUpdater.newUpdater(YangInstanceIdentifier.class, String.class, "toStringCache"); + private static final long serialVersionUID = 4L; - private transient volatile ImmutableList legacyPath = null; + private final int hash; private transient volatile String toStringCache = null; - private final ImmutableList getLegacyPath() { - // Temporary variable saves a volatile read - ImmutableList ret = legacyPath; - if (ret == null) { - synchronized (this) { - // We could have used a synchronized block, but let's just not bother - ret = ImmutableList.copyOf(pathArguments); - legacyPath = ret; - } - } - - return ret; + // Package-private to prevent outside subclassing + YangInstanceIdentifier(final int hash) { + this.hash = hash; } + @Nonnull abstract YangInstanceIdentifier createRelativeIdentifier(int skipFromRoot); + @Nonnull abstract Collection tryPathArguments(); + @Nonnull abstract Collection tryReversePathArguments(); + + /** + * Check if this instance identifier has empty path arguments, e.g. it is + * empty and corresponds to {@link #EMPTY}. + * + * @return True if this instance identifier is empty, false otherwise. + */ + public abstract boolean isEmpty(); + + /** + * Return the conceptual parent {@link YangInstanceIdentifier}, which has + * one item less in {@link #getPathArguments()}. + * + * @return Parent {@link YangInstanceIdentifier}, or null if this is object is {@link #EMPTY}. + */ + @Nullable public abstract YangInstanceIdentifier getParent(); + /** * Returns a list of path arguments. * @@ -97,18 +110,15 @@ public final class YangInstanceIdentifier implements Path getPath() { - return getLegacyPath(); - } + public abstract List getPath(); /** * Returns an ordered iteration of path arguments. * * @return Immutable iteration of path arguments. */ - public Iterable getPathArguments() { - return pathArguments; - } + @Override + public abstract Collection getPathArguments(); /** * Returns an iterable of path arguments in reverse order. This is useful @@ -116,9 +126,8 @@ public final class YangInstanceIdentifier implements Path getReversePathArguments() { - return getLegacyPath().reverse(); - } + @Override + public abstract Collection getReversePathArguments(); /** * Returns the last PathArgument. This is equivalent of iterating @@ -126,39 +135,28 @@ public final class YangInstanceIdentifier implements Path path, final int hash) { - this.pathArguments = Preconditions.checkNotNull(path, "path must not be null."); - this.hash = hash; - } + public static YangInstanceIdentifier create(final Iterable path) { + if (Iterables.isEmpty(path)) { + return EMPTY; + } - private static final YangInstanceIdentifier trustedCreate(final Iterable path) { final HashCodeBuilder hash = new HashCodeBuilder<>(); for (PathArgument a : path) { hash.addArgument(a); } - return new YangInstanceIdentifier(path, hash.toInstance()); - } - - public static final YangInstanceIdentifier create(final Iterable path) { - if (Iterables.isEmpty(path)) { - return EMPTY; - } - - return trustedCreate(ImmutableList.copyOf(path)); + return FixedYangInstanceIdentifier.create(path, hash.build()); } - public static final YangInstanceIdentifier create(final PathArgument... path) { + public static YangInstanceIdentifier create(final PathArgument... path) { // We are forcing a copy, since we cannot trust the user return create(Arrays.asList(path)); } @Override - public int hashCode() { + public final int hashCode() { /* * The caching is safe, since the object contract requires * immutability of the object and all objects referenced from this @@ -169,22 +167,24 @@ public final class YangInstanceIdentifier implements Path relativeTo(final YangInstanceIdentifier ancestor) { - final Iterator lit = pathArguments.iterator(); - final Iterator oit = ancestor.pathArguments.iterator(); + final Iterator lit = getPathArguments().iterator(); + final Iterator oit = ancestor.getPathArguments().iterator(); int common = 0; while (oit.hasNext()) { @@ -237,7 +237,8 @@ public final class YangInstanceIdentifier implements Path { /** @@ -447,7 +442,14 @@ public final class YangInstanceIdentifier implements Path entry : keyValues.entrySet()) { @@ -548,9 +550,9 @@ public final class YangInstanceIdentifier implements PathRFC6020 */ public static final class AugmentationIdentifier implements PathArgument { private static final long serialVersionUID = -8122335594681936939L; @@ -611,18 +613,6 @@ public final class YangInstanceIdentifier implements Path childNames) { - this(childNames); - } - /** * Returns set of all possible child nodes * @@ -634,7 +624,7 @@ public final class YangInstanceIdentifier implements Path lit = pathArguments.iterator(); - final Iterator oit = other.pathArguments.iterator(); + final Iterator lit = getPathArguments().iterator(); + final Iterator oit = other.getPathArguments().iterator(); while (lit.hasNext()) { if (!oit.hasNext()) { @@ -759,7 +699,7 @@ public final class YangInstanceIdentifier implements Path