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