1 package org.jadira.usertype.spi.shared;
2
3 import java.io.Serializable;
4 import java.sql.PreparedStatement;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.sql.Types;
8 import java.util.HashMap;
9 import java.util.Map;
10
11 import org.hibernate.HibernateException;
12 import org.hibernate.engine.spi.SharedSessionContractImplementor;
13 import org.hibernate.usertype.UserType;
14
15 public abstract class AbstractMapUserType<K,V> extends AbstractUserType implements UserType, Serializable {
16
17 private static final long serialVersionUID = 4071411441689437245L;
18
19 @Override
20 public int[] sqlTypes() {
21 return new int[] {Types.LONGVARCHAR};
22 }
23
24 @Override
25 public boolean isMutable() {
26 return true;
27 }
28
29 @SuppressWarnings("rawtypes")
30 @Override
31 public Class<Map> returnedClass() {
32 return Map.class;
33 }
34
35 @Override
36 public int hashCode(Object x) throws HibernateException {
37 assert (x != null);
38 return x.hashCode();
39 }
40
41 @Override
42 public Map<K, V> nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor session, Object object) throws SQLException {
43
44 beforeNullSafeOperation(session);
45
46 try {
47 Map<K, V> converted = doNullSafeGet(resultSet, strings, session, object);
48 if (converted == null) {
49 return null;
50 }
51
52 return converted;
53
54 } finally {
55 afterNullSafeOperation(session);
56 }
57 }
58
59 protected Map<K,V> doNullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor session, Object object) throws SQLException {
60
61 String value = resultSet.getString(strings[0]);
62 if (value == null) {
63 return null;
64 }
65 return toMap(value);
66 }
67
68 @SuppressWarnings("unchecked")
69 @Override
70 public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
71
72 beforeNullSafeOperation(session);
73
74 try {
75 doNullSafeSet(preparedStatement, (Map<K, V>) value, index, session);
76
77 } finally {
78 afterNullSafeOperation(session);
79 }
80 }
81
82 protected void doNullSafeSet(PreparedStatement preparedStatement, Map<K, V> value, int index, SharedSessionContractImplementor session) throws SQLException {
83
84 if (value == null) {
85 preparedStatement.setNull(index, sqlTypes()[0]);
86 } else {
87 String strValue = toString((Map<K, V>) value);
88 preparedStatement.setString(index, strValue);
89 }
90 }
91
92 @SuppressWarnings({ "unchecked", "rawtypes" })
93 @Override
94 public Map<String,?> deepCopy(Object value) throws HibernateException {
95
96 if (value == null) {
97 return null;
98 }
99
100 if (!(value instanceof HashMap)) {
101 throw new UnsupportedOperationException("can't convert " + value.getClass());
102 }
103
104 return new HashMap((HashMap) value);
105 }
106
107 @SuppressWarnings("unchecked")
108 @Override
109 public Serializable disassemble(Object value) throws HibernateException {
110 if (!(value instanceof HashMap)) {
111 throw new UnsupportedOperationException("can't convert " + value.getClass());
112 }
113 return toString((Map<K, V>) value);
114 }
115
116 @Override
117 public Object assemble(Serializable value, Object o) throws HibernateException {
118 return toMap((String) value);
119 }
120
121 @Override
122 public Object replace(Object original, Object target, Object owner) throws HibernateException {
123 return deepCopy(original);
124 }
125
126 protected abstract String toString(Map<K, V> map);
127
128 protected abstract Map<K, V> toMap(String value);
129 }