1 /*
2 * The SmartWeb Framework
3 * Copyright (C) 2004-2006
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * For further informations on the SmartWeb Framework please visit
20 *
21 * http://smartweb.sourceforge.net
22 */
23 package net.smartlab.web;
24
25 import java.io.Serializable;
26 import java.sql.PreparedStatement;
27 import java.sql.ResultSet;
28 import java.sql.SQLException;
29 import java.sql.Types;
30
31 import org.hibernate.Hibernate;
32 import org.hibernate.HibernateException;
33 import org.hibernate.usertype.UserType;
34
35 /**
36 * Represents a meta type used to constraint a property to accept only
37 * pre-defined admitted values. Whenever a property needs some sort of
38 * constraint on assignable values, like person gender or process status, a
39 * subclass of <code>Enumeration</code> can be used to enumerate all possible
40 * values.
41 *
42 * @author rlogiacco
43 */
44 public abstract class Enumeration implements UserType, Serializable {
45
46 private final static long serialVersionUID = 8849967605617496075L;
47
48 /**
49 * Type of the persisted field reference.
50 */
51 private final static int[] TYPES = new int[] {Types.SMALLINT};
52
53 /**
54 * The unique identifier used to represent the choice onto the persisted
55 * field.
56 *
57 * @uml.property name="id"
58 */
59 private final int id;
60
61 /**
62 * A brief, human understandable, description of the choice.
63 *
64 * @uml.property name="display"
65 */
66 private final String display;
67
68
69 /**
70 * Default constructor used for internal purposes only.
71 */
72 protected Enumeration() {
73 // Default constructor
74 this.id = -1;
75 this.display = null;
76 }
77
78 /**
79 * Constructs an available choice on a unique identifier and a brief, human
80 * understandable, description.
81 *
82 * @param id the unique identifier for this choice.
83 * @param display a short, human understandable, description of the choice.
84 */
85 protected Enumeration(int id, String display) {
86 this.id = id;
87 this.display = display;
88 }
89
90 /**
91 * Returns the unique identifier for the choice.
92 *
93 * @return the unique identifier for the choice.
94 * @uml.property name="id"
95 */
96 public int getId() {
97 return id;
98 }
99
100 /**
101 * Returns the brief description of the choice.
102 *
103 * @return the brief description of the choice.
104 * @uml.property name="display"
105 */
106 public String getDisplay() {
107 return display;
108 }
109
110 /**
111 * Decodes a unique identifier into an instance of this class. This method
112 * <b>can not</b> return <code>null</code> values, instead it should define
113 * a <i>default</i> value.
114 *
115 * @param id the identifier to decode.
116 * @return an instance of this class.
117 */
118 public abstract Enumeration decode(int id);
119
120 /**
121 * @see java.lang.Object#equals(java.lang.Object)
122 */
123 public boolean equals(Object other) {
124 if (other != null && this.getClass().equals(other.getClass())) {
125 if (((Enumeration)other).id == id) {
126 return true;
127 }
128 }
129 return false;
130 }
131
132 /**
133 * @see java.lang.Object#hashCode()
134 */
135 public int hashCode() {
136 return id;
137 }
138
139 /**
140 * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
141 */
142 public Object deepCopy(Object value) throws HibernateException {
143 return value;
144 }
145
146 /**
147 * @see org.hibernate.usertype.UserType#equals(java.lang.Object,
148 * java.lang.Object)
149 */
150 public boolean equals(Object src, Object dst) throws HibernateException {
151 if (src == dst) {
152 return true;
153 }
154 if (src == null || dst == null) {
155 return false;
156 }
157 return Hibernate.INTEGER.isEqual(src, dst);
158 }
159
160 /**
161 * @see org.hibernate.usertype.UserType#isMutable()
162 */
163 public boolean isMutable() {
164 return false;
165 }
166
167 /**
168 * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,
169 * java.lang.String[], java.lang.Object)
170 */
171 public Object nullSafeGet(ResultSet rows, String[] names, Object owner) throws HibernateException, SQLException {
172 try {
173 int id = ((Integer)Hibernate.INTEGER.nullSafeGet(rows, names[0])).intValue();
174 return this.decode(id);
175 } catch (NullPointerException npe) {
176 return null;
177 }
178 }
179
180 /**
181 * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
182 * java.lang.Object, int)
183 */
184 public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException,
185 SQLException {
186 if (value == null) {
187 statement.setNull(index, TYPES[0]);
188 } else if (value instanceof String) {
189 statement.setString(index, (String)value);
190 } else if (value instanceof Number) {
191 statement.setInt(index, ((Number)value).intValue());
192 } else {
193 try {
194 statement.setInt(index, ((Enumeration)value).getId());
195 } catch (ClassCastException cce) {
196 throw new HibernateException(cce);
197 }
198 }
199 }
200
201 /**
202 * @see org.hibernate.usertype.UserType#returnedClass()
203 */
204 public Class returnedClass() {
205 return this.getClass();
206 }
207
208 /**
209 * @see org.hibernate.usertype.UserType#sqlTypes()
210 */
211 public int[] sqlTypes() {
212 return TYPES;
213 }
214
215 /**
216 * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable,
217 * java.lang.Object)
218 */
219 public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
220 return null;
221 // FIXME: may be an HibernateException is better
222 }
223
224 /**
225 * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
226 */
227 public Serializable disassemble(Object arg0) throws HibernateException {
228 return null;
229 // FIXME: may be an HibernateException is better
230 }
231
232 /**
233 * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
234 */
235 public int hashCode(Object obj) throws HibernateException {
236 return ((Enumeration)obj).getId();
237 }
238
239 /**
240 * @see org.hibernate.usertype.UserType#replace(java.lang.Object,
241 * java.lang.Object, java.lang.Object)
242 */
243 public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
244 return null;
245 // FIXME: may be an HibernateException is better
246 }
247 }