Skip to content

Commit d982941

Browse files
committed
ConversionRequest: track Types, not Classes
A converter may need to verify type compatibility not just at the Class level, but potentially for any generic type. Generic types are not available at runtime from object instances, but they are available in other scenarios; e.g., the ImageJ OPS framework uses the converter framework to decide type compatibility (i.e., assignability or convertibility) based on generic types. This is possible (rather than generics being erased at runtime) because OPS parameters are declared as instance fields, which can be introspected at runtime.
1 parent 44ba930 commit d982941

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

src/main/java/org/scijava/convert/ConversionRequest.java

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
import java.lang.reflect.Type;
3535

36+
import org.scijava.util.GenericUtils;
37+
3638
/**
3739
* Currency for use in {@link Converter} and {@link ConvertService}
3840
* methods.
@@ -57,45 +59,49 @@
5759
* </p>
5860
*
5961
* @author Mark Hiner
62+
* @author Curtis Rueden
6063
*/
6164
public class ConversionRequest {
6265

6366
// -- Fields --
6467

65-
private final Class<?> srcClass;
68+
private final Type srcType;
69+
private final Type destType;
70+
6671
private Object src;
67-
private Class<?> destClass;
68-
private Type destType;
6972

7073
// -- Constructors --
7174

72-
public ConversionRequest(final Object s, final Class<?> d) {
73-
this(s == null ? null : s.getClass(), d);
74-
src = s;
75+
public ConversionRequest(final Object src, final Type destType) {
76+
this(src, src == null ? null : src.getClass(), destType);
7577
}
7678

77-
public ConversionRequest(final Class<?> s, final Class<?> d) {
78-
srcClass = s;
79-
destClass = d;
79+
public ConversionRequest(final Type srcType, final Type destType) {
80+
this(null, srcType, destType);
8081
}
8182

82-
public ConversionRequest(final Object s, final Type d) {
83-
this(s == null ? null : s.getClass(), d);
84-
src = s;
85-
}
86-
87-
public ConversionRequest(final Class<?> s, final Type d) {
88-
srcClass = s;
89-
destType = d;
83+
public ConversionRequest(final Object src, final Type srcType,
84+
final Type destType)
85+
{
86+
this.src = src;
87+
this.srcType = srcType;
88+
this.destType = destType;
9089
}
9190

9291
// -- Accessors --
9392

93+
/**
94+
* @return Source type for conversion or lookup.
95+
*/
96+
public Type sourceType() {
97+
return srcType;
98+
}
99+
94100
/**
95101
* @return Source class for conversion or lookup.
96102
*/
97103
public Class<?> sourceClass() {
98-
return srcClass;
104+
return GenericUtils.getClass(srcType);
99105
}
100106

101107
/**
@@ -116,7 +122,7 @@ public Type destType() {
116122
* @return Destination class for conversion.
117123
*/
118124
public Class<?> destClass() {
119-
return destClass;
125+
return GenericUtils.getClass(destType);
120126
}
121127

122128
// -- Setters --
@@ -128,11 +134,13 @@ public Class<?> destClass() {
128134
* not match {@link #sourceClass()}.
129135
*/
130136
public void setSourceObject(final Object o) {
131-
if (!srcClass.isAssignableFrom(o.getClass())) {
137+
// TODO: More careful check against srcType itself.
138+
if (!sourceClass().isInstance(o)) {
132139
throw new IllegalArgumentException("Object of type: " + o.getClass() +
133-
" provided. Expected: " + srcClass);
140+
" provided. Expected: " + srcType);
134141
}
135142

136143
src = o;
137144
}
145+
138146
}

0 commit comments

Comments
 (0)