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