package edu.ualberta.med.biobank.common.reports;
import java.util.Iterator;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.loader.criteria.CriteriaQueryTranslator;
public class ReportsUtil {
// TODO: share this? get from elsewhere?
private static final String PROPERTY_DELIMITER = "."; //$NON-NLS-1$
public static String getId(String aliasedPropertyString) {
AliasedProperty aliasedProperty = getAliasedProperty(aliasedPropertyString);
if (aliasedProperty != null) {
return aliasedProperty.alias + PROPERTY_DELIMITER + "id"; //$NON-NLS-1$
}
return null;
}
public static Disjunction idIsNullOr(String aliasedProperty) {
Disjunction or = Restrictions.disjunction();
String id = getId(aliasedProperty);
if (id != null) {
or.add(Restrictions.isNull(id));
}
return or;
}
public static Criterion isNotSet(String aliasedProperty) {
Disjunction or = Restrictions.disjunction();
String id = getId(aliasedProperty);
if (id != null) {
or.add(Restrictions.isNull(getId(aliasedProperty)));
}
or.add(Restrictions.isNull(aliasedProperty));
return or;
}
private static AliasedProperty getAliasedProperty(String aliasedProperty) {
int lastDelimiter = aliasedProperty.lastIndexOf(PROPERTY_DELIMITER);
if (lastDelimiter != -1) {
String alias = aliasedProperty.substring(0, lastDelimiter);
String propertyName = aliasedProperty.substring(lastDelimiter + 1);
return new AliasedProperty(alias, propertyName);
}
return null;
}
public static String getSqlColumn(Criteria criteria,
String aliasedPropertyString) {
CriteriaQueryTranslator translator = getCriteriaQueryTranslator(criteria);
String alias = null;
String propertyName = aliasedPropertyString;
AliasedProperty aliasedProperty = getAliasedProperty(aliasedPropertyString);
if (aliasedProperty != null) {
alias = aliasedProperty.alias;
propertyName = aliasedProperty.property;
}
Criteria aliasCriteria = criteria;
if (alias != null) {
aliasCriteria = getCriteriaByAlias(criteria, alias);
}
return translator.getColumn(aliasCriteria, propertyName);
}
private static CriteriaQueryTranslator getCriteriaQueryTranslator(
Criteria criteria) {
CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;
SessionImplementor session = ((CriteriaImpl) criteria).getSession();
SessionFactoryImplementor factory = session.getFactory();
String[] implementors = factory.getImplementors(criteriaImpl
.getEntityOrClassName());
return new CriteriaQueryTranslator(factory, (CriteriaImpl) criteria,
implementors[0], CriteriaQueryTranslator.ROOT_SQL_ALIAS);
}
private static Criteria getCriteriaByAlias(Criteria criteria, String alias) {
@SuppressWarnings("rawtypes")
Iterator subcriterias = ((CriteriaImpl) criteria).iterateSubcriteria();
while (subcriterias.hasNext()) {
Criteria subcriteria = (Criteria) subcriterias.next();
if (subcriteria.getAlias().equals(alias)) {
return subcriteria;
}
}
return null;
}
private static class AliasedProperty {
public final String alias;
public final String property;
public AliasedProperty(String alias, String property) {
this.alias = alias;
this.property = property;
}
}
}