1 package cz.cuni.amis.pogamut.sposh.elements;
2
3 import cz.cuni.amis.pogamut.sposh.engine.PoshEngine;
4 import cz.cuni.amis.pogamut.sposh.exceptions.CycleException;
5 import cz.cuni.amis.pogamut.sposh.exceptions.DuplicateNameException;
6 import cz.cuni.amis.pogamut.sposh.exceptions.InvalidFormatException;
7 import cz.cuni.amis.pogamut.sposh.exceptions.InvalidNameException;
8 import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
9 import java.awt.datatransfer.DataFlavor;
10 import java.io.StringReader;
11 import java.util.*;
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public class Sense extends PoshDummyElement implements Comparable<Sense>, IReferenceElement, INamedElement {
28
29
30
31
32
33
34 public enum Predicate {
35
36 EQUAL(new String[]{"==", "="}),
37 NOT_EQUAL("!="),
38 LOWER("<"),
39 GREATER(">"),
40 LOWER_OR_EQUAL("<="),
41 GREATER_OR_EQUAL(">="),
42 DEFAULT("==");
43 private String[] stringForm = null;
44
45 private Predicate(String form) {
46 stringForm = new String[]{form};
47 }
48
49 private Predicate(String[] form) {
50 stringForm = form;
51 }
52
53
54
55
56
57
58
59 public static Predicate getPredicate(String str) {
60 if (str == null) {
61 return Predicate.DEFAULT;
62 }
63
64 str = str.trim();
65
66 for (Predicate p : Predicate.values()) {
67 for (String form : p.stringForm) {
68 if (form.equals(str)) {
69 return p;
70 }
71 }
72 }
73 throw new IllegalArgumentException("String \"" + str + "\" is not a predicate.");
74 }
75
76
77
78
79
80
81
82 public int getId() {
83 for (int i = 0; i < Predicate.values().length; i++) {
84 if (values()[i] == this) {
85 return i;
86 }
87 }
88 throw new RuntimeException("Predicate \"" + this.toString() + "\" wasn't found in list of predicates.");
89 }
90
91 @Override
92 public String toString() {
93 return stringForm[0];
94 }
95
96
97
98
99 public static Predicate[] getPredicates() {
100 List<Predicate> predicates = new LinkedList<Predicate>();
101 for (Predicate predicate : values()) {
102 if (predicate != Predicate.DEFAULT) {
103 predicates.add(predicate);
104 }
105 }
106 return predicates.toArray(new Predicate[predicates.size()]);
107 }
108 }
109
110
111
112 private PrimitiveCall senseCall;
113
114
115
116
117 private boolean compare = true;
118
119
120
121 private Predicate _predicate = Predicate.DEFAULT;
122
123
124
125 private Object operand = true;
126
127
128
129
130
131
132
133 public Sense(String senseName) {
134 this(new PrimitiveCall(senseName));
135 }
136
137
138
139
140
141
142
143 public Sense(PrimitiveCall senseCall) {
144 this.senseCall = senseCall;
145 this.compare = false;
146 }
147
148
149
150
151
152
153
154 public Sense(PrimitiveCall senseCall, Object operand, Predicate predicate) {
155 assert predicate != null;
156
157 this.senseCall = senseCall;
158 this.compare = true;
159 this.operand = operand;
160 this._predicate = predicate;
161 }
162 public static final String psSenseName = "paSenseName";
163 public static final String psArgs = "paSenseArgs";
164 public static final String psPredicateIndex = "paPredicate";
165 public static final String psValue = "paValue";
166 public static final String psType = "paType";
167
168
169
170
171 public PrimitiveCall getCall() {
172 return senseCall;
173 }
174
175
176
177
178
179
180
181 public void setSenseName(String newSenseName) throws InvalidNameException {
182 newSenseName = newSenseName.trim();
183
184 if (!newSenseName.matches(IDENT_PATTERN)) {
185 throw InvalidNameException.create(newSenseName);
186 }
187
188 String oldSenseName = this.senseCall.getName();
189
190 this.senseCall = new PrimitiveCall(newSenseName, senseCall.getParameters());
191 this.firePropertyChange(Sense.psSenseName, oldSenseName, newSenseName);
192 }
193
194
195
196
197
198
199 public String getValueString() {
200 if (operand == null) {
201 return "nil";
202 }
203 if (operand instanceof String) {
204 return '"' + operand.toString() + '"';
205 }
206 return operand.toString();
207 }
208
209
210
211
212
213
214
215
216 public Object getOperand() {
217 return operand;
218 }
219
220
221
222
223
224
225 public void setOperand(Object newValue) {
226 firePropertyChange(Sense.psValue, operand, operand = newValue);
227 }
228
229 public Integer getPredicateIndex() {
230 return this._predicate.getId();
231 }
232
233 public Predicate getPredicate() {
234 return this._predicate;
235 }
236
237
238
239
240
241
242
243 public void setPredicate(Predicate newPredicate) {
244 compare = true;
245 this._predicate = newPredicate;
246 this.firePropertyChange(Sense.psPredicateIndex, null, newPredicate.getId());
247 }
248
249
250
251
252
253
254 public void setPredicateIndex(Integer newPredicateIndex) {
255 if (newPredicateIndex != null) {
256 this._predicate = Predicate.values()[newPredicateIndex];
257 this.firePropertyChange(Sense.psPredicateIndex, null, newPredicateIndex);
258 } else {
259 this._predicate = Predicate.DEFAULT;
260 this.firePropertyChange(Sense.psPredicateIndex, null, Predicate.DEFAULT.getId());
261 }
262 }
263
264 @Override
265 public Arguments getArguments() {
266 return senseCall.getParameters();
267 }
268
269 public void setArguments(Arguments newArguments) {
270 String senseName = senseCall.getName();
271 Arguments oldArguments = senseCall.getParameters();
272 this.senseCall = new PrimitiveCall(senseName, newArguments);
273
274 this.firePropertyChange(Sense.psArgs, oldArguments, newArguments);
275 }
276
277
278
279
280
281
282
283
284
285
286 private FormalParameters getParentParameters() {
287 PoshElement parent = getParent();
288
289 if (parent == null) {
290 return null;
291 }
292
293 if (parent instanceof DriveElement) {
294 return new FormalParameters();
295 }
296 if (parent instanceof DriveCollection) {
297 return new FormalParameters();
298 }
299 if (parent instanceof CompetenceElement) {
300 CompetenceElement cel = (CompetenceElement) parent;
301 Competence competence = cel.getParent();
302 return competence.getParameters();
303 }
304 throw new IllegalStateException("Unexpected parent " + parent.getClass().getCanonicalName());
305 }
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 public void parseSense(String input) throws ParseException {
323
324 String adjustedInput = '(' + input + ')';
325 PoshParser parser = new PoshParser(new StringReader(adjustedInput));
326 FormalParameters parameters = getParentParameters();
327 Sense parsedSense = parser.fullSense(parameters);
328 changeTo(parsedSense);
329 }
330
331
332
333
334
335
336
337 public void changeTo(Sense other) throws InvalidNameException {
338 this.compare = other.compare;
339 this.setSenseName(other.getName());
340 this.setArguments(other.senseCall.getParameters());
341 this.setOperand(other.getOperand());
342 this.setPredicateIndex(other.getPredicateIndex());
343 }
344
345
346
347
348
349
350
351 @Override
352 public String toString() {
353 String res = "(" + senseCall;
354
355 if (compare) {
356 if (operand instanceof String) {
357 res += " \"" + operand + '"';
358 } else {
359 res += " " + operand;
360 }
361 if (_predicate != Predicate.DEFAULT) {
362 res += " " + _predicate;
363 }
364 }
365
366 return res + ")";
367 }
368
369 @Override
370 public String getName() {
371 return senseCall.getName();
372 }
373
374
375
376
377
378
379
380
381
382
383 @Override
384 public void rename(String newName) throws InvalidNameException, CycleException, DuplicateNameException {
385 throw new UnsupportedOperationException("Not yet implemented");
386 }
387
388 @Override
389 public List<PoshElement> getChildDataNodes() {
390 return Collections.<PoshElement>emptyList();
391 }
392
393 @Override
394 public boolean moveChild(int newIndex, PoshElement child) {
395 throw new UnsupportedOperationException();
396 }
397 public static final DataFlavor dataFlavor = new DataFlavor(Sense.class, "sense");
398
399 @Override
400 public DataFlavor getDataFlavor() {
401 return dataFlavor;
402 }
403
404 @Override
405 public LapType getType() {
406 return LapType.SENSE;
407 }
408
409
410
411
412
413
414
415
416
417 public String getRepresentation() {
418 return getRepresentation(getName());
419 }
420
421
422
423
424
425
426
427
428
429
430
431
432 public String getRepresentation(String name) {
433 StringBuilder representation = new StringBuilder(name);
434 Arguments args = senseCall.getParameters();
435 if (!args.isEmpty()) {
436 representation.append('(').append(args.toString()).append(')');
437 }
438
439 boolean predicateIsEqual = _predicate == Predicate.EQUAL || _predicate == Predicate.DEFAULT;
440 boolean valueIsTrue = Boolean.TRUE.equals(operand);
441
442 if (!(predicateIsEqual && valueIsTrue)) {
443 representation.append(_predicate);
444 representation.append(operand);
445 }
446 return representation.toString();
447 }
448
449 @Override
450 public int compareTo(Sense o) {
451 return this.getRepresentation().compareTo(o.getRepresentation());
452 }
453
454
455
456
457
458
459
460
461
462
463 public Trigger<?> getTrigger() {
464 PoshElement senseParent = this.getParent();
465 Trigger<?> senseTrigger;
466 if (senseParent instanceof DriveCollection) {
467 DriveCollection dc = (DriveCollection) senseParent;
468 senseTrigger = dc.getGoal();
469 } else if (senseParent instanceof CompetenceElement) {
470 CompetenceElement celParent = (CompetenceElement) senseParent;
471 senseTrigger = celParent.getTrigger();
472 } else if (senseParent instanceof DriveElement) {
473 DriveElement driveParent = (DriveElement) senseParent;
474 senseTrigger = driveParent.getTrigger();
475 } else {
476 throw new IllegalArgumentException("Unexpected parent of sense " + this.getRepresentation() + ": " + senseParent);
477 }
478 return senseTrigger;
479 }
480
481
482
483
484
485
486
487
488
489 public void removeFromParent() {
490 assert getParent() != null;
491 Trigger<?> senseTrigger = getTrigger();
492 senseTrigger.remove(this);
493 }
494 }