1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.statemachine.transition;
21
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.util.Arrays;
25
26 import org.apache.mina.statemachine.State;
27 import org.apache.mina.statemachine.StateMachine;
28 import org.apache.mina.statemachine.context.StateContext;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class MethodSelfTransition extends AbstractSelfTransition {
46 private static final Logger LOGGER = LoggerFactory.getLogger(MethodTransition.class);
47
48 private Method method;
49
50 private final Object target;
51
52 private static final Object[] EMPTY_ARGUMENTS = new Object[0];
53
54
55
56
57
58
59
60 public MethodSelfTransition(Method method, Object target) {
61 super();
62 this.method = method;
63 this.target = target;
64 }
65
66
67
68
69
70
71
72 public MethodSelfTransition(String methodName, Object target) {
73
74 this.target = target;
75
76 Method[] candidates = target.getClass().getMethods();
77 Method result = null;
78
79 for (Method candidate : candidates) {
80 if (candidate.getName().equals(methodName)) {
81 if (result != null) {
82 throw new AmbiguousMethodException(methodName);
83 }
84
85 result = candidate;
86 }
87 }
88
89 if (result == null) {
90 throw new NoSuchMethodException(methodName);
91 }
92
93 this.method = result;
94
95 }
96
97
98
99
100 public Method getMethod() {
101 return method;
102 }
103
104
105
106
107 @Override
108 public boolean doExecute(StateContext stateContext, State state) {
109 Class<?>[] types = method.getParameterTypes();
110
111 if (types.length == 0) {
112 invokeMethod(EMPTY_ARGUMENTS);
113
114 return true;
115 }
116
117 if (types.length > 2) {
118 return false;
119 }
120
121 Object[] args = new Object[types.length];
122
123 int i = 0;
124
125 if (types[i].isAssignableFrom(StateContext.class)) {
126 args[i++] = stateContext;
127 }
128
129 if ((i < types.length) && types[i].isAssignableFrom(State.class)) {
130 args[i++] = state;
131 }
132
133 invokeMethod(args);
134
135 return true;
136 }
137
138 private void invokeMethod(Object[] arguments) {
139 try {
140 if (LOGGER.isDebugEnabled()) {
141 LOGGER.debug("Executing method " + method + " with arguments " + Arrays.asList(arguments));
142 }
143
144 method.invoke(target, arguments);
145 } catch (InvocationTargetException ite) {
146 if (ite.getCause() instanceof RuntimeException) {
147 throw (RuntimeException) ite.getCause();
148 }
149
150 throw new MethodInvocationException(method, ite);
151 } catch (IllegalAccessException iae) {
152 throw new MethodInvocationException(method, iae);
153 }
154 }
155 }