package edu.ualberta.med.biobank.common.wrappers.checks;
import java.text.MessageFormat;
import java.util.Collection;
import org.hibernate.Query;
import org.hibernate.Session;
import edu.ualberta.med.biobank.common.util.HibernateUtil;
import edu.ualberta.med.biobank.common.wrappers.ModelWrapper;
import edu.ualberta.med.biobank.common.wrappers.Property;
import edu.ualberta.med.biobank.common.wrappers.actions.WrapperAction;
import edu.ualberta.med.biobank.common.wrappers.util.LazyMessage;
import edu.ualberta.med.biobank.server.applicationservice.exceptions.BiobankSessionException;
import edu.ualberta.med.biobank.server.applicationservice.exceptions.InvalidOptionException;
/**
* Checks that the {@link ModelWrapper}'s wrapped object has a valid value, i.e.
* that the value selected is in the set of legal options.
* <p>
* This check should be performed only <em>if the object being checked is
* persisted</em>. It is easier to do this since the check can be done with HQL.
*
* @author jferland
*
* @param <E>
*/
public class LegalOptionCheck<E> extends WrapperAction<E> {
private static final long serialVersionUID = 1L;
private static final String COUNT_HQL = "SELECT COUNT(option) FROM {0} m JOIN m.{1} option WHERE m = ? AND m.{2} = option"; //$NON-NLS-1$
private final Property<?, ? super E> legalOptions;
private final Property<?, ? super E> selectedOption;
private final LazyMessage exceptionMessage;
/**
*
* @param <T>
* @param wrapper
* @param legalOptions property path to the legal options/ values, from the
* wrapped object
* @param selectedOption property path to the actual selected value, from
* the wrapped object
* @param exceptionMessage message to display if the option is invalid
*/
public <T> LegalOptionCheck(ModelWrapper<E> wrapper,
Property<? extends Collection<? extends T>, ? super E> legalOptions,
Property<? extends T, ? super E> selectedOption,
LazyMessage exceptionMessage) {
super(wrapper);
this.legalOptions = legalOptions;
this.selectedOption = selectedOption;
this.exceptionMessage = exceptionMessage;
}
@Override
public Object doAction(Session session) throws BiobankSessionException {
String hql = MessageFormat.format(COUNT_HQL, getModelClass().getName(),
legalOptions.getName(), selectedOption.getName());
Query query = session.createQuery(hql);
query.setParameter(0, getModel());
Long count = HibernateUtil.getCountFromQuery(query);
if (count <= 0) {
String message = exceptionMessage.format(session);
throw new InvalidOptionException(message);
}
return null;
}
}