io.debezium.document.ComparableValue Maven / Gradle / Ivy
/*
* Copyright Debezium Authors.
*
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.debezium.document;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import io.debezium.annotation.Immutable;
/**
* A specialization of {@link Value} that wraps another {@link Value} that is not comparable.
*
* @author Randall Hauch
*/
@Immutable
final class ComparableValue implements Value {
private static final Map, Type> TYPES_BY_CLASS;
static {
Map, Type> types = new HashMap<>();
types.put(String.class, Type.STRING);
types.put(Boolean.class, Type.BOOLEAN);
types.put(byte[].class, Type.BINARY);
types.put(Integer.class, Type.INTEGER);
types.put(Long.class, Type.LONG);
types.put(Float.class, Type.FLOAT);
types.put(Double.class, Type.DOUBLE);
types.put(BigInteger.class, Type.BIG_INTEGER);
types.put(BigDecimal.class, Type.DECIMAL);
types.put(BasicDocument.class, Type.DOCUMENT);
types.put(BasicArray.class, Type.ARRAY);
TYPES_BY_CLASS = types;
}
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();
}
private final Comparable value;
ComparableValue(Comparable value) {
assert value != null;
this.value = value;
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Value) {
Value that = (Value) obj;
if (this.isNumber() && that.isNumber()) {
if (this.isLong()) {
return this.asLong().equals(that.asLong());
}
if (this.isDouble()) {
return this.asDouble().equals(that.asDouble());
}
if (this.isInteger()) {
return this.asInteger().equals(that.asInteger());
}
if (this.isFloat()) {
return this.asFloat().equals(that.asFloat());
}
if (this.isBigDecimal()) {
return this.asBigDecimal().equals(that.asBigDecimal());
}
if (this.isBigInteger()) {
return this.asBigInteger().equals(that.asBigInteger());
}
}
return this.value.equals(that.asObject());
}
// Compare the value straight away ...
return this.value.equals(obj);
}
@Override
public String toString() {
return value.toString();
}
@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