|
package com.oogly.dao.support.impl; |
|
import java.io.Serializable; |
import java.lang.reflect.Method; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.util.Properties; |
|
import org.hibernate.HibernateException; |
import org.hibernate.type.NullableType; |
import org.hibernate.type.TypeFactory; |
import org.hibernate.usertype.ParameterizedType; |
import org.hibernate.usertype.UserType; |
|
/** |
* GenericEnumUserType. |
* Modified from http://www.hibernate.org/272.html. |
* @author jholloway |
*/ |
public class GenericEnumUserType implements UserType, ParameterizedType { // NOPMD |
|
private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "name"; |
private static final String DEFAULT_VALUE_OF_METHOD_NAME = "valueOf"; |
|
private Class< ? extends Enum> enumClass; |
private Class< ? > identifierType; |
private Method identifierMethod; |
private Method valueOfMethod; |
private NullableType type; |
private int[] sqlTypes; |
|
/** |
* Set parameter values. |
* enumClassName is the className of the enum |
* identifierMethodName is the method name to use for retrieval |
* type is the identifier type |
* valueOfMethod is the method name to use for retrieval |
* @param parameters are the parameters from which we obtain our values for this type |
*/ |
public void setParameterValues(final Properties parameters) { |
|
String enumClassName = parameters.getProperty("enumClassName"); |
|
try { |
enumClass = Class.forName(enumClassName).asSubclass(Enum.class); |
} catch (ClassNotFoundException cfne) { |
throw new HibernateException("Enum class not found", cfne); |
} |
|
String identifierMethodName = parameters.getProperty("identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME); |
|
try { |
|
identifierMethod = enumClass.getMethod(identifierMethodName, |
new Class[0]); |
identifierType = identifierMethod.getReturnType(); |
|
} catch (Exception e) { |
throw new HibernateException("Failed to obtain identifier method", e); |
} |
|
type = (NullableType) TypeFactory.basic(identifierType.getName()); |
|
if (type == null) { |
throw new HibernateException("Unsupported identifier type " + identifierType.getName()); |
} |
|
sqlTypes = new int[] { type.sqlType() }; |
|
String valueOfMethodName = parameters.getProperty("valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME); |
|
try { |
valueOfMethod = enumClass.getMethod(valueOfMethodName, |
new Class[] { identifierType }); |
} catch (Exception e) { |
throw new HibernateException("Failed to obtain valueOf method", e); |
} |
} |
|
/** |
* Get the returned class. |
* @return the enum class |
*/ |
public Class returnedClass() { |
return enumClass; |
} |
|
/** |
* Null safe get. |
* @param resultSet is the result set |
* @param names are the names |
* @param owner is the owner |
* @return an identifier object |
* @throws HibernateException if we cannot invoke the correct method |
* @throws SQLException a SQL exception if there is a syntax error |
*/ |
public Object nullSafeGet(final ResultSet resultSet, |
final String[] names, |
final Object owner) throws HibernateException, SQLException { |
|
Object identifier = type.get(resultSet, names[0]); |
|
if (resultSet.wasNull()) { |
return null; |
} |
|
try { |
return valueOfMethod.invoke(enumClass, new Object[] { identifier }); |
} catch (Exception e) { |
throw new HibernateException("Exception while invoking " |
+ "valueOf method " + valueOfMethod.getName() + " of " |
+ "enumeration class " + enumClass, e); |
} |
} |
|
/** |
* Null safe set method. |
* @param statement is the prepared statement |
* @param value is the value of the object |
* @param index is the index |
* @throws HibernateException a Hibernate type exception |
* @throws SQLException a SQL exception |
*/ |
public void nullSafeSet(final PreparedStatement statement, final Object value, final int index) throws HibernateException, SQLException { |
|
try { |
if (value == null) { |
statement.setNull(index, type.sqlType()); |
} else { |
Object identifier = identifierMethod.invoke(value, |
new Object[0]); |
type.set(statement, identifier, index); |
} |
} catch (Exception e) { |
throw new HibernateException("Exception invoking id method " |
+ identifierMethod.getName() |
+ " of enum class " |
+ enumClass, e); |
} |
} |
|
/** |
* Return the SQL types as an array. |
* @return an int array of SQL types |
*/ |
public int[] sqlTypes() { //NOPMD |
return sqlTypes; |
} |
|
/** |
* Assemble a cached object. |
* @param cached is the cached object |
* @param owner is the owner here |
* @return the assembled object |
* @throws HibernateException a hibernate type exception |
*/ |
public Object assemble(final Serializable cached, |
final Object owner) throws HibernateException { |
return cached; |
} |
|
/** |
* Return a deep copy of the object. |
* @param value is the object to copy |
* @return a copy as an object |
* @throws HibernateException a hibernate type exception |
*/ |
public Object deepCopy(final Object value) throws HibernateException { |
return value; |
} |
|
/** |
* Disassemble an object. |
* @param value is the object to disassemble |
* @return a Serializable object |
* @throws HibernateException a hibernate type exception |
*/ |
public Serializable disassemble(final Object value) throws HibernateException { |
return (Serializable) value; |
} |
|
/** |
* Equals method to compare two objects. |
* @param objectA is the first object to compare |
* @param objectY is the second object to compare |
* @return whether the objects are equal |
* @throws HibernateException a hibernate type exception |
*/ |
public boolean equals(final Object objectA, final Object objectY) throws HibernateException { // NOPMD |
return objectA == objectY; |
} |
|
/** |
* Return the hashcode of the object x. |
* @param objectX is the object to return a hashcode for |
* @return the hashcode integer |
* @throws HibernateException a hibernate type exception |
*/ |
public int hashCode(final Object objectX) throws HibernateException { |
return objectX.hashCode(); |
} |
|
/** |
* Return an immutable object boolean flag. |
* @return an immutable flag |
*/ |
public boolean isMutable() { |
return false; |
} |
|
/** |
* Replace an owners object with a target object. |
* @param original is the original object |
* @param target is the target object |
* @param owner is the owner of the object |
* @return the object replaced |
* @throws HibernateException a hibernate type exception |
*/ |
public Object replace(final Object original, final Object target, final Object owner) throws HibernateException { |
return original; |
} |
} |
|