2 * Copyright (c) 2014, 2015 EBay Software Foundation and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.lib.schema;
11 import com.fasterxml.jackson.databind.JsonNode;
12 import com.google.common.collect.Sets;
14 import org.opendaylight.ovsdb.lib.error.TyperException;
15 import org.opendaylight.ovsdb.lib.notation.ReferencedRow;
16 import org.opendaylight.ovsdb.lib.notation.UUID;
18 public abstract class BaseType<E extends BaseType<E>> {
20 private static BaseType[] types = new BaseType[] {
22 new IntegerBaseType(),
24 new BooleanBaseType(),
28 public static BaseType fromJson(JsonNode json, String keyorval) {
29 BaseType baseType = null;
30 if (json.isValueNode()) {
31 for (BaseType baseTypeFactory : types) {
32 String type = json.asText().trim();
33 baseType = baseTypeFactory.fromString(type);
34 if (baseType != null) {
39 if (!json.has(keyorval)) {
40 throw new TyperException("Not a type");
43 for (BaseType baseTypeFactory : types) {
44 baseType = baseTypeFactory.fromJsonNode(json.get(keyorval), keyorval);
45 if (baseType != null) {
53 protected abstract E fromString(String type);
55 protected abstract void getConstraints(E baseType, JsonNode type);
57 protected E fromJsonNode(JsonNode type, String keyorval) {
62 if (type.isTextual()) {
63 baseType = fromString(type.asText());
64 if (baseType != null) {
69 //json like {"type" : "string", "enum": ["set", ["access", "native-tagged"]]}" for key or value
70 if (type.isObject() && type.has("type")) {
71 baseType = fromString(type.get("type").asText());
72 if (baseType != null) {
73 getConstraints(baseType, type);
80 public abstract Object toValue(JsonNode value);
82 public abstract void validate(Object value);
84 public static class IntegerBaseType extends BaseType<IntegerBaseType> {
85 long min = Long.MIN_VALUE;
86 long max = Long.MAX_VALUE;
90 public IntegerBaseType fromString(String typeString) {
91 return "integer".equals(typeString) ? new IntegerBaseType() : null;
95 protected void getConstraints(IntegerBaseType baseType, JsonNode type) {
96 JsonNode typeMaxNode = type.get("maxInteger");
97 if (typeMaxNode != null) {
98 baseType.setMax(typeMaxNode.asLong());
100 JsonNode typeMinNode = type.get("minInteger");
101 if (typeMinNode != null) {
102 baseType.setMin(typeMinNode.asLong());
108 public Object toValue(JsonNode value) {
109 return value.asLong();
113 public void validate(Object value) {
117 private void populateEnum(JsonNode node) {
118 if (node.has("enum")) {
119 Set<Long> nodesEnums = Sets.newHashSet();
120 JsonNode anEnum = node.get("enum").get(1);
121 for (JsonNode enm : anEnum) {
122 nodesEnums.add(enm.asLong());
128 public long getMin() {
132 public void setMin(long min) {
136 public long getMax() {
140 public void setMax(long max) {
144 public Set<Integer> getEnums() {
148 public void setEnums(Set<Integer> enums) {
153 public String toString() {
154 return "IntegerBaseType";
158 public int hashCode() {
159 final int prime = 31;
161 result = prime * result + ((enums == null) ? 0 : enums.hashCode());
162 result = prime * result + (int) (max ^ (max >>> 32));
163 result = prime * result + (int) (min ^ (min >>> 32));
168 public boolean equals(Object obj) {
175 if (getClass() != obj.getClass()) {
178 IntegerBaseType other = (IntegerBaseType) obj;
180 if (other.enums != null) {
183 } else if (!enums.equals(other.enums)) {
186 if (max != other.max) {
189 if (min != other.min) {
196 public static class RealBaseType extends BaseType<RealBaseType> {
197 double min = Double.MIN_VALUE;
198 double max = Double.MAX_VALUE;
202 public RealBaseType fromString(String typeString) {
203 return "real".equals(typeString) ? new RealBaseType() : null;
207 protected void getConstraints(RealBaseType baseType, JsonNode type) {
208 JsonNode typeMaxNode = type.get("maxReal");
209 if (typeMaxNode != null) {
210 baseType.setMax(typeMaxNode.asLong());
212 JsonNode typeMinNode = type.get("minReal");
213 if (typeMinNode != null) {
214 baseType.setMin(typeMinNode.asLong());
220 public Object toValue(JsonNode value) {
221 return value.asDouble();
225 public void validate(Object value) {
229 private void populateEnum(JsonNode node) {
230 if (node.has("enum")) {
231 Set<Double> nodesEnums = Sets.newHashSet();
232 JsonNode anEnum = node.get("enum").get(1);
233 for (JsonNode enm : anEnum) {
234 nodesEnums.add(enm.asDouble());
239 public double getMin() {
243 public void setMin(double min) {
247 public double getMax() {
251 public void setMax(double max) {
255 public Set<Double> getEnums() {
259 public void setEnums(Set<Double> enums) {
264 public String toString() {
265 return "RealBaseType";
269 public int hashCode() {
270 final int prime = 31;
272 result = prime * result + ((enums == null) ? 0 : enums.hashCode());
274 temp = Double.doubleToLongBits(max);
275 result = prime * result + (int) (temp ^ (temp >>> 32));
276 temp = Double.doubleToLongBits(min);
277 result = prime * result + (int) (temp ^ (temp >>> 32));
282 public boolean equals(Object obj) {
289 if (getClass() != obj.getClass()) {
292 RealBaseType other = (RealBaseType) obj;
294 if (other.enums != null) {
297 } else if (!enums.equals(other.enums)) {
300 if (Double.doubleToLongBits(max) != Double.doubleToLongBits(other.max)) {
303 if (Double.doubleToLongBits(min) != Double.doubleToLongBits(other.min)) {
311 public static class BooleanBaseType extends BaseType {
314 public BooleanBaseType fromString(String typeString) {
315 return "boolean".equals(typeString) ? new BooleanBaseType() : null;
319 protected void getConstraints(BaseType baseType, JsonNode node) {
324 public Object toValue(JsonNode value) {
325 return value.asBoolean();
329 public void validate(Object value) {
334 public String toString() {
335 return "BooleanBaseType";
339 public static class StringBaseType extends BaseType<StringBaseType> {
340 int minLength = Integer.MIN_VALUE;
341 int maxLength = Integer.MAX_VALUE;
345 public StringBaseType fromString(String typeString) {
346 return "string".equals(typeString) ? new StringBaseType() : null;
350 protected void getConstraints(StringBaseType baseType, JsonNode type) {
351 JsonNode typeMaxNode = type.get("maxLength");
352 if (typeMaxNode != null) {
353 baseType.setMaxLength(typeMaxNode.asInt());
355 JsonNode typeMinNode = type.get("minLength");
356 if (typeMinNode != null) {
357 baseType.setMinLength(typeMinNode.asInt());
359 populateEnum(baseType, type);
363 public Object toValue(JsonNode value) {
364 return value.asText();
368 public void validate(Object value) {
372 private void populateEnum(StringBaseType baseType, JsonNode node) {
373 if (node.has("enum")) {
374 Set<String> nodesEnums = Sets.newHashSet();
375 JsonNode enumVal = node.get("enum");
376 if (enumVal.isArray()) {
377 JsonNode anEnum = enumVal.get(1);
378 for (JsonNode enm : anEnum) {
379 nodesEnums.add(enm.asText());
381 } else if (enumVal.isTextual()) {
382 nodesEnums.add(enumVal.asText());
384 baseType.setEnums(nodesEnums);
388 public int getMinLength() {
392 public void setMinLength(int minLength) {
393 this.minLength = minLength;
396 public int getMaxLength() {
400 public void setMaxLength(int maxLength) {
401 this.maxLength = maxLength;
404 public Set<String> getEnums() {
408 public void setEnums(Set<String> enums) {
413 public String toString() {
414 return "StringBaseType";
418 public int hashCode() {
419 final int prime = 31;
421 result = prime * result + ((enums == null) ? 0 : enums.hashCode());
422 result = prime * result + maxLength;
423 result = prime * result + minLength;
428 public boolean equals(Object obj) {
435 if (getClass() != obj.getClass()) {
438 StringBaseType other = (StringBaseType) obj;
440 if (other.enums != null) {
443 } else if (!enums.equals(other.enums)) {
446 if (maxLength != other.maxLength) {
449 if (minLength != other.minLength) {
458 public static class UuidBaseType extends BaseType<UuidBaseType> {
459 // These enum types correspond to JSON values and need to be in lower-case currently
460 public enum RefType { strong, weak }
466 public UuidBaseType fromString(String typeString) {
467 return "uuid".equals(typeString) ? new UuidBaseType() : null;
471 protected void getConstraints(UuidBaseType baseType, JsonNode node) {
472 JsonNode refTableNode = node.get("refTable");
473 baseType.setRefTable(refTableNode != null ? refTableNode.asText() : null);
475 JsonNode refTypeJson = node.get("refType");
476 baseType.setRefType(refTypeJson != null ? RefType.valueOf(refTypeJson.asText()) : RefType.strong);
480 public Object toValue(JsonNode value) {
481 if (value.isArray()) {
482 if (value.size() == 2 && value.get(0).isTextual() && "uuid".equals(value.get(0).asText())) {
483 return new UUID(value.get(1).asText());
487 * UUIDBaseType used by RefTable from SouthBound will always be an Array of ["uuid", <uuid>].
488 * But there are some cases from northbound where the RefTable type can be expanded to a Row
489 * with contents. In those scenarios, just retain the content and return a ReferencedRow for
490 * the upper layer functions to process it.
492 return new ReferencedRow(refTable, value);
498 public void validate(Object value) {
502 public String getRefTable() {
506 public void setRefTable(String refTable) {
507 this.refTable = refTable;
510 public RefType getRefType() {
514 public void setRefType(RefType refType) {
515 this.refType = refType;
519 public String toString() {
520 return "UuidBaseType";
524 public int hashCode() {
525 final int prime = 31;
527 result = prime * result
528 + ((refTable == null) ? 0 : refTable.hashCode());
529 result = prime * result
530 + ((refType == null) ? 0 : refType.hashCode());
535 public boolean equals(Object obj) {
542 if (getClass() != obj.getClass()) {
545 UuidBaseType other = (UuidBaseType) obj;
546 if (refTable == null) {
547 if (other.refTable != null) {
550 } else if (!refTable.equals(other.refTable)) {
553 if (refType != other.refType) {