1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package fr.ove.openmath.jome.model;
30
31 import java.util.*;
32 import fr.ove.utils.*;
33 import fr.ove.openmath.jome.behaviour.*;
34 import fr.ove.openmath.jome.model.*;
35 import fr.ove.openmath.jome.model.events.*;
36 import fr.ove.openmath.jome.ctrlview.events.*;
37 import fr.ove.openmath.jome.model.evaluation.*;
38
39 /***
40 * @author © 2000 DIRAT Laurent
41 * @version 2.1 10/01/2000
42 */
43 public abstract class FormulaTreeStructure extends Node implements ControlListener, Iconifiable, fr.ove.utils.Comparable, Maskable, Modifiable {
44 /***
45 * To check if we consider the instance as a template or not. <BR>
46 * (usefull for the building of the formula tree structure).
47 * By default, the new intance create is not a template.
48 */
49 private boolean isTemplate = false;
50
51 /***
52 * The priority of the instance considered as an operator.
53 */
54 private int asOperatorPriority;
55
56 /***
57 * The priority of the instance considered as an operand.
58 */
59 private int asOperandPriority;
60
61 /***
62 * The list of listeners of the instance
63 */
64 private Vector listeners = new Vector();
65
66 /***
67 * Flag to set if we allow the move of the children (so operands) of the instance.<BR>
68 * In other word, says some kind of commutativity of the operator.<BR>
69 * The default is <CODE>false</CODE> because only "few" operators have this property.
70 */
71 private boolean areOperandsMovable = false;
72
73 /***
74 * The resources manager
75 */
76 static FormulaResourcesManager resourcesManager = new FormulaResourcesManager("fr.ove.openmath.jome.model.resources2");
77
78 /***
79 * theresource indentifier of the instance
80 */
81 private String resourceIdentifier;
82
83 private boolean isCrossRef = false;
84
85
86 public void setCrossRef(boolean ref){
87 isCrossRef = ref;
88 }
89
90 public boolean getCrossRef(){
91 return isCrossRef;
92 }
93
94
95
96
97 /***
98 * Registers another listener to be informed of changes of the FTS.
99 * @param modelListener a listener to add.
100 */
101 public void addModelListener(ModelListener modelListener) {
102 listeners.addElement(modelListener);
103 }
104
105 /***
106 * Removes a listener.
107 * @param modelListener a listener to remove.
108 */
109 public void removeModelListener(ModelListener modelListener) {
110 listeners.removeElement(modelListener);
111 }
112
113 /***
114 * Removes all the listeners.
115 */
116 public void removeAllModelListener() {
117 listeners.setSize(0);
118 }
119
120 /***
121 * Fires a ModelEvent event to registered listeners.
122 * @param modelEvent event encapsulating relevant information.
123 */
124 public void fireModelEvent(ModelEvent modelEvent) {
125 for (int i = 0; i < listeners.size(); i++)
126 ((ModelListener)listeners.elementAt(i)).consumeModelEvent(modelEvent);
127 }
128
129 /***
130 * Returns all the registered listener of the instance.
131 */
132 public Vector getListeners() {
133 return listeners;
134 }
135
136
137
138
139
140 /***
141 * Sets the resource identifier of the instance.
142 * @param the resource identifier.
143 */
144 public void setResourceIdentifier(String resourceIdentifier) {
145 this.resourceIdentifier = resourceIdentifier;
146 }
147
148 /***
149 * Returns the resource identifier of the instance.
150 */
151 public String getResourceIdentifier() {
152 return resourceIdentifier;
153 }
154
155 /***
156 * Sets the as operator priority
157 * @param asOperatorPriority the priority
158 */
159 public void setAsOperatorPriority(int asOperatorPriority) {
160 this.asOperatorPriority = asOperatorPriority;
161 }
162
163 /***
164 * Returns the priority of the instance viewed as an operator.
165 * @return the priority of the instance viewed as an operator.
166 */
167 public int getAsOperatorPriority() {
168 return asOperatorPriority;
169 }
170
171 /***
172 * Sets the as operand priority
173 * @param asOperandPriority the priority
174 */
175 public void setAsOperandPriority(int asOperandPriority) {
176 this.asOperandPriority = asOperandPriority;
177 }
178
179 /***
180 * Returns the priority of the instance viewed as an operand.
181 * @return the priority of the instance viewed as an operand.
182 */
183 public int getAsOperandPriority() {
184 return asOperandPriority;
185 }
186
187 /***
188 * Returns <CODE>true</CODE> if it is a template.<BR>
189 * <CODE>false</CODE> otherwise.
190 */
191 public boolean isTemplate() {
192 return isTemplate;
193 }
194
195 /***
196 * Sets the instance as a template.
197 */
198 public void setIsTemplate(boolean isTemplate) {
199 this.isTemplate = isTemplate;
200 }
201
202 /***
203 * Returns the node (operator), which is the position in the formula tree, where the
204 * instance have to be inserted.
205 *
206 * @param current the current insert position in the formula tree.
207 * @return the insert position in the formula tree for the instance.
208 */
209 public FormulaTreeStructure findLocation(FormulaTreeStructure current) {
210
211 while (asOperandPriority < current.getAsOperatorPriority())
212 current = (FormulaTreeStructure) current.getFather();
213
214 return current;
215 }
216
217 /***
218 * Returns the father of the node which, from the current instance, have the specified
219 * priority.
220 *
221 * @param priority the specified priority.
222 * @return the desired father.
223 */
224 public FormulaTreeStructure goTo(int priority) {
225 FormulaTreeStructure current = this;
226
227
228
229 int prio = current.asOperatorPriority;
230 if (current.asOperatorPriority == priority)
231 current = (FormulaTreeStructure) current.getFather();
232
233 while ((current.asOperatorPriority != priority) &&
234 (((FormulaTreeStructure)current.getFather()).asOperatorPriority != 0))
235 current = (FormulaTreeStructure) current.getFather();
236
237 return (FormulaTreeStructure) current.getFather();
238 }
239
240
241
242
243
244
245 public void setAreOperandsMovable(boolean areOperandsMovable) {
246 this.areOperandsMovable = areOperandsMovable;
247 }
248
249
250
251
252
253 public boolean getAreOperandsMovable() {
254 return areOperandsMovable;
255 }
256
257 /***
258 * Moves the specified list of the instance children to the specified
259 * rank. The first child in the list has its rank setted to the specified
260 * one, the second to the first+1, ...and so on.
261 * @param list the list of the instance operands to move.
262 * @param rank the specified rank.
263 */
264 public void moveOperands(Vector list, int rank) {
265
266 moveChildren(list, rank);
267
268 ModelEvent modelEvent = new ModelEvent(this);
269
270 modelEvent.setAction(ModelEvent.REBUILD, null);
271
272 fireModelEvent(modelEvent);
273
274
275 modelEvent.setAction(ModelEvent.UPDATE, null);
276
277 fireModelEvent(modelEvent);
278 }
279
280
281
282
283
284
285
286
287 /***
288 * Tests if the instance is equal to the specified one.
289 * @param toCompare the instance to compare with the current instance.
290 */
291 public boolean isEqual(fr.ove.utils.Comparable toCompare) {
292
293 return false;
294 }
295
296 /***
297 * Tests if the instance is greater than the specified one.
298 * @param toCompare the instance to compare with the current instance.
299 */
300 public boolean isGreater(fr.ove.utils.Comparable toCompare) {
301
302 return false;
303 }
304
305 /***
306 * Tests if the instance is greater or equal than the specified one.
307 * @param toCompare the instance to compare with the current instance.
308 */
309 public boolean isGreaterOrEqual(fr.ove.utils.Comparable toCompare) {
310
311 return false;
312 }
313
314 /***
315 * Tests if the instance is lesser than the specified one.
316 * @param toCompare the instance to compare with the current instance.
317 */
318 public boolean isLesser(fr.ove.utils.Comparable toCompare) {
319
320 return false;
321 }
322
323 /***
324 * Tests if the instance is lesser or equal than the specified one.
325 * @param toCompare the instance to compare with the current instance.
326 */
327 public boolean isLesserOrEqual(fr.ove.utils.Comparable toCompare) {
328
329 return false;
330 }
331
332
333
334
335
336
337
338
339 /***
340 * Associates an icon name to the instance.
341 * @param iconName the name of the icon
342 */
343 public void setIconName(String iconName) {
344
345
346 }
347
348 /***
349 * Returns the name of the icon associated to the instance.<BR>
350 * The icon name is the name of the ressource identifier where "_Ico" added to the end.
351 * @returns The name of the icon, or <CODE>null</CODE> if there is no name
352 * associated.
353 */
354 public String getIconName() {
355 return resourceIdentifier + "_Ico";
356 }
357
358 /***
359 * @return <CODE>true</CODE> if the instance is an icon. <CODE>false</CODE> otherwise.
360 */
361 public boolean isIcon() {
362 return false;
363 }
364
365 /***
366 * Iconifies the instance.
367 */
368 public void iconify() {
369 if (isIconifiable()) {
370 Icon icon = new Icon(this);
371
372 icon.addIconified(this);
373
374 icon.insert(this);
375 }
376 }
377
378 /***
379 * Uniconifies the instance.
380 */
381 public void uniconify() {
382
383 }
384
385
386 /***
387 * Uniconifies all the iconified parts of the instance.
388 */
389 public void uniconifyAll() {
390 if (getNbChildren() != 0) {
391 boolean rebuildDisplay = false;
392
393
394 FormulaTreeStructure fts = null;
395
396
397
398
399
400
401
402
403
404
405 for (int i = 0; i < getNbChildren(); i++) {
406 fts = (FormulaTreeStructure) getChild(i);
407 if (fts.isIcon()) {
408 fts.uniconify();
409 rebuildDisplay = true;
410 i = -1;
411 }
412 }
413
414
415 for (Enumeration e = getChildren().elements(); e.hasMoreElements(); )
416 ((FormulaTreeStructure) e.nextElement()).uniconifyAll();
417
418
419 if (rebuildDisplay) {
420
421
422
423
424
425
426 ModelEvent modelEvent = new ModelEvent(this);
427 modelEvent.setAction(ModelEvent.REBUILD, null);
428 fireModelEvent(modelEvent);
429 }
430 }
431 }
432
433 /***
434 * Sets the instance as iconifiable.
435 * @param isIconifiable <CODE>true</CODE> if the instance is iconifiable.
436 * <CODE>false</CODE> otherwise.
437 */
438 public void setIsIconifiable(boolean isIconifiable) {
439
440
441 }
442
443 /***
444 * Returns <CODE>true</CODE> if the instance is iconifiable.
445 * <CODE>false</CODE> otherwise.
446 */
447 public boolean isIconifiable() {
448 return true;
449 }
450
451
452
453
454
455
456
457
458
459 /***
460 * Consumes (i.e. treats) the event received.
461 * @param controlEvent the event to consume.
462 */
463 public void consumeControlEvent(ControlEvent controlEvent) {
464 ModelEvent modelEvent;
465 int action = controlEvent.getAction();
466 FormulaTreeStructure fts = null;
467
468 switch (action) {
469 case ControlEvent.ADD :
470
471 break;
472 case ControlEvent.REMOVE :
473
474 break;
475 case ControlEvent.ICONIFY :
476
477 Vector toIconify = (Vector) controlEvent.getArgument();
478 Icon icon = null;
479 if (toIconify.size() == 1) {
480 fts = (FormulaTreeStructure) toIconify.elementAt(0);
481
482 if (fts.isIconifiable()) {
483
484 icon = new Icon(fts);
485
486 icon.addIconified(fts);
487
488 icon.insert(fts);
489 }
490
491 fts = (FormulaTreeStructure) icon.getFather();
492 }
493 else {
494
495
496 fts = (FormulaTreeStructure) ((FormulaTreeStructure) toIconify.elementAt(0)).getFather();
497
498 icon = new Icon(fts);
499
500 int countToIconify = toIconify.size();
501 for (int i = 0; i < countToIconify; i++)
502 icon.addIconified((FormulaTreeStructure) toIconify.elementAt(i));
503
504 icon.insert(icon.getIconified(0));
505 }
506
507
508 modelEvent = new ModelEvent(fts);
509 modelEvent.setAction(ModelEvent.ADD, icon);
510 fts.fireModelEvent(modelEvent);
511
512
513 modelEvent.setAction(ModelEvent.UPDATE, null);
514 fts.fireModelEvent(modelEvent);
515
516 break;
517
518 case ControlEvent.UNICONIFY :
519
520 Icon anIcon = (Icon) controlEvent.getArgument();
521 fts = (FormulaTreeStructure) anIcon.getFather();
522 anIcon.uniconify();
523
524
525
526 modelEvent = new ModelEvent(fts);
527 modelEvent.setAction(ModelEvent.REBUILD, null);
528 fts.fireModelEvent(modelEvent);
529
530
531 modelEvent.setAction(ModelEvent.UPDATE, null);
532
533 fts.fireModelEvent(modelEvent);
534 break;
535
536 case ControlEvent.UNICONIFY_ALL :
537
538 fts = this;
539 while (fts.getFather() != null)
540 fts = (FormulaTreeStructure) getFather();
541
542
543
544 fts.uniconifyAll();
545
546
547
548 modelEvent = new ModelEvent(fts);
549 modelEvent.setAction(ModelEvent.UPDATE, null);
550
551 fts.fireModelEvent(modelEvent);
552 break;
553
554 case ControlEvent.SUBSTITUTE :
555
556
557 Vector toSubstitute = (Vector) controlEvent.getArgument();
558 fts = (FormulaTreeStructure) toSubstitute.elementAt(1);
559
560 Icon substitution = new Icon((String) toSubstitute.elementAt(0));
561
562 int countToIconify = toSubstitute.size();
563
564 if ((countToIconify == 2) && !fts.isIconifiable())
565 break;
566
567 for (int i = 1; i < countToIconify; i++)
568 substitution.addIconified((FormulaTreeStructure) toSubstitute.elementAt(i));
569
570
571 substitution.insert(fts);
572
573
574
575 fts = (FormulaTreeStructure) substitution.getFather();
576
577
578 modelEvent = new ModelEvent(fts);
579 modelEvent.setAction(ModelEvent.ADD, substitution);
580 fts.fireModelEvent(modelEvent);
581
582 modelEvent.setAction(ModelEvent.UPDATE, null);
583 fts.fireModelEvent(modelEvent);
584 break;
585 }
586 }
587
588
589
590
591
592
593
594 /***
595 * Sets the instance as vissible or not.
596 * @param isVisible <CODE>true</CODE> if the instance is visible. <CODE>false</CODE> otherwise.
597 */
598 public void setIsVisble(boolean isVisible) {
599
600
601 }
602
603 /***
604 * Checks if the instance is visible.
605 * @returns <CODE>true</CODE> if the instance is visible. <CODE>false</CODE> otherwise.
606 */
607 public boolean isVisible() {
608
609
610 return true;
611 }
612
613
614
615
616
617
618
619
620 /***
621 * Sets the value.
622 */
623 public void setValue(String value) {
624 }
625
626 /***
627 * Returns the value.
628 */
629 public String getValue() {
630 return null;
631 }
632
633
634
635
636
637
638
639
640 /***
641 * To check is the instance is an operator.
642 * @return <CODE>true</CODE> if it is an operator. <CODE>false</CODE> otherwise.
643 */
644 public abstract boolean isOperator();
645
646 /***
647 * Inserts the instance in the formula tree, from the current insertion position.
648 * (checks the priorities and goes up in the tree if necessary).
649 *
650 * @param current the current insertion position.
651 * @return the new insertion position.
652 */
653 public abstract FormulaTreeStructure insert(FormulaTreeStructure current);
654
655 /***
656 * The Creation of the corresponding linear expression of the formula.
657 */
658 public abstract String createLinear(String linear);
659
660 /***
661 * Evaluates the instance.
662 */
663 public abstract String evaluate();
664 }