/**
* Copyright (C) 2008 - Abiquo Holdings S.L. All rights reserved.
*
* Please see /opt/abiquo/tomcat/webapps/legal/ on Abiquo server
* or contact contact@abiquo.com for licensing information.
*/
package com.abiquo.server.core.common.persistence;
import java.io.Serializable;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.abiquo.server.core.common.GenericEnityBase;
import com.abiquo.server.core.util.FilterOptions;
import com.softwarementors.bzngine.dao.hibernate.JpaHibernateDaoBase;
import com.softwarementors.bzngine.entities.PersistentEntity;
//@PersistenceContext(unitName="abiquoPersistence")
public abstract class DefaultDAOBase<I extends Serializable, T extends GenericEnityBase<I>> extends
JpaHibernateDaoBase<T, I>
{
private boolean managed;
@PersistenceContext
@Override
protected void setEntityManager(final EntityManager entityManager)
{
super.setEntityManager(entityManager);
}
/* default constructor for Spring */
protected DefaultDAOBase(final Class<T> persistentClass)
{
super(persistentClass);
this.managed = true;
}
/*
* @SuppressWarnings("deprecation") public Connection getConnection() { return
* getSession().connection(); }
*/
protected DefaultDAOBase(final Class<T> persistentClass, final EntityManager entityManager)
{
super(persistentClass, entityManager);
}
// TODO: PAG, fix this by changing parameter type for base class isManaged
public boolean isManaged2(final PersistentEntity< ? > entity)
{
assert entity != null;
assert isOpen();
assert isInTransaction();
return entity.getId() != null && getEntityManager().contains(entity);
}
@Override
public boolean isInTransaction()
{
if (!managed)
{
return super.isInTransaction();
}
return TransactionSynchronizationManager.isActualTransactionActive();
}
@Override
public boolean isInReadWriteTransaction()
{
if (!managed)
{
return super.isInReadWriteTransaction();
}
return !TransactionSynchronizationManager.isCurrentTransactionReadOnly();
}
@Override
public boolean isInRollbackTransaction()
{
if (!managed)
{
return super.isInRollbackTransaction();
}
return !TransactionSynchronizationManager.isSynchronizationActive();
}
public T findUniqueByProperty(final String propertyName, final String value)
{
Criterion criterion = Restrictions.eq(propertyName, value);
return findUniqueByCriterions(criterion);
}
protected Criteria createNestedCriteria(final String... propertyNames)
{
Criteria crit = getSession().createCriteria(getPersistentClass());
return createNestedCriteria(crit, propertyNames);
}
protected Criteria createNestedCriteria(final Order order, final String... propertyNames)
{
Criteria crit = getSession().createCriteria(getPersistentClass());
crit.addOrder(order);
return createNestedCriteria(crit, propertyNames);
}
private Criteria createNestedCriteria(final Criteria baseCriteria,
final String... propertyNames)
{
Criteria crit = baseCriteria;
for (String property : propertyNames)
{
crit = crit.createCriteria(property);
}
return crit;
}
protected Number count()
{
Criteria criteria = getSession().createCriteria(getPersistentClass());
return count(criteria);
}
protected Number count(final Criteria criteria)
{
criteria.setProjection(Projections.rowCount());
return (Number) criteria.uniqueResult();
}
/**
* Gets the count result applying a distinct projection over the given property
*
* @param criteria
* @param distinctProperty
* @return the count result applying a distinct projection over the given property
*/
protected Number count(final Criteria criteria, final String distinctProperty)
{
criteria.setProjection(Projections.countDistinct(distinctProperty));
return (Number) criteria.uniqueResult();
}
protected Number count(final Query query, final Map< ? , ? > parameters)
{
String original = query.getQueryString();
StringBuffer countQuery = new StringBuffer();
countQuery.append("select count(*) ");
countQuery.append(original.substring(original.toLowerCase().indexOf("from")));
Query count = getSession().createQuery(countQuery.toString());
count.setProperties(parameters);
return (Number) count.uniqueResult();
}
protected Number countSQL(final SQLQuery query, final Map< ? , ? > parameters)
{
String original = query.getQueryString();
StringBuffer countQuery = new StringBuffer();
countQuery.append("select count(*) ");
countQuery.append(original.substring(original.toLowerCase().indexOf("from")));
SQLQuery count = getSession().createSQLQuery(countQuery.toString());
count.setProperties(parameters);
return (Number) count.uniqueResult();
}
protected Criterion filterBy(final FilterOptions filters, final String... properties)
{
// Search criterias
String textFilter =
filters.getFilter() == null || filters.getFilter().isEmpty() ? "%" : "%"
+ filters.getFilter() + "%";
if (properties.length == 1)
{
return Restrictions.like(properties[0], textFilter);
}
else
{
// If there is more than one property, return a OR criterion to match any of the given
// properties
Disjunction orClause = Restrictions.disjunction();
for (String property : properties)
{
orClause.add(Restrictions.like(property, textFilter));
}
return orClause;
}
}
public void detach(final T entity)
{
this.getEntityManager().detach(entity);
}
public T merge(final T entity)
{
return this.getEntityManager().merge(entity);
}
/**
* This method removes an entity from the session cache. So unsaved (flush) changes to the
* object and further changes won't be persisted.
*
* @param entity entity to be removed from the session.
*/
public void evict(final T entity)
{
((Session) this.getEntityManager().getDelegate()).evict(entity);
}
}