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