/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.masterdb.security.hibernate; import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.EnumMap; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.ObjectUtils; import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.usertype.UserType; import com.opengamma.OpenGammaRuntimeException; /** * Custom Hibernate type for trivial enums. * @param <E> the enum type */ public abstract class EnumUserType<E extends Enum<E>> implements UserType { private final Class<E> _clazz; private final Map<String, E> _stringToEnum; private final Map<E, String> _enumToString; protected EnumUserType(final Class<E> clazz, final E[] values) { _clazz = clazz; _stringToEnum = new HashMap<String, E>(); _enumToString = new EnumMap<E, String>(clazz); for (final E value : values) { final String string = enumToStringNoCache(value); _stringToEnum.put(string, value); _enumToString.put(value, string); } } @Override public Object assemble(Serializable arg0, Object arg1) throws HibernateException { return arg0; } @Override public Object deepCopy(Object arg0) throws HibernateException { return arg0; } @Override public Serializable disassemble(Object arg0) throws HibernateException { return (Serializable) arg0; } @Override public boolean equals(Object x, Object y) throws HibernateException { // Check for either being null for database null semantics which ObjectUtils won't give us if ((x == null) || (y == null)) { return false; } return ObjectUtils.equals(x, y); } @Override public int hashCode(Object arg0) throws HibernateException { return arg0.hashCode(); } @Override public boolean isMutable() { return false; } protected abstract String enumToStringNoCache(E value); protected E stringToEnum(final String string) { final E value = _stringToEnum.get(string); if (value == null) { throw new OpenGammaRuntimeException("unexpected value: " + string); } return value; } @Override public Object nullSafeGet(ResultSet resultSet, String[] columnNames, Object owner) throws HibernateException, SQLException { String databaseValue = resultSet.getString(columnNames[0]); if (resultSet.wasNull()) { return null; } return stringToEnum(databaseValue); } protected String enumToString(final E value) { return _enumToString.get(value); } @SuppressWarnings({ "unchecked", "deprecation" }) @Override public void nullSafeSet(PreparedStatement stmt, Object value, int index) throws HibernateException, SQLException { if (value == null) { // NOTE kirk 2010-06-11 -- This has to remain deprecated due to a bug in Hibernate 3.5.2 // where they deprecated the constants there (e.g. Hibernate.STRING) but didn't put in // the StringType.INSTNANCE you're supposed to use instead. // When we upgrade to a new hibernate which doesn't have this bug, we need to change. stmt.setNull(index, Hibernate.STRING.sqlType()); } else { stmt.setString(index, enumToString((E) value)); } } @Override public Object replace(Object original, Object target, Object owner) throws HibernateException { return original; } @Override public Class<?> returnedClass() { return _clazz; } @SuppressWarnings("deprecation") @Override public int[] sqlTypes() { // NOTE kirk 2010-06-11 -- See note above in nullSafeSet. return new int[] {Hibernate.STRING.sqlType()}; } }