package com.mycorp.myapp.dto;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.StringType;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
@Deprecated
/**
* use org.hibernate.type.EnumType
* Unfortunately this is here to a Category enum being lowercase of 'default' which is a reserved word and can't be used.
*/
public class EnumType implements UserType, ParameterizedType
{
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 int[] sqlTypes;
public static final StringType TYPE = new StringType();
@Override
@SuppressWarnings("unchecked")
public void setParameterValues(final Properties parameters)
{
final String enumClassName = parameters.getProperty("enumClass");
try
{
enumClass = (Class<? extends Enum<?>>) Class.forName(enumClassName).asSubclass(Enum.class);
}
catch (final ClassNotFoundException cfne)
{
throw new HibernateException("Enum class not found", cfne);
}
final String identifierMethodName = parameters.getProperty("identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME);
try
{
identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]);
identifierType = identifierMethod.getReturnType();
}
catch (final Exception e)
{
throw new HibernateException("Failed to obtain identifier method", e);
}
sqlTypes = new int[] { Types.VARCHAR };
final String valueOfMethodName = parameters.getProperty("valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME);
try
{
valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] { identifierType });
}
catch (final Exception e)
{
throw new HibernateException("Failed to obtain valueOf method", e);
}
}
@Override
public Class<? extends Enum<?>> returnedClass()
{
return enumClass;
}
@Override
public int[] sqlTypes()
{
return sqlTypes;
}
@Override
public Object assemble(final Serializable cached, final Object owner) throws HibernateException
{
return cached;
}
@Override
public Object deepCopy(final Object value) throws HibernateException
{
return value;
}
@Override
public Serializable disassemble(final Object value) throws HibernateException
{
return (Serializable) value;
}
// Sonar rule S1201 flags this method. The developer has to use this method signature unless/until we convince Hibernate to change their API or quit using Hibernate.
@Override
public boolean equals(final Object x, final Object y) throws HibernateException
{
return x == y;
}
@Override
public int hashCode(final Object x) throws HibernateException
{
return x.hashCode();
}
@Override
public boolean isMutable()
{
return false;
}
@Override
public Object replace(final Object original, final Object target, final Object owner) throws HibernateException
{
return original;
}
@Override
public Object nullSafeGet(final ResultSet rs, final String[] names, final SessionImplementor session, final Object owner) throws HibernateException, SQLException
{
final Object identifier = TYPE.get(rs, names[0], session);
if (rs.wasNull())
{
return null;
}
try
{
return valueOfMethod.invoke(enumClass, new Object[] { identifier });
}
catch (final Exception e)
{
throw new HibernateException("Exception while invoking valueOf method '" + valueOfMethod.getName() + "' of " + "enumeration class '" + enumClass + "'", e);
}
}
@Override
public void nullSafeSet(final PreparedStatement st, final Object value, final int index, final SessionImplementor session) throws HibernateException, SQLException
{
try
{
if (value == null)
{
st.setNull(index, TYPE.sqlType());
}
else
{
final Object identifier = identifierMethod.invoke(value, new Object[0]);
TYPE.set(st, (String) identifier, index, session);
}
}
catch (final Exception e)
{
throw new HibernateException("Exception while invoking identifierMethod '" + identifierMethod.getName() + "' of " + "enumeration class '" + enumClass + "'", e);
}
}
}