diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespajlib/src/main/java/com/yahoo/data |
Publish
Diffstat (limited to 'vespajlib/src/main/java/com/yahoo/data')
12 files changed, 747 insertions, 0 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/data/access/ArrayTraverser.java b/vespajlib/src/main/java/com/yahoo/data/access/ArrayTraverser.java new file mode 100644 index 00000000000..99d79dd8eb5 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/ArrayTraverser.java @@ -0,0 +1,16 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.data.access; + +/** + * Callback interface for traversing arrays. + * Implement this and call Inspector.traverse() + * and you will get one callback for each array entry. + **/ +public interface ArrayTraverser { + /** + * Callback function to implement. + * @param idx array index for the current array entry. + * @param inspector accessor for the current array entry's value. + **/ + public void entry(int idx, Inspector inspector); +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/Inspectable.java b/vespajlib/src/main/java/com/yahoo/data/access/Inspectable.java new file mode 100644 index 00000000000..bf3344a0fe9 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/Inspectable.java @@ -0,0 +1,12 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.data.access; + +/** + * Minimal API to implement for objects containing or exposing + * structured, generic, schemaless data. Use this when it's + * impractical to implement the Inspector interface directly. + **/ +public interface Inspectable { + /** get an Inspector exposing this object's structured data. */ + public Inspector inspect(); +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/Inspector.java b/vespajlib/src/main/java/com/yahoo/data/access/Inspector.java new file mode 100644 index 00000000000..0b0061792bd --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/Inspector.java @@ -0,0 +1,128 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.data.access; + + +import java.util.Map; + +/** + * This is a generic API for accessing structured, generic, schemaless data. + * An inspector is a handle to a value that has one of 8 specific types: + * EMPTY, the 5 scalar types BOOL, LONG, DOUBLE, STRING, or DATA, the + * simple list-like ARRAY container and the struct-like OBJECT container. + * Instrospection methods are available, but you can also use accessors + * with a default value if you expect a certain type and just want your + * default value if some field doesn't exist or was of the wrong type. + **/ +public interface Inspector extends Inspectable { + + /** + * Check if the inspector is valid. + * If you try to access a field or array entry that does not exist, + * you will get an invalid Inspector returned. + */ + public boolean valid(); + + /** Get the type of an inspector */ + public Type type(); + + /** Get the number of entries in an ARRAY (always returns 0 for non-arrays) */ + public int entryCount(); + + /** Get the number of fields in an OBJECT (always returns 0 for non-objects) */ + public int fieldCount(); + + /** Access the inspector's value if it's a BOOLEAN; otherwise throws exception */ + public boolean asBool(); + + /** Access the inspector's value if it's a LONG (or DOUBLE); otherwise throws exception */ + public long asLong(); + + /** Access the inspector's value if it's a DOUBLE (or LONG); otherwise throws exception */ + public double asDouble(); + + /** Access the inspector's value if it's a STRING; otherwise throws exception */ + public String asString(); + + /** + * Access the inspector's value (in utf-8 representation) if it's + * a STRING; otherwise throws exception + **/ + public byte[] asUtf8(); + + /** Access the inspector's value if it's DATA; otherwise throws exception */ + public byte[] asData(); + + /** Get the inspector's value (or the supplied default), never throws */ + public boolean asBool(boolean defaultValue); + + /** Get the inspector's value (or the supplied default), never throws */ + public long asLong(long defaultValue); + + /** Get the inspector's value (or the supplied default), never throws */ + public double asDouble(double defaultValue); + + /** Get the inspector's value (or the supplied default), never throws */ + public String asString(String defaultValue); + + /** Get the inspector's value (or the supplied default), never throws */ + public byte[] asUtf8(byte[] defaultValue); + + /** Get the inspector's value (or the supplied default), never throws */ + public byte[] asData(byte[] defaultValue); + + /** + * Traverse an array value, performing callbacks for each entry. + * + * If the current Inspector is connected to an array value, + * perform callbacks to the given traverser for each entry + * contained in the array. Otherwise a no-op. + * @param at traverser callback object. + **/ + @SuppressWarnings("overloads") + public void traverse(ArrayTraverser at); + + /** + * Traverse an object value, performing callbacks for each field. + * + * If the current Inspector is connected to an object value, + * perform callbacks to the given traverser for each field + * contained in the object. Otherwise a no-op. + * @param ot traverser callback object. + **/ + @SuppressWarnings("overloads") + public void traverse(ObjectTraverser ot); + + /** + * Access an array entry. + * + * If the current Inspector doesn't connect to an array value, + * or the given array index is out of bounds, the returned + * Inspector will be invalid. + * @param idx array index. + * @return a new Inspector for the entry value. + **/ + public Inspector entry(int idx); + + /** + * Access an field in an object. + * + * If the current Inspector doesn't connect to an object value, or + * the object value does not contain a field with the given symbol + * name, the returned Inspector will be invalid. + * @param name symbol name. + * @return a new Inspector for the field value. + **/ + public Inspector field(String name); + + /** + * Convert an array to an iterable list. Other types will just + * return an empty list. + **/ + public Iterable<Inspector> entries(); + + /** + * Convert an object to an iterable list of (name, value) pairs. + * Other types will just return an empty list. + **/ + public Iterable<Map.Entry<String,Inspector>> fields(); +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/ObjectTraverser.java b/vespajlib/src/main/java/com/yahoo/data/access/ObjectTraverser.java new file mode 100644 index 00000000000..90ff360d63d --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/ObjectTraverser.java @@ -0,0 +1,16 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.data.access; + +/** + * Callback interface for traversing objects. + * Implement this and call Inspector.traverse() + * and you will get one callback for each field in an object. + **/ +public interface ObjectTraverser { + /** + * Callback function to implement. + * @param name the name of the current field. + * @param inspector accessor for the current field's value. + **/ + public void field(String name, Inspector inspector); +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/Type.java b/vespajlib/src/main/java/com/yahoo/data/access/Type.java new file mode 100644 index 00000000000..e09b0ba9adc --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/Type.java @@ -0,0 +1,19 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.data.access; + +/** + * Enumeration of all possible types accessed by the Inspector API. + * Note that: + * - the EMPTY type is used as a placeholder where data is missing. + * - all integers are put into LONGs; the encoding takes care of + * packing small integers compactly so this is also efficient. + * - likeweise DOUBLE is the only floating-point type, but "simple" + * numbers (like 0.0 or 1.0) are packed compactly anyway. + * - DATA can be used anything for wrapping anything else serialized + * as an array of bytes. + * - maps should be represented as an ARRAY of OBJECTs where each + * object has the fields "key" and "value". + **/ +public enum Type { + EMPTY, BOOL, LONG, DOUBLE, STRING, DATA, ARRAY, OBJECT; +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/package-info.java b/vespajlib/src/main/java/com/yahoo/data/access/package-info.java new file mode 100644 index 00000000000..904686c5d78 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/package-info.java @@ -0,0 +1,7 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +@PublicApi +package com.yahoo.data.access; + +import com.yahoo.api.annotations.PublicApi; +import com.yahoo.osgi.annotation.ExportPackage; diff --git a/vespajlib/src/main/java/com/yahoo/data/access/simple/JsonRender.java b/vespajlib/src/main/java/com/yahoo/data/access/simple/JsonRender.java new file mode 100644 index 00000000000..6acc43c2198 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/simple/JsonRender.java @@ -0,0 +1,166 @@ +// Copyright 2016 Yahoo Inc. 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.text.DoubleFormatter; +import com.yahoo.data.access.*; + +/** + * Encodes json from an inspectable object. + * + * @author arnej27959 + */ +public final class JsonRender +{ + public static StringBuilder render(Inspectable value, + StringBuilder target, + boolean compact) + { + StringEncoder enc = new StringEncoder(target, compact); + enc.encode(value.inspect()); + return target; + } + + public static final class StringEncoder implements ArrayTraverser, ObjectTraverser + { + private final StringBuilder out; + private boolean head = true; + private boolean compact; + private int level = 0; + + public StringEncoder(StringBuilder out, boolean compact) { + this.out = out; + this.compact = compact; + } + + public void encode(Inspector top) { + encodeValue(top); + if (!compact) { + out.append('\n'); + } + } + + private void encodeEMPTY() { + out.append("null"); + } + + private void encodeBOOL(boolean value) { + out.append(value ? "true" : "false"); + } + + private void encodeLONG(long value) { + out.append(String.valueOf(value)); + } + + private void encodeDOUBLE(double value) { + if (Double.isNaN(value) || Double.isInfinite(value)) { + out.append("null"); + } else { + out.append(DoubleFormatter.stringValue(value)); + } + } + + static final char[] hex = "0123456789ABCDEF".toCharArray(); + + private void encodeSTRING(String value) { + out.append('"'); + for (char c : value.toCharArray()) { + switch (c) { + case '"': out.append('\\').append('"'); break; + case '\\': out.append('\\').append('\\'); break; + case '\b': out.append('\\').append('b'); break; + case '\f': out.append('\\').append('f'); break; + case '\n': out.append('\\').append('n'); break; + case '\r': out.append('\\').append('r'); break; + case '\t': out.append('\\').append('t'); break; + default: + if (c > 0x1f && c < 127) { + out.append(c); + } else { // requires escaping according to RFC 4627 + out.append('\\').append('u'); + out.append(hex[(c >> 12) & 0xf]); + out.append(hex[(c >> 8) & 0xf]); + out.append(hex[(c >> 4) & 0xf]); + out.append(hex[c & 0xf]); + } + } + } + out.append('"'); + } + + private void encodeDATA(byte[] value) { + out.append('"'); + out.append("0x"); + for (int pos = 0; pos < value.length; pos++) { + out.append(hex[(value[pos] >> 4) & 0xf]); + out.append(hex[value[pos] & 0xf]); + } + out.append('"'); + } + + private void encodeARRAY(Inspector inspector) { + openScope("["); + ArrayTraverser at = this; + inspector.traverse(at); + closeScope("]"); + } + + private void encodeOBJECT(Inspector inspector) { + openScope("{"); + ObjectTraverser ot = this; + inspector.traverse(ot); + closeScope("}"); + } + + private void openScope(String opener) { + out.append(opener); + level++; + head = true; + } + + private void closeScope(String closer) { + level--; + separate(false); + out.append(closer); + } + + private void encodeValue(Inspector inspector) { + switch(inspector.type()) { + case EMPTY: encodeEMPTY(); return; + case BOOL: encodeBOOL(inspector.asBool()); return; + case LONG: encodeLONG(inspector.asLong()); return; + case DOUBLE: encodeDOUBLE(inspector.asDouble()); return; + case STRING: encodeSTRING(inspector.asString()); return; + case DATA: encodeDATA(inspector.asData()); return; + case ARRAY: encodeARRAY(inspector); return; + case OBJECT: encodeOBJECT(inspector); return; + } + assert false : "Should not be reached"; + } + + private void separate(boolean useComma) { + if (!head && useComma) { + out.append(','); + } else { + head = false; + } + if (!compact) { + out.append("\n"); + for (int lvl = 0; lvl < level; lvl++) { out.append(" "); } + } + } + + public void entry(int idx, Inspector inspector) { + separate(true); + encodeValue(inspector); + } + + public void field(String name, Inspector inspector) { + separate(true); + encodeSTRING(name); + out.append(':'); + if (!compact) + out.append(' '); + encodeValue(inspector); + } + } +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/simple/Value.java b/vespajlib/src/main/java/com/yahoo/data/access/simple/Value.java new file mode 100644 index 00000000000..baf5ce3cc54 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/simple/Value.java @@ -0,0 +1,215 @@ +// Copyright 2016 Yahoo Inc. 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.*; +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 Value empty = new EmptyValue(); + private static Value invalid = new Value(); + private static 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 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 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 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 List<Inspector> values = new ArrayList<>(); + 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 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)); + } + } +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/simple/package-info.java b/vespajlib/src/main/java/com/yahoo/data/access/simple/package-info.java new file mode 100644 index 00000000000..730dc508b21 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/simple/package-info.java @@ -0,0 +1,7 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +@PublicApi +package com.yahoo.data.access.simple; + +import com.yahoo.api.annotations.PublicApi; +import com.yahoo.osgi.annotation.ExportPackage; diff --git a/vespajlib/src/main/java/com/yahoo/data/access/slime/SlimeAdapter.java b/vespajlib/src/main/java/com/yahoo/data/access/slime/SlimeAdapter.java new file mode 100644 index 00000000000..adfadfe8bb8 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/slime/SlimeAdapter.java @@ -0,0 +1,156 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.data.access.slime; + + +import java.util.Map; +import java.util.AbstractMap; +import java.util.List; +import java.util.ArrayList; + + +public final class SlimeAdapter implements com.yahoo.data.access.Inspector { + private com.yahoo.slime.Inspector inspector; + public SlimeAdapter(com.yahoo.slime.Inspector inspector) { this.inspector = inspector; } + @Override public boolean equals(Object rhs) { + if (!(rhs instanceof SlimeAdapter)) { + return false; + } + return inspector.equals(((SlimeAdapter)rhs).inspector); + } + @Override public int hashCode() { return inspector.hashCode(); } + @Override public String toString() { return inspector.toString(); } + public com.yahoo.data.access.Inspector inspect() { return this; } + public boolean valid() { return inspector.valid(); } + public com.yahoo.data.access.Type type() { + switch(inspector.type()) { + case NIX: return com.yahoo.data.access.Type.EMPTY; + case BOOL: return com.yahoo.data.access.Type.BOOL; + case LONG: return com.yahoo.data.access.Type.LONG; + case DOUBLE: return com.yahoo.data.access.Type.DOUBLE; + case STRING: return com.yahoo.data.access.Type.STRING; + case DATA: return com.yahoo.data.access.Type.DATA; + case ARRAY: return com.yahoo.data.access.Type.ARRAY; + case OBJECT: return com.yahoo.data.access.Type.OBJECT; + } + return com.yahoo.data.access.Type.EMPTY; + } + private boolean verify(com.yahoo.slime.Type ok_type_a) { + com.yahoo.slime.Type my_type = inspector.type(); + return (valid() && (my_type == ok_type_a)); + } + private boolean verify(com.yahoo.slime.Type ok_type_a, + com.yahoo.slime.Type ok_type_b) + { + com.yahoo.slime.Type my_type = inspector.type(); + return (valid() && (my_type == ok_type_a || my_type == ok_type_b)); + } + private boolean verify(com.yahoo.slime.Type ok_type_a, + com.yahoo.slime.Type ok_type_b, + com.yahoo.slime.Type ok_type_c) + { + com.yahoo.slime.Type my_type = inspector.type(); + return (valid() && (my_type == ok_type_a || my_type == ok_type_b || my_type == ok_type_c)); + } + public int entryCount() { return inspector.entries(); } + public int fieldCount() { return inspector.fields(); } + public boolean asBool() { + if (!verify(com.yahoo.slime.Type.NIX, com.yahoo.slime.Type.BOOL)) { + throw new IllegalStateException("invalid data extraction!"); + } + return inspector.asBool(); + } + public long asLong() { + if (!verify(com.yahoo.slime.Type.NIX, com.yahoo.slime.Type.LONG, com.yahoo.slime.Type.DOUBLE)) { + throw new IllegalStateException("invalid data extraction!"); + } + return inspector.asLong(); + } + public double asDouble() { + if (!verify(com.yahoo.slime.Type.NIX, com.yahoo.slime.Type.DOUBLE, com.yahoo.slime.Type.LONG)) { + throw new IllegalStateException("invalid data extraction!"); + } + return inspector.asDouble(); + } + public String asString() { + if (!verify(com.yahoo.slime.Type.NIX, com.yahoo.slime.Type.STRING)) { + throw new IllegalStateException("invalid data extraction!"); + } + return inspector.asString(); + } + public byte[] asUtf8() { + if (!verify(com.yahoo.slime.Type.NIX, com.yahoo.slime.Type.STRING)) { + throw new IllegalStateException("invalid data extraction!"); + } + return inspector.asUtf8(); + } + public byte[] asData() { + if (!verify(com.yahoo.slime.Type.NIX, com.yahoo.slime.Type.DATA)) { + throw new IllegalStateException("invalid data extraction!"); + } + return inspector.asData(); + } + public boolean asBool(boolean defaultValue) { + if (!verify(com.yahoo.slime.Type.BOOL)) { + return defaultValue; + } + return inspector.asBool(); + } + public long asLong(long defaultValue) { + if (!verify(com.yahoo.slime.Type.LONG, com.yahoo.slime.Type.DOUBLE)) { + return defaultValue; + } + return inspector.asLong(); + } + public double asDouble(double defaultValue) { + if (!verify(com.yahoo.slime.Type.DOUBLE, com.yahoo.slime.Type.LONG)) { + return defaultValue; + } + return inspector.asDouble(); + } + public String asString(String defaultValue) { + if (!verify(com.yahoo.slime.Type.STRING)) { + return defaultValue; + } + return inspector.asString(); + } + public byte[] asUtf8(byte[] defaultValue) { + if (!verify(com.yahoo.slime.Type.STRING)) { + return defaultValue; + } + return inspector.asUtf8(); + } + public byte[] asData(byte[] defaultValue) { + if (!verify(com.yahoo.slime.Type.DATA)) { + return defaultValue; + } + return inspector.asData(); + } + public void traverse(final com.yahoo.data.access.ArrayTraverser at) { + inspector.traverse(new com.yahoo.slime.ArrayTraverser() { + public void entry(int idx, com.yahoo.slime.Inspector inspector) { at.entry(idx, new SlimeAdapter(inspector)); } + }); + } + public void traverse(final com.yahoo.data.access.ObjectTraverser ot) { + inspector.traverse(new com.yahoo.slime.ObjectTraverser() { + public void field(String name, com.yahoo.slime.Inspector inspector) { ot.field(name, new SlimeAdapter(inspector)); } + }); + } + public com.yahoo.data.access.Inspector entry(int idx) { return new SlimeAdapter(inspector.entry(idx)); } + public com.yahoo.data.access.Inspector field(String name) { return new SlimeAdapter(inspector.field(name)); } + public Iterable<com.yahoo.data.access.Inspector> entries() { + final List<com.yahoo.data.access.Inspector> list = new ArrayList<>(); + inspector.traverse(new com.yahoo.slime.ArrayTraverser() { + public void entry(int idx, com.yahoo.slime.Inspector inspector) { list.add(new SlimeAdapter(inspector)); } + }); + return list; + } + public Iterable<Map.Entry<String,com.yahoo.data.access.Inspector>> fields() { + final List<Map.Entry<String,com.yahoo.data.access.Inspector>> list = new ArrayList<>(); + inspector.traverse(new com.yahoo.slime.ObjectTraverser() { + public void field(String name, com.yahoo.slime.Inspector inspector) { + list.add(new AbstractMap.SimpleImmutableEntry<String,com.yahoo.data.access.Inspector>(name, new SlimeAdapter(inspector))); + } + }); + return list; + } +} diff --git a/vespajlib/src/main/java/com/yahoo/data/access/slime/package-info.java b/vespajlib/src/main/java/com/yahoo/data/access/slime/package-info.java new file mode 100644 index 00000000000..bf6ae26baee --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/access/slime/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.data.access.slime; + +import com.yahoo.osgi.annotation.ExportPackage; diff --git a/vespajlib/src/main/java/com/yahoo/data/inspect/slime/.gitignore b/vespajlib/src/main/java/com/yahoo/data/inspect/slime/.gitignore new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/data/inspect/slime/.gitignore |