X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fyang-binding%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fbinding%2FInstanceIdentifier.java;h=0c89142533d5c337fc8a503337f7b5b949fc8177;hb=eb7ab8e1bb6a28cfafd22a5a62ea66e5f85a8c2d;hp=cf69f763d9c124ce471afa609f6fac8618879e32;hpb=b515bd997a4afe8b0f1b9bbe0b585d3330503e4e;p=mdsal.git diff --git a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java index cf69f763d9..0c89142533 100644 --- a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java +++ b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java @@ -8,10 +8,13 @@ package org.opendaylight.yangtools.yang.binding; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Verify.verify; +import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.common.base.VerifyException; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -23,9 +26,7 @@ import java.util.Objects; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.concepts.Immutable; -import org.opendaylight.yangtools.concepts.Path; +import org.opendaylight.yangtools.concepts.HierarchicalIdentifier; import org.opendaylight.yangtools.util.HashCodeBuilder; /** @@ -59,8 +60,8 @@ import org.opendaylight.yangtools.util.HashCodeBuilder; *

* This would be the same as using a path like so, "/nodes/node/openflow:1" to refer to the openflow:1 node */ -public class InstanceIdentifier implements Path>, - Immutable, Serializable { +public class InstanceIdentifier + implements HierarchicalIdentifier> { private static final long serialVersionUID = 3L; /* @@ -90,6 +91,20 @@ public class InstanceIdentifier implements Path @NonNull InstanceIdentifier verifyTarget(final Class<@NonNull N> target) { + verify(target.equals(targetType), "Cannot adapt %s to %s", this, target); + return (InstanceIdentifier) this; + } + /** * Return the path argument chain which makes up this instance identifier. * @@ -201,7 +216,8 @@ public class InstanceIdentifier implements Path @Nullable InstanceIdentifier firstIdentifierOf(final Class type) { + public final @Nullable InstanceIdentifier firstIdentifierOf( + final Class<@NonNull I> type) { int count = 1; for (final PathArgument a : pathArguments) { if (type.equals(a.getType())) { @@ -226,7 +242,7 @@ public class InstanceIdentifier implements Path & DataObject, K extends Identifier> @Nullable K firstKeyOf( - final Class listItem) { + final Class<@NonNull N> listItem) { for (final PathArgument i : pathArguments) { if (listItem.equals(i.getType())) { @SuppressWarnings("unchecked") @@ -325,7 +341,8 @@ public class InstanceIdentifier implements Path> @NonNull InstanceIdentifier child(final Class container) { + public final > @NonNull InstanceIdentifier child( + final Class<@NonNull N> container) { return childIdentifier(Item.of(container)); } @@ -342,7 +359,7 @@ public class InstanceIdentifier implements Path & ChildOf, K extends Identifier> - @NonNull KeyedInstanceIdentifier child(final Class listItem, final K listKey) { + @NonNull KeyedInstanceIdentifier child(final Class<@NonNull N> listItem, final K listKey) { return (KeyedInstanceIdentifier) childIdentifier(IdentifiableItem.of(listItem, listKey)); } @@ -357,8 +374,9 @@ public class InstanceIdentifier implements Path & DataObject, N extends ChildOf> - @NonNull InstanceIdentifier child(final Class caze, final Class container) { + @NonNull InstanceIdentifier child(final Class<@NonNull C> caze, final Class<@NonNull N> container) { return childIdentifier(Item.of(caze, container)); } @@ -375,10 +393,11 @@ public class InstanceIdentifier implements Path & DataObject, K extends Identifier, N extends Identifiable & ChildOf> @NonNull KeyedInstanceIdentifier child( - final Class caze, final Class listItem, final K listKey) { + final Class<@NonNull C> caze, final Class<@NonNull N> listItem, final K listKey) { return (KeyedInstanceIdentifier) childIdentifier(IdentifiableItem.of(caze, listItem, listKey)); } @@ -392,7 +411,7 @@ public class InstanceIdentifier implements Path> @NonNull InstanceIdentifier augmentation( - final Class container) { + final Class<@NonNull N> container) { return childIdentifier(Item.of(container)); } @@ -401,6 +420,7 @@ public class InstanceIdentifier implements Path builder() { return new InstanceIdentifierBuilderImpl<>(Item.of(targetType), pathArguments, hash, isWildcarded()); } @@ -471,6 +491,36 @@ public class InstanceIdentifier implements Path().addNode(IdentifiableItem.of(caze, listItem, listKey)); } + public static > + @NonNull InstanceIdentifierBuilder builderOfInherited(final Class root, final Class container) { + // FIXME: we are losing root identity, hence namespaces may not work correctly + return new InstanceIdentifierBuilderImpl().addWildNode(Item.of(container)); + } + + public static & DataObject, + T extends ChildOf> + @NonNull InstanceIdentifierBuilder builderOfInherited(final Class root, + final Class caze, final Class container) { + // FIXME: we are losing root identity, hence namespaces may not work correctly + return new InstanceIdentifierBuilderImpl().addWildNode(Item.of(caze, container)); + } + + public static & ChildOf, + K extends Identifier> + @NonNull InstanceIdentifierBuilder builderOfInherited(final Class root, + final Class listItem, final K listKey) { + // FIXME: we are losing root identity, hence namespaces may not work correctly + return new InstanceIdentifierBuilderImpl().addNode(IdentifiableItem.of(listItem, listKey)); + } + + public static & DataObject, + N extends Identifiable & ChildOf, K extends Identifier> + @NonNull InstanceIdentifierBuilder builderOfInherited(final Class root, + final Class caze, final Class listItem, final K listKey) { + // FIXME: we are losing root identity, hence namespaces may not work correctly + return new InstanceIdentifierBuilderImpl().addNode(IdentifiableItem.of(caze, listItem, listKey)); + } + /** * Create an instance identifier for a very specific object type. This method implements {@link #create(Iterable)} * semantics, except it is used by internal callers, which have assured that the argument is an immutable Iterable. @@ -481,24 +531,26 @@ public class InstanceIdentifier implements Path internalCreate(final Iterable pathArguments) { - final Iterator it = requireNonNull(pathArguments, "pathArguments may not be null") - .iterator(); + final var it = requireNonNull(pathArguments, "pathArguments may not be null").iterator(); + checkArgument(it.hasNext(), "pathArguments may not be empty"); + final HashCodeBuilder hashBuilder = new HashCodeBuilder<>(); boolean wildcard = false; - PathArgument arg = null; + PathArgument arg; - while (it.hasNext()) { + do { arg = it.next(); - checkArgument(arg != null, "pathArguments may not contain null elements"); + // Non-null is implied by our callers + final var type = verifyNotNull(arg).getType(); + checkArgument(ChildOf.class.isAssignableFrom(type) || Augmentation.class.isAssignableFrom(type), + "%s is not a valid path argument", type); - // TODO: sanity check ChildOf<>; hashBuilder.addArgument(arg); - if (Identifiable.class.isAssignableFrom(arg.getType()) && !(arg instanceof IdentifiableItem)) { + if (Identifiable.class.isAssignableFrom(type) && !(arg instanceof IdentifiableItem)) { wildcard = true; } - } - checkArgument(arg != null, "pathArguments may not be empty"); + } while (it.hasNext()); return trustedCreate(arg, pathArguments, hashBuilder.build(), wildcard); } @@ -518,10 +570,11 @@ public class InstanceIdentifier implements Path create(final Iterable pathArguments) { - if (pathArguments instanceof ImmutableCollection) { + if (pathArguments instanceof ImmutableCollection) { @SuppressWarnings("unchecked") - final Iterable immutableArguments = (Iterable) pathArguments; + final var immutableArguments = (ImmutableCollection) pathArguments; return internalCreate(immutableArguments); } @@ -541,9 +594,11 @@ public class InstanceIdentifier implements Path @NonNull InstanceIdentifier create(final Class type) { - return (InstanceIdentifier) create(ImmutableList.of(Item.of(type))); + public static > @NonNull InstanceIdentifier create( + final Class<@NonNull T> type) { + return (InstanceIdentifier) internalCreate(ImmutableList.of(Item.of(type))); } /** @@ -554,6 +609,7 @@ public class InstanceIdentifier implements Path & DataObject, K extends Identifier> K keyOf( final InstanceIdentifier id) { requireNonNull(id); @@ -808,18 +864,18 @@ public class InstanceIdentifier implements Path extends Builder> { + // FIXME: rename to 'Builder' + // FIXME: introduce KeyedBuilder with specialized build() method + public interface InstanceIdentifierBuilder { /** - * Append the specified container as a child of the current InstanceIdentifier referenced by the builder. - * - * This method should be used when you want to build an instance identifier by appending top-level - * elements - * - * Example, + * Append the specified container as a child of the current InstanceIdentifier referenced by the builder. This + * method should be used when you want to build an instance identifier by appending top-level elements, for + * example *

          *     InstanceIdentifier.builder().child(Nodes.class).build();
          * 
* + *

* NOTE :- The above example is only for illustration purposes InstanceIdentifier.builder() has been deprecated * and should not be used. Use InstanceIdentifier.builder(Nodes.class) instead * @@ -831,11 +887,9 @@ public class InstanceIdentifier implements Path> @NonNull InstanceIdentifierBuilder child(Class container); /** - * Append the specified container as a child of the current InstanceIdentifier referenced by the builder. - * - * This method should be used when you want to build an instance identifier by appending a container node - * to the identifier and the {@code container} is defined in a {@code grouping} used in a {@code case} - * statement. + * Append the specified container as a child of the current InstanceIdentifier referenced by the builder. This + * method should be used when you want to build an instance identifier by appending a container node to the + * identifier and the {@code container} is defined in a {@code grouping} used in a {@code case} statement. * * @param caze Choice case class * @param container Container to append @@ -848,10 +902,9 @@ public class InstanceIdentifier implements Path child(Class caze, Class container); /** - * Append the specified listItem as a child of the current InstanceIdentifier referenced by the builder. - * - * This method should be used when you want to build an instance identifier by appending a specific list element - * to the identifier + * Append the specified listItem as a child of the current InstanceIdentifier referenced by the builder. This + * method should be used when you want to build an instance identifier by appending a specific list element to + * the identifier. * * @param listItem List to append * @param listKey List key @@ -861,13 +914,12 @@ public class InstanceIdentifier implements Path & ChildOf, K extends Identifier> - @NonNull InstanceIdentifierBuilder child(Class listItem, K listKey); + @NonNull InstanceIdentifierBuilder child(Class<@NonNull N> listItem, K listKey); /** - * Append the specified listItem as a child of the current InstanceIdentifier referenced by the builder. - * - * This method should be used when you want to build an instance identifier by appending a specific list element - * to the identifier and the {@code list} is defined in a {@code grouping} used in a {@code case} statement. + * Append the specified listItem as a child of the current InstanceIdentifier referenced by the builder. This + * method should be used when you want to build an instance identifier by appending a specific list element to + * the identifier and the {@code list} is defined in a {@code grouping} used in a {@code case} statement. * * @param caze Choice case class * @param listItem List to append @@ -899,8 +951,7 @@ public class InstanceIdentifier implements Path build(); + @NonNull InstanceIdentifier build(); } private Object writeReplace() throws ObjectStreamException {