aboutsummaryrefslogtreecommitdiffstats
path: root/vespajlib/src/main/java/com/yahoo/data/access/simple/Value.java
blob: c4333ee2c29c8b29299e87536cd4e74362f5ce49 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.data.access.simple;

import com.yahoo.data.access.ArrayTraverser;
import com.yahoo.data.access.Inspector;
import com.yahoo.data.access.ObjectTraverser;
import com.yahoo.data.access.Type;

import java.util.Collections;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ArrayList;
import java.nio.charset.StandardCharsets;

public class Value implements Inspector {

    private static final Value empty = new EmptyValue();
    private static final Value invalid = new Value();
    private static final byte[] empty_array = new byte[0];
    public static Inspector empty() { return empty; }
    public static Inspector invalid() { return invalid; }
    public Inspector inspect() { return this; }
    public boolean valid() { return false; }
    public Type type() { return Type.EMPTY; }
    public int entryCount() { return 0; }
    public int fieldCount() { return 0; }
    public boolean asBool() { throw new IllegalStateException("invalid data access!"); }
    public long asLong() { throw new IllegalStateException("invalid data access!"); }
    public double asDouble() { throw new IllegalStateException("invalid data access!"); }
    public java.lang.String asString() { throw new IllegalStateException("invalid data access!"); }
    public byte[] asUtf8() { throw new IllegalStateException("invalid data access!"); }
    public byte[] asData() { throw new IllegalStateException("invalid data access!"); }
    public boolean asBool(boolean defaultValue) { return defaultValue; }
    public long asLong(long defaultValue) { return defaultValue; }
    public double asDouble(double defaultValue) { return defaultValue; }
    public java.lang.String asString(java.lang.String defaultValue) { return defaultValue; }
    public byte[] asUtf8(byte[] defaultValue) { return defaultValue; }
    public byte[] asData(byte[] defaultValue) { return defaultValue; }
    public void traverse(ArrayTraverser at) {}
    public void traverse(ObjectTraverser ot) {}
    public Inspector entry(int idx) { return invalid; }
    public Inspector field(java.lang.String name) { return invalid; }
    public Iterable<Inspector> entries() { return Collections.emptyList(); }
    public Iterable<Map.Entry<java.lang.String,Inspector>> fields() { return Collections.emptyList(); }
    public StringBuilder writeJson(StringBuilder target) {
        return JsonRender.render(this, target, true);
    }
    public String toJson() { return writeJson(new StringBuilder()).toString(); }
    public String toString() { return toJson(); }
    static public class EmptyValue extends Value {
        public boolean valid() { return true; }
        public boolean asBool() { return false; }
        public long asLong() { return 0L; }
        public double asDouble() { return 0.0; }
        public java.lang.String asString() { return ""; }
        public byte[] asUtf8() { return empty_array; }
        public byte[] asData() { return empty_array; }
    }
    static public class BoolValue extends Value {
        private final boolean value;
        public BoolValue(boolean v) { value = v; }
        public boolean valid() { return true; }
        public Type type() { return Type.BOOL; }
        public boolean asBool() { return value; }
        public boolean asBool(boolean x) { return value; }
    }
    static public class LongValue extends Value {
        private final long value;
        public LongValue(long v) { value = v; }
        public boolean valid() { return true; }
        public Type type() { return Type.LONG; }
        public long asLong() { return value; }
        public double asDouble() { return (double)value; }
        public long asLong(long x) { return value; }
        public double asDouble(double x) { return (double)value; }
    }
    static public class DoubleValue extends Value {
        private final double value;
        public DoubleValue(double v) { value = v; }
        public boolean valid() { return true; }
        public Type type() { return Type.DOUBLE; }
        public double asDouble() { return value; }
        public long asLong() { return (long)value; }
        public double asDouble(double x) { return value; }
        public long asLong(long x) { return (long)value; }
    }
    static public class StringValue extends Value {
        private java.lang.String string_value = null;
        private byte[] utf8_value = null;
        private void handle_null() {
            if (string_value == null && utf8_value == null) {
                string_value = "";
                utf8_value = empty_array;
            }
        }
        public StringValue(java.lang.String v) {
            string_value = v;
            handle_null();
        }
        public StringValue(byte[] v) {
            utf8_value = v;
            handle_null();
        }
        public boolean valid() { return true; }
        public Type type() { return Type.STRING; }
        public java.lang.String asString() {
            if (string_value == null) {
                string_value = new java.lang.String(utf8_value, StandardCharsets.UTF_8);
            }
            return string_value;
        }
        public java.lang.String asString(java.lang.String x) { return asString(); }
        public byte[] asUtf8() {
            if (utf8_value == null) {
                utf8_value = string_value.getBytes(StandardCharsets.UTF_8);
            }
            return utf8_value;
        }
        public byte[] asUtf8(byte[] x) { return asUtf8(); }
    }
    static public class DataValue extends Value {
        private byte[] value;
        public DataValue(byte[] v) {
            value = v;
            if (v == null) {
                value = empty_array;
            }
        }
        public boolean valid() { return true; }
        public Type type() { return Type.DATA; }
        public byte[] asData() { return value; }
        public byte[] asData(byte[] x) { return value; }
    }
    static public class ArrayValue extends Value {
        private final List<Inspector> values;
        public ArrayValue() {
            values = new ArrayList<>();
        }
        public ArrayValue(int capacity) {
            values = new ArrayList<>(capacity);
        }
        public boolean valid() { return true; }
        public Type type() { return Type.ARRAY; }
        public int entryCount() { return values.size(); }
        public Inspector entry(int idx) {
            if (idx < 0 || idx >= values.size()) {
                return invalid;
            }
            return values.get(idx);
        }
        public void traverse(ArrayTraverser at) {
            int idx = 0;
            for (Inspector i: values) {
                at.entry(idx++, i);
            }
        }
        public Iterable<Inspector> entries() {
            return Collections.unmodifiableList(values);
        }
        public ArrayValue add(Inspector v) {
            if (v == null || !v.valid()) {
                throw new IllegalArgumentException("tried to add an invalid value to an array");
            }
            values.add(v);
            return this;
        }
        public ArrayValue add(java.lang.String value) {
            return add(new Value.StringValue(value));
        }
        public ArrayValue add(long value) {
            return add(new Value.LongValue(value));
        }
        public ArrayValue add(int value) {
            return add(new Value.LongValue(value));
        }
        public ArrayValue add(double value) {
            return add(new Value.DoubleValue(value));
        }
    }
    static public class ObjectValue extends Value {
        private final Map<java.lang.String,Inspector> values = new LinkedHashMap<>();
        public boolean valid() { return true; }
        public Type type() { return Type.OBJECT; }
        public int fieldCount() { return values.size(); }
        public Inspector field(java.lang.String name) {
            Inspector v = values.get(name);
            if (v == null) {
                return invalid;
            }
            return v;
        }
        public void traverse(ObjectTraverser ot) {
            for (Map.Entry<java.lang.String,Inspector> i: values.entrySet()) {
                ot.field(i.getKey(), i.getValue());
            }
        }
        public Iterable<Map.Entry<java.lang.String,Inspector>> fields() {
            return Collections.<java.lang.String,Inspector>unmodifiableMap(values).entrySet();
        }
        public ObjectValue put(java.lang.String name, Inspector v) {
            if (name == null) {
                throw new IllegalArgumentException("field name was <null>");
            }
            if (v == null || !v.valid()) {
                throw new IllegalArgumentException("tried to put an invalid value into an object");
            }
            values.put(name, v);
            return this;
        }
        public ObjectValue put(java.lang.String name, java.lang.String value) {
            return put(name, new Value.StringValue(value));
        }
        public ObjectValue put(java.lang.String name, long value) {
            return put(name, new Value.LongValue(value));
        }
        public ObjectValue put(java.lang.String name, int value) {
            return put(name, new Value.LongValue(value));
        }
        public ObjectValue put(java.lang.String name, double value) {
            return put(name, new Value.DoubleValue(value));
        }
    }
}