X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fbinding%2Fdata%2Fcodec%2Fimpl%2FUnionTypeCodec.java;h=19f79fa2d120237df3e5abea2b119d11b30bf6ac;hb=416f190cf43150c69a01c2da3891e5b495d05b96;hp=c483fe7f25cfa169b32e768dd718bdca9d6ec7fb;hpb=31fc94b009db9c2a0d3c21fdf77dea8599399c30;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionTypeCodec.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionTypeCodec.java index c483fe7f25..19f79fa2d1 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionTypeCodec.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/UnionTypeCodec.java @@ -9,12 +9,15 @@ package org.opendaylight.yangtools.binding.data.codec.impl; import com.google.common.collect.ImmutableSet; import com.google.common.io.BaseEncoding; +import com.google.common.util.concurrent.ExecutionError; +import com.google.common.util.concurrent.UncheckedExecutionException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; import java.util.concurrent.Callable; +import javax.annotation.Nullable; import org.opendaylight.yangtools.concepts.Codec; import org.opendaylight.yangtools.yang.binding.BindingMapping; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; @@ -22,11 +25,14 @@ import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; final class UnionTypeCodec extends ReflectionBasedCodec { + private final Codec identityrefCodec; private final ImmutableSet typeCodecs; private final Constructor charConstructor; - private UnionTypeCodec(final Class unionCls,final Set codecs) { + private UnionTypeCodec(final Class unionCls,final Set codecs, + @Nullable Codec identityrefCodec) { super(unionCls); + this.identityrefCodec = identityrefCodec; try { charConstructor = unionCls.getConstructor(char[].class); typeCodecs = ImmutableSet.copyOf(codecs); @@ -35,37 +41,43 @@ final class UnionTypeCodec extends ReflectionBasedCodec { } } - static Callable loader(final Class unionCls, final UnionTypeDefinition unionType) { + static Callable loader(final Class unionCls, final UnionTypeDefinition unionType, + BindingCodecContext bindingCodecContext) { return new Callable() { @Override public UnionTypeCodec call() throws NoSuchMethodException, SecurityException { + Codec identityrefCodec = null; Set values = new HashSet<>(); - for(TypeDefinition subtype : unionType.getTypes()) { + for (TypeDefinition subtype : unionType.getTypes()) { String methodName = "get" + BindingMapping.getClassName(subtype.getQName()); Method valueGetter = unionCls.getMethod(methodName); Class valueType = valueGetter.getReturnType(); - Codec valueCodec = UnionTypeCodec.getCodecForType(valueType, subtype); + Codec valueCodec = bindingCodecContext.getCodec(valueType, subtype); + if (Class.class.equals(valueType)) { + identityrefCodec = valueCodec; + } values.add(new UnionValueOptionContext(valueType,valueGetter, valueCodec)); } - return new UnionTypeCodec(unionCls, values); + return new UnionTypeCodec(unionCls, values, identityrefCodec); } }; } - private static Codec getCodecForType(final Class valueType, final TypeDefinition subtype) { - if (subtype.getBaseType() instanceof UnionTypeDefinition) { + @Override + public Object deserialize(final Object input) { + if (identityrefCodec != null) { try { - return UnionTypeCodec.loader(valueType, (UnionTypeDefinition) subtype.getBaseType()).call(); - } catch (final Exception e) { - throw new IllegalStateException("Could not construct Union Type Codec"); + Object identityref = identityrefCodec.deserialize(input); + return typeClass.getConstructor(Class.class).newInstance(identityref); + } catch (UncheckedExecutionException | ExecutionError e) { + // ignore this exception caused by deserialize() + } catch (NoSuchMethodException e) { + // caused by getContructor(). this case shouldn't happen. + throw new IllegalStateException("Could not construct instance", e); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + // ignore this exception caused by newInstance() } - } else { - return ValueTypeCodec.getCodecFor(valueType, subtype); } - } - - @Override - public Object deserialize(final Object input) { try { if (input instanceof byte[]) { return charConstructor.newInstance(BaseEncoding.base64().encode((byte[]) input).toCharArray());