1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.example.tapedeck;
21
22 import static org.apache.mina.statemachine.event.IoHandlerEvents.*;
23
24 import org.apache.mina.core.future.IoFutureListener;
25 import org.apache.mina.core.session.IoSession;
26 import org.apache.mina.statemachine.StateControl;
27 import org.apache.mina.statemachine.annotation.IoHandlerTransition;
28 import org.apache.mina.statemachine.annotation.IoHandlerTransitions;
29 import org.apache.mina.statemachine.annotation.State;
30 import org.apache.mina.statemachine.context.AbstractStateContext;
31 import org.apache.mina.statemachine.context.StateContext;
32 import org.apache.mina.statemachine.event.Event;
33
34
35
36
37
38
39 public class TapeDeckServer {
40 @State public static final String ROOT = "Root";
41 @State(ROOT) public static final String EMPTY = "Empty";
42 @State(ROOT) public static final String LOADED = "Loaded";
43 @State(ROOT) public static final String PLAYING = "Playing";
44 @State(ROOT) public static final String PAUSED = "Paused";
45
46 private final String[] tapes = {
47 "The Knife - Silent Shout",
48 "Kings of convenience - Riot on an empty street"
49 };
50
51 static class TapeDeckContext extends AbstractStateContext {
52 public String tapeName;
53 }
54
55 @IoHandlerTransition(on = SESSION_OPENED, in = EMPTY)
56 public void connect(IoSession session) {
57 session.write("+ Greetings from your tape deck!");
58 }
59
60 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = EMPTY, next = LOADED)
61 public void loadTape(TapeDeckContext context, IoSession session, LoadCommand cmd) {
62 if (cmd.getTapeNumber() < 1 || cmd.getTapeNumber() > tapes.length) {
63 session.write("- Unknown tape number: " + cmd.getTapeNumber());
64 StateControl.breakAndGotoNext(EMPTY);
65 } else {
66 context.tapeName = tapes[cmd.getTapeNumber() - 1];
67 session.write("+ \"" + context.tapeName + "\" loaded");
68 }
69 }
70
71 @IoHandlerTransitions({
72 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = LOADED, next = PLAYING),
73 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = PAUSED, next = PLAYING)
74 })
75 public void playTape(TapeDeckContext context, IoSession session, PlayCommand cmd) {
76 session.write("+ Playing \"" + context.tapeName + "\"");
77 }
78
79 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = PLAYING, next = PAUSED)
80 public void pauseTape(TapeDeckContext context, IoSession session, PauseCommand cmd) {
81 session.write("+ \"" + context.tapeName + "\" paused");
82 }
83
84 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = PLAYING, next = LOADED)
85 public void stopTape(TapeDeckContext context, IoSession session, StopCommand cmd) {
86 session.write("+ \"" + context.tapeName + "\" stopped");
87 }
88
89 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = LOADED, next = EMPTY)
90 public void ejectTape(TapeDeckContext context, IoSession session, EjectCommand cmd) {
91 session.write("+ \"" + context.tapeName + "\" ejected");
92 context.tapeName = null;
93 }
94
95 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = ROOT)
96 public void listTapes(IoSession session, ListCommand cmd) {
97 StringBuilder response = new StringBuilder("+ (");
98 for (int i = 0; i < tapes.length; i++) {
99 response.append(i + 1).append(": ");
100 response.append('"').append(tapes[i]).append('"');
101 if (i < tapes.length - 1) {
102 response.append(", ");
103 }
104 }
105 response.append(')');
106 session.write(response);
107 }
108
109 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = ROOT)
110 public void info(TapeDeckContext context, IoSession session, InfoCommand cmd) {
111 String state = context.getCurrentState().getId().toLowerCase();
112 if (context.tapeName == null) {
113 session.write("+ Tape deck is " + state + "");
114 } else {
115 session.write("+ Tape deck is " + state
116 + ". Current tape: \"" + context.tapeName + "\"");
117 }
118 }
119
120 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = ROOT)
121 public void quit(TapeDeckContext context, IoSession session, QuitCommand cmd) {
122 session.write("+ Bye! Please come back!").addListener(IoFutureListener.CLOSE);
123 }
124
125 @IoHandlerTransition(on = MESSAGE_RECEIVED, in = ROOT, weight = 10)
126 public void error(Event event, StateContext context, IoSession session, Command cmd) {
127 session.write("- Cannot " + cmd.getName()
128 + " while " + context.getCurrentState().getId().toLowerCase());
129 }
130
131 @IoHandlerTransition(on = EXCEPTION_CAUGHT, in = ROOT)
132 public void commandSyntaxError(IoSession session, CommandSyntaxException e) {
133 session.write("- " + e.getMessage());
134 }
135
136 @IoHandlerTransition(on = EXCEPTION_CAUGHT, in = ROOT, weight = 10)
137 public void exceptionCaught(IoSession session, Exception e) {
138 e.printStackTrace();
139 session.close(true);
140 }
141
142 @IoHandlerTransition(in = ROOT, weight = 100)
143 public void unhandledEvent() {
144 }
145
146 }