summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/info
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2008-07-22 09:19:51 +0000
committerBrian S. O'Neill <bronee@gmail.com>2008-07-22 09:19:51 +0000
commitfec4f593ccac17493f0014bd8fabdedc278135c8 (patch)
treec435dcbe45e420f3bf2b91dc70e0e296fdc7687b /src/main/java/com/amazon/carbonado/info
parent005101b7b1e7579b899c8a379f4516309e164c09 (diff)
Added advanced conversion capability when setting query filter properties. This is used to ensure that BigDecimal values are properly normalized.
Diffstat (limited to 'src/main/java/com/amazon/carbonado/info')
-rw-r--r--src/main/java/com/amazon/carbonado/info/ConversionComparator.java213
-rw-r--r--src/main/java/com/amazon/carbonado/info/StorableIntrospector.java1
2 files changed, 1 insertions, 213 deletions
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<Class> {
- 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