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