Fields that have no @Column must now default to non-nullable.

Added experimental support for Enum fields that are mapped to bytes.
This commit is contained in:
Michael Bayne
2006-11-20 23:35:46 +00:00
parent 6c777cebcb
commit 2ab575aa05
2 changed files with 81 additions and 1 deletions
@@ -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:
*
* <code>
* public static YourEnum fromByte (byte value)
* </code>
*
* 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 ();
}
@@ -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;