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 if (result.result == PoshEngine.EvaluationResult.ELEMENT_FIRED) {
133 if (result.type != null && (result.type == FireResult.Type.CONTINUE || result.type == FireResult.Type.FOLLOW || result.type == FireResult.Type.FULFILLED
134 || result.type == FireResult.Type.SURFACE_CONTINUE || result.type == FireResult.Type.FAILED)) {
135 engine.getLog().info("Plan evaluation continues...");
136 continue;
137 }
138 }
139 break;
140 }
141 engine.getLog().info("Plan evaluation end.");
142 }
143
144
145
146
147
148
149
150 protected void logicBeforePlan() {
151 if (workExecutor instanceof ILogicWorkExecutor) {
152 ILogicWorkExecutor logicExecutor = (ILogicWorkExecutor) workExecutor;
153 logicExecutor.logicBeforePlan();
154 }
155 }
156
157
158
159
160
161
162
163 protected void logicAfterPlan() {
164 if (workExecutor instanceof ILogicWorkExecutor) {
165 ILogicWorkExecutor logicExecutor = (ILogicWorkExecutor) workExecutor;
166 logicExecutor.logicAfterPlan();
167 }
168 }
169
170
171
172
173
174
175 protected ITimer createTimer() {
176 return new SystemClockTimer();
177 }
178
179
180
181
182
183
184 protected final ITimer getTimer() {
185 if (timer == null) {
186 timer = createTimer();
187 }
188 return timer;
189 }
190
191
192
193
194
195
196
197 private PoshPlan parsePlan(String planSource) throws ParseException {
198 StringReader planReader = new StringReader(planSource);
199 PoshParser parser = new PoshParser(planReader);
200 return parser.parsePlan();
201 }
202
203
204
205
206
207
208
209
210 private PoshEngine createEngine(int engineId, String planSrc) {
211 try {
212 PoshPlan plan = parsePlan(planSrc);
213 return new PoshEngine(engineId, plan, getTimer(), bot.getLogger().getCategory(SPOSH_LOG_CATEGORY));
214 } catch (ParseException ex) {
215 bot.getLogger().getCategory(SPOSH_LOG_CATEGORY).log(Level.SEVERE, "Parse exceptions during parsing plan:\n{0}\nStacktrace:\n{1}", new Object[]{planSrc, getStackTrace(ex)});
216 throw new IllegalArgumentException(ex);
217 }
218 }
219
220
221
222
223
224
225
226 protected final List<PoshEngine> getEngines() {
227 return engines;
228 }
229
230
231
232
233
234
235
236
237
238
239 protected abstract List<String> getPlans() throws IOException;
240
241
242
243
244
245
246
247 protected final String getPlanFromStream(InputStream in) throws IOException {
248 BufferedReader br = new BufferedReader(new InputStreamReader(in));
249
250 StringBuilder plan = new StringBuilder();
251 String line;
252 try {
253 while ((line = br.readLine()) != null) {
254 plan.append(line);
255 }
256 } finally {
257 br.close();
258 }
259
260 return plan.toString();
261 }
262
263
264
265
266
267
268
269 protected final List<String> getPlansFromDirectory(String directoryPath) throws IOException {
270 List<File> files = new ArrayList<File>();
271 for (File file : new File(directoryPath).listFiles()) {
272 if (".lap".equals(file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(".")))) {
273 files.add(file);
274 }
275 }
276 Collections.sort(files, new Comparator<File>() {
277 @Override
278 public int compare(File o1, File o2) {
279 return o1.getAbsolutePath().compareTo(o2.getAbsolutePath());
280 }
281
282 });
283 List<String> result = new ArrayList<String>();
284 for (File file : files) {
285 result.add(getPlanFromFile(file.getAbsolutePath()));
286 }
287 return result;
288 }
289
290
291
292
293
294
295
296 protected final String getPlanFromFile(String filename) throws IOException {
297 FileInputStream f = new FileInputStream(filename);
298 return getPlanFromStream(f);
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312
313 protected final String getPlanFromResource(String resourcePath) throws IOException {
314 ClassLoader cl = this.getClass().getClassLoader();
315 return getPlanFromStream(cl.getResourceAsStream(resourcePath));
316 }
317 }