All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.yangtools.binding.DataObjectReference Maven / Gradle / Ivy

/*
 * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.yangtools.binding;

import static java.util.Objects.requireNonNull;

import com.google.common.collect.ImmutableList;
import java.io.Serializable;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.binding.impl.AbstractDataObjectReference;
import org.opendaylight.yangtools.binding.impl.AbstractDataObjectReferenceBuilder;
import org.opendaylight.yangtools.binding.impl.DataObjectIdentifierImpl;
import org.opendaylight.yangtools.binding.impl.DataObjectReferenceBuilder;
import org.opendaylight.yangtools.binding.impl.DataObjectReferenceBuilderWithKey;
import org.opendaylight.yangtools.binding.impl.DataObjectReferenceImpl;
import org.opendaylight.yangtools.binding.impl.DataObjectReferenceWithKey;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.KeyedBuilder;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;

/**
 * A reference to a {@link DataObject} with semantics partially overlapping with to YANG {@code instance-identifier}.
 *
 * 

* While this indirection is not something defined in YANG, this class hierarchy arises naturally from the Binding * specification's Java footprint, which uses {@link DataObject} as the baseline self-sufficient addressable construct. * This means users can use a {@link KeyAware} class without specifying the corresponding key -- resulting in an * {@link InexactDataObjectStep}. * *

* There are two kinds of a reference based on their treatment of such a {@link InexactDataObjectStep}: *

    *
  1. {@link DataObjectIdentifier}, which accepts only {@link ExactDataObjectStep}s and represents * a {@link BindingInstanceIdentifier} pointing to a {@link DataObject}
  2. *
  3. {@link DataObjectReference}, which accepts any {@link DataObjectStep} and represents path-based matching * criteria for one or more {@link DataObjectIdentifier}s based on * {@link InexactDataObjectStep#matches(DataObjectStep)}. *
* An explicit conversion to {@link DataObjectIdentifier} can be attempted via {@link #toIdentifier()} method. * *

* The legacy {@link InstanceIdentifier} is implements the second kind via its class hierarchy, but indicates its * compliance via {@link #isExact()} method. Any {@link DataObjectReference} can be converted into an * {@link InstanceIdentifier} via the {@link #toLegacy()} method. * * @param type of {@link DataObject} held in the last step. */ public sealed interface DataObjectReference extends Immutable, Serializable permits DataObjectIdentifier, DataObjectReference.WithKey, AbstractDataObjectReference { /** * A builder of {@link DataObjectReference} objects. * * @param type of {@link DataObject} held in the last step. */ sealed interface Builder permits Builder.WithKey, DataObjectIdentifier.Builder, AbstractDataObjectReferenceBuilder { /** * A builder of {@link DataObjectReference.WithKey} objects. * * @param type of {@link EntryObject} held in the last step. * @param {@link Key} type */ sealed interface WithKey, K extends Key> extends Builder permits DataObjectIdentifier.Builder.WithKey, DataObjectReferenceBuilderWithKey, KeyedBuilder { @Override DataObjectReference.WithKey build(); } /** * Update this builder to build a reference to a specific augmentation of the data object this builder currently * points to. * * @param augmentation type * @param augmentation augmentation class * @return this builder * @throws NullPointerException if {@code augmentation} is {@code null} */ > @NonNull Builder augmentation(@NonNull Class augmentation); /** * Append the specified container as a child of the data object this build currently references. This method * should be used when you want to build an instance identifier by appending top-level elements. * * @param Container type * @param container Container to append * @return this builder * @throws NullPointerException if {@code container} is null */ > @NonNull Builder child(@NonNull Class container); /** * Append the specified container as a child of the data object this build currently references. This method * should be used when you want to build an reference 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 Case type * @param Container type * @param caze Choice case class * @param container Container to append * @return this builder * @throws NullPointerException if {@code container} is null */ & DataObject, N extends ChildOf> @NonNull Builder child( Class caze, @NonNull Class container); /** * Append the specified listItem as a child of the data object this build currently references. This method * should be used when you want to build a reference by appending a specific list element to the identifier. * * @param List type * @param Key type * @param listItem List to append * @param listKey List key * @return this builder * @throws NullPointerException if any argument is null */ & ChildOf, K extends Key> @NonNull WithKey child( @NonNull Class<@NonNull N> listItem, @NonNull K listKey); /** * Append the specified listItem as a child of the data object this build currently references. This * method should be used when you want to build a reference 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 Case type * @param List type * @param Key type * @param caze Choice case class * @param listItem List to append * @param listKey List key * @return this builder * @throws NullPointerException if any argument is null */ & DataObject, K extends Key, N extends EntryObject & ChildOf> @NonNull WithKey child(@NonNull Class caze, @NonNull Class listItem, @NonNull K listKey); /** * Build the data object reference. * * @return resulting {@link DataObjectReference}. */ @NonNull DataObjectReference build(); } /** * A {@link DataObjectReference} pointing to a {@link EntryObject}. * * @param Key type * @param EntryObject type */ sealed interface WithKey, K extends Key> extends DataObjectReference, KeyAware permits DataObjectIdentifier.WithKey, DataObjectReferenceWithKey, KeyedInstanceIdentifier { @Override KeyStep lastStep(); @Override Builder.WithKey toBuilder(); @Override DataObjectIdentifier.WithKey toIdentifier(); @Override default K key() { return lastStep().key(); } /** * Return the key attached to this identifier. This method is equivalent to calling * {@link InstanceIdentifier#keyOf(InstanceIdentifier)}. * * @return Key associated with this instance identifier. * @deprecated Use {@link #key()} instead. */ @Deprecated(since = "14.0.0") default @NonNull K getKey() { return key(); } } /** * Create a new {@link Builder} initialized to produce a reference equal to this one. * * @return A builder instance * @deprecated Use {@link #toBuilder()} instead. */ @Deprecated(since = "14.0.0") default @NonNull Builder builder() { return toBuilder(); } static >> @NonNull Builder builder(final @NonNull Class container) { return new DataObjectReferenceBuilder<>(DataObjectStep.of(container)); } static > & DataObject, T extends ChildOf> @NonNull Builder builder(final @NonNull Class caze, final @NonNull Class container) { return new DataObjectReferenceBuilder<>(DataObjectStep.of(caze, container)); } static & ChildOf>, K extends Key> Builder.@NonNull WithKey builder(final Class listItem, final K listKey) { return new DataObjectReferenceBuilderWithKey<>(new KeyStep<>(listItem, listKey)); } static > & DataObject, N extends EntryObject & ChildOf, K extends Key> Builder.@NonNull WithKey builder(final @NonNull Class caze, final @NonNull Class listItem, final @NonNull K listKey) { return new DataObjectReferenceBuilderWithKey<>(new KeyStep<>(listItem, requireNonNull(caze), listKey)); } static , T extends ChildOf> @NonNull Builder builderOfInherited(final @NonNull Class root, final @NonNull Class container) { // FIXME: we are losing root identity, hence namespaces may not work correctly return new DataObjectReferenceBuilder<>(DataObjectStep.of(container)); } static , C extends ChoiceIn & DataObject, T extends ChildOf> @NonNull Builder builderOfInherited(final Class root, final Class caze, final Class container) { // FIXME: we are losing root identity, hence namespaces may not work correctly return new DataObjectReferenceBuilder<>(DataObjectStep.of(caze, container)); } static , N extends EntryObject & ChildOf, K extends Key> Builder.@NonNull WithKey builderOfInherited(final @NonNull Class root, final @NonNull Class listItem, final @NonNull K listKey) { // FIXME: we are losing root identity, hence namespaces may not work correctly return new DataObjectReferenceBuilderWithKey<>(new KeyStep<>(listItem, listKey)); } static , C extends ChoiceIn & DataObject, N extends EntryObject & ChildOf, K extends Key> Builder.@NonNull WithKey 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 DataObjectReferenceBuilderWithKey<>(new KeyStep<>(listItem, requireNonNull(caze), listKey)); } static @NonNull DataObjectReference ofUnsafeSteps(final Iterable> steps) { return ofUnsafeSteps(ImmutableList.copyOf(steps)); } static @NonNull DataObjectReference ofUnsafeSteps(final List> steps) { return ofUnsafeSteps(ImmutableList.copyOf(steps)); } @SuppressWarnings("unchecked") static @NonNull DataObjectReference ofUnsafeSteps( final ImmutableList> steps) { if (steps.stream().allMatch(ExactDataObjectStep.class::isInstance)) { return DataObjectIdentifierImpl.ofUnsafeSteps( (ImmutableList>) steps); } return DataObjectReferenceImpl.ofUnsafeSteps(steps); } /** * Return the steps of this reference. Returned {@link Iterable} does not support removals and contains one or more * non-null items. * * @return the steps of this reference */ @NonNull Iterable> steps(); /** * Return the last step of this reference. * * @return the last step */ @NonNull DataObjectStep lastStep(); /** * Create a new {@link Builder} initialized to produce a reference equal to this one. * * @return A builder instance */ @NonNull Builder toBuilder(); /** * Return a {@link DataObjectIdentifier} view of this reference, if possible. * * @return A {@link DataObjectIdentifier} * @throws UnsupportedOperationException if this reference is not compatible with {@link DataObjectIdentifier} */ @NonNull DataObjectIdentifier toIdentifier(); /** * Returns {@code true} if this reference is composed solely of {@link ExactDataObjectStep}s. * * @implNote * The default implementation returns {@code false} to simplify implementation hierarchy. * @return {@code true} if this reference is composed solely of {@link ExactDataObjectStep}s */ default boolean isExact() { return false; } /** * Return a legacy {@link InstanceIdentifier} for this reference. * * @return An {@link InstanceIdentifier}. */ default @NonNull InstanceIdentifier toLegacy() { return InstanceIdentifier.unsafeOf(ImmutableList.copyOf(steps())); } /** * Return the steps of this reference. Returned {@link Iterable} does not support removals and contains one or more * non-null ite,s. * * @return the steps of this reference * @deprecated Use {@link #steps()} instead. */ @Deprecated(since = "14.0.0") default @NonNull Iterable> getPathArguments() { return steps(); } /** * Returns {@code true} if this reference contains an {@link InexactDataObjectStep}s. * * @implSpec * The default implementation returns {@code true} to simplify implementation hierarchy. * @return {@code true} if this reference contains an {@link InexactDataObjectStep} * @deprecated Use negated result of {@link #isExact()} instead */ @Deprecated(since = "14.0.0") default boolean isWildcarded() { return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy