1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.statemachine;
21  
22  import java.lang.reflect.Method;
23  import java.util.List;
24  
25  import junit.framework.TestCase;
26  
27  import org.apache.mina.statemachine.State;
28  import org.apache.mina.statemachine.StateMachine;
29  import org.apache.mina.statemachine.StateMachineCreationException;
30  import org.apache.mina.statemachine.StateMachineFactory;
31  import org.apache.mina.statemachine.annotation.Transition;
32  import org.apache.mina.statemachine.annotation.Transitions;
33  import org.apache.mina.statemachine.transition.MethodTransition;
34  
35  /**
36   * Tests {@link StateMachineFactory}.
37   *
38   * @author The Apache MINA Project (dev@mina.apache.org)
39   * @version $Rev: 592475 $, $Date: 2007-11-06 17:03:42 +0100 (Tue, 06 Nov 2007) $
40   */
41  public class StateMachineFactoryTest extends TestCase {
42      Method barInA;
43      Method error;
44      Method fooInA;
45      Method fooInB;
46      Method barInC;
47      Method fooOrBarInCOrFooInD;
48  
49      protected void setUp() throws Exception {
50          barInA = States.class.getDeclaredMethod("barInA", new Class[0]);
51          error = States.class.getDeclaredMethod("error", new Class[0]);
52          fooInA = States.class.getDeclaredMethod("fooInA", new Class[0]);
53          fooInB = States.class.getDeclaredMethod("fooInB", new Class[0]);
54          barInC = States.class.getDeclaredMethod("barInC", new Class[0]);
55          fooOrBarInCOrFooInD = States.class.getDeclaredMethod("fooOrBarInCOrFooInD", new Class[0]);
56      }
57  
58      public void testCreate() throws Exception {
59          States states = new States();
60          StateMachine sm = StateMachineFactory.getInstance(Transition.class).create(States.A, states);
61  
62          State a = sm.getState(States.A);
63          State b = sm.getState(States.B);
64          State c = sm.getState(States.C);
65          State d = sm.getState(States.D);
66  
67          assertEquals(States.A, a.getId());
68          assertNull(a.getParent());
69          assertEquals(States.B, b.getId());
70          assertSame(a, b.getParent());
71          assertEquals(States.C, c.getId());
72          assertSame(b, c.getParent());
73          assertEquals(States.D, d.getId());
74          assertSame(a, d.getParent());
75  
76          List<org.apache.mina.statemachine.transition.Transition> trans = null;
77  
78          trans = a.getTransitions();
79          assertEquals(3, trans.size());
80          assertEquals(new MethodTransition("bar", barInA, states), trans.get(0));
81          assertEquals(new MethodTransition("*", error, states), trans.get(1));
82          assertEquals(new MethodTransition("foo", b, fooInA, states), trans.get(2));
83          
84          trans = b.getTransitions();
85          assertEquals(1, trans.size());
86          assertEquals(new MethodTransition("foo", c, fooInB, states), trans.get(0));
87  
88          trans = c.getTransitions();
89          assertEquals(3, trans.size());
90          assertEquals(new MethodTransition("bar", a, barInC, states), trans.get(0));
91          assertEquals(new MethodTransition("foo", d, fooOrBarInCOrFooInD, states), trans.get(1));
92          assertEquals(new MethodTransition("bar", d, fooOrBarInCOrFooInD, states), trans.get(2));
93  
94          trans = d.getTransitions();
95          assertEquals(1, trans.size());
96          assertEquals(new MethodTransition("foo", fooOrBarInCOrFooInD, states), trans.get(0));
97      }
98      
99      public void testCreateStates() throws Exception {
100         State[] states = StateMachineFactory.createStates(StateMachineFactory.getFields(States.class));
101         assertEquals(States.A, states[0].getId());
102         assertNull(states[0].getParent());
103         assertEquals(States.B, states[1].getId());
104         assertEquals(states[0], states[1].getParent());
105         assertEquals(States.C, states[2].getId());
106         assertEquals(states[1], states[2].getParent());
107         assertEquals(States.D, states[3].getId());
108         assertEquals(states[0], states[3].getParent());
109     }
110     
111     public void testCreateStatesMissingParents() throws Exception {
112         try {
113             StateMachineFactory.createStates(StateMachineFactory.getFields(StatesWithMissingParents.class));
114             fail("Missing parents. FsmCreationException expected.");
115         } catch (StateMachineCreationException fce) {
116         }
117     }
118     
119     public static class States {
120         @org.apache.mina.statemachine.annotation.State
121         protected static final String A = "a";
122         @org.apache.mina.statemachine.annotation.State(A)
123         protected static final String B = "b";
124         @org.apache.mina.statemachine.annotation.State(B)
125         protected static final String C = "c";
126         @org.apache.mina.statemachine.annotation.State(A)
127         protected static final String D = "d";
128         
129         @Transition(on = "bar", in = A)
130         protected void barInA() {
131         }
132 
133         @Transition(on = "bar", in = C, next = A)
134         protected void barInC() {
135         }
136 
137         @Transition(in = A)
138         protected void error() {
139         }
140 
141         @Transition(on = "foo", in = A, next = B)
142         protected void fooInA() {
143         }
144 
145         @Transition(on = "foo", in = B, next = C)
146         protected void fooInB() {
147         }
148 
149         @Transitions( { @Transition(on = { "foo", "bar" }, in = C, next = D), @Transition(on = "foo", in = D) })
150         protected void fooOrBarInCOrFooInD() {
151         }
152       
153     }
154     
155     public static class StatesWithMissingParents {
156         @org.apache.mina.statemachine.annotation.State("b")
157         public static final String A = "a";
158         @org.apache.mina.statemachine.annotation.State("c")
159         public static final String B = "b";
160         @org.apache.mina.statemachine.annotation.State("d")
161         public static final String C = "c";
162         @org.apache.mina.statemachine.annotation.State("e")
163         public static final String D = "d";
164     }
165 }