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