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