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