package org.jadira.usertype.spi.shared;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
public abstract class AbstractMapUserType<K,V> extends AbstractUserType implements UserType, Serializable {
private static final long serialVersionUID = 4071411441689437245L;
@Override
public int[] sqlTypes() {
return new int[] {Types.LONGVARCHAR};
}
@Override
public boolean isMutable() {
return true;
}
@SuppressWarnings("rawtypes")
@Override
public Class<Map> returnedClass() {
return Map.class;
}
@Override
public int hashCode(Object x) throws HibernateException {
assert (x != null);
return x.hashCode();
}
@Override
public Map<K, V> nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor session, Object object) throws SQLException {
beforeNullSafeOperation(session);
try {
Map<K, V> converted = doNullSafeGet(resultSet, strings, session, object);
if (converted == null) {
return null;
}
return converted;
} finally {
afterNullSafeOperation(session);
}
}
protected Map<K,V> doNullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor session, Object object) throws SQLException {
String value = resultSet.getString(strings[0]);
if (value == null) {
return null;
}
return toMap(value);
}
@SuppressWarnings("unchecked")
@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
beforeNullSafeOperation(session);
try {
doNullSafeSet(preparedStatement, (Map<K, V>) value, index, session);
} finally {
afterNullSafeOperation(session);
}
}
protected void doNullSafeSet(PreparedStatement preparedStatement, Map<K, V> value, int index, SharedSessionContractImplementor session) throws SQLException {
if (value == null) {
preparedStatement.setNull(index, sqlTypes()[0]);
} else {
String strValue = toString((Map<K, V>) value);
preparedStatement.setString(index, strValue);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Map<String,?> deepCopy(Object value) throws HibernateException {
if (value == null) {
return null;
}
if (!(value instanceof HashMap)) {
throw new UnsupportedOperationException("can't convert " + value.getClass());
}
return new HashMap((HashMap) value);
}
@SuppressWarnings("unchecked")
@Override
public Serializable disassemble(Object value) throws HibernateException {
if (!(value instanceof HashMap)) {
throw new UnsupportedOperationException("can't convert " + value.getClass());
}
return toString((Map<K, V>) value);
}
@Override
public Object assemble(Serializable value, Object o) throws HibernateException {
return toMap((String) value);
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return deepCopy(original);
}
protected abstract String toString(Map<K, V> map);
protected abstract Map<K, V> toMap(String value);
}