Timeouts and user defined events
Javadoc for this example.
src_examples/net/sourceforge/anotherfsm/examples/timeouts/package-info.java
/*
* Copyright 2013 Michal Turek, AnotherFSM
*
* http://anotherfsm.sourceforge.net/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* The example defines a simple state machine with <em>connected</em> and
* <em>disconnected</em> states. The transitions are done on incoming user
* defined and timeout events.
*
* <h3>Classes and files</h3>
*
* <ul>
* <li>{@link net.sourceforge.anotherfsm.examples.timeouts.ConnectionStateEvent}
* User defined event that causes the transitions.</li>
*
* <li>TimeoutConnection.fsm
* Qfsm data file, the painted diagram.</li>
* <li>TimeoutConnection.xml
* Code generator configuration file.</li>
* <li>generate.sh
* Shell script to execute code generator and generate the files.</li>
*
* <li>{@link net.sourceforge.anotherfsm.examples.timeouts.TimeoutConnectionFsm}
* Defines structure of the state machine, generated file.</li>
* <li>{@link net.sourceforge.anotherfsm.examples.timeouts.TimeoutConnectionProcessor}
* Defines listeners for the transitions, generated file.</li>
*
* <li>{@link net.sourceforge.anotherfsm.examples.timeouts.Timeouts}
* Defines main() method, passes data to the state machine.</li>
* </ul>
*
* @author Michal Turek
*/
package net.sourceforge.anotherfsm.examples.timeouts;
State machine diagram used in this example
src_examples/net/sourceforge/anotherfsm/examples/timeouts/ConnectionStateEvent.java
/*
* Copyright 2013 Michal Turek, AnotherFSM
*
* http://anotherfsm.sourceforge.net/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sourceforge.anotherfsm.examples.timeouts;
import net.sourceforge.anotherfsm.Event;
/**
* Connection state event.
*
* @author Michal Turek
*/
public class ConnectionStateEvent implements Event {
/** Predefined instance. */
public static final ConnectionStateEvent instanceCONNECT = new ConnectionStateEvent(
ConnectionStateEvent.ConnectionState.CONNECT);
/** Predefined instance. */
public static final ConnectionStateEvent instanceDISCONNECT = new ConnectionStateEvent(
ConnectionStateEvent.ConnectionState.DISCONNECT);
/** The state. */
private final ConnectionStateEvent.ConnectionState state;
/**
* Create the object.
*
* @param state
* the state
*/
public ConnectionStateEvent(ConnectionStateEvent.ConnectionState state) {
this.state = state;
}
/**
* Get the state.
*
* @return the state
*/
public ConnectionStateEvent.ConnectionState getState() {
return state;
}
@Override
public int hashCode() {
return 86543221 + state.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof ConnectionStateEvent))
return false;
ConnectionStateEvent other = (ConnectionStateEvent) obj;
return state.equals(other.state);
}
@Override
public String toString() {
return getClass().getSimpleName() + "(" + state + ")";
}
/**
* The connection state.
*
* @author Michal Turek
*/
public static enum ConnectionState {
CONNECT, DISCONNECT
}
}
src_examples/net/sourceforge/anotherfsm/examples/timeouts/Timeouts.java
/*
* Copyright 2013 Michal Turek, AnotherFSM
*
* http://anotherfsm.sourceforge.net/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sourceforge.anotherfsm.examples.timeouts;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Locale;
import net.sourceforge.anotherfsm.AnotherFsm;
import net.sourceforge.anotherfsm.FsmException;
import net.sourceforge.anotherfsm.StateMachine;
import net.sourceforge.anotherfsm.logger.FsmLogger;
import net.sourceforge.anotherfsm.logger.StdStreamLoggerFactory;
/**
* The main class, simple parser of user connect/disconnect commands.
*
* @author Michal Turek
*/
public class Timeouts {
static {
// Register factory of loggers before any logger is created
AnotherFsm.setLoggerFactory(new StdStreamLoggerFactory());
}
/** The logger object for this class. */
private final static FsmLogger logger = AnotherFsm
.getLogger(Timeouts.class);
/**
* The application start function.
*
* @param args
* the input arguments, unused
*/
public static void main(String[] args) {
// Create the state machine with timeouts
try (StateMachine machine = new TimeoutConnectionProcessor(
Timeouts.class.getSimpleName())) {
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in, "UTF-8"));
// Building done in the constructor, prepare for events processing
machine.start();
while (true) {
logger.info("Type a command: [exit|connect|disconnect]");
// Ignore empty commands (enter presses)
String command = null;
while (command == null || command.isEmpty())
command = in.readLine();
// Exit on 'exit' command
if ("exit".equals(command)) {
logger.info("Exiting...");
break;
}
// Create the event
ConnectionStateEvent.ConnectionState state = null;
try {
state = ConnectionStateEvent.ConnectionState
.valueOf(command.toUpperCase(Locale.ENGLISH));
} catch (IllegalArgumentException e) {
logger.error("Unknown command: " + command);
continue;
}
// Process the event
machine.process(new ConnectionStateEvent(state));
}
} catch (FsmException | IOException e) {
// Process any exception that may occur
logger.fatal("Unexpected exception occurred", e);
}
logger.debug("End of main()");
}
}
Sample output
2013-03-17 17:54:50,904 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition started: @INITIAL@ -> StartEvent -> disconnected
2013-03-17 17:54:50,906 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: @INITIAL@ -> StartEvent -> disconnected
2013-03-17 17:54:50,907 [main] INFO Timeouts - Type a command: [exit|connect|disconnect]
disconnect
2013-03-17 17:54:54,638 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition started: disconnected -> ConnectionStateEvent(DISCONNECT) -> disconnected
2013-03-17 17:54:54,639 [main] INFO TimeoutConnectionProcessor.Timeouts - No action
2013-03-17 17:54:54,639 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: disconnected -> ConnectionStateEvent(DISCONNECT) -> disconnected
2013-03-17 17:54:54,640 [main] INFO Timeouts - Type a command: [exit|connect|disconnect]
connect
2013-03-17 17:55:00,453 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition started: disconnected -> ConnectionStateEvent(CONNECT) -> connected
2013-03-17 17:55:00,454 [main] INFO TimeoutConnectionProcessor.Timeouts - Connected
2013-03-17 17:55:00,454 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: disconnected -> ConnectionStateEvent(CONNECT) -> connected
2013-03-17 17:55:00,455 [main] INFO Timeouts - Type a command: [exit|connect|disconnect]
connect
2013-03-17 17:55:02,710 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition started: connected -> ConnectionStateEvent(CONNECT) -> connected
2013-03-17 17:55:02,710 [main] INFO TimeoutConnectionProcessor.Timeouts - No action
2013-03-17 17:55:02,711 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: connected -> ConnectionStateEvent(CONNECT) -> connected
2013-03-17 17:55:02,711 [main] INFO Timeouts - Type a command: [exit|connect|disconnect]
2013-03-17 17:55:10,454 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Transition started: connected -> TimeoutEvent(LOOP_NO_RESTART, 10000) -> disconnected
2013-03-17 17:55:10,455 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Time for connection expired
2013-03-17 17:55:10,456 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: connected -> TimeoutEvent(LOOP_NO_RESTART, 10000) -> disconnected
connect
2013-03-17 17:55:13,320 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition started: disconnected -> ConnectionStateEvent(CONNECT) -> connected
2013-03-17 17:55:13,320 [main] INFO TimeoutConnectionProcessor.Timeouts - Connected
2013-03-17 17:55:13,321 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: disconnected -> ConnectionStateEvent(CONNECT) -> connected
2013-03-17 17:55:13,321 [main] INFO Timeouts - Type a command: [exit|connect|disconnect]
disconnect
2013-03-17 17:55:17,369 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition started: connected -> ConnectionStateEvent(DISCONNECT) -> disconnected
2013-03-17 17:55:17,370 [main] INFO TimeoutConnectionProcessor.Timeouts - Disconnected
2013-03-17 17:55:17,370 [main] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: connected -> ConnectionStateEvent(DISCONNECT) -> disconnected
2013-03-17 17:55:17,371 [main] INFO Timeouts - Type a command: [exit|connect|disconnect]
2013-03-17 17:55:27,370 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Transition started: disconnected -> TimeoutEvent(LOOP_RESTART, 10000) -> disconnected
2013-03-17 17:55:27,371 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Nobody is connected
2013-03-17 17:55:27,371 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: disconnected -> TimeoutEvent(LOOP_RESTART, 10000) -> disconnected
not defined
2013-03-17 17:55:31,012 [main] INFO Timeouts - Type a command: [exit|connect|disconnect]
2013-03-17 17:55:31,011 [main] ERROR Timeouts - Unknown command: not defined
2013-03-17 17:55:37,371 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Transition started: disconnected -> TimeoutEvent(LOOP_RESTART, 10000) -> disconnected
2013-03-17 17:55:37,372 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Nobody is connected
2013-03-17 17:55:37,372 [TimeoutConnectionProcessor.Timeouts] INFO TimeoutConnectionProcessor.Timeouts - Transition finished: disconnected -> TimeoutEvent(LOOP_RESTART, 10000) -> disconnected
exit
2013-03-17 17:55:40,066 [main] INFO Timeouts - Exiting...
2013-03-17 17:55:40,067 [main] DEBUG Timeouts - End of main()