1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.search.attribute;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import net.sf.ehcache.search.SearchException;
23
24 /***
25 * Defines the legal set of runtime types for search attributes
26 *
27 * @author teck
28 */
29 public enum AttributeType {
30
31 /***
32 * Boolean type
33 */
34 BOOLEAN {
35 /***
36 * {@inheritDoc}
37 */
38 @Override
39 public void validateValue(String name, Object value) {
40 if (!(value instanceof Boolean)) {
41 throw new SearchException("Expecting a Boolean value for attribute [" + name + "] but was " + type(value));
42 }
43 }
44 },
45
46 /***
47 * Byte type
48 */
49 BYTE {
50 /***
51 * {@inheritDoc}
52 */
53 @Override
54 public void validateValue(String name, Object value) {
55 if (!(value instanceof Byte)) {
56 throw new SearchException("Expecting a Byte value for attribute [" + name + "] but was " + type(value));
57 }
58 }
59 },
60
61 /***
62 * Character type
63 */
64 CHAR {
65 /***
66 * {@inheritDoc}
67 */
68 @Override
69 public void validateValue(String name, Object value) {
70 if (!(value instanceof Character)) {
71 throw new SearchException("Expecting a Character value for attribute [" + name + "] but was " + type(value));
72 }
73 }
74 },
75
76 /***
77 * Double type
78 */
79 DOUBLE {
80 /***
81 * {@inheritDoc}
82 */
83 @Override
84 public void validateValue(String name, Object value) {
85 if (!(value instanceof Double)) {
86 throw new SearchException("Expecting a Double value for attribute [" + name + "] but was " + type(value));
87 }
88 }
89 },
90
91 /***
92 * Float type
93 */
94 FLOAT {
95 /***
96 * {@inheritDoc}
97 */
98 @Override
99 public void validateValue(String name, Object value) {
100 if (!(value instanceof Float)) {
101 throw new SearchException("Expecting a Float value for attribute [" + name + "] but was " + type(value));
102 }
103 }
104 },
105
106 /***
107 * Integer type
108 */
109 INT {
110 /***
111 * {@inheritDoc}
112 */
113 @Override
114 public void validateValue(String name, Object value) {
115 if (!(value instanceof Integer)) {
116 throw new SearchException("Expecting an Integer value for attribute [" + name + "] but was " + type(value));
117 }
118 }
119 },
120
121 /***
122 * Long type
123 */
124 LONG {
125 /***
126 * {@inheritDoc}
127 */
128 @Override
129 public void validateValue(String name, Object value) {
130 if (!(value instanceof Long)) {
131 throw new SearchException("Expecting a Long value for attribute [" + name + "] but was " + type(value));
132 }
133 }
134 },
135
136 /***
137 * Short type
138 */
139 SHORT {
140 /***
141 * {@inheritDoc}
142 */
143 @Override
144 public void validateValue(String name, Object value) {
145 if (!(value instanceof Short)) {
146 throw new SearchException("Expecting a Short value for attribute [" + name + "] but was " + type(value));
147 }
148 }
149 },
150
151 /***
152 * Date type
153 */
154 DATE {
155 /***
156 * {@inheritDoc}
157 */
158 @Override
159 public void validateValue(String name, Object value) {
160 if (value == null || value.getClass() != java.util.Date.class) {
161 throw new SearchException("Expecting a java.util.Date value for attribute [" + name + "] but was " + type(value));
162 }
163 }
164 },
165
166 /***
167 * SQL Date type
168 */
169 SQL_DATE {
170 /***
171 * {@inheritDoc}
172 */
173 @Override
174 public void validateValue(String name, Object value) {
175 if (value == null || value.getClass() != java.sql.Date.class) {
176 throw new SearchException("Expecting a java.sql.Date value for attribute [" + name + "] but was " + type(value));
177 }
178 }
179 },
180
181 /***
182 * Enum type
183 */
184 ENUM {
185 /***
186 * {@inheritDoc}
187 */
188 @Override
189 public void validateValue(String name, Object value) {
190 if (!(value instanceof Enum)) {
191 throw new SearchException("Expecting a enum value for attribute [" + name + "] but was " + type(value));
192 }
193 }
194 },
195
196 /***
197 * String type
198 */
199 STRING {
200 /***
201 * {@inheritDoc}
202 */
203 @Override
204 public void validateValue(String name, Object value) {
205 if (!(value instanceof String)) {
206 throw new SearchException("Expecting a String value for attribute [" + name + "] but was " + type(value));
207 }
208 }
209 };
210
211 private static final Map<Class, AttributeType> MAPPINGS = new HashMap<Class, AttributeType>();
212
213 /***
214 * Get the appropriate @{link {@link AttributeType} enum for the given object value.
215 *
216 * @param name the attribute name (only meaningful to message if exception thrown)
217 * @param value the value to lookup the type for
218 * @return the attribute type for this value
219 * @throws SearchException if the given value is not valid for a search attribute
220 */
221 public static AttributeType typeFor(String name, Object value) throws SearchException {
222 if (name == null) {
223 throw new NullPointerException("null name");
224 }
225 if (value == null) {
226 throw new NullPointerException("null value");
227 }
228
229 AttributeType type = typeForOrNull(value);
230 if (type != null) {
231 return type;
232 }
233
234 throw new SearchException("Unsupported type for search attribute [" + name + "]: " + value.getClass().getName());
235 }
236
237 private static AttributeType typeForOrNull(Object value) {
238 AttributeType type = MAPPINGS.get(value.getClass());
239 if (type != null) {
240 return type;
241 }
242
243
244 if (value instanceof Enum) {
245 return ENUM;
246 }
247
248 return null;
249 }
250
251 /***
252 * Test the given value to see if it is a legal type
253 *
254 * @param value
255 * @return true if the given value is valid as a search attribute
256 */
257 public static boolean isSupportedType(Object value) {
258 if (value == null) {
259 return true;
260 }
261
262 return typeForOrNull(value) != null;
263 }
264
265 /***
266 * Validate that the given value is in fact of the correct type
267 *
268 * @param name the attribute name (only meaningful to message if exception thrown)
269 * @param value the value to validate against this type
270 * @throws SearchException if the given value is not a valid instance of this type
271 */
272 public abstract void validateValue(String name, Object value) throws SearchException;
273
274 /***
275 * Is this type comparable?
276 *
277 * @return true if this type is comparable
278 */
279 public boolean isComparable() {
280
281 return true;
282 }
283
284 private static String type(Object value) {
285 if (value == null) {
286 return "null";
287 }
288 return value.getClass().getName();
289 }
290
291 static {
292 MAPPINGS.put(Boolean.class, BOOLEAN);
293 MAPPINGS.put(Byte.class, BYTE);
294 MAPPINGS.put(Character.class, CHAR);
295 MAPPINGS.put(Double.class, DOUBLE);
296 MAPPINGS.put(Float.class, FLOAT);
297 MAPPINGS.put(Integer.class, INT);
298 MAPPINGS.put(Long.class, LONG);
299 MAPPINGS.put(Short.class, SHORT);
300 MAPPINGS.put(String.class, STRING);
301 MAPPINGS.put(java.util.Date.class, DATE);
302 MAPPINGS.put(java.sql.Date.class, SQL_DATE);
303 }
304
305 }