diff --git a/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java b/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java index 47b60edbf..6e77ab354 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java +++ b/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java @@ -396,7 +396,10 @@ public class ModelGenerator { subSubActivity.addParameterBag(bag); subActivity.addElement(subSubActivity); - action = createAction("action_" + id, "Action " + name, "Use"); + action = createAction("action1_" + id, "Action " + name, "Use"); + subSubActivity.addElement(action); + + action = createAction("action2_" + id, "Action " + name, "Use"); subSubActivity.addElement(action); rootActivity.setPolicyDefs(createPolicyDefs()); 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 c069a57e3..041681190 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 @@ -15,7 +15,15 @@ */ package li.strolch.model; +import java.util.Iterator; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import li.strolch.exception.StrolchException; +import li.strolch.model.activity.Activity; +import li.strolch.model.activity.IActivityElement; import li.strolch.utils.dbc.DBC; /** @@ -28,9 +36,13 @@ public enum State { PLANNED("Planned"), //$NON-NLS-1$ EXECUTION("Execution"), //$NON-NLS-1$ STOPPED("Stopped"), //$NON-NLS-1$ + WARNING("Warning"), //$NON-NLS-1$ + ERROR("Error"), //$NON-NLS-1$ EXECUTED("Executed"), //$NON-NLS-1$ CLOSED("Closed"); //$NON-NLS-1$ + private static final Logger logger = LoggerFactory.getLogger(State.class); + private String state; private State(String state) { @@ -41,6 +53,42 @@ public enum State { return this.state; } + /** + * @return true if the state is {@link #CREATED} + */ + public boolean inCreatedPhase() { + return this == CREATED; + } + + /** + * @return true if the state is one of {@link #PLANNING} or {@link #PLANNED} + */ + public boolean inPlanningPhase() { + return this == PLANNING || this == PLANNED; + } + + /** + * @return true if the state is one of {@link #EXECUTION}, {@link #STOPPED}, {@link #WARNING}, {@link #ERROR} or + * {@link #EXECUTED} + */ + public boolean inExecutionPhase() { + return this == EXECUTION || this == STOPPED || this == WARNING || this == ERROR || this == EXECUTED; + } + + /** + * @return true if the state is one of {@link #STOPPED}, {@link #WARNING} or {@link #ERROR} + */ + public boolean inExecutionWarningPhase() { + return this == STOPPED || this == WARNING || this == ERROR; + } + + /** + * @return true if the state is {@link #CLOSED} + */ + public boolean inClosedPhase() { + return this == CLOSED; + } + public static State parse(String s) { DBC.PRE.assertNotEmpty("Value may not be null", s); for (State state : values()) { @@ -50,4 +98,87 @@ public enum State { throw new StrolchException("No State for " + s); } + + public static State max(State state1, State state2) { + return state1.ordinal() >= state2.ordinal() ? state1 : state2; + } + + public static State min(State state1, State state2) { + return state1.ordinal() <= state2.ordinal() ? state1 : state2; + } + + public static State getState(Activity activity) { + + Iterator> elementIterator = activity.elementIterator(); + + IActivityElement first = elementIterator.next().getValue(); + State state = first.getState(); + + while (elementIterator.hasNext()) { + IActivityElement child = elementIterator.next().getValue(); + State childState = child.getState(); + + // error trumps all + if (childState == State.ERROR) { + state = State.ERROR; + break; + } + + // then in execution warning + if (childState.inExecutionWarningPhase()) { + if (state.inExecutionWarningPhase()) + state = State.max(state, childState); + else + state = childState; + } + + // then execution + else if (childState.inExecutionPhase()) { + if (!state.inExecutionWarningPhase()) { + if (state.inExecutionPhase()) + state = State.min(state, childState); + else + state = State.EXECUTION; + } + } + + // then planning + else if (childState.inPlanningPhase()) { + if (state.inExecutionPhase()) { + if (!state.inExecutionWarningPhase()) + state = State.EXECUTION; + } else { + if (state.inPlanningPhase()) + state = State.min(state, childState); + else if ((state.inClosedPhase() || state.inCreatedPhase()) && childState.inPlanningPhase()) + state = State.PLANNING; + } + } + + // then created + else if (childState.inCreatedPhase()) { + if (state.inExecutionPhase()) { + if (!state.inExecutionWarningPhase()) + state = State.EXECUTION; + } else { + if (state.inPlanningPhase()) { + state = State.PLANNING; + } + } + } + + // then closed + else if (childState.inClosedPhase()) { + state = State.min(state, childState); + } + + // should never occur + else { + logger.warn("Else case for getState() child: " + child.getLocator() + " childState: " + childState + + " state: " + state); + } + } + + return state; + } } diff --git a/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java b/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java index 2b94f4b1b..0ea3e5327 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java +++ b/li.strolch.model/src/main/java/li/strolch/model/activity/Activity.java @@ -28,7 +28,6 @@ import li.strolch.model.GroupedParameterizedElement; import li.strolch.model.Locator; import li.strolch.model.Locator.LocatorBuilder; import li.strolch.model.State; -import li.strolch.model.StrolchElement; import li.strolch.model.StrolchRootElement; import li.strolch.model.Tags; import li.strolch.model.Version; @@ -223,18 +222,9 @@ public class Activity extends GroupedParameterizedElement @Override public State getState() { - State state = State.CREATED; - if (this.elements == null) - return state; - Iterator> elementIterator = elementIterator(); - while (elementIterator.hasNext()) { - IActivityElement child = elementIterator.next().getValue(); - State childState = child.getState(); - if (childState.ordinal() < state.ordinal()) { - state = childState; - } - } - return state; + if (this.elements == null || this.elements.isEmpty()) + return State.CREATED; + return State.getState(this); } @Override @@ -272,7 +262,7 @@ public class Activity extends GroupedParameterizedElement } @Override - public StrolchElement getParent() { + public Activity getParent() { return this.parent; } diff --git a/li.strolch.model/src/main/java/li/strolch/model/activity/IActivityElement.java b/li.strolch.model/src/main/java/li/strolch/model/activity/IActivityElement.java index e6a4e20b2..2d807c762 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/activity/IActivityElement.java +++ b/li.strolch.model/src/main/java/li/strolch/model/activity/IActivityElement.java @@ -33,9 +33,15 @@ public interface IActivityElement extends StrolchElement { public State getState(); public void setParent(Activity activity); - - public void accept(IActivityElementVisitor visitor); + + @Override + public Activity getParent(); + + @Override + public Activity getRootElement(); @Override public IActivityElement getClone(); + + public void accept(IActivityElementVisitor visitor); } diff --git a/li.strolch.model/src/main/resources/StrolchModel-1.4.xsd b/li.strolch.model/src/main/resources/StrolchModel-1.4.xsd index 1576c1dea..950fe1bce 100644 --- a/li.strolch.model/src/main/resources/StrolchModel-1.4.xsd +++ b/li.strolch.model/src/main/resources/StrolchModel-1.4.xsd @@ -145,6 +145,8 @@ + + diff --git a/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java b/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java index b2c94a4c0..e59856b1f 100644 --- a/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java +++ b/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java @@ -94,7 +94,7 @@ public class ActivityTest { @Test public void testState() { - Assert.assertEquals(State.CREATED, this.activity.getState()); + Assert.assertEquals(State.PLANNING, this.activity.getState()); } @Test(expected = StrolchException.class) diff --git a/li.strolch.model/src/test/java/li/strolch/model/activity/StateTest.java b/li.strolch.model/src/test/java/li/strolch/model/activity/StateTest.java new file mode 100644 index 000000000..367d153fa --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/activity/StateTest.java @@ -0,0 +1,404 @@ +package li.strolch.model.activity; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Before; +import org.junit.Test; + +import li.strolch.model.ModelGenerator; +import li.strolch.model.State; + +public class StateTest { + + private Activity activity; + private Activity subActivity; + private Activity subSubActivity; + private Action action; + private Action subAction; + private Action subSubAction1; + private Action subSubAction2; + + @Before + public void before() { + + this.activity = ModelGenerator.createActivity("1", "Activity 1", "ToStock", TimeOrdering.SERIES); + assertNotNull(this.activity); + + this.action = this.activity.getElement("action_1"); + assertNotNull(this.action); + + this.subActivity = this.activity.getElement("sub_1"); + assertNotNull(this.subActivity); + + this.subAction = this.subActivity.getElement("action_1"); + assertNotNull(this.subAction); + + this.subSubActivity = this.subActivity.getElement("subSub_1"); + assertNotNull(this.subSubActivity); + + this.subSubAction1 = this.subSubActivity.getElement("action1_1"); + assertNotNull(this.subSubAction1); + + this.subSubAction2 = this.subSubActivity.getElement("action2_1"); + assertNotNull(this.subSubAction2); + } + + @Test + public void shouldTestCreated() { + assertEquals(State.CREATED, this.activity.getState()); + + this.action.setState(State.PLANNED); + assertEquals(State.PLANNING, this.activity.getState()); + + this.subAction.setState(State.EXECUTED); + assertEquals(State.CREATED, this.subSubActivity.getState()); + } + + @Test + public void shouldTestPlanning() { + + this.action.setState(State.PLANNED); + assertEquals(State.PLANNING, this.activity.getState()); + + this.action.setState(State.PLANNING); + assertEquals(State.PLANNING, this.activity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.PLANNING); + this.subSubAction1.setState(State.PLANNING); + assertEquals(State.PLANNING, this.activity.getState()); + + this.subSubAction1.setState(State.CREATED); + assertEquals(State.PLANNING, this.activity.getState()); + assertEquals(State.PLANNING, this.subActivity.getState()); + assertEquals(State.CREATED, this.subSubActivity.getState()); + } + + @Test + public void shouldTestPlanned() { + + this.action.setState(State.PLANNED); + this.subAction.setState(State.PLANNING); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.PLANNING, this.activity.getState()); + assertEquals(State.PLANNING, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.PLANNING); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNING); + + assertEquals(State.PLANNING, this.activity.getState()); + assertEquals(State.PLANNING, this.subActivity.getState()); + assertEquals(State.PLANNING, this.subSubActivity.getState()); + } + + @Test + public void shouldTestExecution() { + + this.action.setState(State.EXECUTION); + this.subAction.setState(State.PLANNING); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.PLANNING, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTION); + this.subAction.setState(State.EXECUTION); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.EXECUTION); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNING); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.PLANNING, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.PLANNED); + this.subSubAction1.setState(State.EXECUTION); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.PLANNED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.EXECUTION); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.EXECUTED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTED, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.EXECUTED); + + assertEquals(State.EXECUTED, this.activity.getState()); + assertEquals(State.EXECUTED, this.subActivity.getState()); + assertEquals(State.EXECUTED, this.subSubActivity.getState()); + + this.action.setState(State.CREATED); + this.subAction.setState(State.CREATED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.EXECUTED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTED, this.subSubActivity.getState()); + + this.action.setState(State.CREATED); + this.subAction.setState(State.CREATED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.CREATED); + this.subAction.setState(State.CREATED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.EXECUTED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTED, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.PLANNING); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + } + + @Test + public void shouldTestWarning() { + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.WARNING); + + assertEquals(State.WARNING, this.activity.getState()); + assertEquals(State.WARNING, this.subActivity.getState()); + assertEquals(State.WARNING, this.subSubActivity.getState()); + + this.action.setState(State.WARNING); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.EXECUTED); + + assertEquals(State.WARNING, this.activity.getState()); + assertEquals(State.EXECUTED, this.subActivity.getState()); + assertEquals(State.EXECUTED, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTION); + this.subAction.setState(State.WARNING); + this.subSubAction1.setState(State.EXECUTION); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.WARNING, this.activity.getState()); + assertEquals(State.WARNING, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.WARNING); + this.subSubAction1.setState(State.EXECUTION); + this.subSubAction2.setState(State.EXECUTION); + + assertEquals(State.WARNING, this.activity.getState()); + assertEquals(State.WARNING, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + } + + @Test + public void shouldTestError() { + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.ERROR); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.ERROR, this.activity.getState()); + assertEquals(State.ERROR, this.subActivity.getState()); + assertEquals(State.ERROR, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.ERROR); + this.subSubAction1.setState(State.WARNING); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.ERROR, this.activity.getState()); + assertEquals(State.ERROR, this.subActivity.getState()); + assertEquals(State.WARNING, this.subSubActivity.getState()); + + this.action.setState(State.ERROR); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.ERROR, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTION); + this.subAction.setState(State.ERROR); + this.subSubAction1.setState(State.EXECUTION); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.ERROR, this.activity.getState()); + assertEquals(State.ERROR, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.ERROR); + this.subSubAction1.setState(State.EXECUTION); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.ERROR, this.activity.getState()); + assertEquals(State.ERROR, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + } + + @Test + public void shouldTestStopped() { + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.STOPPED); + + assertEquals(State.STOPPED, this.activity.getState()); + assertEquals(State.STOPPED, this.subActivity.getState()); + assertEquals(State.STOPPED, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.STOPPED); + this.subSubAction1.setState(State.WARNING); + + assertEquals(State.WARNING, this.activity.getState()); + assertEquals(State.WARNING, this.subActivity.getState()); + assertEquals(State.WARNING, this.subSubActivity.getState()); + + this.action.setState(State.STOPPED); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.EXECUTED); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.STOPPED, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTION); + this.subAction.setState(State.STOPPED); + this.subSubAction1.setState(State.EXECUTION); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.STOPPED, this.activity.getState()); + assertEquals(State.STOPPED, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.PLANNED); + this.subAction.setState(State.STOPPED); + this.subSubAction1.setState(State.EXECUTION); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.STOPPED, this.activity.getState()); + assertEquals(State.STOPPED, this.subActivity.getState()); + assertEquals(State.EXECUTION, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.WARNING); + this.subSubAction1.setState(State.ERROR); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.ERROR, this.activity.getState()); + assertEquals(State.ERROR, this.subActivity.getState()); + assertEquals(State.ERROR, this.subSubActivity.getState()); + + this.action.setState(State.EXECUTED); + this.subAction.setState(State.ERROR); + this.subSubAction1.setState(State.WARNING); + this.subSubAction2.setState(State.CREATED); + + assertEquals(State.ERROR, this.activity.getState()); + assertEquals(State.ERROR, this.subActivity.getState()); + assertEquals(State.WARNING, this.subSubActivity.getState()); + } + + @Test + public void shouldTestClosed() { + + this.action.setState(State.CLOSED); + this.subAction.setState(State.PLANNING); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.PLANNING, this.activity.getState()); + assertEquals(State.PLANNING, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + + this.action.setState(State.CLOSED); + this.subAction.setState(State.EXECUTION); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + + this.action.setState(State.CLOSED); + this.subAction.setState(State.EXECUTED); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.EXECUTION, this.activity.getState()); + assertEquals(State.EXECUTION, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + + this.action.setState(State.CLOSED); + this.subAction.setState(State.CLOSED); + this.subSubAction1.setState(State.PLANNED); + this.subSubAction2.setState(State.PLANNED); + + assertEquals(State.PLANNING, this.activity.getState()); + assertEquals(State.PLANNING, this.subActivity.getState()); + assertEquals(State.PLANNED, this.subSubActivity.getState()); + } +} diff --git a/li.strolch.website/www.strolch.li/xsd/StrolchModel-1.4.xsd b/li.strolch.website/www.strolch.li/xsd/StrolchModel-1.4.xsd index 1576c1dea..950fe1bce 100644 --- a/li.strolch.website/www.strolch.li/xsd/StrolchModel-1.4.xsd +++ b/li.strolch.website/www.strolch.li/xsd/StrolchModel-1.4.xsd @@ -145,6 +145,8 @@ + +