package org.molgenis.protocol.service; import java.io.Serializable; import java.text.ParseException; import java.util.ArrayList; import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.molgenis.framework.db.Database; import org.molgenis.framework.db.DatabaseException; import org.molgenis.framework.db.jdbc.JDBCDatabase; import org.molgenis.framework.db.jpa.JpaDatabase; import org.molgenis.protocol.Workflow; import org.molgenis.protocol.WorkflowElement; import org.molgenis.util.Tuple; public class WorkflowService implements Serializable { private static final long serialVersionUID = -262659898183648343L; private Database db = null; public void setDatabase(Database db) { this.db = db; } /** * Find workflow elements in the order they have been specified inside a * workflow * * @param workflow * @return workflow elements * @throws DatabaseException * @throws ParseException */ public List<WorkflowElement> findWorkflowElements(Workflow workflow) throws DatabaseException, ParseException { List<WorkflowElement> result = new ArrayList<WorkflowElement>(); List<Integer> weIds = new ArrayList<Integer>(); List<WorkflowElement> elements; String sql = "SELECT DISTINCT we.id FROM WorkflowElement we JOIN WorkflowElement_Workflow wew ON (we.id = wew.WorkflowElement) LEFT JOIN WorkflowElement_PreviousSteps wep ON (we.id = wep.WorkflowElement) WHERE wep.WorkflowElement IS NULL AND wew.Workflow = " + workflow.getId(); if (this.db instanceof JDBCDatabase) { List<Tuple> ids = ((JDBCDatabase) this.db).sql(sql); for (Tuple entry : ids) weIds.add(entry.getInt(0)); } else if (this.db instanceof JpaDatabase) { weIds = this.db.getEntityManager().createNativeQuery(sql).getResultList(); } else throw new UnsupportedOperationException("Unsupported database mapper"); elements = this.db.query(WorkflowElement.class).in(WorkflowElement.ID, weIds).find(); while (CollectionUtils.isNotEmpty(elements)) { result.addAll(elements); elements = this.findNextWorkflowElements(elements); } return result; } /** * Helper to select the next following WorkflowElements, i.e. where the * previous steps are the current ones * * @param elements * @return List of next WorkflowElements * @throws DatabaseException * @throws ParseException */ private List<WorkflowElement> findNextWorkflowElements(List<WorkflowElement> elements) throws DatabaseException, ParseException { List<WorkflowElement> nextElements = new ArrayList<WorkflowElement>(); for (WorkflowElement element : elements) { List<Integer> weIds = new ArrayList<Integer>(); String sql = "SELECT WorkflowElement FROM WorkflowElement_PreviousSteps WHERE PreviousSteps = " + element.getId(); if (this.db instanceof JDBCDatabase) { List<Tuple> ids = ((JDBCDatabase) this.db).sql(sql); for (Tuple entry : ids) weIds.add(entry.getInt(0)); } else if (this.db instanceof JpaDatabase) { weIds = this.db.getEntityManager().createNativeQuery(sql).getResultList(); } else throw new UnsupportedOperationException("Unsupported database mapper"); if (weIds.size() > 0) nextElements.addAll(this.db.query(WorkflowElement.class) .in(WorkflowElement.ID, weIds).find()); } return nextElements; } }