package edu.ualberta.med.biobank.test.action; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Restrictions; import edu.ualberta.med.biobank.common.action.Action; import edu.ualberta.med.biobank.common.action.ActionContext; import edu.ualberta.med.biobank.common.action.ActionResult; import edu.ualberta.med.biobank.common.action.exception.AccessDeniedException; import edu.ualberta.med.biobank.common.action.exception.ActionException; import edu.ualberta.med.biobank.model.User; import edu.ualberta.med.biobank.test.SessionProvider; public class LocalActionExecutor implements IActionExecutor { private final SessionProvider sessionProvider; private Integer userId; public LocalActionExecutor(SessionProvider sessionProvider) { this.sessionProvider = sessionProvider; } @Override public void setUserId(Integer userId) { this.userId = userId; } @Override public Integer getUserId() { return userId; } @Override public <T extends ActionResult> T exec(Action<T> action) throws ActionException { // to behave like we sent this action to the server, we must open a new // session and close it before and after this action is executed, every // time. The User object should also be loaded fresh from the database. Session session = sessionProvider.openSession(); Transaction transaction = session.beginTransaction(); try { User user = (User) session.createCriteria(User.class) .add(Restrictions.eq("id", userId)) .list().iterator().next(); ActionContext context = new ActionContext(user, session, null); if (!action.isAllowed(context)) throw new AccessDeniedException(); T result = action.run(context); transaction.commit(); return result; } catch (RuntimeException e) { transaction.rollback(); throw e; } finally { session.clear(); session.close(); } } }