Union codec in fromType method
[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 UnionTypeDefinition) {
124             codec = UNION_DEFAULT_CODEC;
125         } else if (superType instanceof UnsignedIntegerTypeDefinition) {
126             if (UINT8_QNAME.equals(superType.getQName())) {
127                 codec = UINT8_DEFAULT_CODEC;
128             }
129             if (UINT16_QNAME.equals(superType.getQName())) {
130                 codec = UINT16_DEFAULT_CODEC;
131             }
132             if (UINT32_QNAME.equals(superType.getQName())) {
133                 codec = UINT32_DEFAULT_CODEC;
134             }
135             if (UINT64_QNAME.equals(superType.getQName())) {
136                 codec = UINT64_DEFAULT_CODEC;
137             }
138         }
139         return (TypeDefinitionAwareCodec<?, T>) codec;
140     }
141
142     public static class BooleanCodecStringImpl extends TypeDefinitionAwareCodec<Boolean, BooleanTypeDefinition>
143             implements BooleanCodec<String> {
144
145         protected BooleanCodecStringImpl(Optional<BooleanTypeDefinition> typeDef) {
146             super(typeDef, Boolean.class);
147         }
148
149         @Override
150         public String serialize(Boolean data) {
151             return data.toString();
152         }
153
154         @Override
155         public Boolean deserialize(String stringRepresentation) {
156             return Boolean.parseBoolean(stringRepresentation);
157         }
158     };
159
160     public static class Uint8CodecStringImpl extends TypeDefinitionAwareCodec<Short, UnsignedIntegerTypeDefinition>
161             implements Uint8Codec<String> {
162
163         protected Uint8CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
164             super(typeDef, Short.class);
165         }
166
167         @Override
168         public String serialize(Short data) {
169             return data.toString();
170         }
171
172         @Override
173         public Short deserialize(String stringRepresentation) {
174             return Short.parseShort(stringRepresentation);
175         }
176     };
177
178     public static class Uint16CodecStringImpl extends TypeDefinitionAwareCodec<Integer, UnsignedIntegerTypeDefinition>
179             implements Uint16Codec<String> {
180         protected Uint16CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
181             super(typeDef, Integer.class);
182         }
183
184         @Override
185         public Integer deserialize(String stringRepresentation) {
186             return Integer.parseInt(stringRepresentation);
187         }
188
189         @Override
190         public String serialize(Integer data) {
191             return data.toString();
192         }
193     };
194
195     public static class Uint32CodecStringImpl extends TypeDefinitionAwareCodec<Long, UnsignedIntegerTypeDefinition>
196             implements Uint32Codec<String> {
197
198         protected Uint32CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
199             super(typeDef, Long.class);
200         }
201
202         @Override
203         public Long deserialize(String stringRepresentation) {
204             return Long.parseLong(stringRepresentation);
205         }
206
207         @Override
208         public String serialize(Long data) {
209             return data.toString();
210         }
211     };
212
213     public static class Uint64CodecStringImpl extends
214             TypeDefinitionAwareCodec<BigInteger, UnsignedIntegerTypeDefinition> implements Uint64Codec<String> {
215
216         protected Uint64CodecStringImpl(Optional<UnsignedIntegerTypeDefinition> typeDef) {
217             super(typeDef, BigInteger.class);
218         }
219
220         @Override
221         public BigInteger deserialize(String stringRepresentation) {
222             // FIXME: Implement codec correctly
223             return BigInteger.valueOf(Long.valueOf(stringRepresentation));
224         }
225
226         @Override
227         public String serialize(BigInteger data) {
228             return data.toString();
229         }
230     };
231
232     public static class StringCodecStringImpl extends TypeDefinitionAwareCodec<String, StringTypeDefinition> implements
233             StringCodec<String> {
234
235         protected StringCodecStringImpl(Optional<StringTypeDefinition> typeDef) {
236             super(typeDef, String.class);
237         }
238
239         @Override
240         public String deserialize(String stringRepresentation) {
241             return stringRepresentation;
242         }
243
244         @Override
245         public String serialize(String data) {
246             return data.toString();
247         }
248     };
249
250     public static class Int16CodecStringImpl extends TypeDefinitionAwareCodec<Short, IntegerTypeDefinition> implements
251             Int16Codec<String> {
252
253         protected Int16CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
254             super(typeDef, Short.class);
255         }
256
257         @Override
258         public Short deserialize(String stringRepresentation) {
259             return Short.valueOf(stringRepresentation);
260         }
261
262         @Override
263         public String serialize(Short data) {
264             return data.toString();
265         }
266     };
267
268     public static class Int32CodecStringImpl extends TypeDefinitionAwareCodec<Integer, IntegerTypeDefinition> implements
269             Int32Codec<String> {
270
271         protected Int32CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
272             super(typeDef, Integer.class);
273         }
274
275         @Override
276         public Integer deserialize(String stringRepresentation) {
277             return Integer.valueOf(stringRepresentation);
278         }
279
280         @Override
281         public String serialize(Integer data) {
282             return data.toString();
283         }
284     };
285
286     public static class Int64CodecStringImpl extends TypeDefinitionAwareCodec<Long, IntegerTypeDefinition> implements
287             Int64Codec<String> {
288
289         protected Int64CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
290             super(typeDef, Long.class);
291         }
292
293         @Override
294         public Long deserialize(String stringRepresentation) {
295             return Long.parseLong(stringRepresentation);
296         }
297
298         @Override
299         public String serialize(Long data) {
300             return data.toString();
301         }
302     };
303
304     public static class Int8CodecStringImpl extends TypeDefinitionAwareCodec<Byte, IntegerTypeDefinition> implements
305             Int8Codec<String> {
306
307         protected Int8CodecStringImpl(Optional<IntegerTypeDefinition> typeDef) {
308             super(typeDef, Byte.class);
309         }
310
311         @Override
312         public Byte deserialize(String stringRepresentation) {
313             return Byte.parseByte(stringRepresentation);
314         }
315
316         @Override
317         public String serialize(Byte data) {
318             return data.toString();
319         }
320     };
321
322     public static class EmptyCodecStringImpl extends TypeDefinitionAwareCodec<Void, EmptyTypeDefinition> implements
323             EmptyCodec<String> {
324
325         protected EmptyCodecStringImpl(Optional<EmptyTypeDefinition> typeDef) {
326             super(typeDef, Void.class);
327         }
328
329         @Override
330         public String serialize(Void data) {
331             return "";
332         }
333
334         @Override
335         public Void deserialize(String stringRepresentation) {
336             return null;
337         }
338     };
339
340     public static final class BinaryCodecStringImpl extends TypeDefinitionAwareCodec<byte[], BinaryTypeDefinition>
341             implements BinaryCodec<String> {
342
343         protected BinaryCodecStringImpl(Optional<BinaryTypeDefinition> typeDef) {
344             super(typeDef, byte[].class);
345         }
346
347         @Override
348         public String serialize(byte[] data) {
349             return BaseEncoding.base64().encode(data);
350         }
351
352         @Override
353         public byte[] deserialize(String stringRepresentation) {
354             return BaseEncoding.base64().decode(stringRepresentation);
355         }
356     };
357
358     public static final class BitsCodecStringImpl extends TypeDefinitionAwareCodec<Set<String>, BitsTypeDefinition>
359             implements BitsCodec<String> {
360
361         @SuppressWarnings("unchecked")
362         protected BitsCodecStringImpl(Optional<BitsTypeDefinition> typeDef) {
363             super(typeDef, (Class<Set<String>>) ((Class<?>) Set.class));
364         }
365
366         @Override
367         public String serialize(Set<String> data) {
368             return Joiner.on(" ").join(data).toString();
369         }
370
371         @Override
372         public Set<String> deserialize(String stringRepresentation) {
373             String[] strings = stringRepresentation.split(" ");
374             return ImmutableSet.copyOf(strings);
375         }
376     };
377
378     public static class EnumCodecStringImpl extends TypeDefinitionAwareCodec<String, EnumTypeDefinition> implements
379             EnumCodec<String> {
380
381         protected EnumCodecStringImpl(Optional<EnumTypeDefinition> typeDef) {
382             super(typeDef, String.class);
383         }
384
385         @Override
386         public String deserialize(String stringRepresentation) {
387             return stringRepresentation;
388         }
389
390         @Override
391         public String serialize(String data) {
392             return data.toString();
393         }
394     };
395
396     public static class DecimalCodecStringImpl extends TypeDefinitionAwareCodec<BigDecimal, DecimalTypeDefinition>
397             implements DecimalCodec<String> {
398
399         protected DecimalCodecStringImpl(Optional<DecimalTypeDefinition> typeDef) {
400             super(typeDef, BigDecimal.class);
401         }
402
403         @Override
404         public String serialize(BigDecimal data) {
405             return data.toString();
406         }
407
408         @Override
409         public BigDecimal deserialize(String stringRepresentation) {
410             return new BigDecimal(stringRepresentation);
411         }
412     };
413
414     public static class UnionCodecStringImpl extends TypeDefinitionAwareCodec<String, UnionTypeDefinition> implements
415             UnionCodec<String> {
416
417         protected UnionCodecStringImpl(Optional<UnionTypeDefinition> typeDef) {
418             super(typeDef, String.class);
419         }
420
421         @Override
422         public String serialize(String data) {
423             return data;
424         }
425
426         @Override
427         public String deserialize(String stringRepresentation) {
428             return stringRepresentation;
429         }
430     };
431 }