X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fcodec%2FTypeDefinitionAwareCodec.java;h=e735b28d61ec1192ad8383430dc21b3d0a06d337;hb=153362f50d57c7e3b39e07b626d8acf238aa88ed;hp=dfb02c5d5f5834b64ab5fd8086b3939e468a9456;hpb=c13d86aaecf1bd9b6ba491b6e341d23c901c3eef;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/TypeDefinitionAwareCodec.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/TypeDefinitionAwareCodec.java index dfb02c5d5f..e735b28d61 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/TypeDefinitionAwareCodec.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/TypeDefinitionAwareCodec.java @@ -16,12 +16,21 @@ import static org.opendaylight.yangtools.yang.model.util.BaseTypes.UINT32_QNAME; import static org.opendaylight.yangtools.yang.model.util.BaseTypes.UINT64_QNAME; import static org.opendaylight.yangtools.yang.model.util.BaseTypes.UINT8_QNAME; +import com.google.common.base.CharMatcher; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import com.google.common.io.BaseEncoding; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; - +import javax.xml.bind.DatatypeConverter; import org.opendaylight.yangtools.yang.data.api.codec.BinaryCodec; import org.opendaylight.yangtools.yang.data.api.codec.BitsCodec; import org.opendaylight.yangtools.yang.data.api.codec.BooleanCodec; @@ -45,30 +54,27 @@ import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair; import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition; -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableSet; -import com.google.common.io.BaseEncoding; - public abstract class TypeDefinitionAwareCodec> implements DataStringCodec { private static final Pattern intPattern = Pattern.compile("[+-]?[1-9][0-9]*$"); private static final Pattern hexPattern = Pattern.compile("[+-]?0[xX][0-9a-fA-F]+"); private static final Pattern octalPattern = Pattern.compile("[+-]?0[1-7][0-7]*$"); + // For up to two characters, this is very fast + private static final CharMatcher X_MATCHER = CharMatcher.anyOf("xX"); + private final Optional typeDefinition; private final Class inputClass; private static final int provideBase(final String integer) { if (integer == null) { - throw new IllegalArgumentException("String representing integer number cannot be NULL!"); + throw new IllegalArgumentException("String representing integer number cannot be NULL"); } if ((integer.length() == 1) && (integer.charAt(0) == '0')) { @@ -87,12 +93,12 @@ public abstract class TypeDefinitionAwareCodec> i if (octMatcher.matches()) { return 8; } else { - String formatedMessage = String.format("Incorrect lexical representation of Integer value: %s" - + "%nThe Integer value can be defined as " - + "%n- Integer Number," - + "%n- Hexadecimal Number (prefix 0x)," - + "%n- Octal Number (prefix 0)." - + "%nThe sign vlues are allowed. Spaces between digits are NOT allowed!", integer); + String formatedMessage = String.format("Incorrect lexical representation of integer value: %s." + + "%nAn integer value can be defined as: " + + "%n - a decimal number," + + "%n - a hexadecimal number (prefix 0x)," + + "%n - an octal number (prefix 0)." + + "%nSigned values are allowed. Spaces between digits are NOT allowed.", integer); throw new NumberFormatException(formatedMessage); } } @@ -104,70 +110,55 @@ public abstract class TypeDefinitionAwareCodec> i throw new IllegalArgumentException( "String representing integer number in Hexadecimal format cannot be NULL!"); } - final String normalizedString; - if (hexInt.contains("x")) { - normalizedString = hexInt.replace("x", ""); - } else if (hexInt.contains("X")) { - normalizedString = hexInt.replace("X", ""); - } else { - normalizedString = hexInt; - } - return normalizedString; + + return X_MATCHER.removeFrom(hexInt); } - public static final BinaryCodecStringImpl BINARY_DEFAULT_CODEC = new BinaryCodecStringImpl( + private static final BinaryCodecStringImpl BINARY_DEFAULT_CODEC = new BinaryCodecStringImpl( Optional. absent()); - public static final BitsCodecStringImpl BITS_DEFAULT_CODEC = new BitsCodecStringImpl( - Optional. absent()); - - public static final BooleanCodecStringImpl BOOLEAN_DEFAULT_CODEC = new BooleanCodecStringImpl( + private static final BooleanCodecStringImpl BOOLEAN_DEFAULT_CODEC = new BooleanCodecStringImpl( Optional. absent()); - public static final DecimalCodecStringImpl DECIMAL64_DEFAULT_CODEC = new DecimalCodecStringImpl( + private static final DecimalCodecStringImpl DECIMAL64_DEFAULT_CODEC = new DecimalCodecStringImpl( Optional. absent()); - public static final EmptyCodecStringImpl EMPTY_DEFAULT_CODEC = new EmptyCodecStringImpl( + private static final EmptyCodecStringImpl EMPTY_DEFAULT_CODEC = new EmptyCodecStringImpl( Optional. absent()); - public static final EnumCodecStringImpl ENUMERATION_DEFAULT_CODEC = new EnumCodecStringImpl( - Optional. absent()); - - public static final Int8CodecStringImpl INT8_DEFAULT_CODEC = new Int8CodecStringImpl( + private static final Int8CodecStringImpl INT8_DEFAULT_CODEC = new Int8CodecStringImpl( Optional. absent()); - public static final Int16CodecStringImpl INT16_DEFAULT_CODEC = new Int16CodecStringImpl( + private static final Int16CodecStringImpl INT16_DEFAULT_CODEC = new Int16CodecStringImpl( Optional. absent()); - public static final Int32CodecStringImpl INT32_DEFAULT_CODEC = new Int32CodecStringImpl( + private static final Int32CodecStringImpl INT32_DEFAULT_CODEC = new Int32CodecStringImpl( Optional. absent()); - public static final Int64CodecStringImpl INT64_DEFAULT_CODEC = new Int64CodecStringImpl( + private static final Int64CodecStringImpl INT64_DEFAULT_CODEC = new Int64CodecStringImpl( Optional. absent()); - public static final StringCodecStringImpl STRING_DEFAULT_CODEC = new StringCodecStringImpl( + private static final StringCodecStringImpl STRING_DEFAULT_CODEC = new StringCodecStringImpl( Optional. absent()); - public static final Uint8CodecStringImpl UINT8_DEFAULT_CODEC = new Uint8CodecStringImpl( + private static final Uint8CodecStringImpl UINT8_DEFAULT_CODEC = new Uint8CodecStringImpl( Optional. absent()); - public static final Uint16CodecStringImpl UINT16_DEFAULT_CODEC = new Uint16CodecStringImpl( + private static final Uint16CodecStringImpl UINT16_DEFAULT_CODEC = new Uint16CodecStringImpl( Optional. absent()); - public static final Uint32CodecStringImpl UINT32_DEFAULT_CODEC = new Uint32CodecStringImpl( + private static final Uint32CodecStringImpl UINT32_DEFAULT_CODEC = new Uint32CodecStringImpl( Optional. absent()); - public static final Uint64CodecStringImpl UINT64_DEFAULT_CODEC = new Uint64CodecStringImpl( + private static final Uint64CodecStringImpl UINT64_DEFAULT_CODEC = new Uint64CodecStringImpl( Optional. absent()); - public static final UnionCodecStringImpl UNION_DEFAULT_CODEC = new UnionCodecStringImpl( - Optional. absent()); - + @Override public Class getInputClass() { return inputClass; } - protected TypeDefinitionAwareCodec(Optional typeDefinition, Class outputClass) { + protected TypeDefinitionAwareCodec(final Optional typeDefinition, final Class outputClass) { Preconditions.checkArgument(outputClass != null, "Output class must be specified."); this.typeDefinition = typeDefinition; this.inputClass = outputClass; @@ -178,12 +169,12 @@ public abstract class TypeDefinitionAwareCodec> i } @SuppressWarnings({ "rawtypes", "unchecked" }) - public static final TypeDefinitionAwareCodec> from(TypeDefinition typeDefinition) { - final TypeDefinitionAwareCodec codec = fromType(typeDefinition); - return (TypeDefinitionAwareCodec>) codec; + public static final TypeDefinitionAwareCodec> from(final TypeDefinition typeDefinition) { + return fromType(typeDefinition); } - public static final > TypeDefinitionAwareCodec fromType(T typeDefinition) { + @SuppressWarnings("unchecked") + public static final > TypeDefinitionAwareCodec fromType(final T typeDefinition) { T superType = typeDefinition; while (superType.getBaseType() != null) { superType = superType.getBaseType(); @@ -195,7 +186,7 @@ public abstract class TypeDefinitionAwareCodec> i if (superType instanceof BinaryTypeDefinition) { codec = BINARY_DEFAULT_CODEC; } else if (superType instanceof BitsTypeDefinition) { - codec = BITS_DEFAULT_CODEC; + codec = new BitsCodecStringImpl( Optional.of( (BitsTypeDefinition)superType ) ); } else if (superType instanceof BooleanTypeDefinition) { codec = BOOLEAN_DEFAULT_CODEC; } else if (superType instanceof DecimalTypeDefinition) { @@ -203,7 +194,7 @@ public abstract class TypeDefinitionAwareCodec> i } else if (superType instanceof EmptyTypeDefinition) { codec = EMPTY_DEFAULT_CODEC; } else if (superType instanceof EnumTypeDefinition) { - codec = ENUMERATION_DEFAULT_CODEC; + codec = new EnumCodecStringImpl( Optional.of( (EnumTypeDefinition)superType ) ); } else if (superType instanceof IntegerTypeDefinition) { if (INT8_QNAME.equals(superType.getQName())) { codec = INT8_DEFAULT_CODEC; @@ -217,7 +208,7 @@ public abstract class TypeDefinitionAwareCodec> i } else if (superType instanceof StringTypeDefinition) { codec = STRING_DEFAULT_CODEC; } else if (superType instanceof UnionTypeDefinition) { - codec = UNION_DEFAULT_CODEC; + codec = new UnionCodecStringImpl( Optional.of( (UnionTypeDefinition)superType ) ); } else if (superType instanceof UnsignedIntegerTypeDefinition) { if (UINT8_QNAME.equals(superType.getQName())) { codec = UINT8_DEFAULT_CODEC; @@ -232,25 +223,24 @@ public abstract class TypeDefinitionAwareCodec> i codec = UINT64_DEFAULT_CODEC; } } - @SuppressWarnings("unchecked") - TypeDefinitionAwareCodec ret = (TypeDefinitionAwareCodec) codec; - return ret; + + return codec; } public static class BooleanCodecStringImpl extends TypeDefinitionAwareCodec implements BooleanCodec { - protected BooleanCodecStringImpl(Optional typeDef) { + protected BooleanCodecStringImpl(final Optional typeDef) { super(typeDef, Boolean.class); } @Override - public String serialize(Boolean data) { + public String serialize(final Boolean data) { return data == null ? "" : data.toString(); } @Override - public Boolean deserialize(String stringRepresentation) { + public Boolean deserialize(final String stringRepresentation) { return Boolean.valueOf(stringRepresentation); } }; @@ -258,17 +248,17 @@ public abstract class TypeDefinitionAwareCodec> i public static class Uint8CodecStringImpl extends TypeDefinitionAwareCodec implements Uint8Codec { - protected Uint8CodecStringImpl(Optional typeDef) { + protected Uint8CodecStringImpl(final Optional typeDef) { super(typeDef, Short.class); } @Override - public String serialize(Short data) { + public String serialize(final Short data) { return data == null ? "" : data.toString(); } @Override - public Short deserialize(String stringRepresentation) { + public Short deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return Short.valueOf(normalizeHexadecimal(stringRepresentation), base); @@ -279,12 +269,12 @@ public abstract class TypeDefinitionAwareCodec> i public static class Uint16CodecStringImpl extends TypeDefinitionAwareCodec implements Uint16Codec { - protected Uint16CodecStringImpl(Optional typeDef) { + protected Uint16CodecStringImpl(final Optional typeDef) { super(typeDef, Integer.class); } @Override - public Integer deserialize(String stringRepresentation) { + public Integer deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return Integer.valueOf(normalizeHexadecimal(stringRepresentation), base); @@ -293,7 +283,7 @@ public abstract class TypeDefinitionAwareCodec> i } @Override - public String serialize(Integer data) { + public String serialize(final Integer data) { return data == null ? "" : data.toString(); } }; @@ -301,12 +291,12 @@ public abstract class TypeDefinitionAwareCodec> i public static class Uint32CodecStringImpl extends TypeDefinitionAwareCodec implements Uint32Codec { - protected Uint32CodecStringImpl(Optional typeDef) { + protected Uint32CodecStringImpl(final Optional typeDef) { super(typeDef, Long.class); } @Override - public Long deserialize(String stringRepresentation) { + public Long deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return Long.valueOf(normalizeHexadecimal(stringRepresentation), base); @@ -315,7 +305,7 @@ public abstract class TypeDefinitionAwareCodec> i } @Override - public String serialize(Long data) { + public String serialize(final Long data) { return data == null ? "" : data.toString(); } }; @@ -323,12 +313,12 @@ public abstract class TypeDefinitionAwareCodec> i public static class Uint64CodecStringImpl extends TypeDefinitionAwareCodec implements Uint64Codec { - protected Uint64CodecStringImpl(Optional typeDef) { + protected Uint64CodecStringImpl(final Optional typeDef) { super(typeDef, BigInteger.class); } @Override - public BigInteger deserialize(String stringRepresentation) { + public BigInteger deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return new BigInteger(normalizeHexadecimal(stringRepresentation), base); @@ -337,7 +327,7 @@ public abstract class TypeDefinitionAwareCodec> i } @Override - public String serialize(BigInteger data) { + public String serialize(final BigInteger data) { return data == null ? "" : data.toString(); } }; @@ -345,30 +335,30 @@ public abstract class TypeDefinitionAwareCodec> i public static class StringCodecStringImpl extends TypeDefinitionAwareCodec implements StringCodec { - protected StringCodecStringImpl(Optional typeDef) { + protected StringCodecStringImpl(final Optional typeDef) { super(typeDef, String.class); } @Override - public String deserialize(String stringRepresentation) { - return stringRepresentation; + public String deserialize(final String stringRepresentation) { + return stringRepresentation == null ? "" : stringRepresentation; } @Override - public String serialize(String data) { - return data == null ? "" : data.toString(); + public String serialize(final String data) { + return data == null ? "" : data; } }; public static class Int16CodecStringImpl extends TypeDefinitionAwareCodec implements Int16Codec { - protected Int16CodecStringImpl(Optional typeDef) { + protected Int16CodecStringImpl(final Optional typeDef) { super(typeDef, Short.class); } @Override - public Short deserialize(String stringRepresentation) { + public Short deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return Short.valueOf(normalizeHexadecimal(stringRepresentation), base); @@ -377,7 +367,7 @@ public abstract class TypeDefinitionAwareCodec> i } @Override - public String serialize(Short data) { + public String serialize(final Short data) { return data == null ? "" : data.toString(); } }; @@ -385,12 +375,12 @@ public abstract class TypeDefinitionAwareCodec> i public static class Int32CodecStringImpl extends TypeDefinitionAwareCodec implements Int32Codec { - protected Int32CodecStringImpl(Optional typeDef) { + protected Int32CodecStringImpl(final Optional typeDef) { super(typeDef, Integer.class); } @Override - public Integer deserialize(String stringRepresentation) { + public Integer deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return Integer.valueOf(normalizeHexadecimal(stringRepresentation), base); @@ -399,7 +389,7 @@ public abstract class TypeDefinitionAwareCodec> i } @Override - public String serialize(Integer data) { + public String serialize(final Integer data) { return data == null ? "" : data.toString(); } }; @@ -407,12 +397,12 @@ public abstract class TypeDefinitionAwareCodec> i public static class Int64CodecStringImpl extends TypeDefinitionAwareCodec implements Int64Codec { - protected Int64CodecStringImpl(Optional typeDef) { + protected Int64CodecStringImpl(final Optional typeDef) { super(typeDef, Long.class); } @Override - public Long deserialize(String stringRepresentation) { + public Long deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return Long.valueOf(normalizeHexadecimal(stringRepresentation), base); @@ -421,7 +411,7 @@ public abstract class TypeDefinitionAwareCodec> i } @Override - public String serialize(Long data) { + public String serialize(final Long data) { return data == null ? "" : data.toString(); } }; @@ -429,12 +419,12 @@ public abstract class TypeDefinitionAwareCodec> i public static class Int8CodecStringImpl extends TypeDefinitionAwareCodec implements Int8Codec { - protected Int8CodecStringImpl(Optional typeDef) { + protected Int8CodecStringImpl(final Optional typeDef) { super(typeDef, Byte.class); } @Override - public Byte deserialize(String stringRepresentation) { + public Byte deserialize(final String stringRepresentation) { int base = provideBase(stringRepresentation); if (base == 16) { return Byte.valueOf(normalizeHexadecimal(stringRepresentation), base); @@ -443,7 +433,7 @@ public abstract class TypeDefinitionAwareCodec> i } @Override - public String serialize(Byte data) { + public String serialize(final Byte data) { return data == null ? "" : data.toString(); } }; @@ -451,17 +441,19 @@ public abstract class TypeDefinitionAwareCodec> i public static class EmptyCodecStringImpl extends TypeDefinitionAwareCodec implements EmptyCodec { - protected EmptyCodecStringImpl(Optional typeDef) { + protected EmptyCodecStringImpl(final Optional typeDef) { super(typeDef, Void.class); } @Override - public String serialize(Void data) { + public String serialize(final Void data) { return ""; } @Override - public Void deserialize(String stringRepresentation) { + public Void deserialize(final String stringRepresentation) { + Preconditions.checkArgument( Strings.isNullOrEmpty( stringRepresentation ), + "The value must be empty" ); return null; } }; @@ -469,18 +461,18 @@ public abstract class TypeDefinitionAwareCodec> i public static final class BinaryCodecStringImpl extends TypeDefinitionAwareCodec implements BinaryCodec { - protected BinaryCodecStringImpl(Optional typeDef) { + protected BinaryCodecStringImpl(final Optional typeDef) { super(typeDef, byte[].class); } @Override - public String serialize(byte[] data) { + public String serialize(final byte[] data) { return data == null ? "" : BaseEncoding.base64().encode(data); } @Override - public byte[] deserialize(String stringRepresentation) { - return BaseEncoding.base64().decode(stringRepresentation); + public byte[] deserialize(final String stringRepresentation) { + return stringRepresentation == null ? null : DatatypeConverter.parseBase64Binary(stringRepresentation); } }; @@ -491,20 +483,38 @@ public abstract class TypeDefinitionAwareCodec> i public static final Splitter SPLITTER = Splitter.on(' ').omitEmptyStrings().trimResults(); @SuppressWarnings("unchecked") - protected BitsCodecStringImpl(Optional typeDef) { + protected BitsCodecStringImpl(final Optional typeDef) { super(typeDef, (Class>) ((Class) Set.class)); } @Override - public String serialize(Set data) { + public String serialize(final Set data) { return data == null ? "" : JOINER.join(data); } @Override - public Set deserialize(String stringRepresentation) { - if (stringRepresentation == null) + public Set deserialize(final String stringRepresentation) { + if (stringRepresentation == null) { return ImmutableSet.of(); + } + Iterable strings = SPLITTER.split(stringRepresentation); + + if( getTypeDefinition().isPresent() ) { + Set allowedNames = Sets.newHashSet(); + for( BitsTypeDefinition.Bit bit: getTypeDefinition().get().getBits() ) { + allowedNames.add( bit.getName() ); + } + + for( String bit: strings ) { + if( !allowedNames.contains( bit ) ) { + throw new IllegalArgumentException( + "Invalid value \"" + bit + "\" for bits type. Allowed values are: " + + allowedNames ); + } + } + } + return ImmutableSet.copyOf(strings); } }; @@ -512,53 +522,94 @@ public abstract class TypeDefinitionAwareCodec> i public static class EnumCodecStringImpl extends TypeDefinitionAwareCodec implements EnumCodec { - protected EnumCodecStringImpl(Optional typeDef) { + protected EnumCodecStringImpl(final Optional typeDef) { super(typeDef, String.class); } @Override - public String deserialize(String stringRepresentation) { + public String deserialize(final String stringRepresentation) { + if( getTypeDefinition().isPresent() ) { + Set allowedNames = Sets.newHashSet(); + for( EnumPair pair: getTypeDefinition().get().getValues() ) { + allowedNames.add( pair.getName() ); + } + + if( !allowedNames.contains( stringRepresentation ) ) { + throw new IllegalArgumentException( + "Invalid value \"" + stringRepresentation + "\" for enum type. Allowed values are: " + + allowedNames ); + } + } + return stringRepresentation; } @Override - public String serialize(String data) { - return data == null ? "" : data.toString(); + public String serialize(final String data) { + return data == null ? "" : data; } }; public static class DecimalCodecStringImpl extends TypeDefinitionAwareCodec implements DecimalCodec { - protected DecimalCodecStringImpl(Optional typeDef) { + protected DecimalCodecStringImpl(final Optional typeDef) { super(typeDef, BigDecimal.class); } @Override - public String serialize(BigDecimal data) { + public String serialize(final BigDecimal data) { return data == null ? "" : data.toString(); } @Override - public BigDecimal deserialize(String stringRepresentation) { + public BigDecimal deserialize(final String stringRepresentation) { + Preconditions.checkArgument( stringRepresentation != null , "Input cannot be null" ); return new BigDecimal(stringRepresentation); } }; - public static class UnionCodecStringImpl extends TypeDefinitionAwareCodec implements + public static class UnionCodecStringImpl extends TypeDefinitionAwareCodec implements UnionCodec { - protected UnionCodecStringImpl(Optional typeDef) { - super(typeDef, String.class); + protected UnionCodecStringImpl(final Optional typeDef) { + super(typeDef, Object.class); } @Override - public String serialize(String data) { - return data == null ? "" : data; + public String serialize(final Object data) { + return data == null ? "" : data.toString(); } @Override - public String deserialize(String stringRepresentation) { + public Object deserialize(final String stringRepresentation) { + if( getTypeDefinition().isPresent() ) { + boolean valid = false; + for( TypeDefinition type: getTypeDefinition().get().getTypes() ) { + TypeDefinitionAwareCodec> typeAwareCodec = from( type ); + if( typeAwareCodec == null ) { + // This is a type for which we have no codec (eg identity ref) so we'll say it's valid + // but we'll continue in case there's another type for which we do have a codec. + valid = true; + continue; + } + + try { + typeAwareCodec.deserialize( stringRepresentation ); + valid = true; + break; + } + catch( Exception e ) { + // invalid - try the next union type. + } + } + + if( !valid ) { + throw new IllegalArgumentException( + "Invalid value \"" + stringRepresentation + "\" for union type." ); + } + } + return stringRepresentation; } };