1
2
3
4
5
6 package fr.ifremer.quadrige3.core.dao;
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 import java.util.Calendar;
29 import java.util.Date;
30 import java.util.List;
31 import java.util.StringTokenizer;
32 import org.apache.commons.beanutils.ConversionException;
33 import org.apache.commons.beanutils.ConvertUtils;
34 import org.apache.commons.beanutils.Converter;
35 import org.apache.commons.beanutils.PropertyUtils;
36 import org.apache.commons.beanutils.converters.IntegerConverter;
37 import org.apache.commons.beanutils.converters.LongConverter;
38 import org.apache.commons.beanutils.converters.ShortConverter;
39 import org.hibernate.HibernateException;
40 import org.hibernate.Session;
41 import org.hibernate.criterion.MatchMode;
42 import org.hibernate.criterion.Projections;
43
44
45
46
47 @SuppressWarnings({"unchecked"})
48 public class PropertySearch
49 extends CriteriaSearch
50 {
51 private Search search;
52
53
54
55
56
57
58
59
60
61 public PropertySearch(
62 final Session session,
63 final Class entityType,
64 final Search searchIn)
65 {
66 super(session, entityType);
67 this.search = searchIn;
68 try
69 {
70 this.initializeConverters();
71 this.getConfiguration().setForceEagerLoading(searchIn.isEagerFetching());
72 final SearchParameter[] parameters = searchIn.getParameters();
73 if (parameters != null)
74 {
75 for (int ctr = 0; ctr < parameters.length; ctr++)
76 {
77 final SearchParameter searchParameter = parameters[ctr];
78
79 Object value;
80 switch (searchParameter.getComparator())
81 {
82 case SearchParameter.IN_COMPARATOR :
83 value = searchParameter.getValue();
84 break;
85 case SearchParameter.NOT_IN_COMPARATOR :
86 value = searchParameter.getValue();
87 break;
88 default :
89 value = this.getValue(entityType, searchParameter);
90 break;
91 }
92
93
94 final CriteriaSearchParameter parameter =
95 new CriteriaSearchParameter(value,
96 searchParameter.getName(),
97 searchParameter.getComparator());
98 parameter.setOrderDirection(searchParameter.getOrder());
99 parameter.setSearchIfNull(searchParameter.isSearchIfNull());
100 switch (searchParameter.getMatch())
101 {
102 case SearchParameter.MATCH_ANYWHERE :
103 parameter.setMatchMode(MatchMode.ANYWHERE);
104 break;
105 case SearchParameter.MATCH_START :
106 parameter.setMatchMode(MatchMode.START);
107 break;
108 case SearchParameter.MATCH_END :
109 parameter.setMatchMode(MatchMode.END);
110 break;
111 default:
112 parameter.setMatchMode(MatchMode.EXACT);
113 break;
114 }
115 this.addParameter(parameter);
116 if (searchIn.isUseSqlLimiting())
117 {
118 if (searchIn.getPageNumber() > 0 && searchIn.getPageSize() > 0)
119 {
120
121 this.getConfiguration().setFirstResult(new Integer(this.calculateFirstResult(searchIn.getPageNumber(), searchIn.getPageSize())));
122 this.getConfiguration().setMaximumResultSize(new Integer(searchIn.getPageSize()));
123 }
124 }
125 }
126 }
127 }
128 catch (Exception exception)
129 {
130 throw new RuntimeException(exception);
131 }
132 }
133
134
135
136
137 private int totalCount;
138
139
140
141
142
143 public int getTotalCount()
144 {
145 int count;
146 if (this.search.isUseSqlLimiting())
147 {
148
149 this.getConfiguration().setFirstResult(new Integer(0));
150 this.getRootCriteria().setProjection(
151 Projections.projectionList().add(
152 Projections.rowCount()));
153 count = ((Long)this.executeAsList().iterator().next()).intValue();
154 }
155 else
156 {
157 count = this.totalCount;
158 }
159 return count;
160 }
161
162
163
164
165 @Override
166 public List executeAsList()
167 throws HibernateException
168 {
169 List results = super.executeAsList();
170 if (!this.search.isUseSqlLimiting() && this.search.getPageNumber() > 0 && this.search.getPageSize() > 0)
171 {
172 int start = this.calculateFirstResult(this.search.getPageNumber(), this.search.getPageSize());
173 int end = this.calculateLastResult(this.search.getPageNumber(), this.search.getPageSize());
174 this.totalCount = results.size();
175 if (this.totalCount < start)
176 {
177 start = this.totalCount;
178 }
179 if (this.totalCount < end)
180 {
181 end = this.totalCount;
182 }
183 results = results.subList(start, end);
184 }
185 return results;
186 }
187
188
189
190
191
192
193
194
195
196
197 private int calculateFirstResult(int pageNumber, int pageSize)
198 {
199 int firstResult = 0;
200 if (pageNumber > 0 && pageSize > 0)
201 {
202 firstResult = (pageNumber - 1) * pageSize;
203 }
204 return firstResult;
205 }
206
207
208
209
210
211
212
213
214
215
216 private int calculateLastResult(int pageNumber, int pageSize)
217 {
218 int lastResult = 0;
219 if (pageNumber > 0 && pageSize > 0)
220 {
221 lastResult = pageNumber * pageSize;
222 }
223 return lastResult;
224 }
225
226 private static final String PERIOD = ".";
227
228
229
230
231
232 private void initializeConverters()
233 {
234 ConvertUtils.register(new LongConverter(null), Long.class);
235 ConvertUtils.register(new IntegerConverter(null), Integer.class);
236 ConvertUtils.register(new ShortConverter(null), Short.class);
237 ConvertUtils.register(new CalendarConverter(), Calendar.class);
238 ConvertUtils.register(new DateConverter(), Date.class);
239 }
240
241
242
243
244
245
246
247
248
249
250
251 protected Object convert(Object value, Class type)
252 {
253 Converter converter = ConvertUtils.lookup(type);
254 Object result;
255 if (converter != null)
256 {
257 result = converter.convert(type, value);
258 }
259 else
260 {
261 result = value;
262 }
263 return result;
264 }
265
266
267
268
269
270
271
272
273 private Object getValue(Class type, final SearchParameter parameter)
274 {
275 try
276 {
277 Object value = parameter.getValue();
278
279 if (value != null && !value.getClass().equals(Class.class))
280 {
281 Class propertyType = type;
282 for (final StringTokenizer tokenizer = new StringTokenizer(parameter.getName(), PERIOD); tokenizer.hasMoreTokens();)
283 {
284 final String token = tokenizer.nextToken().trim();
285 Class lastType = type;
286 type = CriteriaSearchProperties.getPropertyType(type, token);
287 if (!tokenizer.hasMoreTokens())
288 {
289 break;
290 }
291 if (type == null)
292 {
293 throw new RuntimeException("No accessible property named '" + token + "', exists on: " + lastType.getName());
294 }
295 propertyType = type;
296 }
297 final Object object = propertyType.newInstance();
298 final String name = parameter.getName().replaceAll(".*\\" + PERIOD, "");
299 try
300 {
301 value = convert(value, PropertyUtils.getPropertyType(object, name));
302 }
303 catch (final NoSuchMethodException noSuchMethodException)
304 {
305 throw new RuntimeException("No accessible property named '" + name + "', exists on: " + propertyType.getName());
306 }
307 }
308 return value;
309 }
310 catch (final Exception exception)
311 {
312 throw new RuntimeException(exception);
313 }
314 }
315
316
317
318
319 private static final class DateConverter
320 implements Converter
321 {
322 public DateConverter()
323 {
324
325 }
326
327
328
329
330 public Object convert(
331 Class type,
332 Object value)
333 throws ConversionException
334 {
335 if (value != null)
336 {
337 try
338 {
339 if (value instanceof Calendar)
340 {
341 value = ((Calendar)value).getTime();
342 }
343 }
344 catch (Exception ex)
345 {
346 throw new ConversionException(ex);
347 }
348 }
349 return value;
350 }
351 }
352
353
354
355
356 private static final class CalendarConverter
357 implements Converter
358 {
359 public CalendarConverter()
360 {
361
362 }
363
364
365
366
367 public Object convert(
368 Class type,
369 Object value)
370 throws ConversionException
371 {
372 if (value != null)
373 {
374 try
375 {
376 if (value instanceof Date)
377 {
378 Calendar calendar = Calendar.getInstance();
379 calendar.setTime((Date)value);
380 value = calendar;
381 }
382 }
383 catch (Exception ex)
384 {
385 throw new ConversionException(ex);
386 }
387 }
388 return value;
389 }
390 }
391 }