From abb67fcf38fdf119522795cc8adab2c265216daf Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 8 Jun 2016 19:09:17 +0200 Subject: [PATCH] BUG-6028: check value types for encapsulation This is a fast check to see if the argument matches expected value class. If it does not it does not make sense to invoke the serializer, as it will fail. Change-Id: I4ca556fea057f2188fa1c34d303467565af38d5c Signed-off-by: Robert Varga (cherry picked from commit a6d0735732b202f40bd37f7ae291c8a4af9e3ccf) --- .../codec/impl/EncapsulatedValueCodec.java | 24 +++++++++++++++---- .../codec/impl/UnionValueOptionContext.java | 6 ++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/EncapsulatedValueCodec.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/EncapsulatedValueCodec.java index 3de5085c1d..03414a0e8e 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/EncapsulatedValueCodec.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/EncapsulatedValueCodec.java @@ -28,25 +28,41 @@ final class EncapsulatedValueCodec extends ReflectionBasedCodec implements Schem private static final MethodType OBJ_METHOD = MethodType.methodType(Object.class, Object.class); private final MethodHandle constructor; private final MethodHandle getter; + private final Class valueType; - private EncapsulatedValueCodec(final Class typeClz, final MethodHandle constructor, final MethodHandle getter) { + private EncapsulatedValueCodec(final Class typeClz, final MethodHandle constructor, final MethodHandle getter, + final Class valueType) { super(typeClz); this.constructor = Preconditions.checkNotNull(constructor); this.getter = Preconditions.checkNotNull(getter); + this.valueType = Preconditions.checkNotNull(valueType); } static Callable loader(final Class typeClz) { return new Callable() { @Override - public EncapsulatedValueCodec call() throws Exception { + public EncapsulatedValueCodec call() throws IllegalAccessException, NoSuchMethodException, SecurityException { final Method m = typeClz.getMethod("getValue"); final MethodHandle getter = LOOKUP.unreflect(m).asType(OBJ_METHOD); - final MethodHandle constructor = LOOKUP.findConstructor(typeClz, MethodType.methodType(void.class, m.getReturnType())).asType(OBJ_METHOD); - return new EncapsulatedValueCodec(typeClz, constructor, getter); + final Class valueType = m.getReturnType(); + + final MethodHandle constructor = LOOKUP.findConstructor(typeClz, + MethodType.methodType(void.class, valueType)).asType(OBJ_METHOD); + return new EncapsulatedValueCodec(typeClz, constructor, getter, valueType); } }; } + /** + * Quick check if a value object has a chance to deserialize using {@link #deserialize(Object)}. + * + * @param value Value to be checked + * @return True if the value can be encapsulated + */ + boolean canAcceptObject(final Object value) { + return valueType.isInstance(value); + } + @Override public Object deserialize(final Object input) { try { diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionValueOptionContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionValueOptionContext.java index 52dd88e33d..06130fb824 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionValueOptionContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionValueOptionContext.java @@ -51,8 +51,12 @@ final class UnionValueOptionContext { } Object deserializeUnion(final Object input) { - final Object value; + // Side-step potential exceptions by checking the type if it is available + if (codec instanceof EncapsulatedValueCodec && !((EncapsulatedValueCodec) codec).canAcceptObject(input)) { + return null; + } + final Object value; try { value = codec.deserialize(input); } catch (Exception e) { -- 2.36.6