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.List;
9
10
11
12
13
14
15
16
17
18
19
20 public class Sense extends PoshDummyElement implements Comparable<Sense>, IReferenceElement, INamedElement {
21
22
23
24
25
26 public enum Predicate {
27
28 EQUAL(new String[]{"==", "="}),
29 NOT_EQUAL("!="),
30 LOWER("<"),
31 GREATER(">"),
32 LOWER_OR_EQUAL("<="),
33 GREATER_OR_EQUAL(">="),
34 DEFAULT("==");
35 private String[] stringForm = null;
36
37 private Predicate(String form) {
38 stringForm = new String[]{form};
39 }
40
41 private Predicate(String[] form) {
42 stringForm = form;
43 }
44
45
46
47
48
49
50 public static Predicate getPredicate(String str) {
51 if (str == null)
52 return Predicate.DEFAULT;
53
54 str = str.trim();
55
56 for (Predicate p : Predicate.values()) {
57 for (String form : p.stringForm) {
58 if (form.equals(str)) {
59 return p;
60 }
61 }
62 }
63 throw new IllegalArgumentException("String \"" + str + "\" is not a predicate.");
64 }
65
66
67
68
69
70 public int getId() {
71 for (int i = 0; i < Predicate.values().length; i++) {
72 if (values()[i] == this) {
73 return i;
74 }
75 }
76 throw new RuntimeException("Predicate \"" + this.toString() + "\" wasn't found in list of predicates.");
77 }
78
79 @Override
80 public String toString() {
81 return stringForm[0];
82 }
83 }
84
85
86
87
88
89
90 private PrimitiveCall senseCall;
91
92
93
94
95 private boolean compare = true;
96
97
98
99 private Predicate _predicate = Predicate.DEFAULT;
100
101
102
103
104 private Object operand = true;
105
106
107
108
109
110
111 public Sense(String senseName) {
112 this(new PrimitiveCall(senseName));
113 }
114
115
116
117
118
119
120 public Sense(PrimitiveCall senseCall) {
121 this.senseCall = senseCall;
122 this.compare = false;
123 }
124
125
126
127
128
129
130
131
132
133
134
135 public Sense(PrimitiveCall senseCall, Object operand, Predicate predicate) {
136 assert predicate!= null;
137
138 this.senseCall = senseCall;
139 this.compare = true;
140 this.operand = operand;
141 this._predicate = predicate;
142 }
143
144 public static final String psSenseName = "paSenseName";
145 public static final String psArgs = "paSenseArgs";
146 public static final String psPredicateIndex = "paPredicate";
147 public static final String psValue = "paValue";
148 public static final String psType = "paType";
149
150
151
152 public String getSenseName() {
153 return senseCall.getName();
154 }
155
156
157
158
159 public PrimitiveCall getSenseCall() {
160 return senseCall;
161 }
162
163
164
165
166
167 public void setSenseName(String newSenseName) throws InvalidNameException {
168 newSenseName = newSenseName.trim();
169
170 if (!newSenseName.matches(IDENT_PATTERN)) {
171 throw InvalidNameException.create(newSenseName);
172 }
173
174 String oldSenseName = this.senseCall.getName();
175
176 this.senseCall = new PrimitiveCall(newSenseName, senseCall.getParameters());
177 this.firePropertyChange(Sense.psSenseName, oldSenseName, newSenseName);
178 }
179
180
181
182
183
184
185 public String getValueString() {
186 if (operand == null) {
187 return "nil";
188 }
189 if (operand instanceof String) {
190 return '"' + operand.toString() + '"';
191 }
192 return operand.toString();
193 }
194
195
196
197
198
199
200
201
202 public Object getOperand() {
203 return operand;
204 }
205
206
207
208
209
210
211 public void setOperand(Object newValue) {
212 firePropertyChange(Sense.psValue, operand, operand = newValue);
213 }
214
215 public Integer getPredicateIndex() {
216 return this._predicate.getId();
217 }
218
219 public Predicate getPredicate() {
220 return this._predicate;
221 }
222
223
224
225
226
227 public void setPredicate(Predicate newPredicate) {
228 compare = true;
229 this._predicate = newPredicate;
230 this.firePropertyChange(Sense.psPredicateIndex, null, newPredicate.getId());
231 }
232
233
234
235
236
237 public void setPredicateIndex(Integer newPredicateIndex) {
238 if (newPredicateIndex != null) {
239 this._predicate = Predicate.values()[newPredicateIndex];
240 this.firePropertyChange(Sense.psPredicateIndex, null, newPredicateIndex);
241 } else {
242 this._predicate = Predicate.DEFAULT;
243 this.firePropertyChange(Sense.psPredicateIndex, null, Predicate.DEFAULT.getId());
244 }
245 }
246
247 @Override
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 }