X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fcodec%2Fimpl%2FDataObjectCodecContext.java;h=b63befcbe96f7ef77125fe1664cbf69ff309e555;hb=9f23891d96e635e1cd30c699f9b72b9336fc9d06;hp=44404ad34649364dd08be9260f6bcb498ab9ed6e;hpb=5901ab384ee5e8c77c19a0e6fde35b7804973dbd;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java index 44404ad346..b63befcbe9 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java @@ -13,6 +13,7 @@ import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.lang.reflect.Method; @@ -27,7 +28,6 @@ import org.opendaylight.mdsal.binding.model.api.Type; import org.opendaylight.mdsal.binding.runtime.api.AugmentRuntimeType; import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType; -import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.BindingObject; import org.opendaylight.yangtools.yang.binding.DataObject; @@ -35,7 +35,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -47,8 +47,9 @@ import org.slf4j.LoggerFactory; * This class is an implementation detail. It is public only due to technical reasons and may change at any time. */ @Beta -public abstract class DataObjectCodecContext - extends AbstractDataObjectCodecContext implements BindingDataObjectCodecTreeNode { +public abstract sealed class DataObjectCodecContext + extends AbstractDataObjectCodecContext implements BindingDataObjectCodecTreeNode + permits CaseCodecContext, ContainerLikeCodecContext, ListCodecContext, NotificationCodecContext { private static final Logger LOG = LoggerFactory.getLogger(DataObjectCodecContext.class); private static final VarHandle MISMATCHED_AUGMENTED; @@ -62,28 +63,29 @@ public abstract class DataObjectCodecContext, DataContainerCodecPrototype.Augmentation> augmentToPrototype; - private final ImmutableMap> yangToAugmentClass; + private final ImmutableMap, AugmentationCodecPrototype> augmentToPrototype; + private final ImmutableMap> yangToAugmentClass; private final @NonNull Class> generatedClass; // Note this the content of this field depends only of invariants expressed as this class's fields or // BindingRuntimeContext. It is only accessed via MISMATCHED_AUGMENTED above. @SuppressWarnings("unused") - private volatile ImmutableMap, DataContainerCodecPrototype> mismatchedAugmented = ImmutableMap.of(); + @SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749") + private volatile ImmutableMap, CommonDataObjectCodecPrototype> mismatchedAugmented = ImmutableMap.of(); - DataObjectCodecContext(final DataContainerCodecPrototype prototype) { + DataObjectCodecContext(final CommonDataObjectCodecPrototype prototype) { this(prototype, CodecItemFactory.of()); } - DataObjectCodecContext(final DataContainerCodecPrototype prototype, final CodecItemFactory itemFactory) { + DataObjectCodecContext(final CommonDataObjectCodecPrototype prototype, final CodecItemFactory itemFactory) { this(prototype, new CodecDataObjectAnalysis<>(prototype, itemFactory, null)); } - DataObjectCodecContext(final DataContainerCodecPrototype prototype, final Method keyMethod) { + DataObjectCodecContext(final CommonDataObjectCodecPrototype prototype, final Method keyMethod) { this(prototype, new CodecDataObjectAnalysis<>(prototype, CodecItemFactory.of(), keyMethod)); } - private DataObjectCodecContext(final DataContainerCodecPrototype prototype, + private DataObjectCodecContext(final CommonDataObjectCodecPrototype prototype, final CodecDataObjectAnalysis analysis) { super(prototype, analysis); @@ -91,8 +93,8 @@ public abstract class DataObjectCodecContext>(); - final var augClassToProto = new HashMap, DataContainerCodecPrototype.Augmentation>(); + final var augPathToBinding = new HashMap>(); + final var augClassToProto = new HashMap, AugmentationCodecPrototype>(); for (var augment : analysis.possibleAugmentations) { final var augProto = loadAugmentPrototype(augment); if (augProto != null) { @@ -108,13 +110,13 @@ public abstract class DataObjectCodecContext pathChildPrototype(final Class argType) { + final CommonDataObjectCodecPrototype pathChildPrototype(final Class argType) { final var child = super.pathChildPrototype(argType); return child != null ? child : augmentToPrototype.get(argType); } @Override - final DataContainerCodecPrototype streamChildPrototype(final Class childClass) { + final CommonDataObjectCodecPrototype streamChildPrototype(final Class childClass) { final var child = super.streamChildPrototype(childClass); if (child == null && Augmentation.class.isAssignableFrom(childClass)) { return getAugmentationProtoByClass(childClass); @@ -123,7 +125,7 @@ public abstract class DataObjectCodecContext augmClass) { + private @Nullable AugmentationCodecPrototype getAugmentationProtoByClass(final @NonNull Class augmClass) { final var childProto = augmentToPrototype.get(augmClass); return childProto != null ? childProto : mismatchedAugmentationByClass(augmClass); } - private DataContainerCodecPrototype.@Nullable Augmentation mismatchedAugmentationByClass( - final @NonNull Class childClass) { + private @Nullable AugmentationCodecPrototype mismatchedAugmentationByClass(final @NonNull Class childClass) { /* * It is potentially mismatched valid augmentation - we look up equivalent augmentation using reflection * and walk all stream child and compare augmentations classes if they are equivalent. When we find a match * we'll cache it so we do not need to perform reflection operations again. */ - final var local = - (ImmutableMap, DataContainerCodecPrototype.Augmentation>) MISMATCHED_AUGMENTED.getAcquire(this); + final var local = (ImmutableMap, AugmentationCodecPrototype>) MISMATCHED_AUGMENTED.getAcquire(this); final var mismatched = local.get(childClass); return mismatched != null ? mismatched : loadMismatchedAugmentation(local, childClass); } - private DataContainerCodecPrototype.@Nullable Augmentation loadMismatchedAugmentation( - final ImmutableMap, DataContainerCodecPrototype.Augmentation> oldMismatched, + private @Nullable AugmentationCodecPrototype loadMismatchedAugmentation( + final ImmutableMap, AugmentationCodecPrototype> oldMismatched, final @NonNull Class childClass) { @SuppressWarnings("rawtypes") - final Class augTarget = BindingReflections.findAugmentationTarget((Class) childClass); + final Class augTarget = findAugmentationTarget((Class) childClass); // Do not bother with proposals which are not augmentations of our class, or do not match what the runtime // context would load. if (getBindingClass().equals(augTarget) && belongsToRuntimeContext(childClass)) { @@ -172,19 +171,18 @@ public abstract class DataObjectCodecContext, DataContainerCodecPrototype.Augmentation> oldMismatched, - final @NonNull Class childClass, final DataContainerCodecPrototype.@NonNull Augmentation prototype) { - + private @NonNull AugmentationCodecPrototype cacheMismatched( + final @NonNull ImmutableMap, AugmentationCodecPrototype> oldMismatched, + final @NonNull Class childClass, final @NonNull AugmentationCodecPrototype prototype) { var expected = oldMismatched; while (true) { final var newMismatched = - ImmutableMap., DataContainerCodecPrototype>builderWithExpectedSize(expected.size() + 1) + ImmutableMap., CommonDataObjectCodecPrototype>builderWithExpectedSize(expected.size() + 1) .putAll(expected) .put(childClass, prototype) .build(); - final var witness = (ImmutableMap, DataContainerCodecPrototype.Augmentation>) + final var witness = (ImmutableMap, AugmentationCodecPrototype>) MISMATCHED_AUGMENTED.compareAndExchangeRelease(this, expected, newMismatched); if (witness == expected) { LOG.trace("Cached mismatched augmentation {} -> {} in {}", childClass, prototype, this); @@ -212,7 +210,7 @@ public abstract class DataObjectCodecContext new NodeIdentifier((QName) stmt.argument())) .collect(ImmutableSet.toImmutableSet()); - final var it = childPaths.iterator(); - if (!it.hasNext()) { + if (childPaths.isEmpty()) { return null; } - final var namespace = it.next().getNodeType().getModule(); final var factory = factory(); final GeneratedType javaType = augment.javaType(); @@ -235,24 +231,23 @@ public abstract class DataObjectCodecContext>, Augmentation> getAllAugmentationsFrom( - final DistinctNodeContainer data) { + Map>, Augmentation> getAllAugmentationsFrom(final DataContainerNode data) { /** * Due to augmentation fields are at same level as direct children the data of each augmentation needs to be * aggregated into own container node, then only deserialized using associated prototype. */ final var builders = new HashMap, DataContainerNodeBuilder>(); for (var childValue : data.body()) { - final var bindingClass = yangToAugmentClass.get(childValue.getIdentifier()); + final var bindingClass = yangToAugmentClass.get(childValue.name()); if (bindingClass != null) { builders.computeIfAbsent(bindingClass, key -> Builders.containerBuilder() - .withNodeIdentifier(new NodeIdentifier(data.getIdentifier().getNodeType()))) + .withNodeIdentifier(new NodeIdentifier(data.name().getNodeType()))) .addChild(childValue); } } @@ -262,7 +257,10 @@ public abstract class DataObjectCodecContext