package edu.ualberta.med.biobank.common.action.container; import java.util.ArrayList; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.ualberta.med.biobank.common.action.Action; import edu.ualberta.med.biobank.common.action.ActionContext; import edu.ualberta.med.biobank.common.action.IdResult; import edu.ualberta.med.biobank.common.action.exception.ActionException; import edu.ualberta.med.biobank.common.permission.container.ContainerUpdatePermission; import edu.ualberta.med.biobank.common.util.RowColPos; import edu.ualberta.med.biobank.model.Container; import edu.ualberta.med.biobank.model.ContainerPosition; public class ContainerMoveAction implements Action<IdResult> { private static final long serialVersionUID = 1L; private static Logger log = LoggerFactory .getLogger(ContainerMoveAction.class.getName()); public final Integer containerToMoveId; public final Integer newParentContainerId; public final String newLabel; private ActionContext context; public ContainerMoveAction(Container containerToMove, Container newParentContainer, String newLabel) { if (containerToMove == null) { throw new IllegalArgumentException("Container to move is null"); } if (newParentContainer == null) { throw new IllegalArgumentException( "New parent container to move to is null"); } if (newLabel == null) { throw new IllegalArgumentException("Move to label is null"); } if (log.isDebugEnabled()) { log.debug("containerToMoveId={} newParentId={} newLabel={}", new Object[] { containerToMove.getLabel(), newParentContainer.getLabel(), newLabel }); } this.containerToMoveId = containerToMove.getId(); this.newParentContainerId = newParentContainer.getId(); this.newLabel = newLabel; } @Override public boolean isAllowed(ActionContext context) throws ActionException { return new ContainerUpdatePermission(containerToMoveId) .isAllowed(context) && new ContainerUpdatePermission(newParentContainerId) .isAllowed(context); } @Override public IdResult run(ActionContext context) throws ActionException { this.context = context; // validation tests will tell us if the new position is not empty Container containerToMove = context.load(Container.class, containerToMoveId); Container newParentContainer = context.load(Container.class, newParentContainerId); try { RowColPos position = newParentContainer.getPositionFromLabelingScheme( newLabel.substring(newParentContainer.getLabel() .length())); ContainerActionHelper.setPosition(context, containerToMove, position, newParentContainerId); context.getSession().saveOrUpdate(containerToMove); context.getSession().flush(); log.debug("container " + containerToMoveId + " moved under parent " + newParentContainerId); } catch (ConstraintViolationException e) { ArrayList<String> msgs = new ArrayList<String>(); for (ConstraintViolation<?> cv : e.getConstraintViolations()) { msgs.add(cv.getMessage()); } throw new ActionException(StringUtils.join(msgs.toArray(), "\n")); } catch (Exception e) { throw new ActionException(e); } // update the path information for this container and its children updateContainerAndChildren(containerToMove, newParentContainer); return new IdResult(containerToMoveId); } private void updateContainerAndChildren(Container container, Container parentContainer) { if (context == null) { throw new IllegalStateException("action context not set"); } ContainerActionHelper.updateContainerPathAndLabel(container, parentContainer); context.getSession().saveOrUpdate(container); log.debug("updateContainerAndChildren: containerId={} label={}", container.getId(), container.getLabel()); for (ContainerPosition childPosition : container.getChildPositions()) { updateContainerAndChildren(childPosition.getContainer(), container); } } }