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%2FCodecDataObject.java;h=65e40086155a3d804c3262dbc1d05ef2105a6643;hb=9f23891d96e635e1cd30c699f9b72b9336fc9d06;hp=6b3b832d4f6969bdf02ad7ad7cdf06ee934afca1;hpb=82684b43090a871c633a333b20fde09c9392fb17;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObject.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObject.java index 6b3b832d4f..65e4008615 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObject.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObject.java @@ -7,17 +7,17 @@ */ package org.opendaylight.mdsal.binding.dom.codec.impl; -import static com.google.common.base.Verify.verify; import static java.util.Objects.requireNonNull; +import com.google.common.base.VerifyException; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.binding.DataObject; -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.MapEntryNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; /** * A base class for {@link DataObject}s backed by {@link DataObjectCodecContext}. While this class is public, it not @@ -41,23 +41,23 @@ public abstract class CodecDataObject implements DataObjec } } - private final @NonNull DataObjectCodecContext context; - @SuppressWarnings("rawtypes") - private final @NonNull DistinctNodeContainer data; + private final @NonNull AbstractDataObjectCodecContext context; + private final @NonNull DataContainerNode data; // Accessed via a VarHandle @SuppressWarnings("unused") // FIXME: consider using a primitive int-based cache (with 0 being uninit) + @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749") private volatile Integer cachedHashcode; - protected CodecDataObject(final DataObjectCodecContext context, final DistinctNodeContainer data) { + protected CodecDataObject(final AbstractDataObjectCodecContext context, final DataContainerNode data) { this.data = requireNonNull(data, "Data must not be null"); this.context = requireNonNull(context, "Context must not be null"); } @Override public final int hashCode() { - final Integer cached = (Integer) CACHED_HASH_CODE.getAcquire(this); + final var cached = (Integer) CACHED_HASH_CODE.getAcquire(this); return cached != null ? cached : loadHashCode(); } @@ -77,14 +77,27 @@ public abstract class CodecDataObject implements DataObjec protected final Object codecMember(final VarHandle handle, final Class bindingClass) { final Object cached = handle.getAcquire(this); - return cached != null ? unmaskNull(cached) : loadMember(handle, context.streamChild(bindingClass)); + return cached != null ? unmaskNull(cached) : loadMember(handle, context.getStreamChild(bindingClass)); } - protected final Object codecMember(final VarHandle handle, final NodeContextSupplier supplier) { + protected final Object codecMember(final VarHandle handle, final CodecContextSupplier supplier) { final Object cached = handle.getAcquire(this); return cached != null ? unmaskNull(cached) : loadMember(handle, supplier.get()); } + protected final @NonNull Object codecMemberOrEmpty(final @Nullable Object value, + final @NonNull Class bindingClass) { + return value != null ? value : emptyObject(bindingClass); + } + + private @NonNull Object emptyObject(final @NonNull Class bindingClass) { + final var childContext = context.getStreamChild(bindingClass); + if (childContext instanceof StructuralContainerCodecContext structural) { + return structural.emptyObject(); + } + throw new VerifyException("Unexpected context " + childContext); + } + protected final @NonNull Object codecKey(final VarHandle handle) { final Object cached = handle.getAcquire(this); return cached != null ? cached : loadKey(handle); @@ -94,19 +107,17 @@ public abstract class CodecDataObject implements DataObjec protected abstract boolean codecEquals(Object obj); - final @NonNull DataObjectCodecContext codecContext() { + final @NonNull AbstractDataObjectCodecContext codecContext() { return context; } - @SuppressWarnings("rawtypes") - final @NonNull DistinctNodeContainer codecData() { + final @NonNull DataContainerNode codecData() { return data; } // Helper split out of codecMember to aid its inlining - private Object loadMember(final VarHandle handle, final NodeCodecContext childCtx) { - @SuppressWarnings("unchecked") - final NormalizedNode child = data.childByArg(childCtx.getDomPathArgument()); + private Object loadMember(final VarHandle handle, final CodecContext childCtx) { + final var child = data.childByArg(childCtx.getDomPathArgument()); // We do not want to use Optional.map() here because we do not want to invoke defaultObject() when we have // normal value because defaultObject() may end up throwing an exception intentionally. @@ -117,10 +128,14 @@ public abstract class CodecDataObject implements DataObjec // Helper split out of codecKey to aid its inlining private @NonNull Object loadKey(final VarHandle handle) { - verify(data instanceof MapEntryNode, "Unsupported value %s", data); - verify(context instanceof KeyedListNodeCodecContext, "Unexpected context %s", context); - final Object obj = ((KeyedListNodeCodecContext) context) - .deserialize(((MapEntryNode) data).getIdentifier()); + if (!(data instanceof MapEntryNode mapEntry)) { + throw new VerifyException("Unsupported value " + data); + } + if (!(context instanceof MapCodecContext listContext)) { + throw new VerifyException("Unexpected context " + context); + } + + final Object obj = listContext.deserialize(mapEntry.name()); // key is known to be non-null, no need to mask it final Object witness = handle.compareAndExchangeRelease(this, null, obj); return witness == null ? obj : witness;