From 0e82904696b61ccc05262c19db1154199e5ddcf6 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Mon, 5 Jul 2010 21:43:10 +0000 Subject: [PATCH] Provide the Transformer with the field's Type rather than it's Class. The Type contains generic type information which would allow a transformer to do the right thing with a field of, say, type Set. If we had unit tests for StringIterable, I'd know that I didn't just break it. I'd also know that it worked in the first place. :) --- .../com/samskivert/depot/Transformer.java | 4 +++- .../com/samskivert/depot/Transformers.java | 19 ++++++++++++------- .../depot/impl/FieldMarshaller.java | 2 +- .../samskivert/depot/tests/TransformTest.java | 5 +++-- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/java/com/samskivert/depot/Transformer.java b/src/java/com/samskivert/depot/Transformer.java index 710cd1d..6005aee 100644 --- a/src/java/com/samskivert/depot/Transformer.java +++ b/src/java/com/samskivert/depot/Transformer.java @@ -20,6 +20,8 @@ package com.samskivert.depot; +import java.lang.reflect.Type; + /** * Transforms a persistent record field into a format that can be read and written by the * underlying database. For example, one might transform an enum into a byte, short or integer. Or @@ -48,5 +50,5 @@ public interface Transformer * * @return the transformed value, which will be stored in a field of the persistent record. */ - F fromPersistent (Class fieldType, T value); + F fromPersistent (Type fieldType, T value); } diff --git a/src/java/com/samskivert/depot/Transformers.java b/src/java/com/samskivert/depot/Transformers.java index 45dde5d..081c59f 100644 --- a/src/java/com/samskivert/depot/Transformers.java +++ b/src/java/com/samskivert/depot/Transformers.java @@ -20,6 +20,9 @@ package com.samskivert.depot; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -65,7 +68,7 @@ public class Transformers } return buf.toString(); } - public String[] fromPersistent (Class ftype, String value) { + public String[] fromPersistent (Type ftype, String value) { String[] values = value.replace("\\\t", "%%ESCTAB%%").split("\t"); for (int ii = 0; ii < values.length; ii++) { values[ii] = values[ii].replace("%%ESCTAB%%", "\t"); @@ -85,7 +88,7 @@ public class Transformers return StringIterable.toPersistent0(Arrays.asList(value)); } - public String[] fromPersistent (Class ftype, String encoded) + public String[] fromPersistent (Type ftype, String encoded) { if (encoded == null) { return null; @@ -102,18 +105,20 @@ public class Transformers return toPersistent0(value); } - public Iterable fromPersistent (Class ftype, String encoded) + public Iterable fromPersistent (Type ftype, String encoded) { ArrayList value = fromPersistent0(encoded); + Type fclass = (ftype instanceof ParameterizedType) ? + ((ParameterizedType)ftype).getRawType() : ftype; if (value == null || - ftype == ArrayList.class || ftype == List.class || ftype == Collection.class || - ftype == Iterable.class) { + fclass == ArrayList.class || fclass == List.class || + fclass == Collection.class || fclass == Iterable.class) { return value; } - if (ftype == LinkedList.class) { + if (fclass == LinkedList.class) { return Lists.newLinkedList(value); } - if (ftype == HashSet.class || ftype == Set.class) { + if (fclass == HashSet.class || fclass == Set.class) { return Sets.newHashSet(value); } // else: reflection? See if it's a collection, call the 0-arg constructor, add all diff --git a/src/java/com/samskivert/depot/impl/FieldMarshaller.java b/src/java/com/samskivert/depot/impl/FieldMarshaller.java index ad7499f..c74d40a 100644 --- a/src/java/com/samskivert/depot/impl/FieldMarshaller.java +++ b/src/java/com/samskivert/depot/impl/FieldMarshaller.java @@ -705,7 +705,7 @@ public abstract class FieldMarshaller } @Override public void writeToObject (Object po, T value) throws IllegalArgumentException, IllegalAccessException { - _field.set(po, _xformer.fromPersistent(_field.getType(), value)); + _field.set(po, _xformer.fromPersistent(_field.getGenericType(), value)); } @Override public void writeToStatement (PreparedStatement ps, int column, T value) throws SQLException { diff --git a/src/java/com/samskivert/depot/tests/TransformTest.java b/src/java/com/samskivert/depot/tests/TransformTest.java index 07d67e8..8a259a5 100644 --- a/src/java/com/samskivert/depot/tests/TransformTest.java +++ b/src/java/com/samskivert/depot/tests/TransformTest.java @@ -21,6 +21,7 @@ package com.samskivert.depot.tests; import java.lang.reflect.Field; +import java.lang.reflect.Type; import java.util.Set; import org.junit.Test; @@ -92,7 +93,7 @@ public class TransformTest extends TestBase return value.value; } - public CustomType fromPersistent (Class ftype, String value) { + public CustomType fromPersistent (Type ftype, String value) { return new CustomType(value); } } @@ -102,7 +103,7 @@ public class TransformTest extends TestBase public Short toPersistent (ShortEnum value) { return value.toShort(); } - public ShortEnum fromPersistent (Class ftype, Short value) { + public ShortEnum fromPersistent (Type ftype, Short value) { @SuppressWarnings("unchecked") Class eclass = (Class)ftype; return fromShort(eclass, value); }