package sushi.bpmn.element; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.EntityTransaction; import javax.persistence.FetchType; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.ManyToMany; import javax.persistence.Query; import javax.persistence.Table; import sushi.bpmn.decomposition.Component; import sushi.bpmn.monitoringpoint.MonitoringPoint; import sushi.persistence.Persistable; import sushi.persistence.Persistor; import sushi.process.SushiProcess; /** * This class is a logical representation of a BPMN process. * @author micha */ /** * @author micha * */ @Entity @Table(name = "BPMNProcess") @Inheritance(strategy=InheritanceType.JOINED) public class BPMNProcess extends AbstractBPMNElement { private static final long serialVersionUID = 1L; @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER) private List<AbstractBPMNElement> BPMNElements = new ArrayList<AbstractBPMNElement>(); public BPMNProcess() { super(); } public BPMNProcess(String ID, String name, List<MonitoringPoint> monitoringPoints) { super(ID, name, monitoringPoints); } public boolean isProcess() { return true; } public void addBPMNElements(List<AbstractBPMNElement> elements) { BPMNElements.addAll(elements); } public void addBPMNElement(AbstractBPMNElement element) { if (element != null && !(BPMNElements.contains(element))) { BPMNElements.add(element); } } public void removeBPMNElements(Collection<AbstractBPMNElement> elements) { BPMNElements.removeAll(elements); } public void removeBPMNElement(AbstractBPMNElement element) { BPMNElements.remove(element); } public List<AbstractBPMNElement> getBPMNElements() { return BPMNElements; } public List<AbstractBPMNElement> getBPMNElementsWithOutSequenceFlows() { List<AbstractBPMNElement> elements = new ArrayList<AbstractBPMNElement>(); for(AbstractBPMNElement element : BPMNElements){ if(!(element instanceof BPMNSequenceFlow)){ elements.add(element); } } return elements; } /** * Return all activities({@link BPMNTask}), which are contained in this process. * @return */ public List<BPMNTask> getAllTasks() { List<BPMNTask> elements = new ArrayList<BPMNTask>(); for(AbstractBPMNElement element : this.getBPMNElementsWithOutSequenceFlows()){ if(element instanceof BPMNTask){ elements.add((BPMNTask) element); } } return elements; } /** * Returns all {@link Component}s, which are contained in this process. * @return */ public List<Component> getAllComponents() { List<Component> elements = new ArrayList<Component>(); for(AbstractBPMNElement element : this.getBPMNElementsWithOutSequenceFlows()){ if(element instanceof Component){ elements.add((Component) element); } } return elements; } /** * Returns a list of all BPMN-IDs of the contained elements. * @return */ public ArrayList<String> getBPMNElementIDs() { ArrayList<String> ids = new ArrayList<String>(); for (AbstractBPMNElement element : BPMNElements) { ids.add(element.getId()); } return ids; } public AbstractBPMNElement getBPMNElementById(String ID) { for (AbstractBPMNElement element : BPMNElements) { if (element.getId().equals(ID)) { return element; } } return null; } public AbstractBPMNElement getBPMNElementByName(String name) { for (AbstractBPMNElement element : BPMNElements) { if (element.getName().equals(name)) { return element; } } return null; } /** * Returns the start event for a process. * @return */ public BPMNStartEvent getStartEvent() { for (AbstractBPMNElement element : BPMNElements) { if (element instanceof BPMNStartEvent) { return (BPMNStartEvent) element; } } return null; } /** * Returns all start events for a process. * @return */ public List<BPMNStartEvent> getStartEvents() { List<BPMNStartEvent> startEvents = new ArrayList<BPMNStartEvent>(); for (AbstractBPMNElement element : BPMNElements) { if (element instanceof BPMNStartEvent) { startEvents.add((BPMNStartEvent) element); } } return startEvents; } /** * Returns the end event for a process. * @return */ public BPMNEndEvent getEndEvent() { for (AbstractBPMNElement element : BPMNElements) { if (element instanceof BPMNEndEvent) { return (BPMNEndEvent) element; } } return null; } /** * Returns all end events for a process. * @return */ public List<BPMNEndEvent> getEndEvents() { List<BPMNEndEvent> endEvents = new ArrayList<BPMNEndEvent>(); for (AbstractBPMNElement element : BPMNElements) { if (element instanceof BPMNEndEvent) { endEvents.add((BPMNEndEvent) element); } } return endEvents; } public AbstractBPMNElement getNextElementFor(AbstractBPMNElement element) { // lookForSequenceFlow for (AbstractBPMNElement flow : BPMNElements) { if (flow.isSequenceFlow()) { BPMNSequenceFlow seqflow = (BPMNSequenceFlow) flow; if (seqflow.getSourceRef().equals(element.getId())) { return getBPMNElementById(seqflow.getTargetRef()); } } } // lookForEvents return getAttachedElementsFor(element); } private AbstractBPMNElement getAttachedElementsFor(AbstractBPMNElement element) { for (AbstractBPMNElement el : BPMNElements) { if (el.isBoundaryEvent()) { BPMNBoundaryEvent event = (BPMNBoundaryEvent) el; if (event.getAttachedToElement().getId().equals(element.getId())) { return event; } } } return null; } public String printProcess() { return printProcess(this); } /** * This method returns a textual representation of all process elements and their monitoring points. * @param process * @return */ public String printProcess(BPMNProcess process) { StringBuffer output = new StringBuffer(); Collection<AbstractBPMNElement> elements = new ArrayList<>(); if(process.getStartEvent() != null){ elements.add(process.getStartEvent()); elements.addAll(process.getStartEvent().getIndirectSuccessors()); } else { elements = process.getBPMNElementsWithOutSequenceFlows(); } for(AbstractBPMNElement element : elements){ output.append(element.toString()); output.append(System.getProperty("line.separator")); for (MonitoringPoint monitoringPoint : element.getMonitoringPoints()) { output.append("[Monitoring Point] " + monitoringPoint.toString()); output.append(System.getProperty("line.separator")); } if(element instanceof BPMNSubProcess){ output.append(printProcess((BPMNSubProcess)element)); } } return output.toString(); } /** * Returns all {@link BPMNProcess}es from the database, which have the specified ID. * @return */ public static BPMNProcess findByID(int ID){ List<BPMNProcess> list = BPMNProcess.findByAttribute("ID", new Integer(ID).toString()); if(list.size() > 0){ return list.get(0); } else { return null; } } /** * Returns all {@link BPMNProcess}es from the database, which have the specified name. * @return */ @SuppressWarnings("unchecked") public static List<BPMNProcess> findByName(String name){ Query query = Persistor.getEntityManager().createNativeQuery("" + "SELECT * " + "FROM BPMNElement " + "WHERE ID IN (" + " SELECT RESULT.ID " + " FROM (" + " SELECT * " + " FROM BPMNElement AS SELECTEDBPMNELEMENT " + " WHERE ID IN (" + " SELECT ID " + " FROM BPMNProcess AS SELECTEDBPMNPROCESS)) AS RESULT" + " WHERE RESULT.NAME ='" + name + "')", BPMNProcess.class); return query.getResultList(); } /** * Returns all {@link BPMNProcess}es from the database, which have the specified attribute and value. * @return */ @SuppressWarnings("unchecked") public static List<BPMNProcess> findByAttribute(String columnName, String value){ Query query = Persistor.getEntityManager().createNativeQuery("SELECT * FROM BPMNProcess WHERE " + columnName + " = '" + value + "'", BPMNProcess.class); return query.getResultList(); } /** * Returns all {@link BPMNProcess}es from the database. * @return */ @SuppressWarnings("unchecked") public static List<BPMNProcess> findAll() { Query q = Persistor.getEntityManager().createQuery("select t from BPMNProcess t"); return q.getResultList(); } /** * Removes all {@link BPMNProcess}es from the database. */ public static void removeAll() { try { EntityTransaction entr = Persistor.getEntityManager().getTransaction(); entr.begin(); Query query = Persistor.getEntityManager().createQuery("DELETE FROM BPMNProcess"); int deleteRecords = query.executeUpdate(); entr.commit(); System.out.println(deleteRecords + " records are deleted."); } catch (Exception ex) { System.out.println(ex.getMessage()); } } /** * Returns all split gateways, contained in this {@link BPMNProcess}. * @return */ public List<AbstractBPMNGateway> getAllSplitGateways() { List<AbstractBPMNGateway> elements = new ArrayList<AbstractBPMNGateway>(); for(AbstractBPMNElement element : this.getBPMNElementsWithOutSequenceFlows()){ if(element instanceof AbstractBPMNGateway && ((AbstractBPMNGateway) element).isSplitGateway()){ elements.add((AbstractBPMNGateway) element); } } return elements; } /** * Returns all joining gateways, contained in this {@link BPMNProcess}. * @return */ public List<AbstractBPMNGateway> getAllJoinGateways() { List<AbstractBPMNGateway> elements = new ArrayList<AbstractBPMNGateway>(); for(AbstractBPMNElement element : this.getBPMNElementsWithOutSequenceFlows()){ if(element instanceof AbstractBPMNGateway && ((AbstractBPMNGateway) element).isJoinGateway()){ elements.add((AbstractBPMNGateway) element); } } return elements; } @Override public Persistable remove() { SushiProcess process = SushiProcess.findByBPMNProcess(this); if (process != null){ process.setBpmnProcess(null); process.merge(); } return super.remove(); } public boolean hasSubProcesses() { for (AbstractBPMNElement element : BPMNElements) { if (element instanceof BPMNSubProcess) { return true; } } return false; } /** * Returns the contained {@link BPMNSubProcess}es, if any. * @return */ public List<BPMNSubProcess> getSubProcesses() { List<BPMNSubProcess> subProcesses = new ArrayList<BPMNSubProcess>(); for (AbstractBPMNElement element : BPMNElements) { if (element instanceof BPMNSubProcess) { subProcesses.add((BPMNSubProcess) element); } } return subProcesses; } public List<AbstractBPMNElement> getSubElementsWithMonitoringpoints(){ List<AbstractBPMNElement> subElementsWithMonitoringpoints = new ArrayList<AbstractBPMNElement>(); for(AbstractBPMNElement subElement : BPMNElements){ if(subElement.hasMonitoringPoints()){ subElementsWithMonitoringpoints.add(subElement); } } return subElementsWithMonitoringpoints; } public static boolean exists(String name) { return !BPMNProcess.findByName(name).isEmpty(); } /** * Searches in all saved {@link BPMNProcess}es for one, which contains the given {@link AbstractBPMNElement}. * @param bpmnElement * @return */ public static BPMNProcess findByContainedElement(AbstractBPMNElement bpmnElement) { for(BPMNProcess process : BPMNProcess.findAll()){ for(AbstractBPMNElement element : process.getBPMNElementsWithOutSequenceFlows()){ if(element.getID() == bpmnElement.getID()){ return process; } } } return null; } }