1 package de.hsofttec.core5.datasource;
   2 
   3 import java.util.Iterator;
   4 import java.util.regex.Pattern;
   5 
   6 import org.apache.commons.lang.StringUtils;
   7 import org.apache.commons.logging.Log;
   8 import org.apache.commons.logging.LogFactory;
   9 import org.apache.tapestry.beaneditor.PropertyModel;
  10 import org.apache.tapestry.grid.GridDataSource;
  11 import org.apache.tapestry.ioc.internal.util.TapestryException;
  12 
  13 import org.hibernate.QueryException;
  14 
  15 import de.hsofttec.core5.dao.GenericDAO;
  16 
  17 /**
  18  * grid datasource for hibernate queries.
  19  *
  20  * @author <a href="mailto:shomburg@hsofttec.com">shomburg</a>
  21  * @version $Id: HibernateDataSource.java 13 2007-09-27 16:25:32Z shomburg $
  22  */
  23 public class HibernateDataSource implements GridDataSource
  24 {
  25     private static Log _logger = LogFactory.getLog(HibernateDataSource.class);
  26     private GenericDAO _genericDAO;
  27     private String _hqlString;
  28     private String _hqlCountString;
  29     private int _rowCount = -1;
  30     private Iterator _pageRowList;
  31 
  32     public HibernateDataSource(GenericDAO genericDAO, String hqlString)
  33     {
  34         this(genericDAO, hqlString, null);
  35     }
  36 
  37     public HibernateDataSource(GenericDAO genericDAO, String hqlString, String hqlSpecialCountString)
  38     {
  39         _genericDAO = genericDAO;
  40         _hqlString = hqlString;
  41         _hqlCountString = hqlSpecialCountString;
  42     }
  43 
  44     /**
  45      * Returns the number of rows available in the data source.
  46      */
  47     public int getAvailableRows()
  48     {
  49         if (_rowCount < 0)
  50             _rowCount = getMaximumResultObjects();
  51 
  52         return _rowCount;
  53     }
  54 
  55     /**
  56      * Invoked to allow the source to prepare to present values. This gives the source a chance to
  57      * pre-fetch data (when appropriate) and informs the source of the desired sort order.
  58      *
  59      * @param startIndex the starting index to be retrieved
  60      * @param endIndex   the ending index to be retrieved
  61      * @param sortModel  the property model that defines what data will be used for sorting, or null if no
  62      *                   sorting is required (in which case, whatever natural order is provided by the
  63      *                   underlying data source will be used)
  64      * @param ascending  if true, then sort ascending, else decending
  65      */
  66     public void prepare(int startIndex, int endIndex, PropertyModel sortModel, boolean ascending)
  67     {
  68         if (_logger.isInfoEnabled())
  69             _logger.info(String.format("processing prepare(%d, %d) for '%s'", 
  70                                        startIndex, endIndex, _genericDAO.getPersistentClass().getName()));
  71 
  72         _pageRowList = _genericDAO.findByQuery(_hqlString, startIndex, endIndex + 1).iterator();
  73     }
  74 
  75     /**
  76      * Returns the row value at the provided index. This method will be invoked in sequential order.
  77      */
  78     public Object getRowValue(int index)
  79     {
  80         Object entityObject = null;
  81 
  82         if (_pageRowList.hasNext())
  83             entityObject = _pageRowList.next();
  84 
  85         return entityObject;
  86     }
  87 
  88     /**
  89      * Returns the type of value in the rows, or null if not known.
  90      *
  91      * @return the row type, or null
  92      */
  93     public Class getRowType()
  94     {
  95         return _genericDAO.getPersistentClass();
  96     }
  97 
  98     /**
  99      * get the maximum count of rows to display.
 100      */
 101     private int getMaximumResultObjects()
 102     {
 103         String tempQuery1;
 104         String queryString = _hqlString;
 105 
 106         try
 107         {
 108             if (_logger.isInfoEnabled())
 109                 _logger.info(String.format("processing getMaximumResultObjects() for '%s'", 
 110                                            _genericDAO.getPersistentClass().getName()));
 111 
 112             if (_hqlCountString != null)
 113                 tempQuery1 = _hqlCountString;
 114             else
 115                 tempQuery1 = convertQueryString(queryString);
 116 
 117             Long result = (Long) _genericDAO.countByQuery(tempQuery1);
 118             if (result == null)
 119                 return 0;
 120 
 121             return result.intValue();
 122         }
 123         catch (QueryException e)
 124         {
 125             throw new TapestryException("entity not \"mapped\" in hibernate.cfg.xml ?", this, e);
 126         }
 127     }
 128 
 129     /**
 130      * den SQL-Query so Aufbauen, das wir einen Count auf die Tabelle absetzen koennen.
 131      */
 132     private String convertQueryString(String originalQueryString)
 133     {
 134         String tempQueryString = StringUtils.substring(originalQueryString, 
 135                                                        StringUtils.indexOf(StringUtils.
 136                                                                            upperCase(originalQueryString), "FROM"));
 137         String convertedQueryString = "SELECT COUNT(*) ";
 138 
 139         // Split input with the pattern
 140         Pattern p = Pattern.compile("[\\s]+");
 141         String[] result = p.split(tempQueryString);
 142 
 143         for (String queryWord : result)
 144         {
 145             //
 146             // ist queryWord ein Query-Fragment, was in einem Count-Query nicht auftauchen darf ?
 147             //
 148             // if (queryWord.equalsIgnoreCase("LEFT") || 
 149                    queryWord.equalsIgnoreCase("JOIN") || 
 150                    queryWord.equalsIgnoreCase("FETCH"))
 151             if (queryWord.equalsIgnoreCase("FETCH"))
 152                 continue;
 153 
 154             if (queryWord.equalsIgnoreCase("ORDER"))
 155                 break;
 156 
 157             convertedQueryString += queryWord + " ";
 158         }
 159 
 160         if (_logger.isInfoEnabled())
 161             _logger.info("source: " + originalQueryString + System.getProperty("line.separator") +
 162                     "dest: " + convertedQueryString);
 163 
 164         return convertedQueryString;
 165     }
 166 }

Tapestry5HibernateGridDatasource1 (last edited 2010-06-12 09:39:14 by LorenzoSimionato)