diff --git a/li.strolch.model/src/main/java/li/strolch/model/State.java b/li.strolch.model/src/main/java/li/strolch/model/State.java index 5259f499e..396f8f50e 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/State.java +++ b/li.strolch.model/src/main/java/li/strolch/model/State.java @@ -72,7 +72,7 @@ public enum State { * {@link #EXECUTED} */ public boolean inExecutionPhase() { - return this == EXECUTION || this == STOPPED || this == WARNING || this == ERROR || this == EXECUTED; + return this == EXECUTION || this == STOPPED || this == WARNING || this == ERROR; } /** @@ -135,28 +135,28 @@ public enum State { * @return true if {@link #inExecutionPhase()} but not executed and not already in warning */ public boolean canSetToWarning() { - return inExecutionPhase() && this != State.EXECUTED; + return inExecutionPhase(); } /** * @return true if {@link #inExecutionPhase()} but not executed and not already stopped */ public boolean canSetToStopped() { - return inExecutionPhase() && this != State.EXECUTED; + return inExecutionPhase(); } /** * @return true if {@link #inExecutionPhase()} but not executed and not already in error */ public boolean canSetToError() { - return inExecutionPhase() && this != State.EXECUTED; + return inExecutionPhase(); } /** * @return true if {@link #inExecutionPhase()} but not executed */ public boolean canSetToExecuted() { - return inExecutionPhase() && this != State.EXECUTED; + return inExecutionPhase(); } public static State parse(String s) { @@ -203,9 +203,9 @@ public enum State { } // then execution - else if (childState.inExecutionPhase()) { + else if (childState.inExecutionPhase() || childState == State.EXECUTED) { if (!state.inExecutionWarningPhase()) { - if (state.inExecutionPhase()) + if (state.inExecutionPhase() || state == State.EXECUTED) state = State.min(state, childState); else state = State.EXECUTION; @@ -214,7 +214,7 @@ public enum State { // then planning else if (childState.inPlanningPhase()) { - if (state.inExecutionPhase()) { + if (state.inExecutionPhase() || state == State.EXECUTED) { if (!state.inExecutionWarningPhase()) state = State.EXECUTION; } else { @@ -227,7 +227,7 @@ public enum State { // then created else if (childState.inCreatedPhase()) { - if (state.inExecutionPhase()) { + if (state.inExecutionPhase() || state == State.EXECUTED) { if (!state.inExecutionWarningPhase()) state = State.EXECUTION; } else { diff --git a/li.strolch.service/src/main/java/li/strolch/execution/command/ExecuteStoppedActionCommand.java b/li.strolch.service/src/main/java/li/strolch/execution/command/ExecuteStoppedActionCommand.java new file mode 100644 index 000000000..75f7c78c5 --- /dev/null +++ b/li.strolch.service/src/main/java/li/strolch/execution/command/ExecuteStoppedActionCommand.java @@ -0,0 +1,51 @@ +package li.strolch.execution.command; + +import java.text.MessageFormat; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.exception.StrolchException; +import li.strolch.model.State; +import li.strolch.model.activity.Action; +import li.strolch.model.activity.Activity; +import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.utils.dbc.DBC; + +public class ExecuteStoppedActionCommand extends ExecutionCommand { + + private Action action; + + public ExecuteStoppedActionCommand(ComponentContainer container, StrolchTransaction tx) { + super(container, tx); + } + + public void setAction(Action action) { + this.action = action; + } + + @Override + public void validate() { + DBC.PRE.assertNotNull("action can not be null", this.action); + + if (this.action.getState() != State.STOPPED) { + String msg = "Action {0} is not in state " + State.STOPPED + " and can thus not be put into execution!"; + msg = MessageFormat.format(msg, this.action.getState(), State.ERROR, this.action.getLocator()); + throw new StrolchException(msg); + } + } + + @Override + public void doCommand() { + Activity rootElement = this.action.getRootElement(); + tx().lock(rootElement); + + State currentState = rootElement.getState(); + rootElement.accept(this); + + updateOrderState(rootElement, currentState, rootElement.getState()); + } + + @Override + public void undo() { + // can't undo execution + } +} diff --git a/li.strolch.service/src/main/java/li/strolch/execution/command/ExecutionCommand.java b/li.strolch.service/src/main/java/li/strolch/execution/command/ExecutionCommand.java index 4a1955954..348953172 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/command/ExecutionCommand.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/command/ExecutionCommand.java @@ -89,13 +89,16 @@ public abstract class ExecutionCommand extends Command implements TimeOrderingVi // in series we can never have two Actions in execution, so if we found the action in execution, we stop if (element instanceof Action // && (state == State.EXECUTION // - || state == State.WARNING)) { + || state == State.WARNING // + || state == State.ERROR)) { break; } boolean canExecute = isExecutable(element); if (canExecute) { element.accept(this); + + // in series we stop when the first action is set to execution break; } } @@ -113,6 +116,8 @@ public abstract class ExecutionCommand extends Command implements TimeOrderingVi if (element.getState().isExecuted()) continue; + // in parallel we execute all the actions in the activity + boolean canExecute = isExecutable(element); if (canExecute) { element.accept(this); @@ -132,8 +137,12 @@ public abstract class ExecutionCommand extends Command implements TimeOrderingVi if (state.compareTo(State.EXECUTION) < 0) return true; - // in stopped or error - return state == State.STOPPED || state == State.ERROR; + // in stopped, means we can re-execute + if (state == State.STOPPED) + return true; + + // if in ERROR, then must first be handled + return false; } @Override