1 package cz.cuni.amis.pogamut.sposh.ut2004;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.InvocationTargetException;
5 import java.util.Collections;
6 import java.util.Set;
7
8 import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
9 import cz.cuni.amis.pogamut.sposh.context.Context;
10 import cz.cuni.amis.pogamut.sposh.context.IUT2004Context;
11 import cz.cuni.amis.pogamut.sposh.engine.PoshEngine;
12 import cz.cuni.amis.pogamut.sposh.exceptions.StateInstantiationException;
13 import cz.cuni.amis.pogamut.sposh.executor.IAction;
14 import cz.cuni.amis.pogamut.sposh.executor.ISense;
15 import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
16 import cz.cuni.amis.pogamut.sposh.executor.StateAction;
17 import cz.cuni.amis.pogamut.sposh.executor.StateSense;
18 import cz.cuni.amis.pogamut.sposh.executor.StateWorkExecutor;
19 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 @AgentScoped
44 public abstract class StateSposhLogicController<BOT extends UT2004Bot, CONTEXT extends IUT2004Context> extends SposhLogicController<BOT, StateWorkExecutor> {
45
46
47 protected CONTEXT context;
48
49
50
51
52
53
54 @Override
55 public void initializeController(BOT bot) {
56 super.initializeController(bot);
57 context = createContext();
58
59 getWorkExecutor();
60 }
61
62
63 @Override
64 public void finishControllerInitialization() {
65 super.finishControllerInitialization();
66 context.finishInitialization();
67 }
68
69
70
71
72
73 public final CONTEXT getContext() {
74 return context;
75 }
76
77
78
79
80
81
82
83
84
85 protected void customPrimitiveInstantiation(StateWorkExecutor executor, Set<String> actions, Set<String> senses) {
86
87 }
88
89
90
91
92
93
94 private Class getActionClass(String actionName) {
95 try {
96 return Class.forName(actionName);
97 } catch (ClassNotFoundException ex) {
98 throw new StateInstantiationException("Unable to find state class for action \"" + actionName + "\"", ex);
99 }
100 }
101
102
103
104
105
106
107 private Class getSenseClass(String senseName) {
108 try {
109 return Class.forName(senseName);
110 } catch (ClassNotFoundException ex) {
111 throw new StateInstantiationException("Unable to find state class for sense \"" + senseName + "\"", ex);
112 }
113 }
114
115
116
117
118
119
120
121
122 private <T> T instantiatePrimitive(Class<T> cls) {
123 String name = cls.getName();
124 try {
125 Constructor primitiveConstructor = null;
126 Constructor<?>[] constructors = cls.getConstructors();
127 for (Constructor<?> constructor : constructors) {
128 Class[] constructorParameters = constructor.getParameterTypes();
129 if (constructorParameters.length != 1) {
130 continue;
131 }
132 if (constructorParameters[0].isAssignableFrom(this.getContext().getClass())) {
133 primitiveConstructor = constructor;
134 }
135 }
136 if (primitiveConstructor == null) {
137 throw new StateInstantiationException("Primitive \"" + name + "\" doesn't have a constructor that has exactly one parameter of class " + this.getContext().getClass().getName());
138 }
139 return (T) primitiveConstructor.newInstance(this.getContext());
140 } catch (InstantiationException ex) {
141 throw new StateInstantiationException("Unable to instantiate primitive \"" + name + "\" (" + ex.getMessage() + ")", ex);
142 } catch (IllegalAccessException ex) {
143 throw new StateInstantiationException("Illegal access protection for primitive \"" + name + "\"", ex);
144 } catch (IllegalArgumentException ex) {
145 throw new StateInstantiationException("Primitive \"" + name + "\" doesn't accept bot class (" + this.bot.getClass().getName() + ") in the constructor.", ex);
146 } catch (InvocationTargetException ex) {
147 throw new StateInstantiationException("Constructor of primitive \"" + name + "\" has thrown an exception (" + ex.getMessage() + ")", ex);
148 }
149 }
150
151 @Override
152 protected StateWorkExecutor createWorkExecutor() {
153 StateWorkExecutor executor = new StateWorkExecutor(log);
154
155
156 Set<String> actions = this.getEngine().getPlan().getActionsNames();
157 Set<String> senses = this.getEngine().getPlan().getSensesNames();
158
159
160 for (String senseName : senses) {
161 if (actions.contains(senseName))
162 throw new StateInstantiationException("List of senses and " + senseName);
163 }
164
165
166
167 customPrimitiveInstantiation(executor, Collections.unmodifiableSet(actions), Collections.unmodifiableSet(senses));
168
169
170 for (String name : actions) {
171 if (executor.isNameUsed(name)) {
172 throw new StateInstantiationException("Action instantiation: Primitive with name \"" + name + "\" is already in has already used in the executor.");
173 }
174 Class<IAction> cls = getActionClass(name);
175 IAction action = instantiatePrimitive(cls);
176 executor.addAction(name, action);
177 }
178 for (String name : senses) {
179 if (executor.isNameUsed(name)) {
180 throw new StateInstantiationException("Sense instantiation: Primitive with name \"" + name + "\" is already in has already used in the executor.");
181 }
182 Class<ISense> cls = getSenseClass(name);
183 ISense sense = instantiatePrimitive(cls);
184 executor.addSense(name, sense);
185 }
186
187 return executor;
188 }
189
190
191
192
193
194 protected abstract CONTEXT createContext();
195 }