View Javadoc
1   // license-header java merge-point
2   //
3   // Attention: Generated code! Do not modify by hand!
4   // Generated by: hibernate/search/PropertySearch.java.vsl in andromda-spring-cartridge.
5   //
6   package fr.ifremer.quadrige2.core.dao;
7   
8   /*-
9    * #%L
10   * Quadrige2 Core :: Server API
11   * %%
12   * Copyright (C) 2017 Ifremer
13   * %%
14   * This program is free software: you can redistribute it and/or modify
15   * it under the terms of the GNU Affero General Public License as published by
16   * the Free Software Foundation, either version 3 of the License, or
17   * (at your option) any later version.
18   * 
19   * This program is distributed in the hope that it will be useful,
20   * but WITHOUT ANY WARRANTY; without even the implied warranty of
21   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22   * GNU General Public License for more details.
23   * 
24   * You should have received a copy of the GNU Affero General Public License
25   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26   * #L%
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   * Provides the ability to search by properties.
47   */
48  @SuppressWarnings({"unchecked"})
49  public class PropertySearch
50      extends CriteriaSearch
51  {
52      private Search search;
53  
54      /**
55       * Constructor for PropertySearch. Creates a <code>PropertySearch</code> instance
56       * from the given arguments.
57       *
58       * @param session The Hibernate session.
59       * @param entityType The <code>Class</code> of the result.
60       * @param searchIn the object that specifies the search criteria.
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                      // - now add the parameter.
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                             // - set the first result as part of pagination support
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      * Stores the total count when sql limiting isn't used.
137      */
138     private int totalCount;
139 
140     /**
141      * Gets the total possible count of objects returned in this search.
142      * @return totalCount
143      */
144     public int getTotalCount()
145     {
146         int count;
147         if (this.search.isUseSqlLimiting())
148         {
149             // Remove first result requirement
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      * @see CriteriaSearch#executeAsList()
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      * Calculates the first result based upon page size and current
191      * desired page.
192      *
193      * @param pageNumber the page number to retrieve.
194      * @param pageSize the page size to retrieve.
195      *
196      * @return the calculated first result.
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      * Calculates the last result based upon page size and current
210      * desired page.
211      *
212      * @param pageNumber the page number to retrieve.
213      * @param pageSize the page size to retrieve.
214      *
215      * @return the calculated first result.
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      * Initializes the converters to behave the way we want when converting values (we don't
231      * want empty strings converted to zeros, like beanutils does by default)
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      * <p>Convert the value to an object of the specified class (if
244      * possible).</p>
245      *
246      * @param value Value to be converted (may be null)
247      * @param type Class of the value to be converted to
248      * @return The converted value
249      *
250      * @exception ConversionException if thrown by an underlying Converter
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      * Converts the value contained within the parameter to the type which Hibernate expects.
269      *
270      * @param entityType the class of the entity for which the search is being performed.
271      * @param parameter the parameter from which to get the value.
272      * @return the appropriate value.
273      */
274     private Object getValue(Class type, final SearchParameter parameter)
275     {
276         try
277         {
278             Object value = parameter.getValue();
279             // - don't try to convert null values or classes
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      * A beanutils converter that converts Calendar objects to Date instances.
319      */
320     private static final class DateConverter
321         implements Converter
322     {
323         public DateConverter()
324         {
325             // Empty block comment
326         }
327 
328         /**
329          * @see org.apache.commons.beanutils.Converter#convert(Class, Object)
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      * A beanutils converter that converts Date objects to Calendar instances.
356      */
357     private static final class CalendarConverter
358         implements Converter
359     {
360         public CalendarConverter()
361         {
362             // Empty block comment
363         }
364 
365         /**
366          * @see org.apache.commons.beanutils.Converter#convert(Class, Object)
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 }