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=909305ec1bdc22a94f15c1d4a9cae6fc1d6715ed;hpb=c6845c69a7e4e47e206697801207151a39c4c866;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 909305ec1b..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,25 +8,25 @@
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;
-import java.io.IOException;
+import java.io.ObjectStreamException;
import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
-import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.concepts.Path;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.HierarchicalIdentifier;
import org.opendaylight.yangtools.util.HashCodeBuilder;
/**
@@ -60,31 +60,20 @@ 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 {
- private static final Field PATHARGUMENTS_FIELD;
- private static final long serialVersionUID = 2L;
+public class InstanceIdentifier
+ implements HierarchicalIdentifier> {
+ private static final long serialVersionUID = 3L;
+
/*
- * Protected to differentiate internal and external access. Internal
- * access is required never to modify the contents. References passed
- * to outside entities have to be wrapped in an unmodifiable view.
+ * Protected to differentiate internal and external access. Internal access is required never to modify
+ * the contents. References passed to outside entities have to be wrapped in an unmodifiable view.
*/
- protected final transient Iterable pathArguments;
- private final Class targetType;
+ final Iterable pathArguments;
+
+ private final @NonNull Class targetType;
private final boolean wildcarded;
private final int hash;
- static {
- final Field f;
- try {
- f = InstanceIdentifier.class.getDeclaredField("pathArguments");
- } catch (NoSuchFieldException | SecurityException e) {
- throw new ExceptionInInitializerError(e);
- }
- f.setAccessible(true);
- PATHARGUMENTS_FIELD = f;
- }
-
InstanceIdentifier(final Class type, final Iterable pathArguments, final boolean wildcarded,
final int hash) {
this.pathArguments = requireNonNull(pathArguments);
@@ -98,16 +87,30 @@ public class InstanceIdentifier implements Path getTargetType() {
+ public final @NonNull Class getTargetType() {
return targetType;
}
+ /**
+ * Perform a safe target type adaptation of this instance identifier to target type. This method is useful when
+ * dealing with type-squashed instances.
+ *
+ * @return Path argument with target type
+ * @throws VerifyException if this instance identifier cannot be adapted to target type
+ * @throws NullPointerException if {@code target} is null
+ */
+ @SuppressWarnings("unchecked")
+ public final @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.
*
* @return Path argument chain. Immutable and does not contain nulls.
*/
- public final Iterable getPathArguments() {
+ public final @NonNull Iterable getPathArguments() {
return Iterables.unmodifiableIterable(pathArguments);
}
@@ -213,7 +216,8 @@ public class InstanceIdentifier implements Path 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())) {
@@ -234,28 +238,11 @@ public class InstanceIdentifier implements Path & DataObject, K extends Identifier> K firstKeyOf(final Class listItem,
- final Class listKey) {
- return firstKeyOf(listItem);
- }
-
- /**
- * Return the key associated with the first component of specified type in
- * an identifier.
- *
- * @param listItem component type
- * @return key associated with the component, or null if the component type
- * is not present.
- */
- public final & DataObject, K extends Identifier> K firstKeyOf(
- final Class listItem) {
+ public final & DataObject, K extends Identifier> @Nullable K firstKeyOf(
+ final Class<@NonNull N> listItem) {
for (final PathArgument i : pathArguments) {
if (listItem.equals(i.getType())) {
@SuppressWarnings("unchecked")
@@ -340,7 +327,7 @@ public class InstanceIdentifier implements Path InstanceIdentifier childIdentifier(final AbstractPathArgument arg) {
+ private @NonNull InstanceIdentifier childIdentifier(final AbstractPathArgument arg) {
return trustedCreate(arg, Iterables.concat(pathArguments, Collections.singleton(arg)),
HashCodeBuilder.nextHashCode(hash, arg), isWildcarded());
}
@@ -354,7 +341,8 @@ public class InstanceIdentifier implements Path> InstanceIdentifier child(final Class container) {
+ public final > @NonNull InstanceIdentifier child(
+ final Class<@NonNull N> container) {
return childIdentifier(Item.of(container));
}
@@ -370,8 +358,8 @@ public class InstanceIdentifier implements Path & ChildOf super T>, K extends Identifier> KeyedInstanceIdentifier
- child(final Class listItem, final K listKey) {
+ public final & ChildOf super T>, K extends Identifier>
+ @NonNull KeyedInstanceIdentifier child(final Class<@NonNull N> listItem, final K listKey) {
return (KeyedInstanceIdentifier) childIdentifier(IdentifiableItem.of(listItem, listKey));
}
@@ -386,8 +374,9 @@ public class InstanceIdentifier implements Path & DataObject, N extends ChildOf super C>> InstanceIdentifier child(
- final Class caze, final Class container) {
+ // FIXME: add a proper caller
+ public final & DataObject, N extends ChildOf super C>>
+ @NonNull InstanceIdentifier child(final Class<@NonNull C> caze, final Class<@NonNull N> container) {
return childIdentifier(Item.of(caze, container));
}
@@ -404,10 +393,11 @@ public class InstanceIdentifier implements Path & DataObject, K extends Identifier,
- N extends Identifiable & ChildOf super C>> KeyedInstanceIdentifier child(final Class caze,
- final Class listItem, final K listKey) {
+ N extends Identifiable & ChildOf super C>> @NonNull KeyedInstanceIdentifier child(
+ final Class<@NonNull C> caze, final Class<@NonNull N> listItem, final K listKey) {
return (KeyedInstanceIdentifier) childIdentifier(IdentifiableItem.of(caze, listItem, listKey));
}
@@ -420,34 +410,18 @@ public class InstanceIdentifier implements Path> InstanceIdentifier augmentation(
- final Class container) {
+ public final > @NonNull InstanceIdentifier augmentation(
+ final Class<@NonNull N> container) {
return childIdentifier(Item.of(container));
}
- @Deprecated
- private List legacyCache;
-
- /**
- * Return the path as a list.
- *
- * @deprecated Use {@link #getPathArguments()} instead.
- */
- @Deprecated
- public final List getPath() {
- if (legacyCache == null) {
- legacyCache = ImmutableList.copyOf(pathArguments);
- }
-
- return legacyCache;
- }
-
/**
* Create a builder rooted at this key.
*
* @return A builder instance
*/
- public InstanceIdentifierBuilder builder() {
+ // FIXME: rename this method to 'toBuilder()'
+ public @NonNull InstanceIdentifierBuilder builder() {
return new InstanceIdentifierBuilderImpl<>(Item.of(targetType), pathArguments, hash, isWildcarded());
}
@@ -459,11 +433,27 @@ public class InstanceIdentifier implements Path> InstanceIdentifierBuilder builder(
+ public static > @NonNull InstanceIdentifierBuilder builder(
final Class container) {
return new InstanceIdentifierBuilderImpl().addWildNode(Item.of(container));
}
+ /**
+ * Create an InstanceIdentifierBuilder for a specific type of InstanceIdentifier as specified by container in
+ * a {@code grouping} used in the {@code case} statement.
+ *
+ * @param caze Choice case class
+ * @param container Base container
+ * @param Case type
+ * @param Type of the container
+ * @return A new {@link InstanceIdentifierBuilder}
+ * @throws NullPointerException if any argument is null
+ */
+ public static & DataObject, T extends ChildOf super C>>
+ @NonNull InstanceIdentifierBuilder builder(final Class caze, final Class container) {
+ return new InstanceIdentifierBuilderImpl().addWildNode(Item.of(caze, container));
+ }
+
/**
* Create an InstanceIdentifierBuilder for a specific type of InstanceIdentifier which represents an
* {@link IdentifiableItem}.
@@ -476,10 +466,61 @@ public class InstanceIdentifier implements Path & ChildOf extends DataRoot>,
- K extends Identifier> InstanceIdentifierBuilder builder(final Class listItem, final K listKey) {
+ K extends Identifier> @NonNull InstanceIdentifierBuilder builder(final Class listItem,
+ final K listKey) {
+ return new InstanceIdentifierBuilderImpl().addNode(IdentifiableItem.of(listItem, listKey));
+ }
+
+ /**
+ * Create an InstanceIdentifierBuilder for a specific type of InstanceIdentifier which represents an
+ * {@link IdentifiableItem} in a {@code grouping} used in the {@code case} statement.
+ *
+ * @param caze Choice case class
+ * @param listItem list item class
+ * @param listKey key value
+ * @param Case type
+ * @param List type
+ * @param List key
+ * @return A new {@link InstanceIdentifierBuilder}
+ * @throws NullPointerException if any argument is null
+ */
+ public static & DataObject,
+ N extends Identifiable & ChildOf super C>, K extends Identifier>
+ @NonNull InstanceIdentifierBuilder builder(final Class caze, final Class listItem,
+ final K listKey) {
+ return new InstanceIdentifierBuilderImpl().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 super C>>
+ @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 super R>,
+ 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 super C>, 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.
@@ -489,25 +530,27 @@ public class InstanceIdentifier implements Path internalCreate(final Iterable pathArguments) {
- final Iterator extends PathArgument> it = requireNonNull(pathArguments, "pathArguments may not be null")
- .iterator();
+ private static @NonNull InstanceIdentifier> internalCreate(final Iterable pathArguments) {
+ 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);
}
@@ -527,10 +570,11 @@ public class InstanceIdentifier implements Path create(final Iterable extends PathArgument> pathArguments) {
- if (pathArguments instanceof ImmutableCollection>) {
+ // FIXME: rename to 'unsafeOf()'
+ public static @NonNull InstanceIdentifier> create(final Iterable extends PathArgument> pathArguments) {
+ if (pathArguments instanceof ImmutableCollection) {
@SuppressWarnings("unchecked")
- final Iterable immutableArguments = (Iterable) pathArguments;
+ final var immutableArguments = (ImmutableCollection) pathArguments;
return internalCreate(immutableArguments);
}
@@ -550,9 +594,11 @@ public class InstanceIdentifier implements Path 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)));
}
/**
@@ -563,6 +609,7 @@ public class InstanceIdentifier implements Path & DataObject, K extends Identifier> K keyOf(
final InstanceIdentifier id) {
requireNonNull(id);
@@ -574,7 +621,7 @@ public class InstanceIdentifier implements Path InstanceIdentifier trustedCreate(final PathArgument arg,
+ static @NonNull InstanceIdentifier trustedCreate(final PathArgument arg,
final Iterable pathArguments, final int hash, boolean wildcarded) {
if (Identifiable.class.isAssignableFrom(arg.getType()) && !wildcarded) {
Identifier> key = null;
@@ -600,7 +647,7 @@ public class InstanceIdentifier implements Path getType();
+ @NonNull Class extends DataObject> getType();
/**
* Return an optional enclosing case type. This is used only when {@link #getType()} references a node defined
@@ -616,7 +663,8 @@ public class InstanceIdentifier implements Path implements PathArgument, Serializable {
private static final long serialVersionUID = 1L;
- private final Class type;
+
+ private final @NonNull Class type;
AbstractPathArgument(final Class type) {
this.type = requireNonNull(type, "Type may not be null.");
@@ -677,14 +725,7 @@ public class InstanceIdentifier implements Path extends AbstractPathArgument {
private static final long serialVersionUID = 1L;
- /**
- * Construct an Item.
- *
- * @param type Backing class
- * @deprecated Use {@link #of(Class)} instead.
- */
- @Deprecated
- public Item(final Class type) {
+ Item(final Class type) {
super(type);
}
@@ -696,7 +737,7 @@ public class InstanceIdentifier implements Path Item of(final Class type) {
+ public static @NonNull Item of(final Class type) {
return new Item<>(type);
}
@@ -711,7 +752,7 @@ public class InstanceIdentifier implements Path & DataObject, T extends ChildOf super C>> Item of(
+ public static & DataObject, T extends ChildOf super C>> @NonNull Item of(
final Class caseType, final Class type) {
return new CaseItem<>(caseType, type);
}
@@ -732,17 +773,10 @@ public class InstanceIdentifier implements Path & DataObject, T extends Identifier>
extends AbstractPathArgument {
private static final long serialVersionUID = 1L;
- private final T key;
- /**
- * Construct an Item.
- *
- * @param type Backing class
- * @param key key
- * @deprecated Use {@link #of(Class, Identifier)} instead.
- */
- @Deprecated
- public IdentifiableItem(final Class type, final T key) {
+ private final @NonNull T key;
+
+ IdentifiableItem(final Class type, final T key) {
super(type);
this.key = requireNonNull(key, "Key may not be null.");
}
@@ -757,8 +791,8 @@ public class InstanceIdentifier implements Path & DataObject, I extends Identifier> IdentifiableItem of(
- final Class type, final I key) {
+ public static & DataObject, I extends Identifier>
+ @NonNull IdentifiableItem of(final Class type, final I key) {
return new IdentifiableItem<>(type, key);
}
@@ -775,8 +809,8 @@ public class InstanceIdentifier implements Path & DataObject, T extends ChildOf super C> & Identifiable,
- I extends Identifier> IdentifiableItem of(final Class caseType, final Class type,
- final I key) {
+ I extends Identifier> @NonNull IdentifiableItem of(final Class caseType,
+ final Class type, final I key) {
return new CaseIdentifiableItem<>(caseType, type, key);
}
@@ -786,7 +820,7 @@ public class InstanceIdentifier implements Path 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
*
@@ -850,14 +884,12 @@ public class InstanceIdentifier implements Path> InstanceIdentifierBuilder child(Class container);
+ > @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
@@ -866,14 +898,13 @@ public class InstanceIdentifier implements Path & DataObject, N extends ChildOf super C>> InstanceIdentifierBuilder child(
- Class caze, Class container);
+ & DataObject, N extends ChildOf super C>>
+ @NonNull InstanceIdentifierBuilder 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
@@ -882,14 +913,13 @@ public class InstanceIdentifier implements Path & ChildOf super T>, K extends Identifier> InstanceIdentifierBuilder child(
- Class listItem, K listKey);
+ & ChildOf super T>, K extends Identifier>
+ @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
@@ -901,8 +931,8 @@ public class InstanceIdentifier