Implementation for Binary codec
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / codec / TypeDefinitionAwareCodec.java
1 package org.opendaylight.yangtools.yang.data.impl.codec;
2
3 import static org.opendaylight.yangtools.yang.model.util.BaseTypes.*;
4
5 import java.math.BigDecimal;
6 import java.math.BigInteger;
7 import java.util.Set;
8
9 import javax.xml.bind.DatatypeConverter;
10
11 import org.opendaylight.yangtools.yang.data.api.codec.*;
12 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
13 import org.opendaylight.yangtools.yang.model.api.type.*;
14
15 import com.google.common.base.*;
16 import com.google.common.collect.ImmutableSet;
17 import com.google.common.io.BaseEncoding;
18
19 public abstract class TypeDefinitionAwareCodec<J, T extends TypeDefinition<T>> implements DataStringCodec<J> {
20
21     private final Optional<T> typeDefinition;
22     private final Class<J> inputClass;
23
24     public static final BinaryCodecStringImpl BINARY_DEFAULT_CODEC = new BinaryCodecStringImpl(
25             Optional.<BinaryTypeDefinition> absent());
26
27     public static final BitsCodecStringImpl BITS_DEFAULT_CODEC = new BitsCodecStringImpl(
28             Optional.<BitsTypeDefinition> absent());
29
30     public static final BooleanCodecStringImpl BOOLEAN_DEFAULT_CODEC = new BooleanCodecStringImpl(
31             Optional.<BooleanTypeDefinition> absent());
32
33     public static final DecimalCodecStringImpl DECIMAL64_DEFAULT_CODEC = new DecimalCodecStringImpl(
34             Optional.<DecimalTypeDefinition> absent());
35
36     public static final EmptyCodecStringImpl EMPTY_DEFAULT_CODEC = new EmptyCodecStringImpl(
37             Optional.<EmptyTypeDefinition> absent());
38
39     public static final EnumCodecStringImpl ENUMERATION_DEFAULT_CODEC = new EnumCodecStringImpl(
40             Optional.<EnumTypeDefinition> absent());
41
42     public static final Int8CodecStringImpl INT8_DEFAULT_CODEC = new Int8CodecStringImpl(
43             Optional.<IntegerTypeDefinition> absent());
44
45     public static final Int16CodecStringImpl INT16_DEFAULT_CODEC = new Int16CodecStringImpl(
46             Optional.<IntegerTypeDefinition> absent());
47
48     public static final Int32CodecStringImpl INT32_DEFAULT_CODEC = new Int32CodecStringImpl(
49             Optional.<IntegerTypeDefinition> absent());
50
51     public static final Int64CodecStringImpl INT64_DEFAULT_CODEC = new Int64CodecStringImpl(
52             Optional.<IntegerTypeDefinition> absent());
53
54     public static final StringCodecStringImpl STRING_DEFAULT_CODEC = new StringCodecStringImpl(
55             Optional.<StringTypeDefinition> absent());
56
57     public static final Uint8CodecStringImpl UINT8_DEFAULT_CODEC = new Uint8CodecStringImpl(
58             Optional.<UnsignedIntegerTypeDefinition> absent());
59
60     public static final Uint16CodecStringImpl UINT16_DEFAULT_CODEC = new Uint16CodecStringImpl(
61             Optional.<UnsignedIntegerTypeDefinition> absent());
62
63     public static final Uint32CodecStringImpl UINT32_DEFAULT_CODEC = new Uint32CodecStringImpl(
64             Optional.<UnsignedIntegerTypeDefinition> absent());
65
66     public static final Uint64CodecStringImpl UINT64_DEFAULT_CODEC = new Uint64CodecStringImpl(
67             Optional.<UnsignedIntegerTypeDefinition> absent());
68
69     public Class<J> getInputClass() {
70         return inputClass;
71     }
72
73     protected TypeDefinitionAwareCodec(Optional<T> typeDefinition, Class<J> outputClass) {
74         Preconditions.checkArgument(outputClass != null, "Output class must be specified.");
75         this.typeDefinition = typeDefinition;
76         this.inputClass = outputClass;
77     }
78
79     public Optional<T> getTypeDefinition() {
80         return typeDefinition;
81     }
82
83     @SuppressWarnings({ "rawtypes", "unchecked" })
84     public static final TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> from(TypeDefinition typeDefinition) {
85         final TypeDefinitionAwareCodec codec = fromType(typeDefinition);
86         return (TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>) codec;
87     }
88
89     public static final <T extends TypeDefinition<T>> TypeDefinitionAwareCodec<?, T> fromType(T typeDefinition) {
90         T superType = typeDefinition;
91         while (superType.getBaseType() != null) {
92             superType = superType.getBaseType();
93         }
94
95         @SuppressWarnings("rawtypes")
96         TypeDefinitionAwareCodec codec = null;
97
98         if (superType instanceof BinaryTypeDefinition) {
99             codec = BINARY_DEFAULT_CODEC;
100         } else if (superType instanceof BitsTypeDefinition) {
101             codec = BITS_DEFAULT_CODEC;
102         } else if (superType instanceof BooleanTypeDefinition) {
103             codec = BOOLEAN_DEFAULT_CODEC;
104         } else if (superType instanceof DecimalTypeDefinition) {
105             codec = DECIMAL64_DEFAULT_CODEC;
106         } else if (superType instanceof EmptyTypeDefinition) {
107             codec = EMPTY_DEFAULT_CODEC;
108         } else if (superType instanceof EnumTypeDefinition) {
109             codec = ENUMERATION_DEFAULT_CODEC;
110         } else if (superType instanceof IntegerTypeDefinition) {
111             if (INT8_QNAME.equals(superType.getQName())) {
112                 codec = INT8_DEFAULT_CODEC;
113             } else if (INT16_QNAME.equals(superType.getQName())) {
114                 codec = INT16_DEFAULT_CODEC;
115             } else if (INT32_QNAME.equals(superType.getQName())) {
116                 codec = INT32_DEFAULT_CODEC;
117             } else if (INT64_QNAME.equals(superType.getQName())) {
118                 codec = INT64_DEFAULT_CODEC;
119             }
120         } else if (superType instanceof StringTypeDefinition) {
121             codec = STRING_DEFAULT_CODEC;
122         } else if (superType instanceof UnsignedIntegerTypeDefinition) {
123             if (UINT8_QNAME.equals(superType.getQName())) {
124                 codec = UINT8_DEFAULT_CODEC;
125             }
126             if (UINT16_QNAME.equals(superType.getQName())) {
127                 codec = UINT16_DEFAULT_CODEC;
128             }
129             if (UINT32_QNAME.equals(superType.getQName())) {
130                 codec = UINT32_DEFAULT_CODEC;
131             }
132             if (UINT64_QNAME.equals(superType.getQName())) {
133                 codec = UINT64_DEFAULT_CODEC;
134             }
135         }
136         return (TypeDefinitionAwareCodec<?, T>) codec;
137     }
138
139     public static class BooleanCodecStringImpl extends TypeDefinitionAwareCodec<Boolean, BooleanTypeDefinition>
140             implements BooleanCodec<String> {
141
142         protected BooleanCodecStringImpl(Optional<BooleanTypeDefinition> typeDef) {
143             super(typeDef, Boolean.class);
144         }
145
146         @Override
147         public String serialize(Boolean data) {
148             return data.toString();
149         }
150
151         @Override
152         public Boolean deserialize(String stringRepresentation) {
153             return Boolean.parseBoolean(stringRepresentation);
154         }
155     };
156
157     public static class Uint8CodecStringImpl extends TypeDefinitionAwareCodec<Short, UnsignedIntegerTypeDefinition>
158             implements Uint8Codec<String> {
159
160         protected Uint8CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
161             super(typeDef, Short.class);
162         }
163
164         @Override
165         public String serialize(Short data) {
166             return data.toString();
167         }
168
169         @Override
170         public Short deserialize(String stringRepresentation) {
171             return Short.parseShort(stringRepresentation);
172         }
173     };
174
175     public static class Uint16CodecStringImpl extends TypeDefinitionAwareCodec<Integer, UnsignedIntegerTypeDefinition>
176             implements Uint16Codec<String> {
177         protected Uint16CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
178             super(typeDef, Integer.class);
179         }
180
181         @Override
182         public Integer deserialize(String stringRepresentation) {
183             return Integer.parseInt(stringRepresentation);
184         }
185
186         @Override
187         public String serialize(Integer data) {
188             return data.toString();
189         }
190     };
191
192     public static class Uint32CodecStringImpl extends TypeDefinitionAwareCodec<Long, UnsignedIntegerTypeDefinition>
193             implements Uint32Codec<String> {
194
195         protected Uint32CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
196             super(typeDef, Long.class);
197         }
198
199         @Override
200         public Long deserialize(String stringRepresentation) {
201             return Long.parseLong(stringRepresentation);
202         }
203
204         @Override
205         public String serialize(Long data) {
206             return data.toString();
207         }
208     };
209
210     public static class Uint64CodecStringImpl extends
211             TypeDefinitionAwareCodec<BigInteger, UnsignedIntegerTypeDefinition> implements Uint64Codec<String> {
212
213         protected Uint64CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
214             super(typeDef, BigInteger.class);
215         }
216
217         @Override
218         public BigInteger deserialize(String stringRepresentation) {
219             // FIXME: Implement codec correctly
220             return BigInteger.valueOf(Long.valueOf(stringRepresentation));
221         }
222
223         @Override
224         public String serialize(BigInteger data) {
225             return data.toString();
226         }
227     };
228
229     public static class StringCodecStringImpl extends TypeDefinitionAwareCodec<String, StringTypeDefinition> implements
230             StringCodec<String> {
231
232         protected StringCodecStringImpl(Optional<StringTypeDefinition> typeDef) {
233             super(typeDef, String.class);
234         }
235
236         @Override
237         public String deserialize(String stringRepresentation) {
238             return stringRepresentation;
239         }
240
241         @Override
242         public String serialize(String data) {
243             return data.toString();
244         }
245     };
246
247     public static class Int16CodecStringImpl extends TypeDefinitionAwareCodec<Short, IntegerTypeDefinition> implements
248             Int16Codec<String> {
249
250         protected Int16CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
251             super(typeDef, Short.class);
252         }
253
254         @Override
255         public Short deserialize(String stringRepresentation) {
256             return Short.valueOf(stringRepresentation);
257         }
258
259         @Override
260         public String serialize(Short data) {
261             return data.toString();
262         }
263     };
264
265     public static class Int32CodecStringImpl extends TypeDefinitionAwareCodec<Integer, IntegerTypeDefinition> implements
266             Int32Codec<String> {
267
268         protected Int32CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
269             super(typeDef, Integer.class);
270         }
271
272         @Override
273         public Integer deserialize(String stringRepresentation) {
274             return Integer.valueOf(stringRepresentation);
275         }
276
277         @Override
278         public String serialize(Integer data) {
279             return data.toString();
280         }
281     };
282
283     public static class Int64CodecStringImpl extends TypeDefinitionAwareCodec<Long, IntegerTypeDefinition> implements
284             Int64Codec<String> {
285
286         protected Int64CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
287             super(typeDef, Long.class);
288         }
289
290         @Override
291         public Long deserialize(String stringRepresentation) {
292             return Long.parseLong(stringRepresentation);
293         }
294
295         @Override
296         public String serialize(Long data) {
297             return data.toString();
298         }
299     };
300
301     public static class Int8CodecStringImpl extends TypeDefinitionAwareCodec<Byte, IntegerTypeDefinition> implements
302             Int8Codec<String> {
303
304         protected Int8CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
305             super(typeDef, Byte.class);
306         }
307
308         @Override
309         public Byte deserialize(String stringRepresentation) {
310             return Byte.parseByte(stringRepresentation);
311         }
312
313         @Override
314         public String serialize(Byte data) {
315             return data.toString();
316         }
317     };
318
319     public static class EmptyCodecStringImpl extends TypeDefinitionAwareCodec<Void, EmptyTypeDefinition> implements
320             EmptyCodec<String> {
321
322         protected EmptyCodecStringImpl(Optional<EmptyTypeDefinition> typeDef) {
323             super(typeDef, Void.class);
324         }
325
326         @Override
327         public String serialize(Void data) {
328             return "";
329         }
330
331         @Override
332         public Void deserialize(String stringRepresentation) {
333             return null;
334         }
335     };
336
337     public static final class BinaryCodecStringImpl extends TypeDefinitionAwareCodec<byte[], BinaryTypeDefinition>
338             implements BinaryCodec<String> {
339
340         protected BinaryCodecStringImpl(Optional<BinaryTypeDefinition> typeDef) {
341             super(typeDef, byte[].class);
342         }
343
344         @Override
345         public String serialize(byte[] data) {
346             return BaseEncoding.base64().encode(data);
347         }
348
349         @Override
350         public byte[] deserialize(String stringRepresentation) {
351             return BaseEncoding.base64().decode(stringRepresentation);
352         }
353     };
354
355     public static final class BitsCodecStringImpl extends TypeDefinitionAwareCodec<Set<String>, BitsTypeDefinition>
356             implements BitsCodec<String> {
357
358         @SuppressWarnings("unchecked")
359         protected BitsCodecStringImpl(Optional<BitsTypeDefinition> typeDef) {
360             super(typeDef, (Class<Set<String>>) ((Class<?>) Set.class));
361         }
362
363         @Override
364         public String serialize(Set<String> data) {
365             return Joiner.on(" ").join(data).toString();
366         }
367
368         @Override
369         public Set<String> deserialize(String stringRepresentation) {
370             String[] strings = stringRepresentation.split(" ");
371             return ImmutableSet.copyOf(strings);
372         }
373     };
374
375     public static class EnumCodecStringImpl extends TypeDefinitionAwareCodec<String, EnumTypeDefinition> implements
376             EnumCodec<String> {
377
378         protected EnumCodecStringImpl(Optional<EnumTypeDefinition> typeDef) {
379             super(typeDef, String.class);
380         }
381
382         @Override
383         public String deserialize(String stringRepresentation) {
384             return stringRepresentation;
385         }
386
387         @Override
388         public String serialize(String data) {
389             return data.toString();
390         }
391     };
392
393     public static class DecimalCodecStringImpl extends TypeDefinitionAwareCodec<BigDecimal, DecimalTypeDefinition>
394             implements DecimalCodec<String> {
395
396         protected DecimalCodecStringImpl(Optional<DecimalTypeDefinition> typeDef) {
397             super(typeDef, BigDecimal.class);
398         }
399
400         @Override
401         public String serialize(BigDecimal data) {
402             return data.toString();
403         }
404
405         @Override
406         public BigDecimal deserialize(String stringRepresentation) {
407             return new BigDecimal(stringRepresentation);
408         }
409     };
410 }