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 CommonEnumTypeHandler implements 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());
}
}