All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vladsch.boxed.json.BoxedJsValue Maven / Gradle / Ivy

There is a newer version: 0.5.34
Show newest version
package com.vladsch.boxed.json;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.json.JsonValue;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Implements extended json values used for representing nested searches that are erroneous
 * 

* Includes propagating value types: * HAD_NULL : somewhere along the path a value was null * HAD_MISSING : somewhere along the path a value was not found, includes array index out of bounds and object key missing * HAD_INVALID : somewhere along the path a value of the wrong type was encountered, class cast exception equivalent */ public interface BoxedJsValue extends JsonValue { @NotNull BoxedValueType getBoxedValueType(); @Nullable default JsonValue.ValueType getValueType() { return getUnboxedValueType() == null ? JsonValue.ValueType.NULL : getUnboxedValueType(); } @Nullable default JsonValue.ValueType getUnboxedValueType() { return getBoxedValueType().getUnboxedValueType(); } /** * Get underlying unboxed json value * * @return unboxed json value or JsonValue.NULL if none */ @NotNull JsonValue jsonValue(); default @NotNull BoxedJsValue asJsLiteral() { return BoxedJson.asJsLiteral(this); } default @NotNull BoxedJsObject asJsObject() { return BoxedJson.asJsObject(this); } default @NotNull BoxedJsArray asJsArray() { return BoxedJson.asJsArray(this); } default @NotNull BoxedJsNumber asJsNumber() { return BoxedJson.asJsNumber(this); } default @NotNull BoxedJsString asJsString() { return BoxedJson.asJsString(this); } default @NotNull BoxedJsValue asJsBoolean() { return BoxedJson.asJsBoolean(this); } default @NotNull BoxedJsValue asJsNull() { return BoxedJson.asJsNull(this); } default boolean isInvalidJsonValue() { return getBoxedValueType().getUnboxedValueType() == null; } default boolean isValid() { return getBoxedValueType().getUnboxedValueType() != null; } default boolean isValidOrMissing() { return isValid() || hadMissing(); } default boolean isLiteral() { return isValid() && !(isArray() || isObject()); } default boolean isArray() { return getBoxedValueType().getUnboxedValueType() == ValueType.ARRAY; } default boolean isObject() { return getBoxedValueType().getUnboxedValueType() == ValueType.OBJECT; } default boolean isString() { return getBoxedValueType().getUnboxedValueType() == ValueType.STRING; } default boolean isNumber() { return getBoxedValueType().getUnboxedValueType() == ValueType.NUMBER; } default boolean isTrue() { return getBoxedValueType().getUnboxedValueType() == ValueType.TRUE; } default boolean isFalse() { return getBoxedValueType().getUnboxedValueType() == ValueType.FALSE; } default boolean isNull() { return getBoxedValueType().getUnboxedValueType() == ValueType.NULL; } default boolean hadNull() { return this.getBoxedValueType() == BoxedValueType.HAD_NULL; } default boolean hadMissing() { return this.getBoxedValueType() == BoxedValueType.HAD_MISSING; } default boolean hadInvalid() { return this.getBoxedValueType() == BoxedValueType.HAD_INVALID; } // if not valid, use default default boolean isTrue(boolean defaultValue) { return getBoxedValueType().getUnboxedValueType() == ValueType.TRUE || (isInvalidJsonValue() && defaultValue); } default boolean isFalse(boolean defaultValue) { return getBoxedValueType().getUnboxedValueType() == ValueType.FALSE || (isInvalidJsonValue() && defaultValue); } /** * Returns the end value of evaluating lookups based on a path of . or [n] separated * parts. A dot designates an object key lookup, a [n] an array lookup. Returned value is * either the last looked up element or * * @param path path to evaluate * @return value at path (check for validity) */ @NotNull default BoxedJsValue eval(final String path) { return BoxedJson.eval(this, path); } default @NotNull BoxedJsArray evalJsArray(final String path) { return eval(path).asJsArray(); } default @NotNull BoxedJsObject evalJsObject(final String path) { return eval(path).asJsObject(); } default @NotNull BoxedJsNumber evalJsNumber(final String path) { return eval(path).asJsNumber(); } default @NotNull BoxedJsString evalJsString(final String path) { return eval(path).asJsString(); } default @NotNull BoxedJsValue evalJsBoolean(final String path) { return eval(path).asJsBoolean(); } default int evalInt(final String path) { return eval(path).asJsNumber().intValue(); } default long evalLong(final String path) { return eval(path).asJsNumber().longValue(); } default @NotNull BigDecimal evalBigDecimal(final String path) { return eval(path).asJsNumber().bigDecimalValue(); } default @NotNull BigInteger evalBigInteger(final String path) { return eval(path).asJsNumber().bigIntegerValue(); } default double evalDouble(final String path) { return eval(path).asJsNumber().doubleValue(); } default float evalFloat(final String path) { return eval(path).asJsNumber().floatValue(); } default @NotNull String evalString(final String path) { return eval(path).asJsString().getString(); } default boolean evalBoolean(final String path) { return eval(path).asJsBoolean().isTrue(); } // with defaults default int evalInt(final String path, final int defaultValue) { return eval(path).asJsNumber().intValue(defaultValue); } default long evalLong(final String path, final long defaultValue) { return eval(path).asJsNumber().longValue(defaultValue); } default @NotNull BigDecimal evalBigDecimal(final String path, final BigDecimal defaultValue) { return eval(path).asJsNumber().bigDecimalValue(defaultValue); } default @NotNull BigInteger evalBigInteger(final String path, final BigInteger defaultValue) { return eval(path).asJsNumber().bigIntegerValue(defaultValue); } default double evalDouble(final String path, final double defaultValue) { return eval(path).asJsNumber().doubleValue(defaultValue); } default float evalFloat(final String path, final float defaultValue) { return eval(path).asJsNumber().floatValue(defaultValue); } default @NotNull String evalString(final String path, final String defaultValue) { return eval(path).asJsString().getString(defaultValue); } default boolean evalBoolean(final String path, final boolean defaultValue) { return eval(path).asJsBoolean().isTrue(defaultValue); } /** * Set the end of the path to given value *

* If a part along the path is missing it will be set to the corresponding path part: object or array. * new array will only be created for a missing part if its index is 0. *

* for example: '{ "name": "abc", "arr": [1,2,3] }'.evalSet("arr[4]", JsonValue.TRUE) will result in * '{ "name": "abc", "arr": [1,2,3,true] }', you can also specify an empty index to mean one beyond the end, * ie. previous is the same as .evalSet("arr[]", JsonValue.TRUE) *

* '{ "name": "abc", "arr": [1,2,3] }'.evalSet("result.value.set[]", JsonValue.NULL) will result in * '{ "name": "abc", "arr": [1,2,3], "result" : { "value": { "set":[ null ] } } }' * * @param path p * @param value value to set * @return result of setting the final part, array returns value, object returns value for new parts, or old value at part. * If result.isValid() is false then no changes were made because of errors */ default @NotNull BoxedJsValue evalSet(final String path, JsonValue value) { return BoxedJson.evalSet(this, path, value); } default @NotNull BoxedJsValue evalSet(final String path, int value) { return evalSet(path, JsNumber.of(value)).asJsNumber(); } default @NotNull BoxedJsValue evalSet(final String path, long value) { return evalSet(path, JsNumber.of(value)).asJsNumber(); } default @NotNull BoxedJsValue evalSet(final String path, BigInteger value) { return evalSet(path, JsNumber.of(value)).asJsNumber(); } default @NotNull BoxedJsValue evalSet(final String path, double value) { return evalSet(path, JsNumber.of(value)).asJsNumber(); } default @NotNull BoxedJsValue evalSet(final String path, float value) { return evalSet(path, JsNumber.of(value)).asJsNumber(); } default @NotNull BoxedJsValue evalSet(final String path, BigDecimal value) { return evalSet(path, JsNumber.of(value)).asJsNumber(); } default @NotNull BoxedJsValue evalSet(final String path, String value) { return evalSet(path, JsString.of(value)).asJsString(); } default @NotNull BoxedJsValue evalSet(final String path, boolean value) { return evalSet(path, value ? JsonValue.TRUE : JsonValue.FALSE); } default @NotNull BoxedJsValue evalSetTrue(final String path) { return evalSet(path, true); } default @NotNull BoxedJsValue evalSetFalse(final String path) { return evalSet(path, false); } default @NotNull BoxedJsValue evalSetNull(final String path) { return evalSet(path, JsonValue.NULL); } enum BoxedValueType { ARRAY(ValueType.ARRAY), OBJECT(ValueType.OBJECT), STRING(ValueType.STRING), NUMBER(ValueType.NUMBER), TRUE(ValueType.TRUE), FALSE(ValueType.FALSE), NULL(ValueType.NULL), HAD_NULL, HAD_MISSING, HAD_INVALID; private final @Nullable ValueType myValueType; BoxedValueType(@NotNull ValueType valueType) { myValueType = valueType; } BoxedValueType() { myValueType = null; } @Nullable public ValueType getUnboxedValueType() { return myValueType; } @NotNull private T selectOneOf(T hadNull, T hadMissing, T hadInvalid) { switch (this) { case HAD_NULL: return hadNull; case HAD_MISSING: return hadMissing; case HAD_INVALID: default: return hadInvalid; } } @NotNull public BoxedJsNumber asJsNumber() { return selectOneOf(HAD_NULL_NUMBER, HAD_MISSING_NUMBER, HAD_INVALID_NUMBER);} @NotNull public BoxedJsString asJsString() { return selectOneOf(HAD_NULL_STRING, HAD_MISSING_STRING, HAD_INVALID_STRING);} @NotNull public BoxedJsValue asJsLiteral() { return selectOneOf(HAD_NULL_LITERAL, HAD_MISSING_LITERAL, HAD_INVALID_LITERAL);} @NotNull public BoxedJsArray asJsArray() { return selectOneOf(HAD_NULL_ARRAY, HAD_MISSING_ARRAY, HAD_INVALID_ARRAY);} @NotNull public BoxedJsObject asJsObject() { return selectOneOf(HAD_NULL_OBJECT, HAD_MISSING_OBJECT, HAD_INVALID_OBJECT);} @NotNull public BoxedJsValue asJsOfType(JsonValue other) { if (other == null) { return HAD_NULL.asJsLiteral(); } switch (other.getValueType()) { case ARRAY: return asJsArray(); case OBJECT: return asJsObject(); case STRING: return asJsString(); case NUMBER: return asJsNumber(); case TRUE: case FALSE: case NULL: default: return asJsLiteral(); } } public static BoxedValueType getBoxedType(@NotNull ValueType valueType) { switch (valueType) { case ARRAY: return ARRAY; case OBJECT: return OBJECT; case STRING: return STRING; case NUMBER: return NUMBER; case TRUE: return TRUE; case FALSE: return FALSE; case NULL: return NULL; } return HAD_INVALID; } } BoxedJsValue HAD_NULL_LITERAL = new BoxedJsInvalidLiteral() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_NULL;} }; BoxedJsValue HAD_MISSING_LITERAL = new BoxedJsInvalidLiteral() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_MISSING;} }; BoxedJsValue HAD_INVALID_LITERAL = new BoxedJsInvalidLiteral() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_INVALID;} }; BoxedJsNumber HAD_NULL_NUMBER = new BoxedJsInvalidNumber() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_NULL;} }; BoxedJsNumber HAD_MISSING_NUMBER = new BoxedJsInvalidNumber() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_MISSING;} }; BoxedJsNumber HAD_INVALID_NUMBER = new BoxedJsInvalidNumber() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_INVALID;} }; BoxedJsString HAD_NULL_STRING = new BoxedJsInvalidString() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_NULL;} }; BoxedJsString HAD_MISSING_STRING = new BoxedJsInvalidString() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_MISSING;} }; BoxedJsString HAD_INVALID_STRING = new BoxedJsInvalidString() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_INVALID;} }; BoxedJsArray HAD_NULL_ARRAY = new BoxedJsArrayBase() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_NULL;} }; BoxedJsArray HAD_MISSING_ARRAY = new BoxedJsArrayBase() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_MISSING;} }; BoxedJsArray HAD_INVALID_ARRAY = new BoxedJsArrayBase() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_INVALID;} }; BoxedJsObject HAD_NULL_OBJECT = new BoxedJsObjectBase() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_NULL;} }; BoxedJsObject HAD_MISSING_OBJECT = new BoxedJsObjectBase() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_MISSING;} }; BoxedJsObject HAD_INVALID_OBJECT = new BoxedJsObjectBase() { @NotNull @Override public BoxedValueType getBoxedValueType() { return BoxedValueType.HAD_INVALID;} }; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy