diff --git a/src/main/java/org/caosdb/server/jobs/core/CheckStateTransition.java b/src/main/java/org/caosdb/server/jobs/core/CheckStateTransition.java index 642d63bc4a091538bf6e8d4747256e833e0f51c0..b1a5ac7782236b88493e3c7f9b9cb14bc4123d52 100644 --- a/src/main/java/org/caosdb/server/jobs/core/CheckStateTransition.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckStateTransition.java @@ -8,6 +8,12 @@ import org.caosdb.server.jobs.JobAnnotation; import org.caosdb.server.jobs.JobExecutionTime; import org.caosdb.server.transaction.WriteTransaction; +/** + * Check if the attempted state transition is allowed. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + * + */ @JobAnnotation( time = JobExecutionTime.CHECK, transaction = WriteTransaction.class, @@ -20,6 +26,11 @@ public class CheckStateTransition extends EntityStateJob { new Message(MessageType.Error, "Initial state not allowed."); private static final Message FINAL_STATE_NOT_ALLOWED = new Message(MessageType.Error, "Final state not allowed."); + + /** + * The forceFinalState flag is especially useful if you want to delete + * entities in the middle of the state machine's usual state cycle. + */ private static final String FORCE_FINAL_STATE = "forceFinalState"; @Override @@ -87,8 +98,7 @@ public class CheckStateTransition extends EntityStateJob { private void checkFinalState(State fromState) throws Message { if (!fromState.isFinal()) { - if ("true" - .equalsIgnoreCase(getTransaction().getContainer().getFlags().get(FORCE_FINAL_STATE))) { + if ("true".equalsIgnoreCase(getTransaction().getContainer().getFlags().get(FORCE_FINAL_STATE)) || "true".equalsIgnoreCase(getEntity().getFlag(FORCE_FINAL_STATE))) { // TODO permissions return; } diff --git a/src/main/java/org/caosdb/server/jobs/core/EntityStateJob.java b/src/main/java/org/caosdb/server/jobs/core/EntityStateJob.java index 6137f72fb199aa45a354449199962fa0cea8f8a2..fcc200aef772ea58426732d4d10f2d1fec8934cf 100644 --- a/src/main/java/org/caosdb/server/jobs/core/EntityStateJob.java +++ b/src/main/java/org/caosdb/server/jobs/core/EntityStateJob.java @@ -6,7 +6,6 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; -import org.caosdb.server.database.backend.transaction.GetIDByName; import org.caosdb.server.database.exceptions.EntityDoesNotExistException; import org.caosdb.server.datatype.AbstractCollectionDatatype; import org.caosdb.server.datatype.CollectionValue; @@ -68,8 +67,6 @@ public abstract class EntityStateJob extends EntityJob { new Message(MessageType.Error, "Could not generate the state message."); public static final Message COULD_NOT_GENERATE_TRANSITIONS = new Message(MessageType.Error, "Could not generate transitions."); - public static final Message COULD_NOT_GENERATE_STATES = - new Message(MessageType.Error, "Could not generate states."); public static final Message STATE_MODEL_NOT_SPECIFIED = new Message(MessageType.Error, "State model not specified."); public static final Message STATE_NOT_SPECIFIED = @@ -260,7 +257,7 @@ public abstract class EntityStateJob extends EntityJob { public EntityInterface getStateEntity() throws Message { if (this.stateEntity == null) { - this.stateEntity = retrieveStateEntity(getStateModelEntity(), this.getStateName()); + this.stateEntity = retrieveStateEntity(this.getStateName()); } return this.stateEntity; } @@ -301,11 +298,14 @@ public abstract class EntityStateJob extends EntityJob { private State finalState; public StateModel(EntityInterface stateModelEntity) throws Message { + long time1 = System.currentTimeMillis(); this.name = stateModelEntity.getName(); - this.states = getStates(stateModelEntity); this.transitions = getTransitions(stateModelEntity); + this.states = getStates(transitions, this); this.finalState = getFinalState(stateModelEntity); this.initialState = getInitialState(stateModelEntity); + long time2 = System.currentTimeMillis(); + getTransaction().getTransactionBenchmark().addMeasurement(this.getClass().getSimpleName() + "::1", time2 - time1); } private State getInitialState(EntityInterface stateModelEntity) throws Message { @@ -356,34 +356,15 @@ public abstract class EntityStateJob extends EntityJob { return result; } - private Set<State> getStates(EntityInterface stateModelEntity) throws Message { - for (Property p : stateModelEntity.getProperties()) { - if (p.getName().equals(STATE_RECORD_TYPE_NAME)) { - return createStates(p, stateModelEntity); - } - } - return null; - } - - private Set<State> createStates(Property p, EntityInterface stateModelEntity) throws Message { - if (!(p.getDatatype() instanceof AbstractCollectionDatatype)) { - return null; - } - try { - Set<State> result = new HashSet<>(); - p.parseValue(); - CollectionValue vals = (CollectionValue) p.getValue(); - for (IndexedSingleValue val : vals) { - if (val.getWrapped() instanceof ReferenceValue) { - Integer refid = ((ReferenceValue) val.getWrapped()).getId(); - EntityInterface stateEntity = retrieveValidEntity(refid); - result.add(new State(stateEntity, stateModelEntity)); - } - } - return result; - } catch (Exception e) { - throw COULD_NOT_GENERATE_STATES; + private Set<State> getStates(Set<Transition> transitions, StateModel stateModel) throws Message { + Iterator<Transition> it = transitions.iterator(); + Set<State> result = new HashSet<>(); + while(it.hasNext()) { + Transition t = it.next(); + result.add(t.getFromState()); + result.add(t.getToState()); } + return result; } public String getName() { @@ -415,31 +396,14 @@ public abstract class EntityStateJob extends EntityJob { } } - protected EntityInterface retrieveStateEntity(EntityInterface stateModelEntity, String stateName) + protected EntityInterface retrieveStateEntity(String stateName) throws Message { - - List<Integer> list; try { - list = execute(new GetIDByName(stateName)).getList(); + return retrieveValidEntity(retrieveValidIDByName(stateName)); } catch (EntityDoesNotExistException e) { throw STATE_NOT_IN_STATE_MODEL; } - for (Property p : stateModelEntity.getProperties()) { - if (Objects.equals(p.getName(), STATE_RECORD_TYPE_NAME)) { - p.parseValue(); - for (IndexedSingleValue val : ((CollectionValue) p.getValue())) { - ReferenceValue refid = (ReferenceValue) val.getWrapped(); - - // match id - for (Integer id : list) { - if (Objects.equals(refid.getId(), id)) { - return retrieveValidEntity(id); - } - } - } - } - } - throw STATE_NOT_IN_STATE_MODEL; + } protected EntityInterface retrieveStateModelEntity(String stateModel) throws Message { @@ -554,7 +518,10 @@ public abstract class EntityStateJob extends EntityJob { "FIND RECORD " + STATE_MODEL_RECORD_TYPE_NAME + " WHICH REFERENCES " - + Integer.toString(stateEntity.getId()), + + TRANSITION_RECORD_TYPE_NAME + + " WHICH REFERENCES " + + Integer.toString(stateEntity.getId()) + , getUser(), null); query.execute(getTransaction().getAccess()); diff --git a/src/main/java/org/caosdb/server/jobs/core/MakeStateMessage.java b/src/main/java/org/caosdb/server/jobs/core/MakeStateMessage.java index 3fb97b49bf3f1b5bab105164f9ecfee5d020949a..6b252f3fff272eaf353cc577fb807a057923bc1f 100644 --- a/src/main/java/org/caosdb/server/jobs/core/MakeStateMessage.java +++ b/src/main/java/org/caosdb/server/jobs/core/MakeStateMessage.java @@ -7,12 +7,22 @@ import org.caosdb.server.jobs.JobAnnotation; import org.caosdb.server.jobs.JobExecutionTime; import org.caosdb.server.transaction.Retrieve; +/** + * Remove the state property from the entity and, iff necessary, convert it into + * a State instance which is then being appended to the entity's messages. + * + * If this job belongs to a Write transaction there is already a State instance + * present and the conversion is not necessary. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ @JobAnnotation(loadAlways = true, time = JobExecutionTime.POST_TRANSACTION) public class MakeStateMessage extends EntityStateJob { @Override protected void run() { try { + // fetch all state properties and remove them from the entity (indicated by "true") List<Property> stateProperties = getStateProperties(true); // only add the State during Retrieve. In all other cases, the State is already present. diff --git a/src/main/java/org/caosdb/server/utils/fsm/ActionNotAllowedException.java b/src/main/java/org/caosdb/server/utils/fsm/ActionNotAllowedException.java deleted file mode 100644 index ad643a0aade5e8285fa0aea7a92026995b9ccd61..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/ActionNotAllowedException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -public class ActionNotAllowedException extends RuntimeException { - - private final String action; - - public ActionNotAllowedException(final String action) { - this.action = action; - } - - private static final long serialVersionUID = -4324962066954446942L; - - @Override - public String getMessage() { - return "The action `" + this.action + "` is not allowed in the current state."; - } -} diff --git a/src/main/java/org/caosdb/server/utils/fsm/FiniteStateMachine.java b/src/main/java/org/caosdb/server/utils/fsm/FiniteStateMachine.java deleted file mode 100644 index f8bdccac726bfe25d7644f6dc689b54113f981c7..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/FiniteStateMachine.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -import java.util.List; -import java.util.Map; - -public abstract class FiniteStateMachine<S extends State, T extends Transition> { - - public FiniteStateMachine(final S initial, final Map<S, Map<T, S>> transitions) - throws StateNotReachableException { - this.currentState = initial; - this.transitions = transitions; - checkEveryStateReachable(); - } - - private void checkEveryStateReachable() throws StateNotReachableException { - for (final State s : getAllStates()) { - if (!s.equals(this.currentState) && !stateIsReachable(s)) { - throw new StateNotReachableException(s); - } - } - } - - private boolean stateIsReachable(final State s) { - for (final Map<T, S> map : this.transitions.values()) { - if (map.containsValue(s)) { - return true; - } - } - return false; - } - - private final Map<S, Map<T, S>> transitions; - private S currentState = null; - - public void trigger(final T t) throws TransitionNotAllowedException { - final S old = this.currentState; - this.currentState = getNextState(t); - onAfterTransition(old, t, this.currentState); - } - - S getNextState(final T t) throws TransitionNotAllowedException { - final Map<T, S> map = this.transitions.get(this.currentState); - if (map != null && map.containsKey(t)) { - return map.get(t); - } - throw new TransitionNotAllowedException(this.getCurrentState(), t); - } - - public S getCurrentState() { - return this.currentState; - } - - public List<? extends State> getAllStates() { - return this.currentState.getAllStates(); - } - - /** - * Override this method in subclasses. The method is called immediately after a transition - * finished. - * - * @param from - * @param transition - * @param to - */ - protected void onAfterTransition(final S from, final T transition, final S to) {} -} diff --git a/src/main/java/org/caosdb/server/utils/fsm/MissingImplementationException.java b/src/main/java/org/caosdb/server/utils/fsm/MissingImplementationException.java deleted file mode 100644 index 8282e5dd7e7bea4368acf2c7e77b536fab301ad6..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/MissingImplementationException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -public class MissingImplementationException extends Exception { - - public MissingImplementationException(final State s) { - super("The state `" + s.toString() + "` has no implementation."); - } - - private static final long serialVersionUID = -1138551658177420875L; -} diff --git a/src/main/java/org/caosdb/server/utils/fsm/State.java b/src/main/java/org/caosdb/server/utils/fsm/State.java deleted file mode 100644 index 81b76aa599a90de2c8b3c8ddd295e62ce47dae12..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/State.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -import java.util.List; - -public interface State { - - public List<State> getAllStates(); -} diff --git a/src/main/java/org/caosdb/server/utils/fsm/StateNotReachableException.java b/src/main/java/org/caosdb/server/utils/fsm/StateNotReachableException.java deleted file mode 100644 index 3970f60e5cf6e86096b0992419b14350c43b42ee..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/StateNotReachableException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -public class StateNotReachableException extends Exception { - - public StateNotReachableException(final State s) { - super("The state `" + s.toString() + "` is not reachable."); - } - - private static final long serialVersionUID = -1826791324169513493L; -} diff --git a/src/main/java/org/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java b/src/main/java/org/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java deleted file mode 100644 index d37d83783bd7f4aaa1db573f76315d0b51bd5fbb..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -import java.util.Map; - -public class StrategyFiniteStateMachine<S extends State, T extends Transition, I> - extends FiniteStateMachine<S, T> { - - public StrategyFiniteStateMachine( - final S initial, final Map<S, I> stateImplementations, final Map<S, Map<T, S>> transitions) - throws MissingImplementationException, StateNotReachableException { - super(initial, transitions); - this.stateImplementations = stateImplementations; - checkImplementationsComplete(); - } - - /** - * Check if every state has it's implementation. - * - * @throws MissingImplementationException - */ - private void checkImplementationsComplete() throws MissingImplementationException { - for (final State s : getAllStates()) { - if (!this.stateImplementations.containsKey(s)) { - throw new MissingImplementationException(s); - } - } - } - - private final Map<S, I> stateImplementations; - - public I getImplementation() { - return getImplementation(getCurrentState()); - } - - public I getImplementation(final S state) { - return this.stateImplementations.get(state); - } -} diff --git a/src/main/java/org/caosdb/server/utils/fsm/Transition.java b/src/main/java/org/caosdb/server/utils/fsm/Transition.java deleted file mode 100644 index 41921b76cfc7ceed6e396551807e4b199486f0cf..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/Transition.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -public interface Transition {} diff --git a/src/main/java/org/caosdb/server/utils/fsm/TransitionNotAllowedException.java b/src/main/java/org/caosdb/server/utils/fsm/TransitionNotAllowedException.java deleted file mode 100644 index f0547704e250db5c5088c5019a85974c2f4e6254..0000000000000000000000000000000000000000 --- a/src/main/java/org/caosdb/server/utils/fsm/TransitionNotAllowedException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -public class TransitionNotAllowedException extends Exception { - - private static final long serialVersionUID = -7236981582249457939L; - - public TransitionNotAllowedException(final State state, final Transition transition) { - super( - "The transition `" - + transition.toString() - + "` is not allowed in state `" - + state.toString() - + "."); - } -} diff --git a/src/test/java/org/caosdb/server/utils/fsm/TestFiniteStateMachine.java b/src/test/java/org/caosdb/server/utils/fsm/TestFiniteStateMachine.java deleted file mode 100644 index 2a7b726b84464f3a7d287434b2767a34baaf4b50..0000000000000000000000000000000000000000 --- a/src/test/java/org/caosdb/server/utils/fsm/TestFiniteStateMachine.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -import static org.junit.Assert.assertEquals; - -import com.google.common.collect.Lists; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -class SimpleFiniteStateMachine extends FiniteStateMachine<State, Transition> { - - public SimpleFiniteStateMachine( - final State initial, final Map<State, Map<Transition, State>> transitions) - throws StateNotReachableException { - super(initial, transitions); - } -} - -enum TestState implements State { - State1, - State2, - State3; - - @Override - public List<State> getAllStates() { - return Lists.newArrayList(values()); - } -} - -enum TestTransition implements Transition { - toState2, - toState3 -} - -public class TestFiniteStateMachine { - - @Rule public ExpectedException exc = ExpectedException.none(); - - @Test - public void testTransitionNotAllowedException() - throws StateNotReachableException, TransitionNotAllowedException { - final Map<State, Map<Transition, State>> map = new HashMap<>(); - final HashMap<Transition, State> from1 = new HashMap<>(); - from1.put(TestTransition.toState2, TestState.State2); - from1.put(TestTransition.toState3, TestState.State3); - map.put(TestState.State1, from1); - - final SimpleFiniteStateMachine fsm = new SimpleFiniteStateMachine(TestState.State1, map); - assertEquals(TestState.State1, fsm.getCurrentState()); - fsm.trigger(TestTransition.toState2); - assertEquals(TestState.State2, fsm.getCurrentState()); - - // only 1->2 and from 1->3 is allowed. not 2->3 - this.exc.expect(TransitionNotAllowedException.class); - fsm.trigger(TestTransition.toState3); - } - - @Test - public void testStateNotReachable() throws StateNotReachableException { - final Map<State, Map<Transition, State>> empty = new HashMap<>(); - - this.exc.expect(StateNotReachableException.class); - new SimpleFiniteStateMachine(TestState.State1, empty); - } -} diff --git a/src/test/java/org/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java b/src/test/java/org/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java deleted file mode 100644 index ebf719b1eaa4b56f3b64bdd9371f121231b4ed68..0000000000000000000000000000000000000000 --- a/src/test/java/org/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.utils.fsm; - -import java.util.HashMap; -import java.util.Map; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class TestStrategyFiniteStateMachine { - - @Rule public ExpectedException exc = ExpectedException.none(); - - @Test - public void testStateHasNoImplementation() - throws MissingImplementationException, StateNotReachableException { - final Map<State, Map<Transition, State>> map = new HashMap<>(); - final HashMap<Transition, State> from1 = new HashMap<>(); - from1.put(TestTransition.toState2, TestState.State2); - from1.put(TestTransition.toState3, TestState.State3); - map.put(TestState.State1, from1); - - final Map<State, Object> stateImplementations = new HashMap<>(); - - this.exc.expect(MissingImplementationException.class); - new StrategyFiniteStateMachine<State, Transition, Object>( - TestState.State1, stateImplementations, map); - } -}