1 package cz.cuni.amis.pogamut.sposh.ut2004;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9 import java.io.PrintWriter;
10 import java.io.StringReader;
11 import java.io.StringWriter;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.Comparator;
15 import java.util.LinkedList;
16 import java.util.List;
17 import java.util.logging.Level;
18
19 import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
20 import cz.cuni.amis.pogamut.sposh.elements.ParseException;
21 import cz.cuni.amis.pogamut.sposh.elements.PoshParser;
22 import cz.cuni.amis.pogamut.sposh.elements.PoshPlan;
23 import cz.cuni.amis.pogamut.sposh.engine.FireResult;
24 import cz.cuni.amis.pogamut.sposh.engine.PoshEngine;
25 import cz.cuni.amis.pogamut.sposh.engine.PoshEngine.EvaluationResultInfo;
26 import cz.cuni.amis.pogamut.sposh.engine.timer.ITimer;
27 import cz.cuni.amis.pogamut.sposh.engine.timer.SystemClockTimer;
28 import cz.cuni.amis.pogamut.sposh.executor.ILogicWorkExecutor;
29 import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
30 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
31 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004BotLogicController;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 @AgentScoped
47 public abstract class SposhLogicController<BOT extends UT2004Bot, WORK_EXECUTOR extends IWorkExecutor> extends UT2004BotLogicController<BOT> {
48
49 public static final String SPOSH_LOG_CATEGORY = "SPOSH";
50
51
52
53 private List<PoshEngine> engines = new LinkedList<PoshEngine>();
54
55
56
57
58 private WORK_EXECUTOR workExecutor;
59
60
61
62 private ITimer timer;
63
64
65
66
67
68
69
70
71
72 @Override
73 public void initializeController(BOT bot) {
74 super.initializeController(bot);
75 createEngines();
76 }
77
78 private void createEngines() {
79 try {
80 int planId = 0;
81 for (String planSrc : getPlans()) {
82 engines.add(createEngine(planId++, planSrc));
83 }
84 } catch (IOException ex) {
85 bot.getLogger().getCategory(SPOSH_LOG_CATEGORY).log(Level.SEVERE, "IOException {0} - Stacktrace:\n{1}", new Object[]{ex.getMessage(), getStackTrace(ex)});
86 throw new IllegalStateException(ex);
87 }
88 }
89
90 private String getStackTrace(Exception ex) {
91 StringWriter sw = new StringWriter();
92 ex.printStackTrace(new PrintWriter(sw));
93 return sw.toString();
94 }
95
96
97
98
99
100
101 protected abstract WORK_EXECUTOR createWorkExecutor();
102
103
104
105
106
107
108 protected final WORK_EXECUTOR getWorkExecutor() {
109 if (workExecutor == null) {
110 workExecutor = createWorkExecutor();
111 }
112 return workExecutor;
113 }
114
115
116
117
118
119 @Override
120 public final void logic() {
121 logicBeforePlan();
122 for (int engineId = 0; engineId < engines.size(); engineId++) {
123 iterateEngine(engines.get(engineId), engineId);
124 }
125 logicAfterPlan();
126 }
127
128 private void iterateEngine(PoshEngine engine, int engineId) {
129 engine.getLog().log(Level.INFO, "Invoking Yaposh engine " + engineId + " for plan: " + engine.getName());
130 while (true) {
131 EvaluationResultInfo result = engine.evaluatePlan(getWorkExecutor());
132 engine.getLog().fine("Element result: " + result.result + " / " + result.type);
133 if (result.result == PoshEngine.EvaluationResult.ELEMENT_FIRED) {
134 if (result.type != null && (result.type == FireResult.Type.CONTINUE || result.type == FireResult.Type.FOLLOW || result.type == FireResult.Type.FULFILLED
135 || result.type == FireResult.Type.SURFACE_CONTINUE || result.type == FireResult.Type.FAILED)) {
136 engine.getLog().info("Plan evaluation continues...");
137 continue;
138 }
139 }
140 break;
141 }
142 engine.getLog().info("Plan evaluation end.");
143 }
144
145
146
147
148
149
150
151 protected void logicBeforePlan() {
152 if (workExecutor instanceof ILogicWorkExecutor) {
153 ILogicWorkExecutor logicExecutor = (ILogicWorkExecutor) workExecutor;
154 logicExecutor.logicBeforePlan();
155 }
156 }
157
158
159
160
161
162
163
164 protected void logicAfterPlan() {
165 if (workExecutor instanceof ILogicWorkExecutor) {
166 ILogicWorkExecutor logicExecutor = (ILogicWorkExecutor) workExecutor;
167 logicExecutor.logicAfterPlan();
168 }
169 }
170
171
172
173
174
175
176 protected ITimer createTimer() {
177 return new SystemClockTimer();
178 }
179
180
181
182
183
184
185 protected final ITimer getTimer() {
186 if (timer == null) {
187 timer = createTimer();
188 }
189 return timer;
190 }
191
192
193
194
195
196
197
198 private PoshPlan parsePlan(String planSource) throws ParseException {
199 StringReader planReader = new StringReader(planSource);
200 PoshParser parser = new PoshParser(planReader);
201 return parser.parsePlan();
202 }
203
204
205
206
207
208
209
210
211 private PoshEngine createEngine(int engineId, String planSrc) {
212 try {
213 PoshPlan plan = parsePlan(planSrc);
214 return new PoshEngine(engineId, plan, getTimer(), bot.getLogger().getCategory(SPOSH_LOG_CATEGORY));
215 } catch (ParseException ex) {
216 bot.getLogger().getCategory(SPOSH_LOG_CATEGORY).log(Level.SEVERE, "Parse exceptions during parsing plan:\n{0}\nStacktrace:\n{1}", new Object[]{planSrc, getStackTrace(ex)});
217 throw new IllegalArgumentException(ex);
218 }
219 }
220
221
222
223
224
225
226
227 protected final List<PoshEngine> getEngines() {
228 return engines;
229 }
230
231
232
233
234
235
236
237
238
239
240 protected abstract List<String> getPlans() throws IOException;
241
242
243
244
245
246
247
248 protected final String getPlanFromStream(InputStream in) throws IOException {
249 BufferedReader br = new BufferedReader(new InputStreamReader(in));
250
251 StringBuilder plan = new StringBuilder();
252 String line;
253 try {
254 while ((line = br.readLine()) != null) {
255 plan.append(line);
256 }
257 } finally {
258 br.close();
259 }
260
261 return plan.toString();
262 }
263
264
265
266
267
268
269
270 protected final List<String> getPlansFromDirectory(String directoryPath) throws IOException {
271 List<File> files = new ArrayList<File>();
272 for (File file : new File(directoryPath).listFiles()) {
273 if (".lap".equals(file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(".")))) {
274 files.add(file);
275 }
276 }
277 Collections.sort(files, new Comparator<File>() {
278 @Override
279 public int compare(File o1, File o2) {
280 return o1.getAbsolutePath().compareTo(o2.getAbsolutePath());
281 }
282
283 });
284 List<String> result = new ArrayList<String>();
285 for (File file : files) {
286 result.add(getPlanFromFile(file.getAbsolutePath()));
287 }
288 return result;
289 }
290
291
292
293
294
295
296
297 protected final String getPlanFromFile(String filename) throws IOException {
298 FileInputStream f = new FileInputStream(filename);
299 return getPlanFromStream(f);
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314 protected final String getPlanFromResource(String resourcePath) throws IOException {
315 ClassLoader cl = this.getClass().getClassLoader();
316 return getPlanFromStream(cl.getResourceAsStream(resourcePath));
317 }
318 }