1
2
3
4 package org.company.thesandbox.data;
5
6 import java.io.Serializable;
7 import java.lang.reflect.Method;
8 import java.sql.PreparedStatement;
9 import java.sql.ResultSet;
10 import java.sql.SQLException;
11 import java.util.Properties;
12
13 import org.hibernate.HibernateException;
14 import org.hibernate.type.NullableType;
15 import org.hibernate.type.TypeFactory;
16 import org.hibernate.usertype.ParameterizedType;
17 import org.hibernate.usertype.UserType;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class GenericEnumUserType implements UserType, ParameterizedType {
74 private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "id";
75
76 private static final String DEFAULT_VALUE_OF_METHOD_NAME = "value";
77
78 private Class<? extends Enum> enumClass;
79
80 private Class<?> identifierType;
81
82 private Method identifierMethod;
83
84 private Method valueOfMethod;
85
86 private NullableType type;
87
88 private int[] sqlTypes;
89
90 public void setParameterValues(Properties parameters) {
91 String enumClassName = parameters.getProperty("enumClass");
92 try {
93 enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
94 } catch (ClassNotFoundException cfne) {
95 throw new HibernateException("Enum class not found", cfne);
96 }
97
98 String identifierMethodName = parameters.getProperty("identifierMethod",
99 DEFAULT_IDENTIFIER_METHOD_NAME);
100
101 try {
102 identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]);
103 identifierType = identifierMethod.getReturnType();
104 } catch (Exception e) {
105 throw new HibernateException("Failed to obtain identifier method", e);
106 }
107
108 type = (NullableType) TypeFactory.basic(identifierType.getName());
109
110 if (type == null)
111 throw new HibernateException("Unsupported identifier type " + identifierType.getName());
112
113 sqlTypes = new int[] { type.sqlType() };
114
115 String valueOfMethodName = parameters.getProperty("valueOfMethod",
116 DEFAULT_VALUE_OF_METHOD_NAME);
117
118 try {
119 valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] { identifierType });
120 } catch (Exception e) {
121 throw new HibernateException("Failed to obtain valueOf method", e);
122 }
123 }
124
125 public Class returnedClass() {
126 return enumClass;
127 }
128
129 public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
130 throws HibernateException, SQLException {
131 Object identifier = type.get(rs, names[0]);
132 if (rs.wasNull()) {
133 return null;
134 }
135
136 try {
137 return valueOfMethod.invoke(enumClass, new Object[] { identifier });
138 } catch (Exception e) {
139 throw new HibernateException("Exception while invoking valueOf method '"
140 + valueOfMethod.getName() + "' of " + "enumeration class '" + enumClass + "'",
141 e);
142 }
143 }
144
145 public void nullSafeSet(PreparedStatement st, Object value, int index)
146 throws HibernateException, SQLException {
147 try {
148 if (value == null) {
149 st.setNull(index, type.sqlType());
150 } else {
151 Object identifier = identifierMethod.invoke(value, new Object[0]);
152 type.set(st, identifier, index);
153 }
154 } catch (Exception e) {
155 throw new HibernateException("Exception while invoking identifierMethod '"
156 + identifierMethod.getName() + "' of " + "enumeration class '" + enumClass
157 + "'", e);
158 }
159 }
160
161 public int[] sqlTypes() {
162 return sqlTypes;
163 }
164
165 public Object assemble(Serializable cached, Object owner) throws HibernateException {
166 return cached;
167 }
168
169 public Object deepCopy(Object value) throws HibernateException {
170 return value;
171 }
172
173 public Serializable disassemble(Object value) throws HibernateException {
174 return (Serializable) value;
175 }
176
177 public boolean equals(Object x, Object y) throws HibernateException {
178 return x == y;
179 }
180
181 public int hashCode(final Object x) throws HibernateException {
182 return x.hashCode();
183 }
184
185 public boolean isMutable() {
186 return false;
187 }
188
189 public Object replace(Object original, Object target, Object owner) throws HibernateException {
190 return original;
191 }
192 }