package edu.ualberta.med.biobank.common.wrappers.actions; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import edu.ualberta.med.biobank.common.util.HibernateUtil; import edu.ualberta.med.biobank.common.util.StringUtil; import edu.ualberta.med.biobank.common.wrappers.ModelWrapper; import edu.ualberta.med.biobank.common.wrappers.Property; import edu.ualberta.med.biobank.server.applicationservice.exceptions.BiobankSessionException; /** * Counts the number of model objects (of type {@link E}) that have same value * for the given {@link Property}-s of the given model object, * <em>including</em> the given model object. <em>The model object (wrapped by * the given {@link ModelWrapper}) must be saved * (persistent)</em>. * * @author jferland * * @param <E> */ public class PropertyCountAction<E> extends WrapperAction<E> { private static final long serialVersionUID = 1L; private static final String PROPERTIES_EMPTY_ERRMSG = "No properties were given to count. At least one property is required."; //$NON-NLS-1$ private static final String HQL = "SELECT COUNT(*) FROM {0} o WHERE ({1}) = (SELECT {2} FROM {0} o2 WHERE o2 = ?)"; //$NON-NLS-1$ private final Collection<Property<?, ? super E>> properties; /** * * @param wrapper {@link ModelWrapper} which holds the model object * @param properties to ensure uniqueness on */ public PropertyCountAction(ModelWrapper<E> wrapper, Collection<Property<?, ? super E>> properties) { super(wrapper); if (properties == null || properties.isEmpty()) { throw new IllegalArgumentException(PROPERTIES_EMPTY_ERRMSG); } this.properties = properties; } @Override public Long doAction(Session session) throws BiobankSessionException { String modelClassName = getModelClass().getName(); List<String> propertyNames = getPropertyNames(properties); String hqlProperties = StringUtil.join(propertyNames, ", "); //$NON-NLS-1$ List<String> subPropertyNames = getPropertyNames("o2.", properties); //$NON-NLS-1$ String subHqlProperties = StringUtil.join(subPropertyNames, ", "); //$NON-NLS-1$ String hql = MessageFormat.format(HQL, modelClassName, hqlProperties, subHqlProperties); Query query = session.createQuery(hql); query.setParameter(0, getModel()); Long count = HibernateUtil.getCountFromQuery(query); return count; } private List<String> getPropertyNames( Collection<Property<?, ? super E>> properties) { return getPropertyNames("", properties); //$NON-NLS-1$ } private List<String> getPropertyNames(String prefix, Collection<Property<?, ? super E>> properties) { List<String> names = new ArrayList<String>(); for (Property<?, ?> property : properties) { names.add(prefix + property.getName()); } return names; } }