package com.joe.utilities.core.hibernate.repository.impl;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.joe.utilities.core.hibernate.repository.LookupRepository;
import com.joe.utilities.core.hibernate.repository.LookupRepository.State;
import com.joe.utilities.core.hibernate.repository.LookupRepository.TX_TYPE;
import com.joe.utilities.core.stdfield.domain.IStandardFieldMapping;
import com.joe.utilities.core.util.ILookupProfile;
import com.joe.utilities.core.util.IStandardFieldLookupProfile;
import com.joe.utilities.core.util.Utils;
/**
* Hibernate-specific database access to lookup table operations.
* @author Dave Ousey
*
* Creation date: 1/8/2007 4:45 PM
* Copyright (c) 2007 MEDecision, Inc. All rights reserved.
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public class LookupRepositoryImpl extends HibernateDaoSupport implements LookupRepository
{
/**
* Contructor with dependent Session object
* @param session
*/
public LookupRepositoryImpl(HibernateTemplate hibernateTemplate) {
setHibernateTemplate(hibernateTemplate);
}
/**
* @see com.med.utilities.repository.LookupRepository#getLookupList(java.lang.String)
*/
@SuppressWarnings("unchecked")
public List<ILookupProfile> getLookupList(String domainClassName)
{
try
{
List<ILookupProfile> returnList = getHibernateTemplate().loadAll(Class.forName(domainClassName));
return returnList;
}
catch (ClassNotFoundException e)
{
throw new RuntimeException("Domain class name '"+domainClassName+"' cannot be mapped to a runtime class.", e);
}
}
/**
* @see com.med.utilities.repository.LookupRepository#getLookupFilteredList(java.lang.String, java.lang.String, java.lang.String)
*/
@SuppressWarnings("unchecked")
public List<ILookupProfile> getLookupFilteredList(String domainClassName, String lookupVariableName, String filter)
{
List<ILookupProfile> returnList = getHibernateTemplate().findByNamedParam(
"from " + domainClassName + " as className where className." + lookupVariableName +" = :filter",
"filter", filter);
return returnList;
}
/**
* @see com.med.utilities.repository.LookupRepository#getLookupValue(java.lang.String, java.lang.String)
*/
public ILookupProfile getLookupValue(String domainClassName, String code)
{
// Locate matching lookup value for given domain class name and code
List<ILookupProfile> returnList = getLookupList(domainClassName);
for (ILookupProfile lookup : returnList)
{
if (lookup.getCode().equals(code))
return lookup;
}
return null;
}
/**
* @see com.med.utilities.repository.LookupRepository#saveLookupValue(java.lang.String, ILookupProfile)
*/
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void saveLookupValue(String domainClassName, ILookupProfile lookupProfile) {
throw new RuntimeException("This does not work yet.");
}
/**
* @see com.med.utilities.repository.LookupRepository#saveLookups(java.util.Collection)
*/
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void saveLookups(String domainClassName, Collection<? extends ILookupProfile> lookupCollection)
{
if (lookupCollection == null)
return;
// Note: this logic assumes that we are only inserting new records.
if (lookupCollection.size() > 0)
{
Session session = getSession(false);
for (ILookupProfile lookup : lookupCollection)
{
session.save(lookup);
}
}
}
/**
* @see com.med.utilities.repository.LookupRepository#isLookupValueValidInDatabase(java.lang.Class, java.io.Serializable)
*/
public boolean isLookupValueValidInDatabase(Class theClass,Serializable key) {
Object theObject = getHibernateTemplate().get(theClass, key);
if (theObject==null)return false;
return true;
}
/**
* @see com.med.utilities.repository.LookupRepository#getStandardFieldLookupList(java.lang.String)
*/
@SuppressWarnings("unchecked")
public List<IStandardFieldLookupProfile> getStandardFieldLookupList(String domainClassName)
{
try
{
return getHibernateTemplate().loadAll(Class.forName(domainClassName));
}
catch (ClassNotFoundException e)
{
throw new RuntimeException("Domain class name '"+domainClassName+"' cannot be mapped to a runtime class.", e);
}
}
/**
* @see com.med.utilities.repository.LookupRepository#getStandardFieldLookupValue(java.lang.String, java.lang.String)
*/
public IStandardFieldLookupProfile getStandardFieldLookupValue(String domainClassName, String code)
{
// Locate matching lookup value for given domain class name and code
List<IStandardFieldLookupProfile> returnList = getStandardFieldLookupList(domainClassName);
for (IStandardFieldLookupProfile lookup : returnList)
{
if (lookup.getCode().equals(code))
return lookup;
}
return null;
}
/**
* @see com.med.utilities.repository.LookupRepository#getStandardFieldLookupValue(java.lang.String, java.lang.String)
*/
public IStandardFieldLookupProfile getStandardFieldLookupValueByDescription(String domainClassName, String desc)
{
// Locate matching lookup value for given domain class name and desc
List<IStandardFieldLookupProfile> returnList = getStandardFieldLookupList(domainClassName);
for (IStandardFieldLookupProfile lookup : returnList)
{
if (lookup.getDescription().equalsIgnoreCase(desc))
return lookup;
}
return null;
}
/**
* @see com.med.utilities.repository.LookupRepository#saveStandardFieldLookups(java.util.Collection)
*/
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void saveStandardFieldLookups(String domainClassName, Collection<? extends IStandardFieldLookupProfile> lookupCollection)
{
if (lookupCollection == null)
return;
if (lookupCollection.size() > 0)
{
Session session = getSession(false);
for (IStandardFieldLookupProfile lookup : lookupCollection)
{
session.saveOrUpdate(lookup);
lookup.setNew(false);
}
}
}
/**
* @see com.med.utilities.repository.LookupRepository#saveStandardFieldLookupValue(java.lang.String, ILookupProfile)
*/
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void saveStandardFieldLookupValue(String domainClassName, IStandardFieldLookupProfile lookupProfile) {
if (lookupProfile == null)
return;
getSession(false).saveOrUpdate(lookupProfile);
lookupProfile.setNew(false);
}
/**
* @see com.med.utilities.repository.LookupRepository#getStandardFieldLookupByDescription(java.lang.String, java.lang.String)
*/
public IStandardFieldLookupProfile getStandardFieldLookupByDescription(String domainClassName, String description)
{
// Locate matching lookup value for given domain class name and description
List<IStandardFieldLookupProfile> returnList = getStandardFieldLookupList(domainClassName);
for (IStandardFieldLookupProfile lookup : returnList)
{
if (lookup.getDescription().equals(description))
return lookup;
}
return null;
}
/**
* @see com.med.utilities.repository.LookupRepository#evaluateExistingStandardFieldLookup(String, String, String)
*/
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public Collection<IStandardFieldLookupProfile> evaluateExistingStandardFieldLookup(String domainClassName, String code, String description)
{
if (domainClassName == null || domainClassName.length() == 0)
throw new IllegalArgumentException("domainClassName cannot be null");
List<IStandardFieldLookupProfile> results = null;
try
{
Criteria criteriaQuery = getSession(false).createCriteria(Class.forName(domainClassName));
if (code != null && description != null)
criteriaQuery.add(Restrictions.or(Restrictions.like("code", code), Restrictions.like("description", description)));
else if (code != null)
criteriaQuery.add(Restrictions.like("code", code));
else if (description != null)
criteriaQuery.add(Restrictions.like("description", description));
results = criteriaQuery.list();
}catch(ClassNotFoundException e){
throw new RuntimeException("Domain class name '"+domainClassName+"' cannot be mapped to a runtime class.", e);
}
// Remove these items from the first level cache to avoid non-unique object exceptions if
// Existing standard field lookup is updated in same Hibernate session
for (IStandardFieldLookupProfile item : results)
{
getHibernateTemplate().evict(item);
}
return results;
}
/**
* @see com.med.utilities.repository.LookupRepository#getStandardFieldLookupFilteredList(String, String, String)
*/
@SuppressWarnings("unchecked")
public List<IStandardFieldLookupProfile> getStandardFieldLookupFilteredList(String domainClassName, String lookupVariableName, String filter)
{
List<IStandardFieldLookupProfile> returnList = getHibernateTemplate().findByNamedParam(
"from " + domainClassName + " as className where className." + lookupVariableName +" = :filter",
"filter", filter);
return returnList;
}
/**
* @see com.med.utilities.repository.LookupRepository#isLookupFilteredValueValidInDatabase(String, String, String, String)
*/
public boolean isLookupFilteredValueValidInDatabase(String theClassName, String key, String lookupDomainName, String filterValue) {
try {
Object theObject = getSession(false).createCriteria(Class.forName(theClassName), "desc")
.add(Restrictions.eq("desc.code" , key))
.add(Restrictions.eq("desc."+lookupDomainName, filterValue))
.uniqueResult();
if (theObject == null) return false;
}catch (ClassNotFoundException e)
{
throw new RuntimeException("Domain class name '"+theClassName+"' cannot be mapped to a runtime class.", e);
}
return true;
}
/**
* @see com.med.utilities.repository.LookupRepository#getStandardFieldMappings(java.lang.String, boolean, java.lang.String)
*/
public List<IStandardFieldMapping> getStandardFieldMappings(String mappingClassName, boolean isPrimary, String filterValue) {
String hql = "from " + mappingClassName + " as className ";
if (filterValue != null) {
hql += "where className." + (isPrimary ? "primaryStandardField" : "secondaryStandardField") + ".code = ?";
return getHibernateTemplate().find(hql, filterValue);
} else {
return getHibernateTemplate().find(hql);
}
}
@SuppressWarnings("unchecked")
public List<IStandardFieldLookupProfile> getStandardFieldLookupList(
final String domainClassName,
final String sortColumn,
final boolean sortAscending,
final int startRow,
final int endRow) {
return (List<IStandardFieldLookupProfile>)
getHibernateTemplate().execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException,
SQLException {
String hql = "select a from " + domainClassName + " a " +
"order by a." + sortColumn +
(sortAscending ? " asc " : " desc ");
Query query = session.createQuery(hql);
query.setFirstResult(startRow);
query.setMaxResults((endRow-startRow) + 1);
return query.list();
}
});
}
/**
* looks up standard field list with a filter. The query's "where" clause is "like 'filterValue%'".
*/
@SuppressWarnings("unchecked")
@Transactional(readOnly = true)
public List<IStandardFieldLookupProfile> getStandardFieldLookupListWithPartialFilter(
String domainClassName,
String sortColumn,
boolean sortAscending,
int startRow,
int endRow,
String filterFieldName,
String filterValue,
boolean activeOnly) {
if (domainClassName == null || domainClassName.length() == 0)
throw new IllegalArgumentException("domainClassName cannot be null");
List<IStandardFieldLookupProfile> results = null;
Criteria criteriaQuery;
String likeFilter = filterValue+"%";
try
{
criteriaQuery = getSession(false).createCriteria(Class.forName(domainClassName));
if (filterFieldName != null && filterFieldName.length() != 0){
criteriaQuery.add(Restrictions.ilike(filterFieldName, likeFilter));
if (activeOnly)
criteriaQuery.add(Restrictions.eq("active",new Boolean(true)));
if (sortAscending)
criteriaQuery.addOrder(Order.asc(sortColumn));
else
criteriaQuery.addOrder(Order.desc(sortColumn));
criteriaQuery.setFirstResult(startRow);
criteriaQuery.setMaxResults(endRow-startRow);
}
results = criteriaQuery.list();
}catch(ClassNotFoundException e){
throw new RuntimeException("Domain class name '"+domainClassName+"' cannot be mapped to a runtime class.", e);
}
// Remove these items from the first level cache to avoid non-unique object exceptions if
// Existing standard field lookup is updated in same Hibernate session
for (IStandardFieldLookupProfile item : results)
{
getHibernateTemplate().evict(item);
}
return results;
}
@SuppressWarnings("unchecked")
@Override
public Integer getStandardFieldLookupCount(String domainClassName) {
DetachedCriteria criteria = DetachedCriteria.forEntityName(domainClassName);
criteria.setProjection(Projections.count("code"));
List result = getHibernateTemplate().findByCriteria(criteria);
return ((Number)result.get(0)).intValue();
}
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void delete(ILookupProfile profile) {
getHibernateTemplate().delete(profile);
}
private Criteria createStandardFieldFilterCriteria(Session session,
String domainClassName,
IStandardFieldLookupProfile example,
Boolean activeSetting) {
final Example ex = Example.create(example);
ex.enableLike(MatchMode.START);
ex.ignoreCase();
ex.excludeProperty("active");
Criteria crit = session.createCriteria(domainClassName);
crit.add(ex);
// Limitation in hibernate doesn't consider the primary key when doing query by
// example, so we have to do it ourselves. argh...
if (! Utils.isBlankOrNull(example.getCode())) {
crit.add(Restrictions.ilike("code", example.getCode().toLowerCase() + "%"));
}
if (activeSetting != null) {
crit.add(Restrictions.eq("active", activeSetting));
}
return crit;
}
@Override
public Integer getStandardFieldLookupListCount(
final IStandardFieldLookupProfile example,
final Boolean activeSetting) {
return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException,
SQLException {
Criteria crit = createStandardFieldFilterCriteria(session, example.getClass().getName(), example, activeSetting);
crit.setProjection(Projections.count("id"));
return ((Number)crit.uniqueResult()).intValue();
}
});
}
@Override
@SuppressWarnings("unchecked")
public <T extends IStandardFieldLookupProfile> List<T> getStandardFieldLookupList(
final T example,
final Boolean activeSetting,
final String sortColumn,
final boolean sortAscending,
final int startRow,
final int endRow) {
return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException,
SQLException {
Criteria crit = createStandardFieldFilterCriteria(session, example.getClass().getName(), example, activeSetting);
crit.setFirstResult(startRow);
crit.setMaxResults(endRow-startRow+1);
if (sortAscending) {
crit.addOrder(Order.asc(sortColumn));
}
else {
crit.addOrder(Order.desc(sortColumn));
}
return crit.list();
}
});
}
@Override
public List<IStandardFieldLookupProfile> getStandardFieldLookupList(String domainClassName, String txType, String state) {
try
{
final Class<?> clazz = Class.forName(domainClassName);
final DetachedCriteria dc = DetachedCriteria.forClass(clazz, "field");
/*
* first handle whether the field is to be active or inactive
*/
if(state.equals(State.ACTIVE))
{
dc.add(Property.forName("field.active").eq(Boolean.TRUE));
}
else if(state.equals(State.INACTIVE)) {
dc.add(Property.forName("field.active").eq(Boolean.FALSE));
}
else
{
// return all
}
/*
* then handle whether it's supposed to be MEDICAL or BH
*/
if(txType.equals(TX_TYPE.BH)) {
dc.add(Property.forName("field.behavioralHealth").eq(Boolean.TRUE));
} else if(txType.equals(TX_TYPE.MEDICAL)) {
dc.add(Property.forName("field.behavioralHealth").in(Arrays.asList(new Boolean[]{Boolean.FALSE, null})));
}
return (List<IStandardFieldLookupProfile>) getHibernateTemplate().findByCriteria(dc);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException("Domain class name '"+domainClassName+"' cannot be mapped to a runtime class.", e);
}
}
}