952b6ce1bb0345823e6794bf378a92865c3bf5cf
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / restconf / impl / RestCodec.java
1 package org.opendaylight.controller.sal.restconf.impl;
2
3 import java.net.URI;
4
5 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
6 import org.opendaylight.controller.sal.rest.impl.RestUtil;
7 import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
8 import org.opendaylight.yangtools.concepts.Codec;
9 import org.opendaylight.yangtools.yang.common.QName;
10 import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
11 import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
12 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
13 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
14 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
15 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 public class RestCodec {
20
21     private RestCodec() {
22     }
23
24     public static final Codec<Object, Object> from(TypeDefinition<?> typeDefinition, MountInstance mountPoint) {
25         return new ObjectCodec(typeDefinition, mountPoint);
26     }
27
28     @SuppressWarnings("rawtypes")
29     public static final class ObjectCodec implements Codec<Object, Object> {
30
31         private final Logger logger = LoggerFactory.getLogger(RestCodec.class);
32
33         public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl();
34         private final Codec identityrefCodec;
35
36         private final TypeDefinition<?> type;
37
38         private ObjectCodec(TypeDefinition<?> typeDefinition, MountInstance mountPoint) {
39             type = RestUtil.resolveBaseTypeFrom(typeDefinition);
40             if (type instanceof IdentityrefTypeDefinition) {
41                 identityrefCodec = new IdentityrefCodecImpl(mountPoint);
42             } else {
43                 identityrefCodec = null;
44             }
45         }
46
47         @SuppressWarnings("unchecked")
48         @Override
49         public Object deserialize(Object input) {
50             try {
51                 if (type instanceof IdentityrefTypeDefinition) {
52                     return identityrefCodec.deserialize(input);
53                 } else if (type instanceof LeafrefTypeDefinition) {
54                     return LEAFREF_DEFAULT_CODEC.deserialize(input);
55                 } else {
56                     TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
57                             .from(type);
58                     if (typeAwarecodec != null) {
59                         return typeAwarecodec.deserialize(String.valueOf(input));
60                     } else {
61                         logger.debug("Codec for type \"" + type.getQName().getLocalName()
62                                 + "\" is not implemented yet.");
63                         return null;
64                     }
65                 }
66             } catch (ClassCastException e) { // TODO remove this catch when
67                                              // everyone use codecs
68                 logger.error(
69                         "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
70                         e);
71                 return input;
72             }
73         }
74
75         @SuppressWarnings("unchecked")
76         @Override
77         public Object serialize(Object input) {
78             try {
79                 if (type instanceof IdentityrefTypeDefinition) {
80                     return identityrefCodec.serialize(input);
81                 } else if (type instanceof LeafrefTypeDefinition) {
82                     return LEAFREF_DEFAULT_CODEC.serialize(input);
83                 } else {
84                     TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
85                             .from(type);
86                     if (typeAwarecodec != null) {
87                         return typeAwarecodec.serialize(input);
88                     } else {
89                         logger.debug("Codec for type \"" + type.getQName().getLocalName()
90                                 + "\" is not implemented yet.");
91                         return null;
92                     }
93                 }
94             } catch (ClassCastException e) { // TODO remove this catch when
95                                              // everyone use codecs
96                 logger.error(
97                         "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
98                         e);
99                 return input;
100             }
101         }
102
103     }
104
105     public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
106
107         private final MountInstance mountPoint;
108         
109         public IdentityrefCodecImpl(MountInstance mountPoint) {
110             this.mountPoint = mountPoint;
111         }
112         
113         @Override
114         public IdentityValuesDTO serialize(QName data) {
115             return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix());
116         }
117
118         @Override
119         public QName deserialize(IdentityValuesDTO data) {
120             IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
121             String namespace = valueWithNamespace.getNamespace();
122             URI validNamespace;
123             if (mountPoint != null) {
124                 validNamespace = ControllerContext.getInstance().findNamespaceByModuleName(mountPoint, namespace);
125             } else {
126                 validNamespace = ControllerContext.getInstance().findNamespaceByModuleName(namespace);
127             }
128             if (validNamespace == null) {
129                 validNamespace = URI.create(namespace);
130             }
131             return QName.create(validNamespace, null, valueWithNamespace.getValue());
132         }
133         
134     }
135
136     public static class LeafrefCodecImpl implements LeafrefCodec<String> {
137
138         @Override
139         public String serialize(Object data) {
140             return String.valueOf(data);
141         }
142
143         @Override
144         public Object deserialize(String data) {
145             return data;
146         }
147
148     }
149
150 }