2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.impl.codec;
10 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.INT16_QNAME;
11 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.INT32_QNAME;
12 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.INT64_QNAME;
13 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.INT8_QNAME;
14 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.UINT16_QNAME;
15 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.UINT32_QNAME;
16 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.UINT64_QNAME;
17 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.UINT8_QNAME;
19 import java.math.BigDecimal;
20 import java.math.BigInteger;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
25 import org.opendaylight.yangtools.yang.data.api.codec.BinaryCodec;
26 import org.opendaylight.yangtools.yang.data.api.codec.BitsCodec;
27 import org.opendaylight.yangtools.yang.data.api.codec.BooleanCodec;
28 import org.opendaylight.yangtools.yang.data.api.codec.DecimalCodec;
29 import org.opendaylight.yangtools.yang.data.api.codec.EmptyCodec;
30 import org.opendaylight.yangtools.yang.data.api.codec.EnumCodec;
31 import org.opendaylight.yangtools.yang.data.api.codec.Int16Codec;
32 import org.opendaylight.yangtools.yang.data.api.codec.Int32Codec;
33 import org.opendaylight.yangtools.yang.data.api.codec.Int64Codec;
34 import org.opendaylight.yangtools.yang.data.api.codec.Int8Codec;
35 import org.opendaylight.yangtools.yang.data.api.codec.StringCodec;
36 import org.opendaylight.yangtools.yang.data.api.codec.Uint16Codec;
37 import org.opendaylight.yangtools.yang.data.api.codec.Uint32Codec;
38 import org.opendaylight.yangtools.yang.data.api.codec.Uint64Codec;
39 import org.opendaylight.yangtools.yang.data.api.codec.Uint8Codec;
40 import org.opendaylight.yangtools.yang.data.api.codec.UnionCodec;
41 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
42 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
43 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
44 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
45 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
46 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
47 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
48 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
49 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
50 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
51 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
53 import com.google.common.base.Joiner;
54 import com.google.common.base.Optional;
55 import com.google.common.base.Preconditions;
56 import com.google.common.base.Splitter;
57 import com.google.common.collect.ImmutableSet;
58 import com.google.common.io.BaseEncoding;
60 public abstract class TypeDefinitionAwareCodec<J, T extends TypeDefinition<T>> implements DataStringCodec<J> {
62 private static final Pattern intPattern = Pattern.compile("[+-]?[1-9][0-9]*$");
63 private static final Pattern hexPattern = Pattern.compile("[+-]?0[xX][0-9a-fA-F]+");
64 private static final Pattern octalPattern = Pattern.compile("[+-]?0[1-7][0-7]*$");
66 private final Optional<T> typeDefinition;
67 private final Class<J> inputClass;
69 private static final int provideBase(final String integer) {
70 if (integer == null) {
71 throw new IllegalArgumentException("String representing integer number cannot be NULL!");
74 if ((integer.length() == 1) && (integer.charAt(0) == '0')) {
78 final Matcher intMatcher = intPattern.matcher(integer);
79 if (intMatcher.matches()) {
82 final Matcher hexMatcher = hexPattern.matcher(integer);
83 if (hexMatcher.matches()) {
86 final Matcher octMatcher = octalPattern.matcher(integer);
87 if (octMatcher.matches()) {
90 String formatedMessage = String.format("Incorrect lexical representation of Integer value: %s"
91 + "%nThe Integer value can be defined as "
92 + "%n- Integer Number,"
93 + "%n- Hexadecimal Number (prefix 0x),"
94 + "%n- Octal Number (prefix 0)."
95 + "%nThe sign vlues are allowed. Spaces between digits are NOT allowed!", integer);
96 throw new NumberFormatException(formatedMessage);
102 private static String normalizeHexadecimal(final String hexInt) {
103 if (hexInt == null) {
104 throw new IllegalArgumentException(
105 "String representing integer number in Hexadecimal format cannot be NULL!");
107 final String normalizedString;
108 if (hexInt.contains("x")) {
109 normalizedString = hexInt.replace("x", "");
110 } else if (hexInt.contains("X")) {
111 normalizedString = hexInt.replace("X", "");
113 normalizedString = hexInt;
115 return normalizedString;
118 public static final BinaryCodecStringImpl BINARY_DEFAULT_CODEC = new BinaryCodecStringImpl(
119 Optional.<BinaryTypeDefinition> absent());
121 public static final BitsCodecStringImpl BITS_DEFAULT_CODEC = new BitsCodecStringImpl(
122 Optional.<BitsTypeDefinition> absent());
124 public static final BooleanCodecStringImpl BOOLEAN_DEFAULT_CODEC = new BooleanCodecStringImpl(
125 Optional.<BooleanTypeDefinition> absent());
127 public static final DecimalCodecStringImpl DECIMAL64_DEFAULT_CODEC = new DecimalCodecStringImpl(
128 Optional.<DecimalTypeDefinition> absent());
130 public static final EmptyCodecStringImpl EMPTY_DEFAULT_CODEC = new EmptyCodecStringImpl(
131 Optional.<EmptyTypeDefinition> absent());
133 public static final EnumCodecStringImpl ENUMERATION_DEFAULT_CODEC = new EnumCodecStringImpl(
134 Optional.<EnumTypeDefinition> absent());
136 public static final Int8CodecStringImpl INT8_DEFAULT_CODEC = new Int8CodecStringImpl(
137 Optional.<IntegerTypeDefinition> absent());
139 public static final Int16CodecStringImpl INT16_DEFAULT_CODEC = new Int16CodecStringImpl(
140 Optional.<IntegerTypeDefinition> absent());
142 public static final Int32CodecStringImpl INT32_DEFAULT_CODEC = new Int32CodecStringImpl(
143 Optional.<IntegerTypeDefinition> absent());
145 public static final Int64CodecStringImpl INT64_DEFAULT_CODEC = new Int64CodecStringImpl(
146 Optional.<IntegerTypeDefinition> absent());
148 public static final StringCodecStringImpl STRING_DEFAULT_CODEC = new StringCodecStringImpl(
149 Optional.<StringTypeDefinition> absent());
151 public static final Uint8CodecStringImpl UINT8_DEFAULT_CODEC = new Uint8CodecStringImpl(
152 Optional.<UnsignedIntegerTypeDefinition> absent());
154 public static final Uint16CodecStringImpl UINT16_DEFAULT_CODEC = new Uint16CodecStringImpl(
155 Optional.<UnsignedIntegerTypeDefinition> absent());
157 public static final Uint32CodecStringImpl UINT32_DEFAULT_CODEC = new Uint32CodecStringImpl(
158 Optional.<UnsignedIntegerTypeDefinition> absent());
160 public static final Uint64CodecStringImpl UINT64_DEFAULT_CODEC = new Uint64CodecStringImpl(
161 Optional.<UnsignedIntegerTypeDefinition> absent());
163 public static final UnionCodecStringImpl UNION_DEFAULT_CODEC = new UnionCodecStringImpl(
164 Optional.<UnionTypeDefinition> absent());
166 public Class<J> getInputClass() {
170 protected TypeDefinitionAwareCodec(Optional<T> typeDefinition, Class<J> outputClass) {
171 Preconditions.checkArgument(outputClass != null, "Output class must be specified.");
172 this.typeDefinition = typeDefinition;
173 this.inputClass = outputClass;
176 public Optional<T> getTypeDefinition() {
177 return typeDefinition;
180 @SuppressWarnings({ "rawtypes", "unchecked" })
181 public static final TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> from(TypeDefinition typeDefinition) {
182 final TypeDefinitionAwareCodec codec = fromType(typeDefinition);
183 return (TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>) codec;
186 public static final <T extends TypeDefinition<T>> TypeDefinitionAwareCodec<?, T> fromType(T typeDefinition) {
187 T superType = typeDefinition;
188 while (superType.getBaseType() != null) {
189 superType = superType.getBaseType();
192 @SuppressWarnings("rawtypes")
193 TypeDefinitionAwareCodec codec = null;
195 if (superType instanceof BinaryTypeDefinition) {
196 codec = BINARY_DEFAULT_CODEC;
197 } else if (superType instanceof BitsTypeDefinition) {
198 codec = BITS_DEFAULT_CODEC;
199 } else if (superType instanceof BooleanTypeDefinition) {
200 codec = BOOLEAN_DEFAULT_CODEC;
201 } else if (superType instanceof DecimalTypeDefinition) {
202 codec = DECIMAL64_DEFAULT_CODEC;
203 } else if (superType instanceof EmptyTypeDefinition) {
204 codec = EMPTY_DEFAULT_CODEC;
205 } else if (superType instanceof EnumTypeDefinition) {
206 codec = ENUMERATION_DEFAULT_CODEC;
207 } else if (superType instanceof IntegerTypeDefinition) {
208 if (INT8_QNAME.equals(superType.getQName())) {
209 codec = INT8_DEFAULT_CODEC;
210 } else if (INT16_QNAME.equals(superType.getQName())) {
211 codec = INT16_DEFAULT_CODEC;
212 } else if (INT32_QNAME.equals(superType.getQName())) {
213 codec = INT32_DEFAULT_CODEC;
214 } else if (INT64_QNAME.equals(superType.getQName())) {
215 codec = INT64_DEFAULT_CODEC;
217 } else if (superType instanceof StringTypeDefinition) {
218 codec = STRING_DEFAULT_CODEC;
219 } else if (superType instanceof UnionTypeDefinition) {
220 codec = UNION_DEFAULT_CODEC;
221 } else if (superType instanceof UnsignedIntegerTypeDefinition) {
222 if (UINT8_QNAME.equals(superType.getQName())) {
223 codec = UINT8_DEFAULT_CODEC;
225 if (UINT16_QNAME.equals(superType.getQName())) {
226 codec = UINT16_DEFAULT_CODEC;
228 if (UINT32_QNAME.equals(superType.getQName())) {
229 codec = UINT32_DEFAULT_CODEC;
231 if (UINT64_QNAME.equals(superType.getQName())) {
232 codec = UINT64_DEFAULT_CODEC;
235 @SuppressWarnings("unchecked")
236 TypeDefinitionAwareCodec<?, T> ret = (TypeDefinitionAwareCodec<?, T>) codec;
240 public static class BooleanCodecStringImpl extends TypeDefinitionAwareCodec<Boolean, BooleanTypeDefinition>
241 implements BooleanCodec<String> {
243 protected BooleanCodecStringImpl(Optional<BooleanTypeDefinition> typeDef) {
244 super(typeDef, Boolean.class);
248 public String serialize(Boolean data) {
249 return data == null ? "" : data.toString();
253 public Boolean deserialize(String stringRepresentation) {
254 return Boolean.valueOf(stringRepresentation);
258 public static class Uint8CodecStringImpl extends TypeDefinitionAwareCodec<Short, UnsignedIntegerTypeDefinition>
259 implements Uint8Codec<String> {
261 protected Uint8CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
262 super(typeDef, Short.class);
266 public String serialize(Short data) {
267 return data == null ? "" : data.toString();
271 public Short deserialize(String stringRepresentation) {
272 int base = provideBase(stringRepresentation);
274 return Short.valueOf(normalizeHexadecimal(stringRepresentation), base);
276 return Short.valueOf(stringRepresentation, base);
280 public static class Uint16CodecStringImpl extends TypeDefinitionAwareCodec<Integer, UnsignedIntegerTypeDefinition>
281 implements Uint16Codec<String> {
282 protected Uint16CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
283 super(typeDef, Integer.class);
287 public Integer deserialize(String stringRepresentation) {
288 int base = provideBase(stringRepresentation);
290 return Integer.valueOf(normalizeHexadecimal(stringRepresentation), base);
292 return Integer.valueOf(stringRepresentation, base);
296 public String serialize(Integer data) {
297 return data == null ? "" : data.toString();
301 public static class Uint32CodecStringImpl extends TypeDefinitionAwareCodec<Long, UnsignedIntegerTypeDefinition>
302 implements Uint32Codec<String> {
304 protected Uint32CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
305 super(typeDef, Long.class);
309 public Long deserialize(String stringRepresentation) {
310 int base = provideBase(stringRepresentation);
312 return Long.valueOf(normalizeHexadecimal(stringRepresentation), base);
314 return Long.valueOf(stringRepresentation, base);
318 public String serialize(Long data) {
319 return data == null ? "" : data.toString();
323 public static class Uint64CodecStringImpl extends
324 TypeDefinitionAwareCodec<BigInteger, UnsignedIntegerTypeDefinition> implements Uint64Codec<String> {
326 protected Uint64CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
327 super(typeDef, BigInteger.class);
331 public BigInteger deserialize(String stringRepresentation) {
332 int base = provideBase(stringRepresentation);
334 return new BigInteger(normalizeHexadecimal(stringRepresentation), base);
336 return new BigInteger(stringRepresentation, base);
340 public String serialize(BigInteger data) {
341 return data == null ? "" : data.toString();
345 public static class StringCodecStringImpl extends TypeDefinitionAwareCodec<String, StringTypeDefinition> implements
346 StringCodec<String> {
348 protected StringCodecStringImpl(Optional<StringTypeDefinition> typeDef) {
349 super(typeDef, String.class);
353 public String deserialize(String stringRepresentation) {
354 return stringRepresentation;
358 public String serialize(String data) {
359 return data == null ? "" : data.toString();
363 public static class Int16CodecStringImpl extends TypeDefinitionAwareCodec<Short, IntegerTypeDefinition> implements
366 protected Int16CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
367 super(typeDef, Short.class);
371 public Short deserialize(String stringRepresentation) {
372 int base = provideBase(stringRepresentation);
374 return Short.valueOf(normalizeHexadecimal(stringRepresentation), base);
376 return Short.valueOf(stringRepresentation, base);
380 public String serialize(Short data) {
381 return data == null ? "" : data.toString();
385 public static class Int32CodecStringImpl extends TypeDefinitionAwareCodec<Integer, IntegerTypeDefinition> implements
388 protected Int32CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
389 super(typeDef, Integer.class);
393 public Integer deserialize(String stringRepresentation) {
394 int base = provideBase(stringRepresentation);
396 return Integer.valueOf(normalizeHexadecimal(stringRepresentation), base);
398 return Integer.valueOf(stringRepresentation, base);
402 public String serialize(Integer data) {
403 return data == null ? "" : data.toString();
407 public static class Int64CodecStringImpl extends TypeDefinitionAwareCodec<Long, IntegerTypeDefinition> implements
410 protected Int64CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
411 super(typeDef, Long.class);
415 public Long deserialize(String stringRepresentation) {
416 int base = provideBase(stringRepresentation);
418 return Long.valueOf(normalizeHexadecimal(stringRepresentation), base);
420 return Long.valueOf(stringRepresentation, base);
424 public String serialize(Long data) {
425 return data == null ? "" : data.toString();
429 public static class Int8CodecStringImpl extends TypeDefinitionAwareCodec<Byte, IntegerTypeDefinition> implements
432 protected Int8CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
433 super(typeDef, Byte.class);
437 public Byte deserialize(String stringRepresentation) {
438 int base = provideBase(stringRepresentation);
440 return Byte.valueOf(normalizeHexadecimal(stringRepresentation), base);
442 return Byte.valueOf(stringRepresentation, base);
446 public String serialize(Byte data) {
447 return data == null ? "" : data.toString();
451 public static class EmptyCodecStringImpl extends TypeDefinitionAwareCodec<Void, EmptyTypeDefinition> implements
454 protected EmptyCodecStringImpl(Optional<EmptyTypeDefinition> typeDef) {
455 super(typeDef, Void.class);
459 public String serialize(Void data) {
464 public Void deserialize(String stringRepresentation) {
469 public static final class BinaryCodecStringImpl extends TypeDefinitionAwareCodec<byte[], BinaryTypeDefinition>
470 implements BinaryCodec<String> {
472 protected BinaryCodecStringImpl(Optional<BinaryTypeDefinition> typeDef) {
473 super(typeDef, byte[].class);
477 public String serialize(byte[] data) {
478 return data == null ? "" : BaseEncoding.base64().encode(data);
482 public byte[] deserialize(String stringRepresentation) {
483 return BaseEncoding.base64().decode(stringRepresentation);
487 public static final class BitsCodecStringImpl extends TypeDefinitionAwareCodec<Set<String>, BitsTypeDefinition>
488 implements BitsCodec<String> {
490 public static final Joiner JOINER = Joiner.on(" ").skipNulls();
491 public static final Splitter SPLITTER = Splitter.on(' ').omitEmptyStrings().trimResults();
493 @SuppressWarnings("unchecked")
494 protected BitsCodecStringImpl(Optional<BitsTypeDefinition> typeDef) {
495 super(typeDef, (Class<Set<String>>) ((Class<?>) Set.class));
499 public String serialize(Set<String> data) {
500 return data == null ? "" : JOINER.join(data);
504 public Set<String> deserialize(String stringRepresentation) {
505 if (stringRepresentation == null)
506 return ImmutableSet.of();
507 Iterable<String> strings = SPLITTER.split(stringRepresentation);
508 return ImmutableSet.copyOf(strings);
512 public static class EnumCodecStringImpl extends TypeDefinitionAwareCodec<String, EnumTypeDefinition> implements
515 protected EnumCodecStringImpl(Optional<EnumTypeDefinition> typeDef) {
516 super(typeDef, String.class);
520 public String deserialize(String stringRepresentation) {
521 return stringRepresentation;
525 public String serialize(String data) {
526 return data == null ? "" : data.toString();
530 public static class DecimalCodecStringImpl extends TypeDefinitionAwareCodec<BigDecimal, DecimalTypeDefinition>
531 implements DecimalCodec<String> {
533 protected DecimalCodecStringImpl(Optional<DecimalTypeDefinition> typeDef) {
534 super(typeDef, BigDecimal.class);
538 public String serialize(BigDecimal data) {
539 return data == null ? "" : data.toString();
543 public BigDecimal deserialize(String stringRepresentation) {
544 return new BigDecimal(stringRepresentation);
548 public static class UnionCodecStringImpl extends TypeDefinitionAwareCodec<String, UnionTypeDefinition> implements
551 protected UnionCodecStringImpl(Optional<UnionTypeDefinition> typeDef) {
552 super(typeDef, String.class);
556 public String serialize(String data) {
557 return data == null ? "" : data;
561 public String deserialize(String stringRepresentation) {
562 return stringRepresentation;