Migrate TyperUtils.getTableSchema() users
[ovsdb.git] / library / impl / src / main / java / org / opendaylight / ovsdb / lib / schema / ColumnType.java
1 /*
2  * Copyright (c) 2014, 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 package org.opendaylight.ovsdb.lib.schema;
9
10 import com.fasterxml.jackson.databind.JsonNode;
11 import com.google.common.collect.ImmutableList;
12 import java.util.function.Function;
13 import org.opendaylight.ovsdb.lib.error.TyperException;
14 import org.opendaylight.ovsdb.lib.jsonrpc.JsonUtils;
15
16 public abstract class ColumnType {
17     private static final ImmutableList<Function<JsonNode, ColumnType>> FACTORIES = ImmutableList.of(
18         AtomicColumnType::fromJsonNode, KeyValuedColumnType::fromJsonNode);
19
20     private final BaseType baseType;
21     private final long min;
22     private final long max;
23
24     ColumnType(final BaseType baseType, final long min, final long max) {
25         this.baseType = baseType;
26         this.min = min;
27         this.max = max;
28     }
29
30     /**
31      * JSON.
32      * <pre>
33             "type": {
34                 "key": {
35                      "maxInteger": 4294967295,
36                      "minInteger": 0,
37                      "type": "integer"
38                 },
39                 "min": 0,
40                 "value": {
41                     "type": "uuid",
42                     "refTable": "Queue"
43                  },
44                  "max": "unlimited"
45             }</pre>
46      */
47     public static ColumnType fromJson(final JsonNode json) {
48         for (Function<JsonNode, ColumnType> factory : FACTORIES) {
49             ColumnType columnType = factory.apply(json);
50             if (null != columnType) {
51                 return columnType;
52             }
53         }
54         //todo move to speicfic typed exception
55         throw new TyperException(String.format("could not find the right column type %s",
56                 JsonUtils.prettyString(json)));
57     }
58
59     public BaseType getBaseType() {
60         return baseType;
61     }
62
63     public long getMin() {
64         return min;
65     }
66
67     public long getMax() {
68         return max;
69     }
70
71     /*
72      * Per RFC 7047, Section 3.2 <type> :
73      * If "min" or "max" is not specified, each defaults to 1.  If "max" is specified as "unlimited",
74      * then there is no specified maximum number of elements, although the implementation will
75      * enforce some limit.  After considering defaults, "min" must be exactly 0 or
76      * exactly 1, "max" must be at least 1, and "max" must be greater than or equal to "min".
77      *
78      * If "min" and "max" are both 1 and "value" is not specified, the
79      * type is the scalar type specified by "key".
80      */
81     public boolean isMultiValued() {
82         return this.min != this.max;
83     }
84
85     public abstract Object valueFromJson(JsonNode value);
86
87     public void validate(final Object value) {
88         baseType.validate(value);
89     }
90
91     @Override
92     public String toString() {
93         return "ColumnType{"
94                 + "baseType=" + baseType
95                 + ", min=" + min
96                 + ", max=" + max
97                 + '}';
98     }
99
100     @Override
101     public int hashCode() {
102         final int prime = 31;
103         int result = 1;
104         result = prime * result
105                 + (baseType == null ? 0 : baseType.hashCode());
106         result = prime * result + (int) (max ^ max >>> 32);
107         result = prime * result + (int) (min ^ min >>> 32);
108         return result;
109     }
110
111     @Override
112     public boolean equals(final Object obj) {
113         if (this == obj) {
114             return true;
115         }
116         if (obj == null) {
117             return false;
118         }
119         if (getClass() != obj.getClass()) {
120             return false;
121         }
122         ColumnType other = (ColumnType) obj;
123         if (baseType == null) {
124             if (other.baseType != null) {
125                 return false;
126             }
127         } else if (!baseType.equals(other.baseType)) {
128             return false;
129         }
130         if (max != other.max) {
131             return false;
132         }
133         if (min != other.min) {
134             return false;
135         }
136         return true;
137     }
138
139     static long maxFromJson(final JsonNode json) {
140         final JsonNode maxNode = json.get("max");
141         if (maxNode != null) {
142             if (maxNode.isLong()) {
143                 return maxNode.asLong();
144             }
145             if (maxNode.isTextual() && "unlimited".equals(maxNode.asText())) {
146                 return Long.MAX_VALUE;
147             }
148         }
149         return 1;
150     }
151
152     static long minFromJson(final JsonNode json) {
153         final JsonNode minNode = json.get("min");
154         return minNode == null ? 1 : minNode.asLong();
155     }
156 }