Package javango.contrib.hibernate

Source Code of javango.contrib.hibernate.HibernateQuerySet

package javango.contrib.hibernate;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javango.contrib.i18n.I18NProvider;
import javango.db.ManagerException;
import javango.db.QuerySet;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.ScrollableResults;
import org.hibernate.criterion.DetachedCriteria;

import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;

public class HibernateQuerySet<T> implements QuerySet<T>, Iterable<T> {

  protected Map<String, Object> valueFilters = new LinkedHashMap<String, Object>();
  protected Map<String, String> propertyFilters = new LinkedHashMap<String, String>();
  protected List<String> orderbys = new ArrayList<String>();
 
  protected Integer first;
  protected Integer last;
  protected Class<? extends T> clazz;
 
  @Inject
  protected I18NProvider i18n;
  private String _(String format, Object... args) {
    if (i18n == null) {
      return String.format(format, args);
    }
    return i18n.getText(format, args);
  }
   
  // cached local copy of my criteria,  as I am immutable this can be cached once created
  private Criteria _criteria;
 
  HibernateQuerySetHelper qsHelper;

 
  // cached local copy of my count,  as I am immutable this can be cached once known.
  // subsequent calls to count() will always return the same value even if the underlying db changes.
  // i guess this could cause strangeness if the db was updated.  oh well DDN
  Long _count;
 
 
  HibernateUtil hibernateUtil;
 
 
  protected HibernateQuerySet<T> newInstance() throws ManagerException {
    return new HibernateQuerySet<T>(hibernateUtil, clazz);
  }
 
  @Override
  public QuerySet<T> clone() {
    try {
      return newInstance().cloneFrom(this);
    } catch (ManagerException e) {
      LogFactory.getLog(HibernateQuerySet.class).error(e,e);
    }
    return null;
  }
 
  // clone any properties from this object to the other object.  Returns this
  protected HibernateQuerySet<T> cloneFrom(HibernateQuerySet<T> other) throws ManagerException {
    this.valueFilters.putAll(other.valueFilters);
    this.propertyFilters.putAll(other.propertyFilters);
    this.orderbys.addAll(other.orderbys);
    this.first = other.first;
    this.last = other.last;
    return this;
  }
 
  @AssistedInject
  public HibernateQuerySet(HibernateUtil hibernateUtil, @Assisted Class<? extends T> clazz) throws ManagerException {
    super();
    this.hibernateUtil = hibernateUtil;
    this.clazz = clazz;
  }

  public QuerySet<T> filter(Map<String, ?> params, boolean ignoreNulls) throws ManagerException {
    return mapFilter(params, ignoreNulls);
  }
 
  public QuerySet<T> mapFilter(Map<String, ?> params, boolean ignoreNulls) throws ManagerException {
    HibernateQuerySet<T> other = newInstance().cloneFrom(this);
    // ignore null values,  this will change in .34
    // other.filters.putAll(params);
    for(Entry<String, ?> entry : params.entrySet()) {
      if (!ignoreNulls || entry.getValue() != null) other.valueFilters.put(entry.getKey(), entry.getValue());
    }
    return other;
  }

  public QuerySet<T> filter(Map<String, ?> params) throws ManagerException {
    return mapFilter(params,true);
  }
 
  public QuerySet<T> mapFilter(Map<String, ?> params) throws ManagerException {
    return mapFilter(params, true);
  }
 
  public QuerySet<T> filter(Object params) throws ManagerException {
    if (params instanceof Map) {
      return mapFilter((Map)params);
    }
    HibernateQuerySet<T> other = newInstance().cloneFrom(this);

    try {
      Class c = params.getClass();
      java.lang.reflect.Field[] fields = c.getDeclaredFields();
      for (int i=0; i<fields.length; i++) {
        String fieldName = fields[i].getName();
        Object value = PropertyUtils.getProperty(params, fieldName);       
        if (value != null) other.valueFilters.put(fieldName, value);
      }
    } catch (IllegalAccessException e) {
      LogFactory.getLog(HibernateQuerySet.class).error(e,e);
      throw new ManagerException(e);
    } catch (InvocationTargetException e) {
      LogFactory.getLog(HibernateQuerySet.class).error(e,e);
      throw new ManagerException(e);
    } catch (NoSuchMethodException e) {
      LogFactory.getLog(HibernateQuerySet.class).error(e,e);
      throw new ManagerException(e);
   
    return other;
  }

  public QuerySet<T> filter(String property, Object value) throws ManagerException {
    HibernateQuerySet<T> other = newInstance().cloneFrom(this);
    other.valueFilters.put(property, value);
    return other;
  }

  public QuerySet<T> filterByProperty(String propertyA, String propertyB) throws ManagerException {
    HibernateQuerySet<T> other = newInstance().cloneFrom(this);
    other.propertyFilters.put(propertyA, propertyB);
    return other;
  }
 
  public QuerySet<T> limit(int first, int last) throws ManagerException {
    HibernateQuerySet<T> other = newInstance().cloneFrom(this);
    other.first = first;
    other.last = last;
    return other;
  }
 
  public T get() throws ManagerException {
    try {
      return (T)getCriteria().uniqueResult();
    } catch (HibernateException e) {
      LogFactory.getLog(HibernateQuerySet.class).error(_("Hibernate Exception 'get()' while running '%s'", this.toString()));
      throw new ManagerException(e);
    }
  }

  public List<T> list() throws ManagerException {
    try {
      return getCriteria().list();
    } catch (HibernateException e) {     
      LogFactory.getLog(HibernateQuerySet.class).error(_("Hibernate Exception 'list()' while running '%s'", this.toString()));
      LogFactory.getLog(HibernateQuerySet.class).error(e,e);
      LogFactory.getLog(HibernateQuerySet.class).error(e,e.getCause());
      throw new ManagerException("Unable to run query");
    }
  }

  public static class QuerySetIterator<T> implements Iterator<T> {
    public QuerySetIterator(ScrollableResults scrollableResult) {
      this.scrollableResult = scrollableResult;
    }

    private ScrollableResults scrollableResult = null;
    private Object[] nextValue; // for some reason isLast returns false on empty lists..
   
    public boolean hasNext() {
      if (nextValue != null) {
        return true;
      }
     
      boolean found = scrollableResult.next();
      if (!found) return false;
     
     
      nextValue = scrollableResult.get();
      return nextValue != null;
    }

    @SuppressWarnings("unchecked")
    public T next() {
      if (nextValue == null || nextValue.length == 0) {
        return null;
      }
     
      T v = (T)nextValue[0];
      nextValue = null;
      return v;
    }

    public void remove() {
      throw new UnsupportedOperationException("remove not supported");           
    }

  }
  public Iterator<T> iterator() {
    try {
      return new QuerySetIterator<T>(getCriteria().scroll());
    } catch (ManagerException e) {
      LogFactory.getLog(HibernateQuerySet.class).error(_("Hibernate Exception on 'iterator()' while running '%s'", this.toString()));
      LogFactory.getLog(HibernateQuerySet.class).error(e,e);
      throw new RuntimeException(e);
    }
  }

  public QuerySet<T> orderBy(String... orderbys) throws ManagerException {
    HibernateQuerySet<T> other = newInstance().cloneFrom(this);
    for(String order : orderbys) {
      other.orderbys.add(order);
    }
    return other;
  }

//  public QuerySet<T> or(QuerySet<T> _orOther) throws ManagerException {
//    if (_orOther instanceof HibernateQuerySet) {
//      HibernateQuerySet<T> orOther = (HibernateQuerySet<T>)_orOther;
//      if (orOther.clazz != this.clazz) {
//        throw new ManagerException("ORs only supported for the same model");
//      }
//      HibernateQuerySet<T> other = new HibernateQuerySet<T>(this);
//      other.ors = new ArrayList<HibernateQuerySet>();
//      other.ors.add(this);
//      other.ors.add(orOther);
//      return other;
//    }
//    throw new ManagerException("ORs only supported with HibernateQuerySets");
//  }
 
  // impelemtation specific functions 
  public long count() throws ManagerException {
    if (_count == null) {
      try {
        _count = new Long(hibernateUtil.doCount(getRawCriteria().getExecutableCriteria(hibernateUtil.getSession())));
      } catch (HibernateException e) {
        LogFactory.getLog(HibernateQuerySet.class).error(_("Hibernate Exception while running %s", this.toString()));
        throw new ManagerException(e);
      }
    }
    return _count;
  }

  /**
   * Returns a Criteria prior to any limit or orders being applied.
   *
   * @return
   * @throws ManagerException
   */
  public DetachedCriteria getRawCriteria() throws ManagerException {
    DetachedCriteria dc = DetachedCriteria.forClass(clazz);
    qsHelper = new HibernateQuerySetHelper(hibernateUtil, clazz, dc);
    qsHelper.updateCriteria(valueFilters);
    qsHelper.updateCriteriaFromPropertyMap(propertyFilters);
   
    return dc;
  }
 
  /**
   * Returns a hibernate criteria representing this queryset.
   *
   * @return
   */
  public org.hibernate.Criteria getCriteria() throws ManagerException {
    if (_criteria != null) return _criteria;

    _criteria = getRawCriteria().getExecutableCriteria(hibernateUtil.getSession());
   
    if (this.first != null) {
      _criteria.setFirstResult(first < 0 ? 0 : first);
      if (this.last != null) {
        int count = this.last - this.first;
        _criteria.setMaxResults(count > 0 ? count : 1);
      }
    } else if (this.last != null) {
      _criteria.setMaxResults(this.last > 0 ? this.last : 1);
    }
    for (String s : orderbys) {
      qsHelper.addOrderBy(s);
    }
   
    return _criteria;
  }

  @Override
  public String toString() {
    return "HibernateQuerySet [valueFilters=" + valueFilters.toString()
        + ", propertyFilters=" + propertyFilters.toString() + ", orderbys="
        + orderbys + ", first=" + first + ", last=" + last + "]";
  }

  public Class<? extends T> getType() {
    return this.clazz;
  }
//
//  void getPropertyInformation(String path) {
//    String[] parts = path.split("__");
//   
//    QuerySet.Lookup lookupType = QuerySet.Lookup.EQ; // DEFAULT
//    if (parts.length > 1) {
//      String match = parts[parts.length-1];
//      for(QuerySet.Lookup lookup : QuerySet.Lookup.values()) {
//        if (lookup.equals(match)) {
//          lookupType = lookup;
//          break;
//        }
//      }
//    }
//   
//   
//  }
}
TOP

Related Classes of javango.contrib.hibernate.HibernateQuerySet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.