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