package edu.ualberta.med.biobank.common.wrappers.actions;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import edu.ualberta.med.biobank.common.peer.ContainerPeer;
import edu.ualberta.med.biobank.common.peer.ContainerPositionPeer;
import edu.ualberta.med.biobank.common.wrappers.ContainerWrapper;
import edu.ualberta.med.biobank.common.wrappers.Property;
import edu.ualberta.med.biobank.common.wrappers.util.ProxyUtil;
import edu.ualberta.med.biobank.model.Container;
import edu.ualberta.med.biobank.server.applicationservice.exceptions.BiobankSessionException;
public class UpdateContainerChildrenAction extends WrapperAction<Container> {
private static final long serialVersionUID = 1L;
private static final String PATH_DELIMITER =
ContainerWrapper.PATH_DELIMITER;
private static final Property<Container, Container> PARENT_CONTAINER =
ContainerPeer.POSITION
.to(ContainerPositionPeer.PARENT_CONTAINER);
private static final Property<Integer, Container> PARENT_CONTAINER_ID =
PARENT_CONTAINER
.to(ContainerPeer.ID);
private static final Property<String, Container> PARENT_CONTAINER_PATH =
PARENT_CONTAINER
.to(ContainerPeer.PATH);
private static final Property<String, Container> PARENT_CONTAINER_LABEL =
PARENT_CONTAINER
.to(ContainerPeer.LABEL);
// @formatter:off
@SuppressWarnings("nls")
private static final String UPDATE_HQL =
"\nUPDATE " + Container.class.getName() + " o" +
"\n SET o." + ContainerPeer.TOP_CONTAINER.getName() + " = ? " +
"\n ,o." + ContainerPeer.LABEL.getName() + " = ?" +
"\n ,o." + ContainerPeer.PATH.getName() + " = ?" +
"\n WHERE o." + ContainerPeer.ID.getName() + " = ?";
@SuppressWarnings("nls")
private static final String SELECT_CHILDREN_HQL =
"\nSELECT o." + ContainerPeer.ID.getName() +
"\n ,o." + PARENT_CONTAINER_LABEL.getName() +
"\n ,o." + PARENT_CONTAINER_PATH.getName() +
"\n FROM " + Container.class.getName() + " o" +
"\n WHERE o." + PARENT_CONTAINER_ID.getName() + " = ?";
// @formatter:on
private final Container topContainer;
public UpdateContainerChildrenAction(ContainerWrapper wrapper) {
super(wrapper);
this.topContainer = ProxyUtil.convertProxyToObject(wrapper
.getTopContainer().getWrappedObject());
}
@Override
public Object doAction(Session session) throws BiobankSessionException {
Integer id = getModel().getId();
updateChildren(session, id);
return null;
}
private void updateChildren(Session session, Integer parentId)
throws BiobankSessionException {
List<ContainerInfo> children = getChildren(session, parentId);
for (ContainerInfo child : children) {
Integer id = child.getId();
Query query = session.createQuery(UPDATE_HQL);
query.setParameter(0, topContainer);
query.setParameter(1, child.getLabel());
query.setParameter(2, child.getPath());
query.setParameter(3, id);
query.executeUpdate();
updateChildren(session, id);
}
}
private List<ContainerInfo> getChildren(Session session, Integer parentId) {
Query query = session.createQuery(SELECT_CHILDREN_HQL);
query.setParameter(0, parentId);
List<ContainerInfo> children = new ArrayList<ContainerInfo>();
@SuppressWarnings("unchecked")
List<Object[]> results = query.list();
for (Object[] result : results) {
Integer id = (Integer) result[0];
String parentLabel = (String) result[1];
String positionString = (String) result[2];
String parentPath = (String) result[3];
ContainerInfo containerInfo = new ContainerInfo(id, parentLabel,
positionString, parentPath, parentId);
children.add(containerInfo);
}
return children;
}
private static final class ContainerInfo implements Serializable {
private static final long serialVersionUID = 1L;
private final Integer id;
private final String label, path;
public ContainerInfo(Integer id, String parentLabel,
String positionString, String parentPath, Integer parentId) {
this.id = id;
this.label = parentLabel + positionString;
this.path = getPath(parentPath, parentId);
}
public Integer getId() {
return id;
}
public String getLabel() {
return label;
}
public String getPath() {
return path;
}
private static String getPath(String parentPath, Integer parentId) {
StringBuilder path = new StringBuilder();
if (parentPath != null && !parentPath.isEmpty()) {
path.append(parentPath);
path.append(PATH_DELIMITER);
}
path.append(parentId);
return path.toString();
}
}
}