1 package cz.cuni.amis.pogamut.sposh.executor;
2
3 import java.lang.reflect.InvocationTargetException;
4 import java.lang.reflect.Method;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.List;
8
9 import cz.cuni.amis.pogamut.sposh.JavaBehaviour;
10 import cz.cuni.amis.pogamut.sposh.SPOSHAction;
11 import cz.cuni.amis.pogamut.sposh.SPOSHSense;
12 import cz.cuni.amis.pogamut.sposh.engine.PoshEngine;
13 import cz.cuni.amis.pogamut.sposh.engine.VariableContext;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public class BehaviorWorkExecutor implements ILogicWorkExecutor {
34
35
36
37
38 protected class BehaviorMethod {
39
40
41
42 public BehaviorMethod(Object behavior, Method method) {
43 this.behavior = behavior;
44 this.method = method;
45 }
46 public final Object behavior;
47 public final Method method;
48 }
49
50
51
52
53 protected final HashMap<String, BehaviorMethod> primitives = new HashMap<String, BehaviorMethod>();
54
55 protected List<JavaBehaviour> behaviors = new ArrayList<JavaBehaviour>();
56
57
58
59
60 public BehaviorWorkExecutor() {
61 }
62
63
64
65
66
67 public BehaviorWorkExecutor(JavaBehaviour behavior) {
68 addBehavior(behavior);
69 }
70
71
72
73
74
75
76
77
78
79 public synchronized void addBehavior(JavaBehaviour behavior) {
80 behaviors.add(behavior);
81 Method[] methods = behavior.getClass().getMethods();
82
83
84 for (Method method : methods) {
85 boolean isAnnotated =
86 method.isAnnotationPresent(SPOSHAction.class) ||
87 method.isAnnotationPresent(SPOSHSense.class);
88
89 String name = method.getName();
90 if (isAnnotated) {
91 if (primitives.containsKey(name)) {
92 throw new IllegalArgumentException("primitive name clash (there are at least 2 primitives with name \"" + name + "\")");
93 }
94 primitives.put(name, new BehaviorMethod(behavior, method));
95 }
96 }
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110 private Object executePrimitive(String primitive, VariableContext ctx) {
111 BehaviorMethod behaviorMethod = primitives.get(primitive);
112 if (behaviorMethod == null) {
113 throw new IllegalArgumentException("Primitive \"" + primitive + "\" has no behavior method.");
114 }
115
116 Method method = behaviorMethod.method;
117
118
119 Object[] args = new Object[method.getParameterTypes().length];
120 if (method.getParameterTypes().length > 0) {
121 Class firstParameterClass = method.getParameterTypes()[0];
122
123 if (firstParameterClass.equals(VariableContext.class)) {
124 args[0] = ctx;
125 }
126 }
127
128 try {
129 return method.invoke(behaviorMethod.behavior, args);
130 } catch (IllegalAccessException ex) {
131
132 throw new RuntimeException(ex);
133 } catch (IllegalArgumentException ex) {
134
135 throw new RuntimeException(ex);
136 } catch (InvocationTargetException ex) {
137
138 throw new RuntimeException(ex.getCause());
139 }
140 }
141
142
143
144
145 @Override
146 public Object executeSense(String primitive, VariableContext ctx) {
147 return executePrimitive(primitive, ctx);
148 }
149
150
151
152
153 @Override
154 public ActionResult executeAction(String primitive, VariableContext ctx) {
155 return (ActionResult) executePrimitive(primitive, ctx);
156 }
157
158 @Override
159 public void logicAfterPlan() {
160 for (JavaBehaviour behavior : behaviors) {
161 behavior.logicAfterPlan();
162 }
163 }
164
165 @Override
166 public void logicBeforePlan() {
167 for (JavaBehaviour behavior : behaviors) {
168 behavior.logicBeforePlan();
169 }
170 }
171
172 }