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=5dfbfb851377c285961e6e751cfc5e6fce0337ef;hpb=d7102f62fabf0d78c507c4c7a5144248c21360bb;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 5dfbfb8513..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,23 +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 org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.concepts.Immutable; -import org.opendaylight.yangtools.concepts.Path; +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.HierarchicalIdentifier; import org.opendaylight.yangtools.util.HashCodeBuilder; /** @@ -58,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); @@ -96,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); } @@ -211,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())) { @@ -232,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") @@ -338,40 +327,92 @@ 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()); } - public final > InstanceIdentifier child(final Class container) { - return childIdentifier(new Item<>(container)); + /** + * Create an InstanceIdentifier for a child container. This method is a more efficient equivalent to + * {@code builder().child(container).build()}. + * + * @param container Container to append + * @param Container type + * @return An InstanceIdentifier. + * @throws NullPointerException if {@code container} is null + */ + public final > @NonNull InstanceIdentifier child( + final Class<@NonNull N> container) { + return childIdentifier(Item.of(container)); } - public final & ChildOf, K extends Identifier> KeyedInstanceIdentifier - child(final Class listItem, final K listKey) { - return (KeyedInstanceIdentifier) childIdentifier(new IdentifiableItem<>(listItem, listKey)); + /** + * Create an InstanceIdentifier for a child list item. This method is a more efficient equivalent to + * {@code builder().child(listItem, listKey).build()}. + * + * @param listItem List to append + * @param listKey List key + * @param List type + * @param Key type + * @return An InstanceIdentifier. + * @throws NullPointerException if any argument is null + */ + @SuppressWarnings("unchecked") + public final & ChildOf, K extends Identifier> + @NonNull KeyedInstanceIdentifier child(final Class<@NonNull N> listItem, final K listKey) { + return (KeyedInstanceIdentifier) childIdentifier(IdentifiableItem.of(listItem, listKey)); } - public final > InstanceIdentifier augmentation( - final Class container) { - return childIdentifier(new Item<>(container)); + /** + * Create an InstanceIdentifier for a child container. This method is a more efficient equivalent to + * {@code builder().child(caze, container).build()}. + * + * @param caze Choice case class + * @param container Container to append + * @param Case type + * @param Container type + * @return An InstanceIdentifier. + * @throws NullPointerException if any argument is null + */ + // FIXME: add a proper caller + public final & DataObject, N extends ChildOf> + @NonNull InstanceIdentifier child(final Class<@NonNull C> caze, final Class<@NonNull N> container) { + return childIdentifier(Item.of(caze, container)); } - @Deprecated - private List legacyCache; - /** - * Return the path as a list. + * Create an InstanceIdentifier for a child list item. This method is a more efficient equivalent to + * {@code builder().child(caze, listItem, listKey).build()}. * - * @deprecated Use {@link #getPathArguments()} instead. + * @param caze Choice case class + * @param listItem List to append + * @param listKey List key + * @param Case type + * @param List type + * @param Key type + * @return An InstanceIdentifier. + * @throws NullPointerException if any argument is null */ - @Deprecated - public final List getPath() { - if (legacyCache == null) { - legacyCache = ImmutableList.copyOf(pathArguments); - } + // FIXME: add a proper caller + @SuppressWarnings("unchecked") + public final & DataObject, K extends Identifier, + N extends Identifiable & ChildOf> @NonNull KeyedInstanceIdentifier child( + final Class<@NonNull C> caze, final Class<@NonNull N> listItem, final K listKey) { + return (KeyedInstanceIdentifier) childIdentifier(IdentifiableItem.of(caze, listItem, listKey)); + } - return legacyCache; + /** + * Create an InstanceIdentifier for a child augmentation. This method is a more efficient equivalent to + * {@code builder().augmentation(container).build()}. + * + * @param container Container to append + * @param Container type + * @return An InstanceIdentifier. + * @throws NullPointerException if {@code container} is null + */ + public final > @NonNull InstanceIdentifier augmentation( + final Class<@NonNull N> container) { + return childIdentifier(Item.of(container)); } /** @@ -379,30 +420,38 @@ public class InstanceIdentifier implements Path builder() { - return new InstanceIdentifierBuilderImpl<>(new Item<>(targetType), pathArguments, hash, isWildcarded()); + // FIXME: rename this method to 'toBuilder()' + public @NonNull InstanceIdentifierBuilder builder() { + return new InstanceIdentifierBuilderImpl<>(Item.of(targetType), pathArguments, hash, isWildcarded()); } /** - * Create a new InstanceIdentifierBuilder given a base InstanceIdentifier. + * Create an InstanceIdentifierBuilder for a specific type of InstanceIdentifier as specified by container. * - * @deprecated Use {@link #builder()} instead. + * @param container Base container + * @param Type of the container + * @return A new {@link InstanceIdentifierBuilder} + * @throws NullPointerException if {@code container} is null */ - @Deprecated - public static InstanceIdentifierBuilder builder(final InstanceIdentifier base) { - return base.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. + * 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 New IsntanceIdentifierBuilder + * @return A new {@link InstanceIdentifierBuilder} + * @throws NullPointerException if any argument is null */ - public static > InstanceIdentifierBuilder builder( - final Class container) { - return new InstanceIdentifierBuilderImpl().addNode(container); + public static & DataObject, T extends ChildOf> + @NonNull InstanceIdentifierBuilder builder(final Class caze, final Class container) { + return new InstanceIdentifierBuilderImpl().addWildNode(Item.of(caze, container)); } /** @@ -414,10 +463,62 @@ public class InstanceIdentifier implements Path List type * @param List key * @return A new {@link InstanceIdentifierBuilder} + * @throws NullPointerException if any argument is null */ public static & ChildOf, - K extends Identifier> InstanceIdentifierBuilder builder(final Class listItem, final K listKey) { - return new InstanceIdentifierBuilderImpl().addNode(listItem, 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, 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> + @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)); } /** @@ -427,26 +528,29 @@ public class InstanceIdentifier implements Path internalCreate(final Iterable pathArguments) { - final Iterator 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); } @@ -466,14 +570,15 @@ public class InstanceIdentifier implements Path create(final Iterable pathArguments) { - if (pathArguments instanceof ImmutableCollection) { + // FIXME: rename to 'unsafeOf()' + public static @NonNull InstanceIdentifier create(final Iterable pathArguments) { + if (pathArguments instanceof ImmutableCollection) { @SuppressWarnings("unchecked") - final Iterable immutableArguments = (Iterable) pathArguments; + final var immutableArguments = (ImmutableCollection) pathArguments; return internalCreate(immutableArguments); - } else { - return internalCreate(ImmutableList.copyOf(pathArguments)); } + + return internalCreate(ImmutableList.copyOf(pathArguments)); } /** @@ -489,9 +594,11 @@ public class InstanceIdentifier implements Path InstanceIdentifier create(final Class type) { - return (InstanceIdentifier) create(Collections.singletonList(new Item<>(type))); + public static > @NonNull InstanceIdentifier create( + final Class<@NonNull T> type) { + return (InstanceIdentifier) internalCreate(ImmutableList.of(Item.of(type))); } /** @@ -502,6 +609,7 @@ public class InstanceIdentifier implements Path & DataObject, K extends Identifier> K keyOf( final InstanceIdentifier id) { requireNonNull(id); @@ -513,12 +621,12 @@ 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; - if (arg instanceof IdentifiableItem) { - key = ((IdentifiableItem)arg).key; + if (arg instanceof IdentifiableItem) { + key = ((IdentifiableItem)arg).getKey(); } else { wildcarded = true; } @@ -534,14 +642,31 @@ public class InstanceIdentifier implements Path { - Class getType(); + /** + * Return the data object type backing this PathArgument. + * + * @return Data object type. + */ + @NonNull Class getType(); + + /** + * Return an optional enclosing case type. This is used only when {@link #getType()} references a node defined + * in a {@code grouping} which is reference inside a {@code case} statement in order to safely reference the + * node. + * + * @return Optional case class. + */ + default Optional> getCaseType() { + return Optional.empty(); + } } private abstract static class AbstractPathArgument implements PathArgument, Serializable { private static final long serialVersionUID = 1L; - private final Class type; - protected AbstractPathArgument(final Class type) { + private final @NonNull Class type; + + AbstractPathArgument(final Class type) { this.type = requireNonNull(type, "Type may not be null."); } @@ -550,29 +675,44 @@ public class InstanceIdentifier implements Path other = (AbstractPathArgument) obj; - return type.equals(other.type); + return type.equals(other.type) && Objects.equals(getKey(), other.getKey()) + && getCaseType().equals(other.getCaseType()); } @Override - public int compareTo(final PathArgument arg) { - return type.getCanonicalName().compareTo(arg.getType().getCanonicalName()); + public final int compareTo(final PathArgument arg) { + final int cmp = compareClasses(type, arg.getType()); + if (cmp != 0) { + return cmp; + } + final Optional> caseType = getCaseType(); + if (!caseType.isPresent()) { + return arg.getCaseType().isPresent() ? -1 : 1; + } + final Optional> argCaseType = getCaseType(); + return argCaseType.isPresent() ? compareClasses(caseType.get(), argCaseType.get()) : 1; + } + + private static int compareClasses(final Class first, final Class second) { + return first.getCanonicalName().compareTo(second.getCanonicalName()); } } @@ -582,13 +722,41 @@ public class InstanceIdentifier implements Path Item type */ - public static final class Item extends AbstractPathArgument { + public static class Item extends AbstractPathArgument { private static final long serialVersionUID = 1L; - public Item(final Class type) { + Item(final Class type) { super(type); } + /** + * Return a PathArgument instance backed by the specified class. + * + * @param type Backing class + * @param Item type + * @return A new PathArgument + * @throws NullPointerException if {@code} is null. + */ + public static @NonNull Item of(final Class type) { + return new Item<>(type); + } + + /** + * Return a PathArgument instance backed by the specified class, which in turn is defined in a {@code grouping} + * used in a corresponding {@code case} statement. + * + * @param caseType defining case class + * @param type Backing class + * @param Case type + * @param Item type + * @return A new PathArgument + * @throws NullPointerException if any argument is null. + */ + public static & DataObject, T extends ChildOf> @NonNull Item of( + final Class caseType, final Class type) { + return new CaseItem<>(caseType, type); + } + @Override public String toString() { return getType().getName(); @@ -602,28 +770,58 @@ public class InstanceIdentifier implements Path An object that is identifiable by an identifier * @param The identifier of the object */ - public static final class IdentifiableItem & DataObject, T extends Identifier> + public static class IdentifiableItem & DataObject, T extends Identifier> extends AbstractPathArgument { private static final long serialVersionUID = 1L; - private final T key; - 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."); } - public T getKey() { - return this.key; + /** + * Return an IdentifiableItem instance backed by the specified class with specified key. + * + * @param type Backing class + * @param key Key + * @param List type + * @param Key type + * @return An IdentifiableItem + * @throws NullPointerException if any argument is null. + */ + public static & DataObject, I extends Identifier> + @NonNull IdentifiableItem of(final Class type, final I key) { + return new IdentifiableItem<>(type, key); } - @Override - public boolean equals(final Object obj) { - return super.equals(obj) && key.equals(((IdentifiableItem) obj).getKey()); + /** + * Return an IdentifiableItem instance backed by the specified class with specified key. The class is in turn + * defined in a {@code grouping} used in a corresponding {@code case} statement. + * + * @param caseType defining case class + * @param type Backing class + * @param Case type + * @param List type + * @param Key type + * @return A new PathArgument + * @throws NullPointerException if any argument is null. + */ + public static & DataObject, T extends ChildOf & Identifiable, + I extends Identifier> @NonNull IdentifiableItem of(final Class caseType, + final Class type, final I key) { + return new CaseIdentifiableItem<>(caseType, type, key); } + /** + * Return the data object type backing this PathArgument. + * + * @return Data object type. + */ @Override - public int hashCode() { - return super.hashCode() * 31 + key.hashCode(); + public final @NonNull T getKey() { + return key; } @Override @@ -632,44 +830,109 @@ public class InstanceIdentifier implements Path & DataObject, T extends ChildOf> + extends Item { + private static final long serialVersionUID = 1L; + + private final Class caseType; + + CaseItem(final Class caseType, final Class type) { + super(type); + this.caseType = requireNonNull(caseType); + } + + @Override + public Optional> getCaseType() { + return Optional.of(caseType); + } + } + + private static final class CaseIdentifiableItem & DataObject, + T extends ChildOf & Identifiable, K extends Identifier> extends IdentifiableItem { + private static final long serialVersionUID = 1L; + + private final Class caseType; + + CaseIdentifiableItem(final Class caseType, final Class type, final K key) { + super(type, key); + this.caseType = requireNonNull(caseType); + } - public interface InstanceIdentifierBuilder extends Builder> { + @Override + public Optional> getCaseType() { + return Optional.of(caseType); + } + } + + // 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 * - * @param container - * @param - * @return + * @param container Container to append + * @param Container type + * @return this builder + * @throws NullPointerException if {@code container} is null */ - > 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. + * + * @param caze Choice case class + * @param container Container to append + * @param Case type + * @param Container type + * @return this builder + * @throws NullPointerException if {@code container} is null + */ + & DataObject, N extends ChildOf> + @NonNull InstanceIdentifierBuilder child(Class caze, Class container); /** - * Append the specified listItem as a child of the current InstanceIdentifier referenced by the builder. + * 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. * - * 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 + * @param List type + * @param Key type + * @return this builder + * @throws NullPointerException if any argument is null + */ + & ChildOf, 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. * - * @param listItem - * @param listKey - * @param - * @param - * @return + * @param caze Choice case class + * @param listItem List to append + * @param listKey List key + * @param Case type + * @param List type + * @param Key type + * @return this builder + * @throws NullPointerException if any argument is null */ - & ChildOf, K extends Identifier> InstanceIdentifierBuilder child( - Class listItem, K listKey); + & DataObject, K extends Identifier, + N extends Identifiable & ChildOf> @NonNull InstanceIdentifierBuilder child( + Class caze, Class listItem, K listKey); /** * Build an identifier which refers to a specific augmentation of the current InstanceIdentifier referenced by @@ -678,8 +941,9 @@ public class InstanceIdentifier implements Path augmentation type * @return this builder + * @throws NullPointerException if {@code container} is null */ - > InstanceIdentifierBuilder augmentation( + > @NonNull InstanceIdentifierBuilder augmentation( Class container); /** @@ -687,37 +951,10 @@ public class InstanceIdentifier implements Path build(); - - /* - * @deprecated use #build() - */ - @Deprecated - InstanceIdentifier toInstance(); - } - - private void writeObject(final java.io.ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - out.writeInt(Iterables.size(pathArguments)); - for (Object o : pathArguments) { - out.writeObject(o); - } + @NonNull InstanceIdentifier build(); } - private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - - final int size = in.readInt(); - final List args = new ArrayList<>(size); - for (int i = 0; i < size; ++i) { - args.add((PathArgument) in.readObject()); - } - - try { - PATHARGUMENTS_FIELD.set(this, ImmutableList.copyOf(args)); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new IOException(e); - } + private Object writeReplace() throws ObjectStreamException { + return new InstanceIdentifierV3<>(this); } }