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:
Michael Bayne
2009-07-10 17:20:57 +00:00
parent def3d652ad
commit 9469575ad7
2 changed files with 22 additions and 31 deletions
+1 -8
View File
@@ -21,14 +21,7 @@
package com.samskivert.depot;
/**
* An enum value can be used as a field in a persistent object if it implements this interface and
* 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.
* An enum value can be used as a field in a persistent object if it implements this interface.
*/
public interface ByteEnum
{
@@ -23,6 +23,7 @@ package com.samskivert.depot.impl;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.EnumSet;
import java.nio.ByteBuffer;
import java.sql.Blob;
@@ -102,7 +103,14 @@ public abstract class FieldMarshaller<T>
// special Enum types
} 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 {
throw new IllegalArgumentException(
@@ -429,34 +437,24 @@ public abstract class FieldMarshaller<T>
}
}
protected static class ByteEnumMarshaller extends FieldMarshaller<ByteEnum> {
public ByteEnumMarshaller (Class<?> clazz) {
try {
_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.");
}
protected static class ByteEnumMarshaller<E extends Enum<E>> extends FieldMarshaller<ByteEnum> {
public ByteEnumMarshaller (Class<E> clazz) {
_eclass = clazz;
}
@Override public ByteEnum getFromObject (Object po)
throws IllegalArgumentException, IllegalAccessException {
return (ByteEnum) _field.get(po);
}
@Override public ByteEnum getFromSet (ResultSet rs)
throws SQLException {
try {
return (ByteEnum) _factmeth.invoke(null, rs.getByte(getColumnName()));
} catch (SQLException se) {
throw se;
} catch (Exception e) {
throw new RuntimeException(e);
@Override public ByteEnum getFromSet (ResultSet rs) throws SQLException {
byte code = rs.getByte(getColumnName());
for (E value : EnumSet.allOf(_eclass)) {
ByteEnum bvalue = (ByteEnum)value;
if (bvalue.toByte() == code) {
return bvalue;
}
}
return null;
}
@Override public void writeToObject (Object po, ByteEnum value)
throws IllegalArgumentException, IllegalAccessException {
@@ -467,7 +465,7 @@ public abstract class FieldMarshaller<T>
ps.setByte(column, value.toByte());
}
protected Method _factmeth;
protected Class<E> _eclass;
}
protected Field _field;