1 28 package net.sf.jasperreports.engine.query; 29 30 import java.util.Collection ; 31 import java.util.HashMap ; 32 import java.util.HashSet ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.Set ; 37 38 import net.sf.jasperreports.engine.JRDataSource; 39 import net.sf.jasperreports.engine.JRDataset; 40 import net.sf.jasperreports.engine.JRException; 41 import net.sf.jasperreports.engine.JRParameter; 42 import net.sf.jasperreports.engine.JRPropertiesMap; 43 import net.sf.jasperreports.engine.JRRuntimeException; 44 import net.sf.jasperreports.engine.JRValueParameter; 45 import net.sf.jasperreports.engine.data.JRHibernateIterateDataSource; 46 import net.sf.jasperreports.engine.data.JRHibernateListDataSource; 47 import net.sf.jasperreports.engine.data.JRHibernateScrollDataSource; 48 import net.sf.jasperreports.engine.util.JRProperties; 49 import net.sf.jasperreports.engine.util.JRStringUtil; 50 51 import org.apache.commons.logging.Log; 52 import org.apache.commons.logging.LogFactory; 53 import org.hibernate.Hibernate; 54 import org.hibernate.Query; 55 import org.hibernate.ScrollMode; 56 import org.hibernate.ScrollableResults; 57 import org.hibernate.Session; 58 import org.hibernate.type.Type; 59 60 66 public class JRHibernateQueryExecuter extends JRAbstractQueryExecuter 67 { 68 private static final Log log = LogFactory.getLog(JRHibernateQueryExecuter.class); 69 70 private static final Map hibernateTypeMap; 71 72 static 73 { 74 hibernateTypeMap = new HashMap (); 75 hibernateTypeMap.put(Boolean .class, Hibernate.BOOLEAN); 76 hibernateTypeMap.put(Byte .class, Hibernate.BYTE); 77 hibernateTypeMap.put(Double .class, Hibernate.DOUBLE); 78 hibernateTypeMap.put(Float .class, Hibernate.FLOAT); 79 hibernateTypeMap.put(Integer .class, Hibernate.INTEGER); 80 hibernateTypeMap.put(Long .class, Hibernate.LONG); 81 hibernateTypeMap.put(Short .class, Hibernate.SHORT); 82 hibernateTypeMap.put(java.math.BigDecimal .class, Hibernate.BIG_DECIMAL); 83 hibernateTypeMap.put(java.math.BigInteger .class, Hibernate.BIG_INTEGER); 84 hibernateTypeMap.put(Character .class, Hibernate.CHARACTER); 85 hibernateTypeMap.put(String .class, Hibernate.STRING); 86 hibernateTypeMap.put(java.util.Date .class, Hibernate.DATE); 87 hibernateTypeMap.put(java.sql.Timestamp .class, Hibernate.TIMESTAMP); 88 hibernateTypeMap.put(java.sql.Time .class, Hibernate.TIME); 89 } 90 91 private final Integer reportMaxCount; 92 93 private Session session; 94 private Query query; 95 private boolean queryRunning; 96 private ScrollableResults scrollableResults; 97 98 99 public JRHibernateQueryExecuter(JRDataset dataset, Map parameters) 100 { 101 super(dataset, parameters); 102 103 session = (Session) getParameterValue(JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_SESSION); 104 reportMaxCount = (Integer ) getParameterValue(JRParameter.REPORT_MAX_COUNT); 105 106 if (session == null) 107 { 108 log.warn("The supplied org.hibernate.Session object is null."); 109 } 110 111 parseQuery(); 112 } 113 114 115 120 public JRDataSource createDatasource() throws JRException 121 { 122 JRDataSource datasource = null; 123 String queryString = getQueryString(); 124 125 if (session != null && queryString != null && queryString.trim().length() > 0) 126 { 127 createQuery(queryString); 128 129 datasource = createResultDatasource(); 130 } 131 132 return datasource; 133 } 134 135 140 protected JRDataSource createResultDatasource() 141 { 142 JRDataSource resDatasource; 143 144 JRPropertiesMap datasetProperties = dataset.getPropertiesMap(); 145 146 String runType = JRProperties.getProperty(datasetProperties, 147 JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_RUN_TYPE); 148 boolean useFieldDescriptions = JRProperties.getBooleanProperty(datasetProperties, 149 JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_FIELD_MAPPING_DESCRIPTIONS, 150 true); 151 152 if (runType == null || runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_LIST)) 153 { 154 try 155 { 156 int pageSize = JRProperties.getIntegerProperty(datasetProperties, 157 JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_LIST_PAGE_SIZE, 158 0); 159 160 resDatasource = new JRHibernateListDataSource(this, useFieldDescriptions, pageSize); 161 } 162 catch (NumberFormatException e) 163 { 164 throw new JRRuntimeException("The " + JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_LIST_PAGE_SIZE + 165 " property must be numerical."); 166 } 167 } 168 else if (runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_ITERATE)) 169 { 170 resDatasource = new JRHibernateIterateDataSource(this, useFieldDescriptions); 171 } 172 else if (runType.equals(JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_SCROLL)) 173 { 174 resDatasource = new JRHibernateScrollDataSource(this, useFieldDescriptions); 175 } 176 else 177 { 178 throw new JRRuntimeException("Unknown value for the " + JRHibernateQueryExecuterFactory.PROPERTY_HIBERNATE_QUERY_RUN_TYPE + 179 " property. Possible values are " + JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_LIST + ", " + 180 JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_ITERATE + " and " + 181 JRHibernateQueryExecuterFactory.VALUE_HIBERNATE_QUERY_RUN_TYPE_SCROLL + "."); 182 } 183 184 return resDatasource; 185 } 186 187 188 196 protected synchronized void createQuery(String queryString) 197 { 198 if (log.isDebugEnabled()) 199 { 200 log.debug("HQL query: " + queryString); 201 } 202 203 Object filterCollection = getParameterValue(JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_FILTER_COLLECTION); 204 if (filterCollection == null) 205 { 206 query = session.createQuery(queryString); 207 } 208 else 209 { 210 query = session.createFilter(filterCollection, queryString); 211 } 212 query.setReadOnly(true); 213 214 int fetchSize = JRProperties.getIntegerProperty(dataset.getPropertiesMap(), 215 JRJdbcQueryExecuterFactory.PROPERTY_JDBC_FETCH_SIZE, 216 0); 217 if (fetchSize > 0) 218 { 219 query.setFetchSize(fetchSize); 220 } 221 222 setParameters(); 223 } 224 225 228 protected void setParameters() 229 { 230 List parameterNames = getCollectedParameterNames(); 231 232 if (!parameterNames.isEmpty()) 233 { 234 Set namesSet = new HashSet (); 235 236 for (Iterator iter = parameterNames.iterator(); iter.hasNext();) 237 { 238 String parameterName = (String ) iter.next(); 239 if (namesSet.add(parameterName)) 240 { 241 JRValueParameter parameter = getValueParameter(parameterName); 242 setParameter(parameter); 243 } 244 } 245 } 246 } 247 248 249 254 protected void setParameter(JRValueParameter parameter) 255 { 256 String hqlParamName = getHqlParameterName(parameter.getName()); 257 Class clazz = parameter.getValueClass(); 258 Object parameterValue = parameter.getValue(); 259 260 if (log.isDebugEnabled()) 261 { 262 log.debug("Parameter " + hqlParamName + " of type " + clazz.getName() + ": " + parameterValue); 263 } 264 265 Type type = (Type) hibernateTypeMap.get(clazz); 266 267 if (type != null) 268 { 269 query.setParameter(hqlParamName, parameterValue, type); 270 } 271 else if (Collection .class.isAssignableFrom(clazz)) 272 { 273 query.setParameterList(hqlParamName, (Collection ) parameterValue); 274 } 275 else 276 { 277 if (session.getSessionFactory().getClassMetadata(clazz) != null) { 279 query.setEntity(hqlParamName, parameterValue); 280 } 281 else { 283 query.setParameter(hqlParamName, parameterValue); 284 } 285 } 286 } 287 288 289 292 public synchronized void close() 293 { 294 closeScrollableResults(); 295 296 query = null; 297 } 298 299 300 303 public void closeScrollableResults() 304 { 305 if (scrollableResults != null) 306 { 307 try 308 { 309 scrollableResults.close(); 310 } 311 finally 312 { 313 scrollableResults = null; 314 } 315 } 316 } 317 318 319 public synchronized boolean cancelQuery() throws JRException 320 { 321 if (queryRunning) 322 { 323 session.cancelQuery(); 324 return true; 325 } 326 327 return false; 328 } 329 330 protected String getParameterReplacement(String parameterName) 331 { 332 return ':' + getHqlParameterName(parameterName); 333 } 334 335 protected String getHqlParameterName(String parameterName) 336 { 337 return '_' + JRStringUtil.getLiteral(parameterName); 338 } 339 340 341 346 public Type[] getReturnTypes() 347 { 348 return query.getReturnTypes(); 349 } 350 351 352 357 public String [] getReturnAliases() 358 { 359 return query.getReturnAliases(); 360 } 361 362 363 368 public JRDataset getDataset() 369 { 370 return dataset; 371 } 372 373 374 381 public List list() 382 { 383 setMaxCount(); 384 385 setQueryRunning(true); 386 try 387 { 388 return query.list(); 389 } 390 finally 391 { 392 setQueryRunning(false); 393 } 394 } 395 396 protected synchronized void setQueryRunning(boolean queryRunning) 397 { 398 this.queryRunning = queryRunning; 399 } 400 401 402 private void setMaxCount() 403 { 404 if (reportMaxCount != null) 405 { 406 query.setMaxResults(reportMaxCount.intValue()); 407 } 408 } 409 410 411 418 public List list(int firstIndex, int resultCount) 419 { 420 if (reportMaxCount != null && firstIndex + resultCount > reportMaxCount.intValue()) 421 { 422 resultCount = reportMaxCount.intValue() - firstIndex; 423 } 424 425 query.setFirstResult(firstIndex); 426 query.setMaxResults(resultCount); 427 return query.list(); 428 } 429 430 431 436 public Iterator iterate() 437 { 438 setMaxCount(); 439 440 setQueryRunning(true); 441 try 442 { 443 return query.iterate(); 444 } 445 finally 446 { 447 setQueryRunning(false); 448 } 449 } 450 451 452 457 public ScrollableResults scroll() 458 { 459 setMaxCount(); 460 461 setQueryRunning(true); 462 try 463 { 464 scrollableResults = query.scroll(ScrollMode.FORWARD_ONLY); 465 } 466 finally 467 { 468 setQueryRunning(false); 469 } 470 471 return scrollableResults; 472 } 473 } 474 | Popular Tags |