2 * Copyright (C) 2014 EBay Software Foundation
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
8 * Authors : Ashwin Raveendran
10 package org.opendaylight.ovsdb.lib.schema;
12 import org.opendaylight.ovsdb.lib.error.TyperException;
13 import org.opendaylight.ovsdb.lib.jsonrpc.JsonUtils;
14 import org.opendaylight.ovsdb.lib.notation.OvsdbMap;
15 import org.opendaylight.ovsdb.lib.notation.OvsdbSet;
16 import org.slf4j.LoggerFactory;
18 import com.fasterxml.jackson.databind.JsonNode;
21 public abstract class ColumnType {
26 public long getMin() {
30 void setMin(long min) {
34 public long getMax() {
38 void setMax(long max) {
42 private static ColumnType columns[] = new ColumnType[]{
43 new AtomicColumnType(),
44 new KeyValuedColumnType()
52 public ColumnType(BaseType baseType) {
53 this.baseType = baseType;
56 public BaseType getBaseType() {
63 "maxInteger": 4294967295,
77 public static ColumnType fromJson(JsonNode json) {
78 for (ColumnType colType : columns) {
79 ColumnType columnType = colType.fromJsonNode(json);
80 if (null != columnType) {
84 //todo move to speicfic typed exception
85 throw new TyperException(String.format("could not find the right column type %s",
86 JsonUtils.prettyString(json)));
91 * Creates a ColumnType from the JsonNode if the implementation knows how to, returns null otherwise
93 * @param json the JSONNode object that needs to converted
94 * @return a valid SubType or Null (if the JsonNode does not represent
97 protected abstract ColumnType fromJsonNode(JsonNode json);
100 * Per RFC 7047, Section 3.2 <type> :
101 * If "min" or "max" is not specified, each defaults to 1. If "max" is specified as "unlimited", then there is no specified maximum
102 * number of elements, although the implementation will enforce some limit. After considering defaults, "min" must be exactly 0 or
103 * exactly 1, "max" must be at least 1, and "max" must be greater than or equal to "min".
105 * If "min" and "max" are both 1 and "value" is not specified, the
106 * type is the scalar type specified by "key".
108 public boolean isMultiValued() {
109 return this.min != this.max;
112 public abstract Object valueFromJson(JsonNode value);
114 public abstract void validate(Object value);
117 public String toString() {
118 return "ColumnType{" +
119 "baseType=" + baseType +
125 public static class AtomicColumnType extends ColumnType {
126 static final org.slf4j.Logger logger = LoggerFactory.getLogger(AtomicColumnType.class);
127 public AtomicColumnType() {
130 public AtomicColumnType(BaseType baseType1) {
135 public AtomicColumnType fromJsonNode(JsonNode json) {
136 if (json.isObject() && json.has("value")) {
139 BaseType baseType = BaseType.fromJson(json, "key");
141 if (baseType != null) {
143 AtomicColumnType atomicColumnType = new AtomicColumnType(baseType);
145 JsonNode node = null;
146 if ((node = json.get("min")) != null) {
147 atomicColumnType.setMin(node.asLong());
150 if ((node = json.get("max")) != null) {
151 if (node.isNumber()){
152 atomicColumnType.setMax(node.asLong());
153 } else if ("unlimited".equals(node.asText())) {
154 atomicColumnType.setMax(Long.MAX_VALUE);
157 return atomicColumnType;
164 public Object valueFromJson(JsonNode value) {
165 if (isMultiValued()) {
166 OvsdbSet<Object> result = new OvsdbSet<Object>();
167 if(value.isArray()) {
168 if (value.size() == 2) {
169 if (value.get(0).isTextual() && "set".equals(value.get(0).asText())) {
170 for(JsonNode node: value.get(1)) {
171 result.add(getBaseType().toValue(node));
174 result.add(getBaseType().toValue(value));
178 result.add(getBaseType().toValue(value));
182 return getBaseType().toValue(value);
187 public void validate(Object value) {
188 this.baseType.validate(value);
193 public static class KeyValuedColumnType extends ColumnType {
196 public BaseType getKeyType() {
200 public KeyValuedColumnType() {
203 public KeyValuedColumnType(BaseType keyType, BaseType valueType) {
205 this.keyType = keyType;
209 public KeyValuedColumnType fromJsonNode(JsonNode json) {
210 if (json.isValueNode() || !json.has("value")) {
213 BaseType keyType = BaseType.fromJson(json, "key");
214 BaseType valueType = BaseType.fromJson(json, "value");
216 KeyValuedColumnType keyValueColumnType = new KeyValuedColumnType(keyType, valueType);
217 JsonNode node = null;
218 if ((node = json.get("min")) != null) {
219 keyValueColumnType.setMin(node.asLong());
222 if ((node = json.get("max")) != null) {
224 keyValueColumnType.setMax(node.asLong());
225 } else if (node.isTextual() && "unlimited".equals(node.asText())) {
226 keyValueColumnType.setMax(Long.MAX_VALUE);
230 return keyValueColumnType;
234 public Object valueFromJson(JsonNode node) {
235 if (node.isArray()) {
236 if (node.size() == 2) {
237 if (node.get(0).isTextual() && "map".equals(node.get(0).asText())) {
238 OvsdbMap<Object, Object> map = new OvsdbMap<Object, Object>();
239 for (JsonNode pairNode : node.get(1)) {
240 if (pairNode.isArray() && node.size() == 2) {
241 Object key = getKeyType().toValue(pairNode.get(0));
242 Object value = getBaseType().toValue(pairNode.get(1));
247 } else if (node.size() == 0) {
256 public void validate(Object value) {
257 this.baseType.validate(value);