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