@Override public boolean isNull() { return value.isNull(); }
static boolean isNull(Value value) { return value == null || value.isNull(); }
static boolean notNull(Value value) { return value != null && !value.isNull(); }
default boolean isNotNull() { return !isNull(); }
@Override public String asString() { return value.isNull() ? null : value.toString(); }
/** * Determine whether this object has an entry at the given index and the value is null, or if this object has no entry at * the given index. * * @param index the index * @return <code>true</code> if the field value for the name is null or if there is no such field. * @see #isNull(int) */ default boolean isNullOrMissing(int index) { Value value = get(index); return value != null ? value.isNull() : true; }
/** * Determine whether this object has an entry at the given index and the value is null. * * @param index the index * @return <code>true</code> if the entry exists but is null, or false otherwise * @see #isNullOrMissing(int) */ default boolean isNull(int index) { Value value = get(index); return value != null ? value.isNull() : false; }
/** * Compare two {@link Value} objects, which may or may not be null. * * @param value1 the first value object, may be null * @param value2 the second value object, which may be null * @return a negative integer if the first value is less than the second, zero if the values are equivalent (including if both * are null), or a positive integer if the first value is greater than the second */ static int compareTo(Value value1, Value value2) { if (value1 == null) return isNull(value2) ? 0 : -1; return value1.compareTo(value2); }
/** * If a value is a variable-sized integer, invoke the specified consumer with the value, otherwise do nothing. * * @param consumer block to be executed if the value is a big integer * @return true if the block was called, or false otherwise */ default boolean ifNull(NullHandler consumer) { if (isNull()) { consumer.call(); return true; } return false; }
default boolean isNull() { Value v = getValue(); return v == null || v.isNull(); }
/** * Determine whether this object has a field with the given the name and the value is null. This is equivalent to calling: * * <pre> * this.get(name) instanceof Null; * </pre> * * @param fieldName The name of the field * @return <code>true</code> if the field exists but is null, or false otherwise * @see #isNullOrMissing(CharSequence) */ default boolean isNull(CharSequence fieldName) { Value value = get(fieldName); return value != null && value.isNull(); }
/** * Determine whether this object has a field with the given the name and the value is null, or if this object has no field * with * the given name. This is equivalent to calling: * * <pre> * Null.matches(this.get(name)); * </pre> * * @param fieldName The name of the field * @return <code>true</code> if the field value for the name is null or if there is no such field. * @see #isNull(CharSequence) */ default boolean isNullOrMissing(CharSequence fieldName) { Value value = get(fieldName); return value == null || value.isNull(); }
/** * Semantically compare two non-null values. This includes comparing numeric values of different types * (e.g., an integer and long), but excludes {@code null} and {@link Value#nullValue()} references. * * @param value1 the first value; may be null * @param value2 the second value; may be null * @return a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object. */ protected int compareNonNull(Value value1, Value value2) { if (Value.isNull(value1) || Value.isNull(value2)) return 0; return value1.comparable().compareTo(value2.comparable()); }
@Override public int compareTo(Value that) { if (that.isNull()) return 1; if (that.isBinary()) return this.value.length - that.asBytes().length; return 1; }
@Override public boolean equals(Object obj) { if (obj == this) return true; if (obj instanceof Value) { Value that = (Value) obj; if (that.isNull()) return false; if (that.isBinary()) return Arrays.equals(this.value, that.asBytes()); if (that.isString()) return Arrays.equals(this.value, that.asString().getBytes()); return false; } return false; }
/** * Semantically compare two values. This includes comparing numeric values of different types (e.g., an integer and long), * and {@code null} and {@link Value#nullValue()} references. * * @param value1 the first value; may be null * @param value2 the second value; may be null * @return a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object. */ protected int compare(Value value1, Value value2) { if (value1 == null) return Value.isNull(value2) ? 0 : 1; return value1.comparable().compareTo(value2.comparable()); }
/** * Get the existing document value in this document for the given field name, or create a new document if there is no existing * document at this field. * * @param fieldName The name of the field * @return The editable document field value; null if the field exists but is not a document */ default Document getOrCreateDocument(CharSequence fieldName) { Value value = get(fieldName); if (value == null || value.isNull()) { return setDocument(fieldName, (Document) null); } return value.asDocument(); }
/** * Get the existing array value in this document for the given field name, or create a new array if there is no existing array * at this field. * * @param fieldName The name of the field * @return The editable array field value; never null */ default Array getOrCreateArray(CharSequence fieldName) { Value value = get(fieldName); if (value == null || value.isNull()) { return setArray(fieldName, (Array) null); } return value.asArray(); }
static Type typeForValue(Value value) { assert value != null; if (value.isNull()) return Type.NULL; // Check by exact class ... Type type = TYPES_BY_CLASS.get(value.getClass()); if (type != null) return type; // Otherwise, check using instanceof ... if (value.isString()) return Type.STRING; if (value.isBoolean()) return Type.BOOLEAN; if (value.isBinary()) return Type.BINARY; if (value.isInteger()) return Type.INTEGER; if (value.isLong()) return Type.LONG; if (value.isFloat()) return Type.FLOAT; if (value.isDouble()) return Type.DOUBLE; if (value.isBigInteger()) return Type.BIG_INTEGER; if (value.isBigDecimal()) return Type.DECIMAL; if (value.isDocument()) return Type.DOCUMENT; if (value.isArray()) return Type.ARRAY; if (value.isNull()) return Type.NULL; assert false; throw new IllegalStateException(); }
@SuppressWarnings("unchecked") @Override public int compareTo(Value that) { if (Value.isNull(that)) return 1; if ( this.isBoolean() && that.isBoolean() ) { return this.asBoolean().compareTo(that.asBoolean()); } if (this.isNumber() && that.isNumber()) { if (this.isLong()) return this.asLong().compareTo(that.asLong()); if (this.isDouble()) return this.asDouble().compareTo(that.asDouble()); if (this.isInteger()) return this.asInteger().compareTo(that.asInteger()); if (this.isFloat()) return this.asFloat().compareTo(that.asFloat()); if (this.isBigDecimal()) return this.asBigDecimal().compareTo(that.asBigDecimal()); return this.asBigInteger().compareTo(that.asBigInteger()); } if ( this.isDocument() && that.isDocument()) { return this.asDocument().compareTo(that.asDocument()); } if ( this.isArray() && that.isArray() ) { return this.asArray().compareTo(that.asArray()); } Comparable<Object> thisValue = (Comparable<Object>)this.asObject(); Comparable<Object> thatValue = (Comparable<Object>)((ComparableValue)that.comparable()).asObject(); if ( thisValue.getClass().isAssignableFrom(thatValue.getClass())) { return thisValue.compareTo(thatValue); } else if (thatValue.getClass().isAssignableFrom(thisValue.getClass())) { return thatValue.compareTo(thisValue) * -1; // correct for the reversed comparison } return ((Comparable<Object>) this.value).compareTo(that.asObject()); }