My goal was to create a simple, extensible Enum converter that would work with iBatis. This seems like a trivial problem, but took me a while to find a proper solution.
There were some additional preconditions:
- all given Enums are jaxb generated objects - but any standard Java Enum should work
- conversion was 1-to-1, no special conditions and processing
The example Enum for this problem looks like this one (copy&paste from jaxb generated source):
@XmlType(name ="ServiceType")
@XmlEnum
public enum ServiceType {
@XmlEnumValue("stationary")
STATIONARY("stationary"),
@XmlEnumValue("mobile")
MOBILE("mobile");
private final String value;
ServiceType(String v) {
value = v;
}
public String value() {
return value;
}
public static ServiceType fromValue(String v) {
for (ServiceType c: ServiceType.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
}
“No big deal”, you say. I beg to differ. What I wanted to achieve was a simple construction which would look like this when used for another Enum (CommonEnumTypeHandler is the name of my generic converter):
public class ServiceTypeHandler extends CommonEnumTypeHandler{ }
Unfortunately due to the fact, that Java does not have reified generics, which is described in multiple places, I had to stick with passing through a Class type of my enum. So it looks like this:
public class ServiceTypeHandler extends CommonEnumTypeHandler{ public ServiceTypeHandler() { super(ServiceType.class); } }
My final class has to look like this one below:
import java.sql.SQLException; import com.ibatis.sqlmap.client.extensions.ParameterSetter; import com.ibatis.sqlmap.client.extensions.ResultGetter; import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback; public abstract class CommonEnumTypeHandlerimplements TypeHandlerCallback { Class enumClass; public CommonEnumTypeHandler(Class clazz) { this.enumClass = clazz; } public void setParameter(ParameterSetter ps, Object o) throws SQLException { if (o.getClass().isAssignableFrom(enumClass)) { ps.setString(((T) o).name().toUpperCase()); } else throw new SQLException("Excpected " + enumClass + " object than: " + o); } public Object getResult(ResultGetter rs) throws SQLException { Object o = valueOf(rs.getString()); if (o == null) throw new SQLException("Unknown parameter type: " + rs.getString()); return o; } public Object valueOf(String s) { return Enum.valueOf(enumClass, s.toUpperCase()); } }