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%2FNotificationCodecContext.java;h=87da154d3393a6437a1e1d0bf20cda371cccc05c;hb=cb0f3a767fa856c220edd674fda4d55dde408c64;hp=6553f707824baf39ec9930ec67fc7757b5dab20d;hpb=3aa65296b24cb2fe7042a99e581702278451bc35;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/NotificationCodecContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/NotificationCodecContext.java index 6553f70782..87da154d33 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/NotificationCodecContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/NotificationCodecContext.java @@ -8,6 +8,10 @@ package org.opendaylight.mdsal.binding.dom.codec.impl; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Verify.verifyNotNull; +import static net.bytebuddy.implementation.bytecode.member.MethodVariableAccess.loadThis; +import static org.opendaylight.mdsal.binding.dom.codec.impl.ByteBuddyUtils.getField; +import static org.opendaylight.mdsal.binding.dom.codec.impl.ByteBuddyUtils.putField; import com.google.common.base.Throwables; import java.lang.invoke.MethodHandle; @@ -32,31 +36,40 @@ import net.bytebuddy.jar.asm.Opcodes; import net.bytebuddy.matcher.ElementMatchers; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.dom.codec.loader.CodecClassLoader.GeneratorResult; +import org.opendaylight.mdsal.binding.runtime.api.NotificationRuntimeType; +import org.opendaylight.yangtools.yang.binding.BaseNotification; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.EventInstantAware; -import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; -import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; -final class NotificationCodecContext - extends DataObjectCodecContext { +final class NotificationCodecContext + extends DataObjectCodecContext { private static final Generic EVENT_INSTANT_AWARE = TypeDefinition.Sort.describe(EventInstantAware.class); - private static final MethodDescription EVENT_INSTANT = EVENT_INSTANT_AWARE.getDeclaredMethods().getOnly(); + + private static final String EVENT_INSTANT_NAME; + private static final Generic EVENT_INSTANT_RETTYPE; + + static { + final MethodDescription eventInstance = EVENT_INSTANT_AWARE.getDeclaredMethods().getOnly(); + EVENT_INSTANT_NAME = eventInstance.getName(); + EVENT_INSTANT_RETTYPE = eventInstance.getReturnType(); + } + private static final Generic BB_DOCC = TypeDefinition.Sort.describe(DataObjectCodecContext.class); - private static final Generic BB_NNC = TypeDefinition.Sort.describe(NormalizedNodeContainer.class); + private static final Generic BB_DNC = TypeDefinition.Sort.describe(DistinctNodeContainer.class); private static final Generic BB_I = TypeDefinition.Sort.describe(Instant.class); private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class, DataObjectCodecContext.class, - NormalizedNodeContainer.class, Instant.class); - private static final MethodType NOTIFICATION_TYPE = MethodType.methodType(Notification.class, + DistinctNodeContainer.class, Instant.class); + private static final MethodType NOTIFICATION_TYPE = MethodType.methodType(BaseNotification.class, NotificationCodecContext.class, ContainerNode.class, Instant.class); private static final String INSTANT_FIELD = "instant"; private final MethodHandle eventProxy; - NotificationCodecContext(final Class key, final NotificationDefinition schema, + NotificationCodecContext(final Class key, final NotificationRuntimeType schema, final CodecContextFactory factory) { super(DataContainerCodecPrototype.from(key, schema, factory)); final Class bindingClass = getBindingClass(); @@ -71,9 +84,10 @@ final class NotificationCodecContext .name(fqcn) .defineField(INSTANT_FIELD, BB_I, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC) .defineConstructor(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC) - .withParameters(BB_DOCC, BB_NNC, BB_I) + .withParameters(BB_DOCC, BB_DNC, BB_I) .intercept(ConstructorImplementation.INSTANCE) - .define(EVENT_INSTANT).intercept(EventInstantImplementation.INSTANCE) + .defineMethod(EVENT_INSTANT_NAME, EVENT_INSTANT_RETTYPE, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC) + .intercept(EventInstantImplementation.INSTANCE) .make()); }); @@ -87,37 +101,39 @@ final class NotificationCodecContext } @Override - public D deserialize(final NormalizedNode data) { - checkState(data instanceof ContainerNode); + public D deserialize(final NormalizedNode data) { + checkState(data instanceof ContainerNode, "Unexpected data %s", data); return createBindingProxy((ContainerNode) data); } @SuppressWarnings("checkstyle:illegalCatch") - Notification deserialize(final @NonNull ContainerNode data, final @NonNull Instant eventInstant) { + @NonNull BaseNotification deserialize(final @NonNull ContainerNode data, final @NonNull Instant eventInstant) { + final BaseNotification ret; try { - return (Notification) eventProxy.invokeExact(this, data, eventInstant); + ret = (BaseNotification) eventProxy.invokeExact(this, data, eventInstant); } catch (final Throwable e) { Throwables.throwIfUnchecked(e); - throw new IllegalStateException(e); + throw new LinkageError("Failed to instantiate notification", e); } + return verifyNotNull(ret); } @Override - protected Object deserializeObject(final NormalizedNode normalizedNode) { + protected Object deserializeObject(final NormalizedNode normalizedNode) { return deserialize(normalizedNode); } private enum ConstructorImplementation implements Implementation { INSTANCE; - private static final StackManipulation INSTANT_ARG = MethodVariableAccess.REFERENCE.loadFrom(3); + private static final StackManipulation LOAD_INSTANT_ARG = MethodVariableAccess.REFERENCE.loadFrom(3); private static final StackManipulation LOAD_CTOR_ARGS; static { try { LOAD_CTOR_ARGS = MethodVariableAccess.allArgumentsOf(new MethodDescription.ForLoadedConstructor( AugmentableCodecDataObject.class.getDeclaredConstructor(DataObjectCodecContext.class, - NormalizedNodeContainer.class))); + DistinctNodeContainer.class))); } catch (NoSuchMethodException e) { throw new ExceptionInInitializerError(e); } @@ -131,16 +147,16 @@ final class NotificationCodecContext @Override public ByteCodeAppender appender(final Target implementationTarget) { final TypeDescription instrumentedType = implementationTarget.getInstrumentedType(); - final InGenericShape superCtor = instrumentedType.getSuperClass().getDeclaredMethods() + final InGenericShape superCtor = verifyNotNull(instrumentedType.getSuperClass()).getDeclaredMethods() .filter(ElementMatchers.isConstructor()).getOnly(); return new ByteCodeAppender.Simple( - ByteBuddyUtils.THIS, + loadThis(), LOAD_CTOR_ARGS, MethodInvocation.invoke(superCtor), - ByteBuddyUtils.THIS, - INSTANT_ARG, - ByteBuddyUtils.putField(instrumentedType, INSTANT_FIELD), + loadThis(), + LOAD_INSTANT_ARG, + putField(instrumentedType, INSTANT_FIELD), MethodReturn.VOID); } } @@ -156,8 +172,8 @@ final class NotificationCodecContext @Override public ByteCodeAppender appender(final Target implementationTarget) { return new ByteCodeAppender.Simple( - ByteBuddyUtils.THIS, - ByteBuddyUtils.getField(implementationTarget.getInstrumentedType(), INSTANT_FIELD), + loadThis(), + getField(implementationTarget.getInstrumentedType(), INSTANT_FIELD), MethodReturn.REFERENCE); } }