001// license-header java merge-point 002// 003// Attention: Generated code! Do not modify by hand! 004// Generated by: hibernate/search/PropertySearch.java.vsl in andromda-spring-cartridge. 005// 006package fr.ifremer.adagio.core.dao; 007 008/* 009 * #%L 010 * SIH-Adagio :: Core 011 * $Id:$ 012 * $HeadURL:$ 013 * %% 014 * Copyright (C) 2012 - 2014 Ifremer 015 * %% 016 * This program is free software: you can redistribute it and/or modify 017 * it under the terms of the GNU Affero General Public License as published by 018 * the Free Software Foundation, either version 3 of the License, or 019 * (at your option) any later version. 020 * 021 * This program is distributed in the hope that it will be useful, 022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 024 * GNU General Public License for more details. 025 * 026 * You should have received a copy of the GNU Affero General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * #L% 029 */ 030 031import java.util.Calendar; 032import java.util.Date; 033import java.util.List; 034import java.util.StringTokenizer; 035import org.apache.commons.beanutils.ConversionException; 036import org.apache.commons.beanutils.ConvertUtils; 037import org.apache.commons.beanutils.Converter; 038import org.apache.commons.beanutils.PropertyUtils; 039import org.apache.commons.beanutils.converters.IntegerConverter; 040import org.apache.commons.beanutils.converters.LongConverter; 041import org.apache.commons.beanutils.converters.ShortConverter; 042import org.hibernate.HibernateException; 043import org.hibernate.Session; 044import org.hibernate.criterion.MatchMode; 045import org.hibernate.criterion.Projections; 046 047/** 048 * Provides the ability to search by properties. 049 */ 050@SuppressWarnings({"unchecked"}) 051public class PropertySearch 052 extends CriteriaSearch 053{ 054 private Search search; 055 056 /** 057 * Constructor for PropertySearch. Creates a <code>PropertySearch</code> instance 058 * from the given arguments. 059 * 060 * @param session The Hibernate session. 061 * @param entityType The <code>Class</code> of the result. 062 * @param searchIn the object that specifies the search criteria. 063 */ 064 public PropertySearch( 065 final Session session, 066 final Class entityType, 067 final Search searchIn) 068 { 069 super(session, entityType); 070 this.search = searchIn; 071 try 072 { 073 this.initializeConverters(); 074 this.getConfiguration().setForceEagerLoading(searchIn.isEagerFetching()); 075 final SearchParameter[] parameters = searchIn.getParameters(); 076 if (parameters != null) 077 { 078 for (int ctr = 0; ctr < parameters.length; ctr++) 079 { 080 final SearchParameter searchParameter = parameters[ctr]; 081 082 Object value; 083 switch (searchParameter.getComparator()) 084 { 085 case SearchParameter.IN_COMPARATOR : 086 value = searchParameter.getValue(); 087 break; 088 case SearchParameter.NOT_IN_COMPARATOR : 089 value = searchParameter.getValue(); 090 break; 091 default : 092 value = this.getValue(entityType, searchParameter); 093 break; 094 } 095 096 // - now add the parameter. 097 final CriteriaSearchParameter parameter = 098 new CriteriaSearchParameter(value, 099 searchParameter.getName(), 100 searchParameter.getComparator()); 101 parameter.setOrderDirection(searchParameter.getOrder()); 102 parameter.setSearchIfNull(searchParameter.isSearchIfNull()); 103 switch (searchParameter.getMatch()) 104 { 105 case SearchParameter.MATCH_ANYWHERE : 106 parameter.setMatchMode(MatchMode.ANYWHERE); 107 break; 108 case SearchParameter.MATCH_START : 109 parameter.setMatchMode(MatchMode.START); 110 break; 111 case SearchParameter.MATCH_END : 112 parameter.setMatchMode(MatchMode.END); 113 break; 114 default: 115 parameter.setMatchMode(MatchMode.EXACT); 116 break; 117 } 118 this.addParameter(parameter); 119 if (searchIn.isUseSqlLimiting()) 120 { 121 if (searchIn.getPageNumber() > 0 && searchIn.getPageSize() > 0) 122 { 123 // - set the first result as part of pagination support 124 this.getConfiguration().setFirstResult(new Integer(this.calculateFirstResult(searchIn.getPageNumber(), searchIn.getPageSize()))); 125 this.getConfiguration().setMaximumResultSize(new Integer(searchIn.getPageSize())); 126 } 127 } 128 } 129 } 130 } 131 catch (Exception exception) 132 { 133 throw new RuntimeException(exception); 134 } 135 } 136 137 /** 138 * Stores the total count when sql limiting isn't used. 139 */ 140 private int totalCount; 141 142 /** 143 * Gets the total possible count of objects returned in this search. 144 * @return totalCount 145 */ 146 public int getTotalCount() 147 { 148 int count; 149 if (this.search.isUseSqlLimiting()) 150 { 151 // Remove first result requirement 152 this.getConfiguration().setFirstResult(new Integer(0)); 153 this.getRootCriteria().setProjection( 154 Projections.projectionList().add( 155 Projections.rowCount())); 156 count = ((Long)this.executeAsList().iterator().next()).intValue(); 157 } 158 else 159 { 160 count = this.totalCount; 161 } 162 return count; 163 } 164 165 /** 166 * @see CriteriaSearch#executeAsList() 167 */ 168 @Override 169 public List executeAsList() 170 throws HibernateException 171 { 172 List results = super.executeAsList(); 173 if (!this.search.isUseSqlLimiting() && this.search.getPageNumber() > 0 && this.search.getPageSize() > 0) 174 { 175 int start = this.calculateFirstResult(this.search.getPageNumber(), this.search.getPageSize()); 176 int end = this.calculateLastResult(this.search.getPageNumber(), this.search.getPageSize()); 177 this.totalCount = results.size(); 178 if (this.totalCount < start) 179 { 180 start = this.totalCount; 181 } 182 if (this.totalCount < end) 183 { 184 end = this.totalCount; 185 } 186 results = results.subList(start, end); 187 } 188 return results; 189 } 190 191 /** 192 * Calculates the first result based upon page size and current 193 * desired page. 194 * 195 * @param pageNumber the page number to retrieve. 196 * @param pageSize the page size to retrieve. 197 * 198 * @return the calculated first result. 199 */ 200 private int calculateFirstResult(int pageNumber, int pageSize) 201 { 202 int firstResult = 0; 203 if (pageNumber > 0 && pageSize > 0) 204 { 205 firstResult = (pageNumber - 1) * pageSize; 206 } 207 return firstResult; 208 } 209 210 /** 211 * Calculates the last result based upon page size and current 212 * desired page. 213 * 214 * @param pageNumber the page number to retrieve. 215 * @param pageSize the page size to retrieve. 216 * 217 * @return the calculated first result. 218 */ 219 private int calculateLastResult(int pageNumber, int pageSize) 220 { 221 int lastResult = 0; 222 if (pageNumber > 0 && pageSize > 0) 223 { 224 lastResult = pageNumber * pageSize; 225 } 226 return lastResult; 227 } 228 229 private static final String PERIOD = "."; 230 231 /** 232 * Initializes the converters to behave the way we want when converting values (we don't 233 * want empty strings converted to zeros, like beanutils does by default) 234 */ 235 private void initializeConverters() 236 { 237 ConvertUtils.register(new LongConverter(null), Long.class); 238 ConvertUtils.register(new IntegerConverter(null), Integer.class); 239 ConvertUtils.register(new ShortConverter(null), Short.class); 240 ConvertUtils.register(new CalendarConverter(), Calendar.class); 241 ConvertUtils.register(new DateConverter(), Date.class); 242 } 243 244 /** 245 * <p>Convert the value to an object of the specified class (if 246 * possible).</p> 247 * 248 * @param value Value to be converted (may be null) 249 * @param type Class of the value to be converted to 250 * @return The converted value 251 * 252 * @exception ConversionException if thrown by an underlying Converter 253 */ 254 protected Object convert(Object value, Class type) 255 { 256 Converter converter = ConvertUtils.lookup(type); 257 Object result; 258 if (converter != null) 259 { 260 result = converter.convert(type, value); 261 } 262 else 263 { 264 result = value; 265 } 266 return result; 267 } 268 269 /** 270 * Converts the value contained within the parameter to the type which Hibernate expects. 271 * 272 * @param entityType the class of the entity for which the search is being performed. 273 * @param parameter the parameter from which to get the value. 274 * @return the appropriate value. 275 */ 276 private Object getValue(Class type, final SearchParameter parameter) 277 { 278 try 279 { 280 Object value = parameter.getValue(); 281 // - don't try to convert null values or classes 282 if (value != null && !value.getClass().equals(Class.class)) 283 { 284 Class propertyType = type; 285 for (final StringTokenizer tokenizer = new StringTokenizer(parameter.getName(), PERIOD); tokenizer.hasMoreTokens();) 286 { 287 final String token = tokenizer.nextToken().trim(); 288 Class lastType = type; 289 type = CriteriaSearchProperties.getPropertyType(type, token); 290 if (!tokenizer.hasMoreTokens()) 291 { 292 break; 293 } 294 if (type == null) 295 { 296 throw new RuntimeException("No accessible property named '" + token + "', exists on: " + lastType.getName()); 297 } 298 propertyType = type; 299 } 300 final Object object = propertyType.newInstance(); 301 final String name = parameter.getName().replaceAll(".*\\" + PERIOD, ""); 302 try 303 { 304 value = convert(value, PropertyUtils.getPropertyType(object, name)); 305 } 306 catch (final NoSuchMethodException noSuchMethodException) 307 { 308 throw new RuntimeException("No accessible property named '" + name + "', exists on: " + propertyType.getName()); 309 } 310 } 311 return value; 312 } 313 catch (final Exception exception) 314 { 315 throw new RuntimeException(exception); 316 } 317 } 318 319 /** 320 * A beanutils converter that converts Calendar objects to Date instances. 321 */ 322 private static final class DateConverter 323 implements Converter 324 { 325 public DateConverter() 326 { 327 // Empty block comment 328 } 329 330 /** 331 * @see org.apache.commons.beanutils.Converter#convert(Class, Object) 332 */ 333 public Object convert( 334 Class type, 335 Object value) 336 throws ConversionException 337 { 338 if (value != null) 339 { 340 try 341 { 342 if (value instanceof Calendar) 343 { 344 value = ((Calendar)value).getTime(); 345 } 346 } 347 catch (Exception ex) 348 { 349 throw new ConversionException(ex); 350 } 351 } 352 return value; 353 } 354 } 355 356 /** 357 * A beanutils converter that converts Date objects to Calendar instances. 358 */ 359 private static final class CalendarConverter 360 implements Converter 361 { 362 public CalendarConverter() 363 { 364 // Empty block comment 365 } 366 367 /** 368 * @see org.apache.commons.beanutils.Converter#convert(Class, Object) 369 */ 370 public Object convert( 371 Class type, 372 Object value) 373 throws ConversionException 374 { 375 if (value != null) 376 { 377 try 378 { 379 if (value instanceof Date) 380 { 381 Calendar calendar = Calendar.getInstance(); 382 calendar.setTime((Date)value); 383 value = calendar; 384 } 385 } 386 catch (Exception ex) 387 { 388 throw new ConversionException(ex); 389 } 390 } 391 return value; 392 } 393 } 394}