From 9469575ad7d269a083a7d414f96f4d3234c65a77 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Fri, 10 Jul 2009 17:20:57 +0000 Subject: [PATCH] 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. --- src/java/com/samskivert/depot/ByteEnum.java | 9 +--- .../depot/impl/FieldMarshaller.java | 44 +++++++++---------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/java/com/samskivert/depot/ByteEnum.java b/src/java/com/samskivert/depot/ByteEnum.java index 4d4f4d0..95e39e1 100644 --- a/src/java/com/samskivert/depot/ByteEnum.java +++ b/src/java/com/samskivert/depot/ByteEnum.java @@ -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: - * - * - * public static YourEnum fromByte (byte value) - * - * - * 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 { diff --git a/src/java/com/samskivert/depot/impl/FieldMarshaller.java b/src/java/com/samskivert/depot/impl/FieldMarshaller.java index 1e15556..3c0e390 100644 --- a/src/java/com/samskivert/depot/impl/FieldMarshaller.java +++ b/src/java/com/samskivert/depot/impl/FieldMarshaller.java @@ -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 // 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 } } - protected static class ByteEnumMarshaller extends FieldMarshaller { - 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> extends FieldMarshaller { + public ByteEnumMarshaller (Class 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 ps.setByte(column, value.toByte()); } - protected Method _factmeth; + protected Class _eclass; } protected Field _field;