diff --git a/process-analyzer-demo/.settings/org.eclipse.m2e.core.prefs b/process-analyzer-demo/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 00000000..14b697b7 --- /dev/null +++ b/process-analyzer-demo/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/process-analyzer-test/.settings/org.eclipse.m2e.core.prefs b/process-analyzer-test/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 00000000..14b697b7 --- /dev/null +++ b/process-analyzer-test/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/process-analyzer/.settings/org.eclipse.m2e.core.prefs b/process-analyzer/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 00000000..14b697b7 --- /dev/null +++ b/process-analyzer/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/PathFinder.java b/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/PathFinder.java index e62c2342..cab33af2 100644 --- a/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/PathFinder.java +++ b/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/PathFinder.java @@ -27,6 +27,7 @@ import com.axonivy.utils.process.analyzer.internal.model.AnalysisPath; import com.axonivy.utils.process.analyzer.internal.model.CommonElement; import com.axonivy.utils.process.analyzer.internal.model.ProcessElement; +import com.axonivy.utils.process.analyzer.internal.model.SubProcessGroup; import com.axonivy.utils.process.analyzer.internal.model.TaskParallelGroup; import ch.ivyteam.ivy.environment.Ivy; @@ -344,8 +345,11 @@ private List findAnalysisPaths(ProcessElement from, String flowNam if (from.getElement() instanceof NodeElement) { if (from.getElement() instanceof EmbeddedProcessElement) { - List pathFromSubProcess = findPathOfSubProcess(from, flowName, findType); - path = addToPath(path, pathFromSubProcess); + SubProcessGroup subProcessGroup = findPathOfSubProcess(from, flowName, findType); + + path = removeLastElementByClassType(path, EmbeddedProcessElement.class); + + path = addAllToPath(path, List.of(subProcessGroup)); } if (isJoinTaskSwitchGateway(currentPath, from)) { @@ -356,7 +360,7 @@ private List findAnalysisPaths(ProcessElement from, String flowNam var taskParallelGroup = getTaskParallelGroup(from, flowName, findType, currentPath); // If last element is CommonElement(TaskSwitchGateway)-> We will remove it. - path = removeLastTaskSwitchGateway(path); + path = removeLastElementByClassType(path, TaskSwitchGateway.class); path = addAllToPath(path, List.of(taskParallelGroup)); from = getJoinTaskSwithGateWay(taskParallelGroup); @@ -387,21 +391,24 @@ private List findAnalysisPaths(ProcessElement from, String flowNam return path; } - private List removeLastTaskSwitchGateway(List paths) { + + private List removeLastElementByClassType(List paths , Class clazz) { List result = new ArrayList<>(); for (AnalysisPath path : paths) { int lastIndex = getLastIndex(path.getElements()); List pathElements = new ArrayList<>(path.getElements()); - if (pathElements.get(lastIndex) instanceof CommonElement - && pathElements.get(lastIndex).getElement() instanceof TaskSwitchGateway) { + ProcessElement lastElement = pathElements.get(lastIndex); + + if (lastElement instanceof CommonElement && clazz.isInstance(lastElement.getElement())) { pathElements.remove(lastIndex); } + result.add(new AnalysisPath(pathElements)); } return result; } - + private List addToPath(List paths, List subPaths) { if (subPaths.isEmpty()) { return paths; @@ -493,12 +500,15 @@ private TaskParallelGroup getTaskParallelGroup(ProcessElement from, String flowN /** * Find path on sub process */ - private List findPathOfSubProcess(ProcessElement subProcessElement, String flowName, + private SubProcessGroup findPathOfSubProcess(ProcessElement subProcessElement, String flowName, FindType findType) throws Exception { EmbeddedProcessElement processElement = (EmbeddedProcessElement) subProcessElement.getElement(); BaseElement start = processGraph.findOneStartElementOfProcess(processElement.getEmbeddedProcess()); List path = findAnalysisPaths(new CommonElement(start), flowName, findType, emptyList()); - return path; + + SubProcessGroup subProcessGroup = new SubProcessGroup(processElement); + subProcessGroup.setInternalPaths(path); + return subProcessGroup; } private List getSequenceFlows(NodeElement from, String flowName, FindType findType) throws Exception { diff --git a/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/WorkflowPath.java b/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/WorkflowPath.java index a3f9f50c..6fb5afe6 100644 --- a/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/WorkflowPath.java +++ b/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/WorkflowPath.java @@ -21,6 +21,7 @@ import com.axonivy.utils.process.analyzer.internal.model.AnalysisPath; import com.axonivy.utils.process.analyzer.internal.model.CommonElement; import com.axonivy.utils.process.analyzer.internal.model.ProcessElement; +import com.axonivy.utils.process.analyzer.internal.model.SubProcessGroup; import com.axonivy.utils.process.analyzer.internal.model.TaskParallelGroup; import com.axonivy.utils.process.analyzer.model.DetectedAlternative; import com.axonivy.utils.process.analyzer.model.DetectedElement; @@ -133,7 +134,8 @@ private List convertPathToDetectedElements(ProcessElement start continue; } - if (processGraph.isTaskAndCaseModifier(element.getElement()) + if (element instanceof CommonElement + && processGraph.isTaskAndCaseModifier(element.getElement()) && processGraph.isSystemTask(element.getElement())) { continue; } @@ -170,6 +172,24 @@ private List convertPathToDetectedElements(ProcessElement start continue; } + if (element instanceof SubProcessGroup) { + List subPaths = ((SubProcessGroup) element).getInternalPaths(); + List allTaskFromSubPath = new ArrayList<>(); + for(AnalysisPath subPath : subPaths) { + ProcessElement startSubElement = subPath.getElements().get(0); + var startedForSubProcess = Map.of(startSubElement, durationStart); + List subResult = convertPathToDetectedElements(startSubElement, subPath, useCase , startedForSubProcess); + allTaskFromSubPath.addAll(subResult); + } + + if(isNotEmpty(allTaskFromSubPath)) { + result.addAll(allTaskFromSubPath); + durationStart = getMaxDurationUntilEnd(allTaskFromSubPath); + } + + continue; + } + if (element instanceof TaskParallelGroup) { var startedForGroup = element.getElement() == null ? timeUntilStarts : Map.of(element, durationStart); diff --git a/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/model/SubProcessGroup.java b/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/model/SubProcessGroup.java new file mode 100644 index 00000000..296f253e --- /dev/null +++ b/process-analyzer/src/com/axonivy/utils/process/analyzer/internal/model/SubProcessGroup.java @@ -0,0 +1,62 @@ +package com.axonivy.utils.process.analyzer.internal.model; + +import static org.apache.commons.lang3.StringUtils.EMPTY; + +import java.util.List; +import java.util.Objects; + +import ch.ivyteam.ivy.process.model.BaseElement; +import ch.ivyteam.ivy.process.model.value.PID; + +public class SubProcessGroup implements ProcessElement { + private BaseElement element; + List internalPaths; + + public SubProcessGroup(BaseElement element) { + this.element = element; + } + + public List getInternalPaths() { + return internalPaths; + } + + public void setInternalPaths(List internalPaths) { + this.internalPaths = internalPaths; + } + + @Override + public int hashCode() { + return Objects.hash(this.element, this.internalPaths); + } + + @Override + public String toString() { + return String.format("%s : %s ", Objects.toString(element, EMPTY), Objects.toString(internalPaths, EMPTY)); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + if (!(other instanceof SubProcessGroup)) { + return false; + } + SubProcessGroup task = (SubProcessGroup) other; + return Objects.equals(task.element, this.element) && Objects.equals(task.internalPaths, this.internalPaths); + } + + @Override + public PID getPid() { + return element.getPid(); + } + + @Override + public BaseElement getElement() { + return element; + } + +}