Merge branch 'master' into topic/schema
[ovsdb.git] / library / src / main / java / org / opendaylight / ovsdb / lib / notation / json / Converter.java
1 /*
2  * Copyright (C) 2013 EBay Software Foundation
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  * Authors : Ashwin Raveendran
9  */
10 package org.opendaylight.ovsdb.lib.notation.json;
11
12 import org.opendaylight.ovsdb.lib.message.temp.TableUpdates;
13 import org.opendaylight.ovsdb.lib.message.UpdateNotification;
14 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
15 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
16 import org.opendaylight.ovsdb.lib.notation.UUID;
17
18 import com.fasterxml.jackson.databind.DeserializationFeature;
19 import com.fasterxml.jackson.databind.JsonNode;
20 import com.fasterxml.jackson.databind.ObjectMapper;
21 import com.fasterxml.jackson.databind.util.StdConverter;
22
23 public class Converter {
24
25     static AtomDeser atomDeser = new AtomDeser();
26     static MapDeser mapDeser = new MapDeser();
27     static SetDeser setDeser = new SetDeser();
28     static UpdateNotificationDeser unDeser = new UpdateNotificationDeser();
29
30     public static class MapConverter extends StdConverter<JsonNode, OvsDBMap<Object, Object>> {
31         @Override
32         public OvsDBMap<Object, Object> convert(JsonNode value) {
33             return mapDeser.deserialize(value);
34         }
35     }
36
37     public static class SetConverter extends StdConverter<JsonNode, OvsDBSet<Object>> {
38         @Override
39         public OvsDBSet<Object> convert(JsonNode value) {
40             return setDeser.deserialize(value);
41         }
42     }
43
44     public static class UpdateNotificationConverter extends StdConverter<JsonNode, UpdateNotification> {
45         @Override
46         public UpdateNotification convert(JsonNode value) {
47             return unDeser.deserialize(value);
48         }
49     }
50
51     static class MapDeser {
52         public OvsDBMap<Object, Object> deserialize(JsonNode node) {
53             if (node.isArray()) {
54                 if (node.size() == 2) {
55                     if (node.get(0).isTextual() && "map".equals(node.get(0).asText())) {
56                         OvsDBMap<Object, Object> map = new OvsDBMap<Object, Object>();
57                         for (JsonNode pairNode : node.get(1)) {
58                             if (pairNode.isArray() && node.size() == 2) {
59                                 Object key = atomDeser.deserialize(pairNode.get(0));
60                                 Object value = atomDeser.deserialize(pairNode.get(1));
61                                 map.put(key, value);
62                             }
63                         }
64                         return map;
65                     } else if (node.size() == 0) {
66                         return null;
67                     }
68                 }
69             }
70             throw new RuntimeException("not a map type");
71         }
72     }
73
74     static class SetDeser {
75         public OvsDBSet<Object> deserialize(JsonNode node) {
76             OvsDBSet<Object> set = new OvsDBSet<Object>();
77             if (node.isArray()) {
78                 if (node.size() == 2) {
79                     if (node.get(0).isTextual() && "set".equals(node.get(0).asText())) {
80                         for (JsonNode atomNode : node.get(1)) {
81                             set.add(atomDeser.deserialize(atomNode));
82                         }
83                         return set;
84                     }
85                 } else if (node.size() == 0) {
86                     return null;
87                 }
88             }
89             //treat the whole thing as a single Atom
90             Object atom = atomDeser.deserialize(node);
91             if (null != atom) {
92                 set.add(atom);
93             }
94             return set;
95         }
96     }
97
98     static class UpdateNotificationDeser {
99         public UpdateNotification deserialize(JsonNode node) {
100             UpdateNotification un = new UpdateNotification();
101             if (node.isArray()) {
102                 if (node.size() == 2) {
103                     un.setContext(node.get(0).asText());
104                     un.setUpdates(node.get(1));
105                     ObjectMapper objectMapper = new ObjectMapper();
106                     objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
107                     TableUpdates updates = objectMapper.convertValue(node.get(1), TableUpdates.class);
108                     un.setUpdate(updates);
109                     return un;
110                 }
111             }
112             return null;
113         }
114     }
115
116     static class AtomDeser {
117
118         public Object deserialize(JsonNode node) {
119             if (!node.isArray()) {
120                 switch (node.getNodeType()) {
121                     case BOOLEAN:
122                         return node.asBoolean();
123                     case NUMBER:
124                         if (node.isFloatingPointNumber()) {
125                             return node.decimalValue();
126                         } else {
127                             return node.bigIntegerValue();
128                         }
129                     case STRING:
130                         return node.asText();
131                 }
132             }
133
134             if (node.isArray() && node.get(0).isTextual()) {
135                 if ("uuid".equals(node.get(0).asText()) || "named-uuid".equals(node.get(0).asText())) {
136                     return new UUID(node.get(1).asText());
137                 }
138             }
139
140             throw new RuntimeException("not an atom node");
141         }
142     }
143 }