1 package cz.cuni.amis.pogamut.sposh.elements;
2
3 import cz.cuni.amis.pogamut.sposh.exceptions.CycleException;
4 import cz.cuni.amis.pogamut.sposh.exceptions.DuplicateNameException;
5 import java.util.ArrayList;
6 import java.util.List;
7 import java.awt.datatransfer.DataFlavor;
8 import java.io.InputStream;
9 import java.util.Collections;
10 import java.util.HashSet;
11 import java.util.LinkedList;
12 import java.util.Set;
13
14
15
16
17
18
19
20
21
22 public final class PoshPlan extends PoshDummyElement {
23
24 private DocString _docstring = null;
25 private DriveCollection _driveCollection = null;
26 private List<ActionPattern> _actionPatterns = new ArrayList<ActionPattern>();
27 private List<Competence> _competences = new ArrayList<Competence>();
28
29
30
31
32
33
34 public Set<String> getActionsNames() {
35 Set<String> result = new HashSet<String>();
36
37 for (ActionPattern ap : this._actionPatterns) {
38 for (TriggeredAction action : ap.getTriggeredActions()) {
39 String actionName = action.getName();
40 if (!isAP(actionName) && !isC(actionName)) {
41 result.add(actionName);
42 }
43 }
44 }
45
46 for (Competence c : this._competences) {
47 for (CompetenceElement ce : c.getChildDataNodes()) {
48 String actionName = ce.getAction().getName();
49 if (!isAP(actionName) && !isC(actionName)) {
50 result.add(actionName);
51 }
52 }
53 }
54
55 for (DriveElement de : _driveCollection.getDrives()) {
56 String actionName = de.getTriggeredAction().getName();
57 if (!isAP(actionName) && !isC(actionName)) {
58 result.add(actionName);
59 }
60 }
61 return result;
62 }
63
64
65
66
67
68
69 public Set<String> getSensesNames() {
70 Set<String> result = new HashSet<String>();
71
72 Goal dcGoal = this._driveCollection.getGoal();
73 if (dcGoal != null) {
74 for (Sense sense : dcGoal.getSenses()) {
75 result.add(sense.getSenseName());
76 }
77 }
78
79 for (DriveElement de : _driveCollection.getDrives()) {
80 for (Sense sense : de.getTriggers().getSenses()) {
81 result.add(sense.getSenseName());
82 }
83 }
84
85 for (Competence c : this._competences) {
86 for (CompetenceElement ce : c.getChildDataNodes()) {
87 for (Sense sense : ce.getTriggerSenses()) {
88 result.add(sense.getSenseName());
89 }
90 }
91 }
92 return result;
93 }
94
95
96
97
98
99
100
101 public boolean isC(String name) {
102 return getC(name) != null;
103 }
104
105
106
107
108
109
110
111 public Competence getC(String name) {
112 for (Competence c : getCompetences()) {
113 if (c.getName().equals(name)) {
114 return c;
115 }
116 }
117 return null;
118 }
119
120
121
122
123
124
125
126 public boolean isAP(String name) {
127 return getAP(name) != null;
128 }
129
130
131
132
133
134
135
136 public ActionPattern getAP(String name) {
137 for (ActionPattern ap : getActionPatterns()) {
138 if (ap.getName().equals(name)) {
139 return ap;
140 }
141 }
142 return null;
143 }
144
145
146
147
148
149
150
151
152
153 public boolean isUniqueAPorComp(String id) {
154 for (ActionPattern node : _actionPatterns) {
155 if (node.getName().equals(id)) {
156 return false;
157 }
158 }
159
160 for (Competence node : _competences) {
161 if (node.getName().equals(id)) {
162 return false;
163 }
164 }
165
166 return true;
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181 private void refreshActions() {
182
183
184 List<TriggeredAction> actions = new LinkedList<TriggeredAction>();
185
186 List<ActionPattern> aps = this.getActionPatterns();
187 List<Competence> competences = this.getCompetences();
188
189 for (ActionPattern ap : aps) {
190 for (TriggeredAction action : ap.getTriggeredActions()) {
191 actions.add(action);
192 }
193 }
194 for (Competence competence : competences) {
195 for (CompetenceElement ce : competence.getChildDataNodes()) {
196 actions.add(ce.getAction());
197 }
198 }
199
200 if (getDriveCollection() != null) {
201 for (DriveElement de : getDriveCollection().getDrives()) {
202 actions.add(de.getTriggeredAction());
203 }
204 }
205
206 for (TriggeredAction action : actions) {
207 action.setActionName(action.getName());
208 }
209 }
210
211
212
213
214
215
216
217 public void setDocString(DocString docstring) {
218 docstring.setParent(this);
219 if (this._docstring != null) {
220 this._docstring.remove();
221 }
222 this._docstring = docstring;
223 emitChildNode(_docstring);
224 }
225
226
227
228
229
230
231 public void addCompetence(Competence competence) throws DuplicateNameException, CycleException {
232 if (!this.isUniqueAPorComp(competence.getName())) {
233 throw new DuplicateNameException("Competence '" + competence.getName() + "' has duplicate name in POSH plan.");
234 }
235
236 competence.setParent(this);
237 _competences.add(competence);
238
239 if (this.isCycled()) {
240 _competences.remove(competence);
241 throw new CycleException("Competence " + competence.getName() + " is causing cycle.");
242 }
243
244 emitChildNode(competence);
245
246 refreshActions();
247 }
248
249
250
251
252
253
254 public List<Competence> getCompetences() {
255 return Collections.unmodifiableList(this._competences);
256 }
257
258
259
260
261
262
263 public void addActionPattern(ActionPattern actionPattern) throws DuplicateNameException, CycleException {
264 if (!this.isUniqueAPorComp(actionPattern.getName())) {
265 throw new DuplicateNameException("Action pattern '" + actionPattern.getName() + "' has duplicate name in POSH plan.");
266 }
267
268 actionPattern.setParent(this);
269 _actionPatterns.add(actionPattern);
270
271
272 if (this.isCycled()) {
273 _actionPatterns.remove(actionPattern);
274 throw new CycleException("Action pattern '" + actionPattern.getName() + "' is causing cycle.");
275 }
276
277 emitChildNode(actionPattern);
278
279 refreshActions();
280 }
281
282
283
284
285
286
287 public List<ActionPattern> getActionPatterns() {
288 return Collections.unmodifiableList(this._actionPatterns);
289 }
290
291
292
293
294
295
296 protected void setDriveCollection(DriveCollection dc) {
297 dc.setParent(this);
298 if (this._driveCollection != null) {
299 this._driveCollection.remove();
300 }
301
302 this._driveCollection = dc;
303
304 emitChildNode(this._driveCollection);
305 }
306
307 public DriveCollection getDriveCollection() {
308 return this._driveCollection;
309 }
310
311
312
313
314
315
316 public boolean isCycled() {
317
318 for (ActionPattern apNode : this._actionPatterns) {
319 if (findCycle(apNode, new HashSet<String>())) {
320 return true;
321 }
322 }
323 for (Competence compNode : this._competences) {
324 if (findCycle(compNode, new HashSet<String>())) {
325 return true;
326 }
327 }
328 return false;
329 }
330
331 private boolean findCycle(ActionPattern apNode, Set<String> set) {
332 if (set.contains(apNode.getName())) {
333 return true;
334 }
335 set.add(apNode.getName());
336
337 for (TriggeredAction action : apNode._actions) {
338 ActionPattern actionAP;
339 if ((actionAP = getAP(action.getName())) != null) {
340 if (findCycle(actionAP, set)) {
341 return true;
342 }
343 }
344
345 Competence actionComp;
346 if ((actionComp = getC(action.getName())) != null) {
347 if (findCycle(actionComp, set)) {
348 return true;
349 }
350 }
351 }
352 set.remove(apNode.getName());
353 return false;
354 }
355
356 private boolean findCycle(Competence compNode, Set<String> set) {
357 if (set.contains(compNode.getName())) {
358 return true;
359 }
360
361 set.add(compNode.getName());
362
363 for (CompetenceElement cAtom : compNode.getChildDataNodes()) {
364 TriggeredAction action = cAtom.getAction();
365
366 ActionPattern actionAP;
367 if ((actionAP = getAP(action.getName())) != null) {
368 if (findCycle(actionAP, set)) {
369 return true;
370 }
371 }
372
373 Competence actionComp;
374 if ((actionComp = getC(action.getName())) != null) {
375 if (findCycle(actionComp, set)) {
376 return true;
377 }
378 }
379 }
380 set.remove(compNode.getName());
381 return false;
382 }
383
384
385
386
387
388
389
390
391
392
393
394 protected List<String> getAPorCompActions(String ident) {
395 ActionPattern ap = this.getAP(ident);
396 if (ap != null) {
397 LinkedList<String> actionList = new LinkedList<String>();
398
399 for (TriggeredAction a : ap._actions) {
400 actionList.add(a.getName());
401 }
402 return actionList;
403 }
404
405 Competence cn = this.getC(ident);
406 if (cn != null) {
407 LinkedList<String> actionList = new LinkedList<String>();
408 for (CompetenceElement ca : cn.getChildDataNodes()) {
409 if (ca.getAction() != null) {
410 actionList.add(ca.getAction().getName());
411 }
412 }
413 return actionList;
414 }
415 return new LinkedList<String>();
416 }
417
418
419
420
421 @Override
422 public String toString() {
423 String ret = "(";
424
425 if (this._docstring != null) {
426 ret += "\n" + this._docstring.toString();
427 }
428
429 for (Competence node : _competences) {
430 ret += "\n" + node.toString();
431 }
432
433 for (ActionPattern node : _actionPatterns) {
434 ret += "\n" + node.toString();
435 }
436
437 if (this._driveCollection != null) {
438 ret += "\n" + this._driveCollection.toString();
439 }
440
441 ret += "\n)";
442 return ret;
443 }
444
445
446
447
448
449
450
451
452
453 @Override
454 public List<PoshElement> getChildDataNodes() {
455 List<PoshElement> children = new ArrayList<PoshElement>();
456
457 if (this._docstring != null) {
458 children.add(this._docstring);
459 }
460
461 for (Competence competence : _competences) {
462 children.add(competence);
463 }
464
465 for (ActionPattern actionPattern : _actionPatterns) {
466 children.add(actionPattern);
467 }
468
469 if (this._driveCollection != null) {
470 children.add(this._driveCollection);
471 }
472
473 return children;
474 }
475
476
477
478
479
480
481
482 public synchronized void removeListenersFromTree(PoshElementListener listener) {
483 getRootNode().removeListenersFromTree(this, listener);
484 }
485
486
487
488
489 protected synchronized void removeListenersFromTree(PoshElement node, PoshElementListener listener) {
490 node.removeElementListener(listener);
491
492 for (PoshElement child : node.getChildDataNodes()) {
493 removeListenersFromTree(child, listener);
494 }
495 }
496
497 @Override
498 public boolean moveChild(PoshElement child, int relativePosition) {
499 if (this._competences.contains(child)) {
500 return moveNodeInList(_competences, child, relativePosition);
501 }
502 if (this._actionPatterns.contains(child)) {
503 return moveNodeInList(_actionPatterns, child, relativePosition);
504 }
505 return false;
506 }
507 public static final DataFlavor dataFlavor = new DataFlavor(PoshPlan.class, "posh_tree_root");
508
509 @Override
510 public DataFlavor getDataFlavor() {
511 return dataFlavor;
512 }
513
514 @Override
515 public void addChildDataNode(PoshElement newChild) throws ParseException {
516 if (newChild instanceof DocString) {
517 this.setDocString((DocString) newChild);
518 } else if (newChild instanceof Competence) {
519 this.addCompetence((Competence) newChild);
520 } else if (newChild instanceof ActionPattern) {
521 this.addActionPattern((ActionPattern) newChild);
522 } else if (newChild instanceof DriveCollection) {
523 this.setDriveCollection((DriveCollection) newChild);
524 } else {
525 throw new RuntimeException("Class " + newChild.getClass().getSimpleName() + " not accepted.");
526 }
527
528 }
529
530 @Override
531 public void neutralizeChild(PoshElement childNode) {
532 if (this._docstring == childNode) {
533 this._docstring = null;
534 childNode.remove();
535 } else if (this._competences.contains(childNode)) {
536 this._competences.remove(childNode);
537 childNode.remove();
538 } else if (this._actionPatterns.contains(childNode)) {
539 this._actionPatterns.remove(childNode);
540 childNode.remove();
541 } else if (this._driveCollection == childNode) {
542 this._driveCollection = null;
543 childNode.remove();
544 }
545 }
546
547
548
549
550
551
552 public void emitTree() {
553 for (PoshElement pe : this.getChildDataNodes()) {
554 this.emitChildNode(pe);
555 }
556 }
557
558
559
560
561
562
563 public void synchronizePlan(InputStream stream) throws ParseException, CycleException {
564 PoshParser parser = new PoshParser(stream);
565 PoshPlan parsedPlan = parser.parsePlan();
566
567
568 if (_docstring != null) {
569 neutralizeChild(_docstring);
570 }
571 if (_driveCollection != null) {
572 neutralizeChild(_driveCollection);
573 }
574
575 ActionPattern[] aps = getActionPatterns().toArray(new ActionPattern[0]);
576 for (ActionPattern ap : aps) {
577 neutralizeChild(ap);
578 }
579
580 Competence[] cs = getCompetences().toArray(new Competence[0]);
581 for (Competence c : cs) {
582 neutralizeChild(c);
583 }
584
585
586 this.setDocString(parsedPlan._docstring);
587
588 this.setDriveCollection(parsedPlan._driveCollection);
589 for (ActionPattern ap : parsedPlan.getActionPatterns()) {
590 addActionPattern(ap);
591 }
592 for (Competence c : parsedPlan.getCompetences()) {
593 addCompetence(c);
594 }
595 }
596 }