PropertyValueStrategyUtils.java
/*
* Copyright © 2014 - 2021 Leipzig University (Database Research Group)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradoop.common.model.impl.properties.strategies;
import org.gradoop.common.exceptions.UnsupportedTypeException;
import java.math.BigDecimal;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Utility class which mainly handles comparing any values of the type {@code Numerical}.
*/
class PropertyValueStrategyUtils {
/**
* Short type.
*/
private static final int SHORT = 0;
/**
* Integer type.
*/
private static final int INT = 1;
/**
* Long type.
*/
private static final int LONG = 2;
/**
* Float type.
*/
private static final int FLOAT = 3;
/**
* Double type.
*/
private static final int DOUBLE = 4;
/**
* Big decimal type.
*/
private static final int BIG_DECIMAL = 5;
/**
* Compares a numerical to an object. The object needs to be an instance of {@code Number}.
*
* @param aValue first value
* @param other second value
* @return a negative integer, zero, or a positive integer as aValue is less than, equal to, or
* greater than bValue.
* @throws IllegalArgumentException if other is not an instance of number.
*/
static int compareNumerical(Number aValue, Object other) {
if (!(other instanceof Number)) {
throw new IllegalArgumentException(String.format(
"Incompatible types: %s, %s", aValue.getClass(), other.getClass()));
}
Number bValue = (Number) other;
int aType = getType(aValue);
int bType = getType(bValue);
boolean sameType = aType == bType;
int maxType = Math.max(aType, bType);
int result;
if (maxType == SHORT) {
result = Short.compare(aValue.shortValue(), bValue.shortValue());
} else if (maxType == INT) {
int a;
int b;
if (sameType) {
a = aValue.intValue();
b = bValue.intValue();
} else {
a = aType == INT ? aValue.intValue() : aValue.shortValue();
b = bType == INT ? bValue.intValue() : bValue.shortValue();
}
result = Integer.compare(a, b);
} else if (maxType == FLOAT) {
float a;
float b;
if (sameType) {
a = aValue.floatValue();
b = bValue.floatValue();
} else {
a = aType == FLOAT ? aValue.floatValue() : floatValue(aValue, aType);
b = bType == FLOAT ? bValue.floatValue() : floatValue(bValue, bType);
}
result = Float.compare(a, b);
} else if (maxType == LONG) {
long a;
long b;
if (sameType) {
a = aValue.longValue();
b = bValue.longValue();
} else {
a = aType == LONG ? aValue.longValue() : longValue(aValue, aType);
b = bType == LONG ? bValue.longValue() : longValue(bValue, bType);
}
result = Long.compare(a, b);
} else if (maxType == DOUBLE) {
double a;
double b;
if (sameType) {
a = aValue.doubleValue();
b = bValue.doubleValue();
} else {
a = aType == DOUBLE ? aValue.doubleValue() : doubleValue(aValue, aType);
b = bType == DOUBLE ? bValue.doubleValue() : doubleValue(bValue, bType);
}
result = Double.compare(a, b);
} else {
BigDecimal a;
BigDecimal b;
if (sameType) {
a = (BigDecimal) aValue;
b = (BigDecimal) bValue;
} else {
a = aType == BIG_DECIMAL ? (BigDecimal) aValue :
bigDecimalValue(aValue, aType);
b = bType == BIG_DECIMAL ? (BigDecimal) bValue :
bigDecimalValue(bValue, bType);
}
result = a.compareTo(b);
}
return result;
}
/**
* Gets the number type of the provided object.
*
* @param value some number object.
* @return integer representation of the objects data type.
*/
private static int getType(Number value) {
checkNotNull(value);
int type;
if (value instanceof Short) {
type = SHORT;
} else if (value instanceof Integer) {
type = INT;
} else if (value instanceof Long) {
type = LONG;
} else if (value instanceof Float) {
type = FLOAT;
} else if (value instanceof Double) {
type = DOUBLE;
} else if (value instanceof BigDecimal) {
type = BIG_DECIMAL;
} else {
throw new UnsupportedTypeException(value.getClass());
}
return type;
}
/**
* Converts a value of a lower domain numerical type to BigDecimal.
*
* @param value value
* @param type type
* @return converted value
*/
private static BigDecimal bigDecimalValue(Number value, int type) {
switch (type) {
case SHORT:
return BigDecimal.valueOf(value.shortValue());
case INT:
return BigDecimal.valueOf(value.intValue());
case LONG:
return BigDecimal.valueOf(value.longValue());
case FLOAT:
return BigDecimal.valueOf(value.floatValue());
default:
return BigDecimal.valueOf(value.doubleValue());
}
}
/**
* Converts a value of a lower domain numerical type to Double.
*
* @param value value
* @param type type
* @return converted value
*/
private static double doubleValue(Number value, int type) {
switch (type) {
case SHORT:
return value.shortValue();
case INT:
return value.intValue();
case LONG:
return value.longValue();
default:
return value.floatValue();
}
}
/**
* Converts a value of a lower domain numerical type to Long.
*
* @param value value
* @param type type
* @return converted value
*/
private static long longValue(Number value, int type) {
if (type == SHORT) {
return value.shortValue();
}
return value.intValue();
}
/**
* Converts a value of a lower domain numerical type to Float.
*
* @param value value
* @param type type
* @return converted value
*/
private static float floatValue(Number value, int type) {
switch (type) {
case SHORT:
return value.shortValue();
case INT:
return value.intValue();
default:
return value.longValue();
}
}
}