diff --git a/src/java/com/samskivert/jdbc/depot/ByteEnum.java b/src/java/com/samskivert/jdbc/depot/ByteEnum.java new file mode 100644 index 0000000..3e38268 --- /dev/null +++ b/src/java/com/samskivert/jdbc/depot/ByteEnum.java @@ -0,0 +1,39 @@ +// +// $Id$ +// +// samskivert library - useful routines for java programs +// Copyright (C) 2006 Michael Bayne +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.jdbc.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. + */ +public interface ByteEnum +{ + /** + * Returns the byte value to which to map this enum value. + */ + public byte toByte (); +} diff --git a/src/java/com/samskivert/jdbc/depot/FieldMarshaller.java b/src/java/com/samskivert/jdbc/depot/FieldMarshaller.java index bb3dd7b..59d0452 100644 --- a/src/java/com/samskivert/jdbc/depot/FieldMarshaller.java +++ b/src/java/com/samskivert/jdbc/depot/FieldMarshaller.java @@ -21,6 +21,9 @@ package com.samskivert.jdbc.depot; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.sql.Blob; import java.sql.Clob; @@ -93,6 +96,10 @@ public abstract class FieldMarshaller ftype.equals(Clob.class)) { marshaller = new ObjectMarshaller(); + // special Enum types + } else if (ByteEnum.class.isAssignableFrom(ftype)) { + marshaller = new ByteEnumMarshaller(ftype); + } else { throw new IllegalArgumentException( "Cannot marshall field of type '" + ftype.getName() + "'."); @@ -169,7 +176,7 @@ public abstract class FieldMarshaller // read our column metadata from the annotation (if it exists); annoyingly we can't create // a Column instance to read the defaults so we have to duplicate them here int length = 255; - boolean nullable = true; + boolean nullable = false; boolean unique = false; Column column = _field.getAnnotation(Column.class); if (column != null) { @@ -391,6 +398,40 @@ 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."); + } + } + + public void setValue (Object po, PreparedStatement ps, int column) + throws SQLException, IllegalAccessException { + ps.setInt(column, ((ByteEnum)_field.get(po)).toByte()); + } + public void getValue (ResultSet rs, Object po) + throws SQLException, IllegalAccessException { + try { + _field.set(po, _factmeth.invoke(null, rs.getInt(getColumnName()))); + } catch (InvocationTargetException ite) { + throw new RuntimeException(ite); + } + } + public String getColumnType () { + return "TINYINT"; + } + + protected Method _factmeth; + } + protected Field _field; protected String _columnName, _columnDefinition; protected Computed _computed;