diff --git a/pom.xml b/pom.xml
index ddeb71e..e9e560c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
me.bvn13.fsm
fsm
- 2.1.6
+ 2.1.7
jar
diff --git a/src/main/java/me/bvn13/fsm/Fsm.java b/src/main/java/me/bvn13/fsm/Fsm.java
index 10c31c9..1253454 100644
--- a/src/main/java/me/bvn13/fsm/Fsm.java
+++ b/src/main/java/me/bvn13/fsm/Fsm.java
@@ -13,6 +13,8 @@ import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
+import static java.lang.String.format;
+
/**
*
* Final State Machine
@@ -239,6 +241,20 @@ public class Fsm {
addTransition(fromState, toState.getName(), condition);
}
+ /**
+ * Provides a possibility to initialize FSM in custom State
+ * @param name State name (must be added before)
+ */
+ protected void setCurrentState(String name) {
+ try {
+ this.currentState = this.states.get(name);
+ } catch (NullPointerException e) {
+ throw new NotInitializedException(format("Unable to find state '%s'", name), e);
+ }
+ this.done = currentState.isFinish();
+ this.currentState.beforeEvent();
+ }
+
private void switchToNextState(E event) {
if (!transitions.containsKey(currentState.getName())) {
throw new TransitionMissedException(currentState.getName());
@@ -263,9 +279,9 @@ public class Fsm {
}
private void nextState(State state, E event) {
- state.beforeEvent();
previousState = currentState;
currentState = state;
+ currentState.beforeEvent();
}
private void checkStateExist(String name) throws StateAlreadyExistsException {
diff --git a/src/main/java/me/bvn13/fsm/FsmBuilder.java b/src/main/java/me/bvn13/fsm/FsmBuilder.java
index 42862e1..8bd0631 100644
--- a/src/main/java/me/bvn13/fsm/FsmBuilder.java
+++ b/src/main/java/me/bvn13/fsm/FsmBuilder.java
@@ -31,6 +31,11 @@ public class FsmBuilder {
return fsm;
}
+ public T startingAt(String name) {
+ fsm.setCurrentState(name);
+ return fsm;
+ }
+
T getFsm() {
return fsm;
}
diff --git a/src/main/java/me/bvn13/fsm/StateHandler.java b/src/main/java/me/bvn13/fsm/StateHandler.java
index d1cef68..31a4c7c 100644
--- a/src/main/java/me/bvn13/fsm/StateHandler.java
+++ b/src/main/java/me/bvn13/fsm/StateHandler.java
@@ -7,6 +7,6 @@ package me.bvn13.fsm;
@FunctionalInterface
public interface StateHandler {
- void handle(T fms);
+ void handle(T fsm);
}
diff --git a/src/main/java/me/bvn13/fsm/StateProcessor.java b/src/main/java/me/bvn13/fsm/StateProcessor.java
index f9fd70e..9371816 100644
--- a/src/main/java/me/bvn13/fsm/StateProcessor.java
+++ b/src/main/java/me/bvn13/fsm/StateProcessor.java
@@ -8,6 +8,6 @@ package me.bvn13.fsm;
@FunctionalInterface
public interface StateProcessor {
- void process(T fms, E event);
+ void process(T fsm, E event);
}
diff --git a/src/main/java/me/bvn13/fsm/dummy/DummyHandler.java b/src/main/java/me/bvn13/fsm/dummy/DummyHandler.java
index 9559db3..8e2f567 100644
--- a/src/main/java/me/bvn13/fsm/dummy/DummyHandler.java
+++ b/src/main/java/me/bvn13/fsm/dummy/DummyHandler.java
@@ -5,7 +5,7 @@ import me.bvn13.fsm.StateHandler;
public class DummyHandler implements StateHandler {
@Override
- public void handle(T fms) {
+ public void handle(T fsm) {
}
}
diff --git a/src/main/java/me/bvn13/fsm/dummy/DummyProcessor.java b/src/main/java/me/bvn13/fsm/dummy/DummyProcessor.java
index d308a73..2d087b4 100644
--- a/src/main/java/me/bvn13/fsm/dummy/DummyProcessor.java
+++ b/src/main/java/me/bvn13/fsm/dummy/DummyProcessor.java
@@ -5,7 +5,7 @@ import me.bvn13.fsm.StateProcessor;
public class DummyProcessor implements StateProcessor {
@Override
- public void process(T fms, E event) {
+ public void process(T fsm, E event) {
}
}
diff --git a/src/main/java/me/bvn13/fsm/exceptions/AmbiguousTransitionException.java b/src/main/java/me/bvn13/fsm/exceptions/AmbiguousTransitionException.java
index ee6e210..c10c909 100644
--- a/src/main/java/me/bvn13/fsm/exceptions/AmbiguousTransitionException.java
+++ b/src/main/java/me/bvn13/fsm/exceptions/AmbiguousTransitionException.java
@@ -2,6 +2,8 @@ package me.bvn13.fsm.exceptions;
import java.util.List;
+import static java.lang.String.format;
+
/**
* is thrown if there are more than 1 appropriate transition from current state
*/
@@ -10,11 +12,14 @@ public class AmbiguousTransitionException extends FsmException {
super(message);
}
public AmbiguousTransitionException(String from, List next) {
- super("");
- String msg = "";
- for (String to : next) {
- msg += (msg.length() > 0 ? ", " : "") + to;
+ super(format("Ambiguous transition from state %s. Candidates are: %s", from, join(next)));
+ }
+
+ private static String join(List list) {
+ StringBuilder msg = new StringBuilder();
+ for (String to : list) {
+ msg.append(msg.length() > 0 ? ", " : "").append(to);
}
- this.message = String.format("Ambiguous transition from state %s. Candidates are: %s", from, msg);
+ return msg.toString();
}
}
diff --git a/src/main/java/me/bvn13/fsm/exceptions/FsmException.java b/src/main/java/me/bvn13/fsm/exceptions/FsmException.java
index 5205ae9..8a48568 100644
--- a/src/main/java/me/bvn13/fsm/exceptions/FsmException.java
+++ b/src/main/java/me/bvn13/fsm/exceptions/FsmException.java
@@ -1,23 +1,14 @@
package me.bvn13.fsm.exceptions;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
/**
* Parent FSM exception class
*/
public class FsmException extends RuntimeException {
- protected String message;
public FsmException(String message) {
- this.message = message;
+ super(message);
}
- protected String getStackTraceString() {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- this.printStackTrace(pw);
- return sw.toString();
- }
- public void printStackTrace() {
- System.out.println(String.format("FSMException: %s / %s", message, getStackTraceString()));
+
+ public FsmException(String message, Throwable cause) {
+ super(message, cause);
}
}
diff --git a/src/main/java/me/bvn13/fsm/exceptions/NotInitializedException.java b/src/main/java/me/bvn13/fsm/exceptions/NotInitializedException.java
index a002848..3afad58 100644
--- a/src/main/java/me/bvn13/fsm/exceptions/NotInitializedException.java
+++ b/src/main/java/me/bvn13/fsm/exceptions/NotInitializedException.java
@@ -7,7 +7,12 @@ public class NotInitializedException extends FsmException {
public NotInitializedException(String message) {
super(message);
}
+
+ public NotInitializedException(String message, Exception e) {
+ super(message, e);
+ }
+
public NotInitializedException() {
- super("FSM is not inited");
+ super("FSM is not initialized");
}
}
diff --git a/src/test/java/me/bvn13/fsm/tests/FsmTest.java b/src/test/java/me/bvn13/fsm/tests/FsmTest.java
index 38a3140..f79ff1e 100644
--- a/src/test/java/me/bvn13/fsm/tests/FsmTest.java
+++ b/src/test/java/me/bvn13/fsm/tests/FsmTest.java
@@ -92,6 +92,8 @@ public class FsmTest {
.withAfterHandler(fsm -> initAfter.set(true))
.withProcessor((fsm, event) -> initProcess.set(true))
.end()
+ .state("intermediate")
+ .end()
.finish("finish")
.withBeforeHandler(fsm -> finishBefore.set(true))
.withAfterHandler(fsm -> finishAfter.set(true))
@@ -99,17 +101,21 @@ public class FsmTest {
.end()
.withTransition()
.from("init")
+ .to("intermediate")
+ .checking((fsm, event) -> true)
+ .end()
+ .withTransition()
+ .from("intermediate")
.to("finish")
.checking((fsm, event) -> true)
.end()
- .create()
- ;
+ .create();
// @formatter:on
-
+ simpleFsm.process("");
simpleFsm.process("");
- //Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
+ Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
Assert.assertTrue(initBefore.get());
Assert.assertTrue(initProcess.get());
Assert.assertTrue(initAfter.get());
@@ -119,4 +125,67 @@ public class FsmTest {
}
+ @Test
+ public void newSyntaxCustomState() {
+
+ AtomicBoolean initBefore = new AtomicBoolean(false);
+ AtomicBoolean initAfter = new AtomicBoolean(false);
+ AtomicBoolean initProcess = new AtomicBoolean(false);
+ AtomicBoolean intermediateBefore = new AtomicBoolean(false);
+ AtomicBoolean intermediateAfter = new AtomicBoolean(false);
+ AtomicBoolean intermediateProcess = new AtomicBoolean(false);
+ AtomicBoolean finishBefore = new AtomicBoolean(false);
+ AtomicBoolean finishAfter = new AtomicBoolean(false);
+ AtomicBoolean finishProcess = new AtomicBoolean(false);
+
+ // @formatter:off
+
+ SimpleFsm simpleFsm = Fsm
+ ., String>from(SimpleFsm::new)
+ .withStates()
+ .from("init")
+ .withBeforeHandler(fsm -> initBefore.set(true))
+ .withAfterHandler(fsm -> initAfter.set(true))
+ .withProcessor((fsm, event) -> initProcess.set(true))
+ .end()
+ .state("intermediate")
+ .withBeforeHandler(fsm -> intermediateBefore.set(true))
+ .withAfterHandler(fsm -> intermediateAfter.set(true))
+ .withProcessor((fsm, event) -> intermediateProcess.set(true))
+ .end()
+ .finish("finish")
+ .withBeforeHandler(fsm -> finishBefore.set(true))
+ .withAfterHandler(fsm -> finishAfter.set(true))
+ .withProcessor((fsm, event) -> finishProcess.set(true))
+ .end()
+ .withTransition()
+ .from("init")
+ .to("intermediate")
+ .checking((fsm, event) -> true)
+ .end()
+ .withTransition()
+ .from("intermediate")
+ .to("finish")
+ .checking((fsm, event) -> true)
+ .end()
+ .startingAt("intermediate")
+ ;
+
+ // @formatter:on
+
+ simpleFsm.process("");
+
+ Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
+ Assert.assertFalse(initBefore.get());
+ Assert.assertFalse(initProcess.get());
+ Assert.assertFalse(initAfter.get());
+ Assert.assertTrue(intermediateBefore.get());
+ Assert.assertTrue(intermediateAfter.get());
+ Assert.assertTrue(intermediateProcess.get());
+ Assert.assertTrue(finishBefore.get());
+ Assert.assertFalse(finishProcess.get());
+ Assert.assertFalse(finishAfter.get());
+
+ }
+
}