We don't need the fromByte() method, we can just do what the implementation of
all of our fromByte() methods already do which is iterate over the Enum and find the one with the right byte. If we care about performance (which we don't because this is trivial since all of these enums are small), we could even cache a mapping from byte to enum in the field marshaller. No need to foist this reponsibility on the ByteEnum implementor.
This commit is contained in:
@@ -21,14 +21,7 @@
|
|||||||
package com.samskivert.depot;
|
package com.samskivert.depot;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An enum value can be used as a field in a persistent object if it implements this interface and
|
* An enum value can be used as a field in a persistent object if it implements this interface.
|
||||||
* also declares a public static method with the following signature:
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* public static YourEnum fromByte (byte value)
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* which must return the appropriate instance of your enum for the supplied byte.
|
|
||||||
*/
|
*/
|
||||||
public interface ByteEnum
|
public interface ByteEnum
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ package com.samskivert.depot.impl;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import java.sql.Blob;
|
import java.sql.Blob;
|
||||||
@@ -102,7 +103,14 @@ public abstract class FieldMarshaller<T>
|
|||||||
|
|
||||||
// special Enum types
|
// special Enum types
|
||||||
} else if (ByteEnum.class.isAssignableFrom(ftype)) {
|
} else if (ByteEnum.class.isAssignableFrom(ftype)) {
|
||||||
marshaller = new ByteEnumMarshaller(ftype);
|
// do some sanity checking so that the unsafe business we do below is safer
|
||||||
|
if (!Enum.class.isAssignableFrom(ftype)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"ByteEnum not implemented by real Enum: " + field);
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked") ByteEnumMarshaller<?> bem =
|
||||||
|
new ByteEnumMarshaller(ftype);
|
||||||
|
marshaller = bem;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
@@ -429,34 +437,24 @@ public abstract class FieldMarshaller<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class ByteEnumMarshaller extends FieldMarshaller<ByteEnum> {
|
protected static class ByteEnumMarshaller<E extends Enum<E>> extends FieldMarshaller<ByteEnum> {
|
||||||
public ByteEnumMarshaller (Class<?> clazz) {
|
public ByteEnumMarshaller (Class<E> clazz) {
|
||||||
try {
|
_eclass = clazz;
|
||||||
_factmeth = clazz.getMethod("fromByte", new Class[] { Byte.TYPE });
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Could not locate fromByte() method on enum field " + _field.getType() + ".");
|
|
||||||
}
|
|
||||||
if (!Modifier.isPublic(_factmeth.getModifiers()) ||
|
|
||||||
!Modifier.isStatic(_factmeth.getModifiers())) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
_field.getType() + ".fromByte() must be public and static.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public ByteEnum getFromObject (Object po)
|
@Override public ByteEnum getFromObject (Object po)
|
||||||
throws IllegalArgumentException, IllegalAccessException {
|
throws IllegalArgumentException, IllegalAccessException {
|
||||||
return (ByteEnum) _field.get(po);
|
return (ByteEnum) _field.get(po);
|
||||||
}
|
}
|
||||||
@Override public ByteEnum getFromSet (ResultSet rs)
|
@Override public ByteEnum getFromSet (ResultSet rs) throws SQLException {
|
||||||
throws SQLException {
|
byte code = rs.getByte(getColumnName());
|
||||||
try {
|
for (E value : EnumSet.allOf(_eclass)) {
|
||||||
return (ByteEnum) _factmeth.invoke(null, rs.getByte(getColumnName()));
|
ByteEnum bvalue = (ByteEnum)value;
|
||||||
} catch (SQLException se) {
|
if (bvalue.toByte() == code) {
|
||||||
throw se;
|
return bvalue;
|
||||||
} catch (Exception e) {
|
}
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
@Override public void writeToObject (Object po, ByteEnum value)
|
@Override public void writeToObject (Object po, ByteEnum value)
|
||||||
throws IllegalArgumentException, IllegalAccessException {
|
throws IllegalArgumentException, IllegalAccessException {
|
||||||
@@ -467,7 +465,7 @@ public abstract class FieldMarshaller<T>
|
|||||||
ps.setByte(column, value.toByte());
|
ps.setByte(column, value.toByte());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Method _factmeth;
|
protected Class<E> _eclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Field _field;
|
protected Field _field;
|
||||||
|
|||||||
Reference in New Issue
Block a user