From 9043d4167aeab129be1aa786d47d5559e9045301 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 27 Jul 2008 22:44:10 +0000 Subject: Fixed conversion test failures. --- .../java/com/amazon/carbonado/util/Converter.java | 116 ++++++++++++++++----- 1 file changed, 90 insertions(+), 26 deletions(-) (limited to 'src/main/java/com/amazon/carbonado') diff --git a/src/main/java/com/amazon/carbonado/util/Converter.java b/src/main/java/com/amazon/carbonado/util/Converter.java index 33278a4..b15d408 100644 --- a/src/main/java/com/amazon/carbonado/util/Converter.java +++ b/src/main/java/com/amazon/carbonado/util/Converter.java @@ -18,6 +18,7 @@ package com.amazon.carbonado.util; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -49,15 +50,36 @@ import org.cojen.util.SoftValuedHashMap; * @since 1.2 */ public abstract class Converter { - private static final Map cCache = new SoftValuedHashMap(); + private static final Map> cCache = new SoftValuedHashMap(); - public static synchronized C build(Class converterType) { - C converter = (C) cCache.get(converterType); - if (converter == null) { - converter = new Builder(converterType).build(); - cCache.put(converterType, converter); + /** + * @param converterType type of converter to generate + * @throws IllegalArgumentException if converter doesn't a no-arg constructor + */ + public static C build(Class converterType) { + try { + return buildClass(converterType).newInstance(); + } catch (InstantiationException e) { + throw new IllegalArgumentException + ("TypeConverter must have a public no-arg constructor: " + converterType); + } catch (IllegalAccessException e) { + // Not expected to happen, since generated constructors are public. + throw new IllegalArgumentException(e); + } + } + + /** + * @param converterType type of converter to generate + */ + public static synchronized Class buildClass + (Class converterType) + { + Class converterClass = (Class) cCache.get(converterType); + if (converterClass == null) { + converterClass = new Builder(converterType).buildClass(); + cCache.put(converterType, converterClass); } - return converter; + return converterClass; } /** @@ -161,13 +183,6 @@ public abstract class Converter { throw new IllegalArgumentException("Not a TypeConverter: " + converterType); } - try { - converterType.getConstructor(); - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException - ("TypeConverter must have a public no-arg constructor: " + converterType); - } - mConverterType = converterType; mConvertMap = new HashMap>(); @@ -235,7 +250,7 @@ public abstract class Converter { */ } - C build() { + Class buildClass() { ClassInjector ci = ClassInjector .create(mConverterType.getName(), mConverterType.getClassLoader()); @@ -244,7 +259,36 @@ public abstract class Converter { mClassFile.setSourceFile(Converter.class.getName()); mClassFile.setTarget("1.5"); - mClassFile.addDefaultConstructor(); + // Add constructors which match superclass. + int ctorCount = 0; + for (Constructor ctor : mConverterType.getDeclaredConstructors()) { + int modifiers = ctor.getModifiers(); + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers)) { + continue; + } + + ctorCount++; + + TypeDesc[] params = new TypeDesc[ctor.getParameterTypes().length]; + for (int i=0; i