From fec4f593ccac17493f0014bd8fabdedc278135c8 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Tue, 22 Jul 2008 09:19:51 +0000 Subject: Added advanced conversion capability when setting query filter properties. This is used to ensure that BigDecimal values are properly normalized. --- .../carbonado/info/ConversionComparator.java | 213 --------------------- .../carbonado/info/StorableIntrospector.java | 1 + 2 files changed, 1 insertion(+), 213 deletions(-) delete mode 100644 src/main/java/com/amazon/carbonado/info/ConversionComparator.java (limited to 'src/main/java/com/amazon/carbonado/info') diff --git a/src/main/java/com/amazon/carbonado/info/ConversionComparator.java b/src/main/java/com/amazon/carbonado/info/ConversionComparator.java deleted file mode 100644 index 0feac47..0000000 --- a/src/main/java/com/amazon/carbonado/info/ConversionComparator.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. - * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks - * of Amazon Technologies, Inc. or its affiliates. All rights reserved. - * - * 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 com.amazon.carbonado.info; - -import java.util.Comparator; - -import org.cojen.classfile.TypeDesc; - -/** - * Compares type conversions, finding the one that is nearest. - * - * @author Brian S O'Neill - * @since 1.2 - */ -class ConversionComparator implements Comparator { - private final TypeDesc mFrom; - - public ConversionComparator(Class fromType) { - mFrom = TypeDesc.forClass(fromType); - } - - /** - * Returns true if a coversion is possible to the given type. - */ - public boolean isConversionPossible(Class toType) { - return isConversionPossible(mFrom, TypeDesc.forClass(toType)); - } - - @SuppressWarnings("unchecked") - private static boolean isConversionPossible(TypeDesc from, TypeDesc to) { - if (from == to) { - return true; - } - - if (from.toPrimitiveType() != null && to.toPrimitiveType() != null) { - from = from.toPrimitiveType(); - to = to.toPrimitiveType(); - } else { - from = from.toObjectType(); - to = to.toObjectType(); - } - - switch (from.getTypeCode()) { - case TypeDesc.OBJECT_CODE: default: - return to.toClass().isAssignableFrom(from.toClass()); - case TypeDesc.BOOLEAN_CODE: - return to == TypeDesc.BOOLEAN; - case TypeDesc.BYTE_CODE: - return to == TypeDesc.BYTE || to == TypeDesc.SHORT - || to == TypeDesc.INT || to == TypeDesc.LONG - || to == TypeDesc.FLOAT || to == TypeDesc.DOUBLE; - case TypeDesc.SHORT_CODE: - return to == TypeDesc.SHORT - || to == TypeDesc.INT || to == TypeDesc.LONG - || to == TypeDesc.FLOAT || to == TypeDesc.DOUBLE; - case TypeDesc.CHAR_CODE: - return to == TypeDesc.CHAR; - case TypeDesc.INT_CODE: - return to == TypeDesc.INT || to == TypeDesc.LONG || to == TypeDesc.DOUBLE; - case TypeDesc.FLOAT_CODE: - return to == TypeDesc.FLOAT || to == TypeDesc.DOUBLE; - case TypeDesc.LONG_CODE: - return to == TypeDesc.LONG; - case TypeDesc.DOUBLE_CODE: - return to == TypeDesc.DOUBLE; - } - } - - /** - * Evaluates two types, to see which one is nearest to the from type. - * Return {@literal <0} if "a" is nearest, 0 if both are equally good, - * {@literal >0} if "b" is nearest. - */ - public int compare(Class toType_a, Class toType_b) { - TypeDesc from = mFrom; - TypeDesc a = TypeDesc.forClass(toType_a); - TypeDesc b = TypeDesc.forClass(toType_b); - - if (from == a) { - if (from == b) { - return 0; - } - return -1; - } else if (from == b) { - return 1; - } - - int result = compare(from, a, b); - if (result != 0) { - return result; - } - - if (from.isPrimitive()) { - // Try boxing. - if (from.toObjectType() != null) { - from = from.toObjectType(); - return compare(from, a, b); - } - } else { - // Try unboxing. - if (from.toPrimitiveType() != null) { - from = from.toPrimitiveType(); - result = compare(from, a, b); - if (result != 0) { - return result; - } - // Try boxing back up. Test by unboxing 'to' types. - if (!toType_a.isPrimitive() && a.toPrimitiveType() != null) { - a = a.toPrimitiveType(); - } - if (!toType_b.isPrimitive() && b.toPrimitiveType() != null) { - b = b.toPrimitiveType(); - } - return compare(from, a, b); - } - } - - return 0; - } - - private static int compare(TypeDesc from, TypeDesc a, TypeDesc b) { - if (isConversionPossible(from, a)) { - if (isConversionPossible(from, b)) { - if (from.isPrimitive()) { - if (a.isPrimitive()) { - if (b.isPrimitive()) { - // Choose the one with the least amount of widening. - return primitiveWidth(a) - primitiveWidth(b); - } else { - return -1; - } - } else if (b.isPrimitive()) { - return 1; - } - } else { - // Choose the one with the shortest distance up the class - // hierarchy. - Class fromClass = from.toClass(); - if (!fromClass.isInterface()) { - if (a.toClass().isInterface()) { - if (!b.toClass().isInterface()) { - return -1; - } - } else if (b.toClass().isInterface()) { - return 1; - } else { - return distance(fromClass, a.toClass()) - - distance(fromClass, b.toClass()); - } - } - } - } else { - return -1; - } - } else if (isConversionPossible(from, b)) { - return 1; - } - - return 0; - } - - // 1 = boolean, 2 = byte, 3 = short, 4 = char, 5 = int, 6 = float, 7 = long, 8 = double - private static int primitiveWidth(TypeDesc type) { - switch (type.getTypeCode()) { - default: - return 0; - case TypeDesc.BOOLEAN_CODE: - return 1; - case TypeDesc.BYTE_CODE: - return 2; - case TypeDesc.SHORT_CODE: - return 3; - case TypeDesc.CHAR_CODE: - return 4; - case TypeDesc.INT_CODE: - return 5; - case TypeDesc.FLOAT_CODE: - return 6; - case TypeDesc.LONG_CODE: - return 7; - case TypeDesc.DOUBLE_CODE: - return 8; - } - } - - private static int distance(Class from, Class to) { - int distance = 0; - while (from != to) { - from = from.getSuperclass(); - if (from == null) { - return Integer.MAX_VALUE; - } - distance++; - } - return distance; - } -} diff --git a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java index 80d263a..bd1d52b 100644 --- a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java +++ b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java @@ -72,6 +72,7 @@ import com.amazon.carbonado.Version; import com.amazon.carbonado.adapter.AdapterDefinition; import com.amazon.carbonado.constraint.ConstraintDefinition; import com.amazon.carbonado.lob.Lob; +import com.amazon.carbonado.util.ConversionComparator; /** * Supports examination of {@link Storable} types, returning all metadata -- cgit v1.2.3