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<Integer>.

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. :)
This commit is contained in:
Michael Bayne
2010-07-05 21:43:10 +00:00
parent a5fee01354
commit 0e82904696
4 changed files with 19 additions and 11 deletions
@@ -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<F,T>
*
* @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);
}
@@ -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<String> fromPersistent (Class<?> ftype, String encoded)
public Iterable<String> fromPersistent (Type ftype, String encoded)
{
ArrayList<String> 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
@@ -705,7 +705,7 @@ public abstract class FieldMarshaller<T>
}
@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 {
@@ -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<Dummy> eclass = (Class<Dummy>)ftype;
return fromShort(eclass, value);
}