source: trunk/src/org/expeditee/actions/Simple.java@ 390

Last change on this file since 390 was 390, checked in by ra33, 16 years ago

Added auto colour wheel... when drawing rectangles...
Fixed computeTree bug
Added TDFC for rectangles.

File size: 99.7 KB
Line 
1package org.expeditee.actions;
2
3import java.awt.Color;
4import java.awt.Point;
5import java.awt.event.InputEvent;
6import java.awt.geom.Point2D;
7import java.io.BufferedReader;
8import java.io.InputStreamReader;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.HashMap;
12import java.util.LinkedList;
13import java.util.List;
14import java.util.Map;
15import java.util.Random;
16import java.util.regex.Pattern;
17
18import org.expeditee.agents.Agent;
19import org.expeditee.agents.DefaultAgent;
20import org.expeditee.agents.DisplayTree;
21import org.expeditee.agents.SearchAgent;
22import org.expeditee.agents.SearchFramesetAndReplace;
23import org.expeditee.agents.SearchFrameset;
24import org.expeditee.agents.SearchTreeAndReplace;
25import org.expeditee.agents.SearchTree;
26import org.expeditee.agents.WriteTree;
27import org.expeditee.gui.AttributeUtils;
28import org.expeditee.gui.AttributeValuePair;
29import org.expeditee.gui.Browser;
30import org.expeditee.gui.DisplayIO;
31import org.expeditee.gui.Frame;
32import org.expeditee.gui.FrameGraphics;
33import org.expeditee.gui.FrameIO;
34import org.expeditee.gui.FrameMouseActions;
35import org.expeditee.gui.FrameUtils;
36import org.expeditee.gui.FreeItems;
37import org.expeditee.gui.MessageBay;
38import org.expeditee.io.Conversion;
39import org.expeditee.items.Dot;
40import org.expeditee.items.Item;
41import org.expeditee.items.ItemUtils;
42import org.expeditee.items.Line;
43import org.expeditee.items.Text;
44import org.expeditee.items.Item.HighlightMode;
45import org.expeditee.math.ExpediteeJEP;
46import org.expeditee.simple.AboveMaxParametreCountException;
47import org.expeditee.simple.BelowMinParametreCountException;
48import org.expeditee.simple.Context;
49import org.expeditee.simple.IncorrectParametreCountException;
50import org.expeditee.simple.IncorrectTypeException;
51import org.expeditee.simple.Pointers;
52import org.expeditee.simple.Primitives;
53import org.expeditee.simple.SBoolean;
54import org.expeditee.simple.SCharacter;
55import org.expeditee.simple.SInteger;
56import org.expeditee.simple.SPointer;
57import org.expeditee.simple.SPrimitive;
58import org.expeditee.simple.SReal;
59import org.expeditee.simple.SString;
60import org.expeditee.simple.SVariable;
61import org.expeditee.simple.UnitTestFailedException;
62import org.expeditee.stats.AgentStats;
63import org.expeditee.stats.SessionStats;
64import org.nfunk.jep.Node;
65
66public class Simple implements Runnable {
67
68 private static final String DEFAULT_STRING = "$s.";
69
70 private static final String DEFAULT_BOOLEAN = "$b.";
71
72 private static final String DEFAULT_CHAR = "$c.";
73
74 private static final String DEFAULT_INTEGER = "$i.";
75
76 private static final String DEFAULT_REAL = "$r.";
77
78 private static final String DEFAULT_ITEM = "$ip.";
79
80 private static final String DEFAULT_FRAME = "$fp.";
81
82 private static final String DEFAULT_ASSOCIATION = "$ap.";
83
84 private static final String EXIT_TEXT = "exitall";
85
86 private static enum Status {
87 Exit, OK, Break, Continue, Return, TrueIf, FalseIf;
88 };
89
90 private static final String BREAK2_TEXT = "exitrepeat";
91
92 private static final String BREAK_TEXT = "break";
93
94 private static final String CONTINUE2_TEXT = "nextrepeat";
95
96 private static final String CONTINUE_TEXT = "continue";
97
98 private static final String RETURN_TEXT = "return";
99
100 private static final String LOOP_TEXT = "repeat";
101
102 private static final String TOKEN_SEPARATOR = " +";
103
104 public static final String RUN_FRAME_ACTION = "runframe";
105
106 public static final String DEBUG_FRAME_ACTION = "debugframe";
107
108 /**
109 * Keeps track of how many simple programs are running. Used to check if
110 * simple should read in keyboard input. Or if the keyboard input should be
111 * handled normally by Expeditee.
112 */
113 private static int _programsRunning = 0;
114
115 /**
116 * This flag is set to true if Simple should hijack keyboard input from
117 * Expeditee
118 */
119 private static boolean _consumeKeyboardInput = false;
120
121 public static void ProgramFinished() {
122 _programsRunning--;
123 _stop = false;
124 }
125
126 private static LinkedList<Character> _KeyStrokes = new LinkedList<Character>();
127
128 private static boolean _stop;
129
130 private static Agent _agent = null;
131
132 private static boolean _step;
133
134 private static int _stepPause = -1;
135
136 private static Color _stepColor;
137
138 private static boolean _nextStatement;
139
140 public static void KeyStroke(char c) {
141 _KeyStrokes.add(c);
142 }
143
144 public static boolean isProgramRunning() {
145 return _programsRunning > 0;
146 }
147
148 public static boolean consumeKeyboardInput() {
149 return _consumeKeyboardInput && _programsRunning > 0;
150 }
151
152 public static void NewSimpleTest() {
153 Frame newSimpleTest = FrameIO.CreateFrame(DisplayIO.getCurrentFrame()
154 .getFramesetName(), "Test", null);
155 List<String> actions = new ArrayList<String>();
156 actions.add(RUN_FRAME_ACTION);
157 newSimpleTest.getTitleItem().setActions(actions);
158 FrameUtils.DisplayFrame(newSimpleTest, true);
159 MessageBay.displayMessage("New test created");
160 }
161
162 public static void NextTest() {
163 Frame next = DisplayIO.getCurrentFrame();
164 do {
165 next = FrameIO.LoadNext(next);
166 } while (next != null && !next.isTestFrame());
167 FrameUtils.DisplayFrame(next, true);
168 }
169
170 public static void PreviousTest() {
171 Frame prev = DisplayIO.getCurrentFrame();
172 do {
173 prev = FrameIO.LoadPrevious(prev);
174 } while (prev != null && !prev.isTestFrame());
175
176 FrameUtils.DisplayFrame(prev, true);
177 }
178
179 public static void LastTest() {
180 Frame next = FrameIO.LoadLast();
181 Frame lastTest = null;
182 do {
183 // check if its a test frame
184 if (next != null && next.isTestFrame()) {
185 lastTest = next;
186 break;
187 }
188
189 next = FrameIO.LoadPrevious(next);
190 } while (next != null);
191
192 FrameUtils.DisplayFrame(lastTest, true);
193 }
194
195 public static void RunSimpleTests(String frameset) {
196 RunSimpleTests(frameset, false, true);
197 }
198
199 public static void RunSimpleTestsVerbose(String frameset) {
200 RunSimpleTests(frameset, true, true);
201 }
202
203 private String _frameset;
204
205 private static boolean _verbose = false;
206
207 public Simple(String frameset, boolean verbose) {
208 _frameset = frameset;
209 _verbose = verbose;
210 }
211
212 public void run() {
213 runSuite();
214 }
215
216 public boolean runSuite() {
217 int testsPassed = 0;
218 int testsFailed = 0;
219
220 FrameIO.SaveFrame(DisplayIO.getCurrentFrame(), false);
221 MessageBay.displayMessage("Starting test suite: " + _frameset,
222 Color.CYAN);
223
224 // Get the next number in the inf file for the _frameset
225 int lastFrameNo = FrameIO.getLastNumber(_frameset);
226
227 // Loop through all the valid frames in the _frameset
228 for (int i = 1; i <= lastFrameNo; i++) {
229 String nextFrameName = _frameset + i;
230 Frame nextFrame = FrameIO.LoadFrame(nextFrameName);
231 if (nextFrame == null)
232 continue;
233 Text frameTitle = nextFrame.getTitleItem();
234 if (frameTitle == null)
235 continue;
236 // Run the frames with the RunFrame action on the title
237 Text title = frameTitle.copy();
238 List<String> actions = title.getAction();
239 if (actions == null || title.isAnnotation())
240 continue;
241 if (actions.get(0).toLowerCase().equals("runframe")) {
242 boolean passed = true;
243 String errorMessage = null;
244 try {
245 title.setLink(nextFrameName);
246 // TODO add the ability to run a setup frame
247 // which sets up variables to be used in all
248 // tests
249 AgentStats.reset();
250 _KeyStrokes.clear();
251 _programsRunning++;
252 Context context = new Context();
253 RunFrameAndReportError(title, context);
254 _programsRunning--;
255 // if the throws exception annotation is on the frame then
256 // it passes only if an exception is thrown
257 if (title.getParentOrCurrentFrame().hasAnnotation(
258 "ThrowsException")) {
259 errorMessage = "Expected exception " + title.toString();
260 passed = false;
261 }
262 } catch (Exception e) {
263 _programsRunning--;
264 if (e instanceof UnitTestFailedException
265 || !title.getParentOrCurrentFrame().hasAnnotation(
266 "ThrowsException")) {
267 errorMessage = e.getMessage();
268 passed = false;
269 }
270 }
271 if (passed) {
272 if (_verbose)
273 MessageBay.displayMessage("Test passed: "
274 + title.toString(), Item.GREEN);
275 testsPassed++;
276 } else {
277 testsFailed++;
278 // Print out the reason for failed tests
279 MessageBay.linkedErrorMessage(errorMessage);
280 if (Simple._stop) {
281 Simple._stop = false;
282 return false;
283 }
284 }
285 }
286 }
287 // The statement below assumes there are no other programs running at
288 // the same time
289 assert (_programsRunning == 0);
290 // Report the number of test passed and failed
291 MessageBay.displayMessage(
292 "Total tests: " + (testsPassed + testsFailed), Color.CYAN);
293 if (testsPassed > 0)
294 MessageBay.displayMessage("Passed: " + testsPassed, Item.GREEN);
295 if (testsFailed > 0)
296 MessageBay.displayMessage("Failed: " + testsFailed, Color.RED);
297 // Remove items from the cursor...
298 FreeItems.getInstance().clear();
299
300 return testsFailed == 0;
301 }
302
303 /**
304 * Runs a suite of tests stored in a given frameset.
305 *
306 * @param frameset
307 * @param verbose
308 * @param newThread
309 * false if tests should be run on the current frame
310 */
311 public static void RunSimpleTests(String frameset, boolean verbose,
312 boolean newThread) {
313 _stop = false;
314 Simple testSuite = new Simple(frameset, verbose);
315 if (newThread) {
316 Thread t = new Thread(testSuite);
317 t.setPriority(Thread.MIN_PRIORITY);
318 t.start();
319 } else {
320 if (!testSuite.runSuite()) {
321 throw new RuntimeException(frameset + " failed");
322 }
323 }
324
325 }
326
327 private static void RunFrame(Frame frame, Text current,
328 boolean acceptKeyboardInput, boolean step, int pause, Color color) {
329 try {
330 if (current != null) {
331 DisplayIO.addToBack(current.getParent());
332 } else {
333 /*TODO we should not have to pass an item just to run a frame!*/
334 current = new Text("Dummy");
335 current.setLink(frame.getName());
336 }
337
338 _stepColor = color == null ? Color.green : color;
339 _stepColor = new Color(_stepColor.getRed(), _stepColor.getGreen(),
340 _stepColor.getBlue(), 50);
341 _stepPause = pause;
342 _step = step;
343 _consumeKeyboardInput = acceptKeyboardInput;
344 FrameIO.SaveFrame(frame, true);
345
346 // an item without a link signals to run the current frame
347 if (current != null && current.getLink() == null) {
348 // Make a copy but hide it
349 current = current.copy();
350 current.setLink(frame.getName());
351 }
352
353 _KeyStrokes.clear();
354
355 Thread t = new Thread(current);
356 t.setPriority(Thread.MIN_PRIORITY);
357 t.start();
358 } catch (Exception e) {
359 e.printStackTrace();
360 }
361 }
362
363 public static void RunFrame(Frame frame, Text current,
364 boolean acceptKeyboardInput) {
365 RunFrame(frame, current, acceptKeyboardInput, false, 0, null);
366 }
367
368 public static void RunFrame(Frame frame, Text current) {
369 RunFrame(frame, current, false);
370 }
371
372 /**
373 * At present programs which accept keyboard input can not be debugged.
374 *
375 * @param current
376 * @param pause
377 */
378 public static void DebugFrame(Frame frame, Text current, float pause,
379 Color color) {
380 if (isProgramRunning()) {
381 stop();
382 }
383 RunFrame(frame, current, false, true, Math.round(pause * 1000), color);
384 }
385
386 /**
387 * At present programs which accept keyboard input can not be debugged.
388 *
389 * @param current
390 * @param pause
391 * the time to pause between
392 */
393 public static void DebugFrame(Frame frame, Text current, float pause) {
394 DebugFrame(frame, current, pause, null);
395 }
396
397 public static void DebugFrame(Frame frame, Text current) {
398 DebugFrame(frame, current, -1.0F, null);
399 }
400
401 private static void FlagError(Item item) {
402 FrameUtils.DisplayFrame(item.getParent().getName(), true);
403 item.setHighlightMode(HighlightMode.Normal);
404 item.setHighlightColor(Color.CYAN);
405 FrameIO.SaveFrame(item.getParent());
406 }
407
408 /**
409 * Runs a simple code begining on a frame linked to by the specified item
410 * parametre.
411 *
412 * @param current
413 * the item that is linked to the frame to be run.
414 */
415 public static Status RunFrameAndReportError(Item current, Context context)
416 throws Exception {
417 // the item must link to a frame
418 if (current.getLink() == null) {
419 throw new Exception("Could not run unlinked item: "
420 + current.toString());
421 }
422
423 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
424
425 // Create frame variables for each linked annotation item on the frame
426 // which has a single word of text corresponding to the variable name
427 for (Text text : child.getAnnotationItems()) {
428 String link = text.getAbsoluteLink();
429 if (link == null)
430 continue;
431 Frame frame = FrameIO.LoadFrame(link);
432 if (frame == null)
433 continue;
434 // Now save the frame as a variable
435 String varName = text.getText().substring(1).trim();
436 if (varName.indexOf(' ') > 0)
437 continue;
438 context.getPointers().setObject(SPointer.framePrefix + varName,
439 frame);
440 context.getPointers().setObject(SPointer.itemPrefix + varName,
441 frame.getTitleItem());
442 context.getPrimitives().add(SString.prefix + varName,
443 new SString(frame.getName()));
444 }
445
446 if (_step) {
447 if (child != DisplayIO.getCurrentFrame()) {
448 DisplayIO.setCurrentFrame(child, true);
449 }
450 DisplayIO.addToBack(child);
451 }
452
453 AgentStats.FrameExecuted();
454
455 // if the frame could not be loaded
456 if (child == null) {
457 throw new Exception("Could not load item link: "
458 + current.toString());
459 }
460
461 // loop through non-title, non-name, text items
462 List<Text> body = child.getBodyTextItems(false);
463
464 // if no item was found
465 if (body.size() == 0)
466 throw new Exception("No code to be executed: " + current.toString());
467
468 Status lastItemStatus = Status.OK;
469 for (Text item : body) {
470 AgentStats.ItemExecuted();
471 try {
472 Color oldColor = item.getBackgroundColor();
473 if (_step) {
474 pause(item);
475 }
476 lastItemStatus = RunItem(item, context, lastItemStatus);
477 if (_step) {
478 if (item.getLink() == null) {
479 item.setBackgroundColor(oldColor);
480 } else {
481 item.setHighlightMode(Item.HighlightMode.None);
482 }
483 }
484
485 if (lastItemStatus != Status.OK) {
486 if (lastItemStatus != Status.TrueIf
487 && lastItemStatus != Status.FalseIf) {
488 if (_step) {
489 DisplayIO.removeFromBack();
490 }
491 return lastItemStatus;
492 }
493 }
494 } catch (ArrayIndexOutOfBoundsException e) {
495 FlagError(item);
496 throw new Exception("Too few parametres: " + item.toString());
497 } catch (NullPointerException e) {
498 FlagError(item);
499 throw new Exception("Null pointer exception: "
500 + item.toString());
501 } catch (RuntimeException e) {
502 FlagError(item);
503 throw new Exception(e.getMessage() + " " + item.toString());
504 } catch (Exception e) {
505 throw new Exception(e.getMessage());
506 }
507 }
508
509 if (_step) {
510 DisplayIO.removeFromBack();
511 if (DisplayIO.getCurrentFrame() != current.getParent())
512 DisplayIO.setCurrentFrame(current.getParent(), true);
513 }
514
515 return Status.OK;
516 }
517
518 /**
519 * @param item
520 * @param oldColor
521 * @throws Exception
522 * @throws InterruptedException
523 */
524 private static void pause(Text item) throws Exception, InterruptedException {
525 if (!_step)
526 return;
527
528 Color oldColor = item.getBackgroundColor();
529 item.setBackgroundColor(_stepColor);
530 item.setHighlightMode(Item.HighlightMode.None);
531
532 // Make sure we are on the frame with this item
533 Frame parent = item.getParentOrCurrentFrame();
534 if (!parent.equals(DisplayIO.getCurrentFrame())) {
535 DisplayIO.setCurrentFrame(parent, true);
536 }
537
538 FrameGraphics.Repaint();
539
540 int timeRemaining;
541 if (_stepPause < 0)
542 timeRemaining = Integer.MAX_VALUE;
543 else
544 timeRemaining = _stepPause;
545
546 while (timeRemaining > 0 && !_nextStatement) {
547 if (_stop) {
548 item.setBackgroundColor(oldColor);
549 item.setHighlightMode(HighlightMode.Normal, _stepColor);
550 throw new Exception("Program terminated");
551 }
552 Thread.sleep(DefaultAgent.TIMER_RESOLUTION);
553 timeRemaining -= DefaultAgent.TIMER_RESOLUTION;
554 }
555 _nextStatement = false;
556 // Turn off the highlighting
557 item.setBackgroundColor(oldColor);
558 }
559
560 private static void pause(double time) throws Exception {
561 for (int i = 0; i < time * 10; i++) {
562 if (_stop) {
563 throw new Exception("Program terminated");
564 }
565 Thread.yield();
566 Thread.sleep(100);
567 }
568 }
569
570 /**
571 * This method should be modified to parse strings correctly
572 *
573 * @param statement
574 * @return
575 */
576 private static String[] parseStatement(Text code) throws Exception {
577 String statement = code.getText().trim();
578 ArrayList<String> tokens = new ArrayList<String>();
579
580 // At the moment annotation items are ignored by the interpreter
581 // // Check special annotation tags for programs
582 // if (statement.length() > 0 && statement.charAt(0) == '@') {
583 // statement = statement.toLowerCase();
584 // // Flags the next unit test as being required to throw an exception
585 // if (statement.equals("@throwsexception")) {
586 // code.getParentOrCurrentFrame().setThrowsException(true);
587 // }
588 // return null;
589 // }
590
591 for (int i = 0; i < statement.length(); i++) {
592 char c = statement.charAt(i);
593 // ignore spaces
594 if (c != ' ') {
595 int startOfToken = i;
596 if (c == '\"') {
597 int endOfToken = statement.length() - 1;
598 // find the end of the string literal
599 while (statement.charAt(endOfToken) != '\"')
600 endOfToken--;
601 if (endOfToken > startOfToken) {
602 tokens.add(statement.substring(startOfToken,
603 endOfToken + 1));
604 } else {
605 throw new RuntimeException("Expected matching \" ");
606 }
607 break;
608 } else if (c == '#' || c == '/') {
609 break;
610 } else {
611 // read in a normal token
612 while (++i < statement.length()
613 && statement.charAt(i) != ' ')
614 ;
615 tokens.add(statement.substring(startOfToken, i)
616 .toLowerCase());
617 }
618 }
619 }
620
621 String[] a = new String[tokens.size()];
622 a = tokens.toArray(a);
623 code.setProcessedText(a);
624 return a;
625 }
626
627 /**
628 * Runs a SIMPLE procedure statement.
629 *
630 * @param tokens
631 * the parsed Call statement.
632 * @param code
633 * the expeditee item containing the procedure call and the link
634 * to the frame with the procedure code.
635 * @param context
636 * the current context from which the procedure call is being
637 * made.
638 * @throws Exception
639 * when errors occur in running the procedure.
640 */
641 private static Status Call(String[] tokens, Item code, Context context)
642 throws Exception {
643 // Check that the call statement is linked
644 if (code.getLink() == null)
645 throw new Exception("Unlinked call statement: " + code.toString());
646
647 Frame procedure = FrameIO.LoadFrame(code.getAbsoluteLink());
648
649 // Add call to the start of the title if it doesnt exist
650 // This makes the call and signature tokens counts match
651 String procedureTitle = procedure.getTitleItem().getFirstLine();
652 if (!procedureTitle.toLowerCase().startsWith("call "))
653 procedureTitle = "call " + procedureTitle;
654
655 // Check that the calling statement matches the procedure
656 // signature
657 String[] procedureSignature = procedureTitle.split(TOKEN_SEPARATOR);
658
659 // Check for the right amount of parametres
660 if (procedureSignature.length < tokens.length)
661 throw new Exception("Call statement has too many parametres: "
662 + code.toString());
663 else if (procedureSignature.length > tokens.length)
664 throw new Exception("Call statement has too few parametres: "
665 + code.toString());
666 // else if (procedureSignature[1].equals(tokens[1]))
667 // throw new Exception("Call statement and procedure name dont match: "
668 // + code.toString());
669
670 // create the new context for the sub procedure
671 Context newContext = new Context();
672 // Check that the types/prefixes match
673 for (int i = 2; i < tokens.length; i++) {
674 // TODO allow for auto casting of primitives
675 if (tokens[i].substring(1, 2).equals(
676 procedureSignature[i].substring(1, 2))) {
677 // Add the variables to the new context
678 if (Primitives.isPrimitive(tokens[i])) {
679 try {
680 // try and get the value for the variable
681 SPrimitive p = context.getPrimitives().getVariable(
682 tokens[i]);
683 newContext.getPrimitives()
684 .add(procedureSignature[i], p);
685 } catch (Exception e) {
686 // If an exception occurs the variable doesnt
687 // exist in the current context
688 // So the variable must be added to both context
689 context.getPrimitives().add(tokens[i], new SString(""));
690 newContext.getPrimitives().add(procedureSignature[i],
691 new SString(""));
692 }
693 } else if (Pointers.isPointer(tokens[i])) {
694 try {
695 // try and get the value for the variable
696 SPointer p = context.getPointers().getVariable(
697 tokens[i]);
698 newContext.getPointers().add(procedureSignature[i], p);
699 } catch (Exception e) {
700 // If an exception occurs the variable doesnt
701 // exist in the current context
702 // So the variable must be added to both context
703 context.getPointers().setObject(tokens[i], null);
704 newContext.getPointers().setObject(
705 procedureSignature[i], null);
706 }
707 } else
708 throw new Exception("Unrecognised variable type: "
709 + tokens[i] + " in " + code.toString());
710 } else
711 throw new IncorrectTypeException(procedureSignature[i], i);
712 }
713
714 // Follow the link and Run the code for the procedure
715 Status result = RunFrameAndReportError(code, newContext);
716 // If a return statement ends the procedure then we accept this as
717 // normal execution
718 switch (result) {
719 case Return:
720 result = Status.OK;
721 break;
722 case Break:
723 throw new Exception(BREAK_TEXT + " statement without matching "
724 + LOOP_TEXT + " in " + code.toString());
725 case Continue:
726 throw new Exception("");
727 }
728
729 // Now copy the values from the procedure context into the
730 // current context
731 for (int i = 2; i < tokens.length; i++) {
732 try {
733 if (Primitives.isPrimitive(tokens[i])) {
734 // try and get the value for the variable
735 SVariable p = context.getPrimitives()
736 .getVariable(tokens[i]);
737 SVariable newP = newContext.getPrimitives().getVariable(
738 procedureSignature[i]);
739 p.setValue(newP);
740 } else {
741 // try and get the value for the variable
742 SVariable p = context.getPointers().getVariable(tokens[i]);
743 SVariable newP = newContext.getPointers().getVariable(
744 procedureSignature[i]);
745 p.setValue(newP);
746 }
747 } catch (Exception e) {
748 assert (false);
749 }
750 }
751
752 return result;
753 }
754
755 /**
756 * Runs a text item on a frame as a SIMPLE statement. The statement is
757 * parsed and if it is a recognised SIMPLE keyword or procedure the code is
758 * executed.
759 *
760 * @param code
761 * the item containing the code to be executed.
762 * @param context
763 * @return
764 * @throws Exception
765 */
766 private static Status RunItem(Text code, Context context,
767 Status lastItemStatus) throws Exception {
768 if (_stop) {
769 throw new Exception("Program terminated");
770 }
771
772 String[] tokens = code.getProcessedText();
773
774 if (tokens == null) {
775 tokens = parseStatement(code);
776 }
777
778 // Annotation items are ignored after parsing running options
779 if (tokens == null) {
780 return Status.OK;
781 // Comments without links are ignored
782 } else if (tokens.length == 0) {
783 if (code.getLink() == null)
784 return Status.OK;
785 else
786 return RunFrameAndReportError(code, context);
787 }
788
789 // At present only set statements can have literals so they
790 // are the only statements that we have to worry about string
791 // literals
792 if (tokens[0].equals("call") && tokens.length >= 2) {
793 return Call(tokens, code, context);
794 // Check if the user wants to display a message
795 // Check for set statements
796 } else if (tokens[0].startsWith("calculatestring")) {
797 assertMinParametreCount(tokens, 1);
798 String toCalculate = context.getPrimitives().getStringValue(
799 tokens[1]);
800 boolean result = true;
801 String error = "";
802 ExpediteeJEP myParser = new ExpediteeJEP();
803 // Add the variables in the system
804 context.getPrimitives().addToParser(myParser);
805 try {
806 Node equation = myParser.parse(toCalculate);
807 String value = myParser.evaluate(equation, false);
808 // Add a new variable if its an assignment statement
809 String newVar = SReal.prefix + myParser.getNewVariable();
810 if (newVar.length() > 0) {
811 try {
812 context.getPrimitives().setValue(newVar,
813 new SString(value));
814 } catch (IncorrectTypeException e) {
815 result = false;
816 error = e.getMessage();
817 }
818 }
819 if (tokens.length > 2) {
820 context.getPrimitives().setValue(tokens[2],
821 new SString(value));
822 }
823 // TODO get the answer
824 } catch (Throwable e) {
825 result = false;
826 if (myParser.getErrorInfo() == null) {
827 error = e.getMessage();
828 } else {
829 error = myParser.getErrorInfo().replace("\n", "");
830 }
831 }
832 // Set the result variable if there is one
833 if (tokens.length > 3) {
834 context.getPrimitives().setValue(tokens[3],
835 new SBoolean(result));
836 // Set the result variable if there is one
837 if (tokens.length > 4 && !result) {
838 context.getPrimitives().setValue(tokens[4], error);
839 }
840 }
841 } else if (tokens[0].startsWith("issearchpatternvalid")) {
842 assertExactParametreCount(tokens, 2);
843 boolean result = true;
844 try {
845 Pattern.compile(context.getPrimitives().getStringValue(
846 tokens[1]));
847 } catch (Exception e) {
848 result = false;
849 }
850 context.getPrimitives().setValue(tokens[2], new SBoolean(result));
851 } else if (tokens[0].startsWith("search")) {
852 if (tokens[0].equals("searchstr")) {
853 assertExactParametreCount(tokens, 5);
854 String searchStr = context.getPrimitives().getStringValue(
855 tokens[1]);
856 String pattern = context.getPrimitives().getStringValue(
857 tokens[2]);
858 String[] result = searchStr.split(pattern, 2);
859 boolean bFound = result.length > 1;
860 context.getPrimitives().setValue(tokens[3],
861 new SBoolean(bFound));
862 if (bFound) {
863 context.getPrimitives().setValue(tokens[4],
864 new SInteger(result[0].length() + 1));
865 context.getPrimitives().setValue(
866 tokens[5],
867 new SInteger(searchStr.length()
868 - result[1].length()));
869 }
870 } else if (tokens[0].equals("searchitem")) {
871 assertExactParametreCount(tokens, 5);
872 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
873 boolean bFound = false;
874 Item searchItem = (Item) context.getPointers().getVariable(
875 tokens[1]).getValue();
876 if (searchItem instanceof Text) {
877 bFound = context.searchItem((Text) searchItem, context
878 .getPrimitives().getStringValue(tokens[2]), null,
879 tokens[4], tokens[5], null);
880 }
881 context.getPrimitives().setValue(tokens[3],
882 new SBoolean(bFound));
883 } else if (tokens[0].equals("searchframe")) {
884 assertExactParametreCount(tokens, 6);
885 assertVariableType(tokens[1], 1, SPointer.framePrefix);
886 assertVariableType(tokens[4], 4, SPointer.itemPrefix);
887 Frame frameToSearch = (Frame) context.getPointers()
888 .getVariable(tokens[1]).getValue();
889 boolean bFound = false;
890 for (Text itemToSearch : frameToSearch.getTextItems()) {
891 bFound = context.searchItem(itemToSearch, context
892 .getPrimitives().getStringValue(tokens[2]),
893 tokens[4], tokens[5], tokens[6], null);
894 if (bFound)
895 break;
896 }
897 context.getPrimitives().setValue(tokens[3],
898 new SBoolean(bFound));
899 } else if (tokens[0].equals("searchframeset")) {
900 assertMinParametreCount(tokens, 3);
901
902 String frameset = context.getPrimitives().getStringValue(
903 tokens[1]);
904 boolean bReplace = false;
905 if (tokens.length > 4) {
906 bReplace = context.getPrimitives().getBooleanValue(
907 tokens[4]);
908 }
909 String replacementString = null;
910 // If in replacement mode get the string to replace the
911 // searchPattern with
912 if (bReplace) {
913 if (tokens.length > 5) {
914 replacementString = context.getPrimitives()
915 .getStringValue(tokens[5]);
916 } else {
917 replacementString = "";
918 }
919 }
920 String resultsFrameset = context.getPrimitives()
921 .getStringValue(tokens[3]);
922 String pattern = context.getPrimitives().getStringValue(
923 tokens[2]);
924 long firstFrame = 1;
925 long maxFrame = Long.MAX_VALUE;
926 if (tokens.length > 7) {
927 firstFrame = context.getPrimitives().getIntegerValue(
928 tokens[7]);
929 if (tokens.length > 8) {
930 maxFrame = context.getPrimitives().getIntegerValue(
931 tokens[8]);
932 }
933 }
934
935 SearchAgent searchAgent = null;
936
937 // If replacement needs to be done... use the slow search for
938 // now
939 // The fast search does not do replacement
940 if (bReplace) {
941 searchAgent = new SearchFramesetAndReplace(firstFrame,
942 maxFrame, null);
943 } else {
944 searchAgent = new SearchFrameset(firstFrame, maxFrame, null);
945 }
946 searchAgent.initialise(null, null, frameset, resultsFrameset,
947 replacementString, pattern);
948 _agent = searchAgent;
949 searchAgent.run();
950 _agent = null;
951
952 if (tokens.length > 6) {
953 context.getPrimitives().setValue(tokens[6],
954 searchAgent.getResultsFrameName());
955 }
956 } else if (tokens[0].equals("searchtree")) {
957 assertMinParametreCount(tokens, 3);
958
959 String topFrameName = context.getPrimitives().getStringValue(
960 tokens[1]);
961 boolean bReplace = false;
962 if (tokens.length > 4) {
963 bReplace = context.getPrimitives().getBooleanValue(
964 tokens[4]);
965 }
966 String replacementString = null;
967 // If in replacement mode get the string to replace the
968 // searchPattern with
969 if (bReplace) {
970 if (tokens.length > 5) {
971 replacementString = context.getPrimitives()
972 .getStringValue(tokens[5]);
973 } else {
974 replacementString = "";
975 }
976 }
977 String resultsFrameset = context.getPrimitives()
978 .getStringValue(tokens[3]);
979 String pattern = context.getPrimitives().getStringValue(
980 tokens[2]);
981 SearchAgent searchAgent = null;
982 // If replacement needs to be done... use the slow search for
983 // now The fast search does not do replacement
984 if (bReplace) {
985 searchAgent = new SearchTreeAndReplace(null);
986 } else {
987 searchAgent = new SearchTree(null);
988 }
989 _agent = searchAgent;
990 searchAgent.initialise(null, null, topFrameName,
991 resultsFrameset, replacementString, pattern);
992 searchAgent.run();
993 _agent = null;
994 if (tokens.length > 6) {
995 context.getPrimitives().setValue(tokens[6],
996 searchAgent.getResultsFrameName());
997 }
998 } else {
999 throw new Exception("Unsupported search command: "
1000 + code.toString());
1001 }
1002 } else if (tokens[0].startsWith("set")) {
1003 if (tokens[0].equals("set")) {
1004 try {
1005 // Check if we are setting variable to variable
1006 if (tokens[2].startsWith(SVariable.prefix)
1007 && tokens.length == 3) {
1008 context.getPrimitives().set(tokens[1], tokens[2]);
1009 }
1010 // Otherwise we are setting a variable with a literal
1011 else {
1012 // check for strings enclosed in quotes
1013 if (tokens[2].startsWith("\"")) {
1014 context.getPrimitives().setValue(
1015 tokens[1],
1016 new SString(tokens[2].substring(1,
1017 tokens[2].length() - 1)));
1018 // set a literal
1019 } else if (tokens.length == 3) {
1020 context.getPrimitives().setValue(tokens[1],
1021 tokens[2]);
1022 }
1023 }
1024 } catch (Exception e) {
1025 throw new RuntimeException(e.getMessage());
1026 }
1027 } else if (tokens[0].equals("setassociation")) {
1028 assertExactParametreCount(tokens, 3);
1029
1030 Map<String, String> map = (Map<String, String>) context
1031 .getPointers().getVariable(tokens[1]).getValue();
1032 String attribute = context.getPrimitives().getStringValue(
1033 tokens[2]);
1034 String value = context.getPrimitives()
1035 .getStringValue(tokens[3]);
1036 map.put(attribute, value);
1037 } else if (tokens[0].equals("setframevalue")) {
1038 assertMinParametreCount(tokens, 3);
1039 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1040
1041 // Get the attribute to be searched for on the target frame
1042 Frame targetFrame = (Frame) context.getPointers().getVariable(
1043 tokens[1]).getValue();
1044 String targetAttribute = context.getPrimitives()
1045 .getStringValue(tokens[2]).toLowerCase()
1046 + ":";
1047 String value = context.getPrimitives()
1048 .getStringValue(tokens[3]);
1049 Boolean found = false;
1050 Text attributeItem = null;
1051 Item valueItem = null;
1052 // Begin the search
1053 for (Text text : targetFrame.getTextItems()) {
1054 String s = text.getText().toLowerCase();
1055
1056 if (s.startsWith(targetAttribute)) {
1057 attributeItem = text;
1058 AttributeUtils.replaceValue(attributeItem, value);
1059 found = true;
1060 break;
1061 }
1062 }
1063 // Keep looking for a matching value nearby if we found an
1064 // attribute without the value in the same item
1065 if (!found && attributeItem != null) {
1066 Point2D.Float endPoint = attributeItem
1067 .getParagraphEndPosition();
1068
1069 for (Text text : targetFrame.getTextItems()) {
1070 Point startPoint = text.getPosition();
1071 if (Math.abs(startPoint.y - endPoint.y) < 10
1072 && Math.abs(startPoint.x - endPoint.x) < 20) {
1073 found = true;
1074 valueItem = text;
1075 text.setText(value);
1076 break;
1077 }
1078 }
1079 }
1080
1081 // Set the values of the output parametres
1082 if (tokens.length > 4) {
1083 context.getPrimitives().setValue(tokens[4],
1084 new SBoolean(found));
1085 if (tokens.length > 5) {
1086 context.getPointers().setObject(tokens[5],
1087 attributeItem);
1088 if (tokens.length > 6) {
1089 context.getPointers().setObject(tokens[6],
1090 valueItem);
1091 }
1092 }
1093 }
1094 } else if (tokens[0].startsWith("setitem")) {
1095 if (tokens[0].equals("setitemposition")) {
1096 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1097 // assertPrimitiveType(tokens[2], 2);
1098 // assertPrimitiveType(tokens[3], 3);
1099 Item item = (Item) context.getPointers().getVariable(
1100 tokens[1]).getValue();
1101 item.setPosition(context.getPrimitives().getVariable(
1102 tokens[2]).integerValue().intValue(), context
1103 .getPrimitives().getVariable(tokens[3])
1104 .integerValue().intValue());
1105 } else if (tokens[0].equals("setitemthickness")) {
1106 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1107 // assertPrimitiveType(tokens[2], 2);
1108 Item item = (Item) context.getPointers().getVariable(
1109 tokens[1]).getValue();
1110 item.setThickness(context.getPrimitives().getVariable(
1111 tokens[2]).integerValue().intValue());
1112 } else if (tokens[0].equals("setitemwidth")) {
1113 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1114 // assertPrimitiveType(tokens[2], 2);
1115 Item item = (Item) context.getPointers().getVariable(
1116 tokens[1]).getValue();
1117 item.setWidth(context.getPrimitives()
1118 .getVariable(tokens[2]).integerValue().intValue());
1119 } else if (tokens[0].equals("setitemsize")) {
1120 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1121 // assertPrimitiveType(tokens[2], 2);
1122 Item item = (Item) context.getPointers().getVariable(
1123 tokens[1]).getValue();
1124 item.setSize(context.getPrimitives().getVariable(tokens[2])
1125 .integerValue().intValue());
1126 } else if (tokens[0].equals("setitemlink")) {
1127 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1128 // assertPrimitiveType(tokens[2], 2);
1129 Item item = (Item) context.getPointers().getVariable(
1130 tokens[1]).getValue();
1131 item.setLink(context.getPrimitives().getVariable(tokens[2])
1132 .stringValue());
1133 } else if (tokens[0].equals("setitemdata")) {
1134 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1135 // assertPrimitiveType(tokens[2], 2);
1136 Item item = (Item) context.getPointers().getVariable(
1137 tokens[1]).getValue();
1138 item.setData(context.getPrimitives().getVariable(tokens[2])
1139 .stringValue());
1140 } else if (tokens[0].equals("setitemaction")) {
1141 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1142 // assertPrimitiveType(tokens[2], 2);
1143 Item item = (Item) context.getPointers().getVariable(
1144 tokens[1]).getValue();
1145 item.setAction(context.getPrimitives().getVariable(
1146 tokens[2]).stringValue());
1147 } else if (tokens[0].equals("setitemfillcolor")) {
1148 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1149 // assertPrimitiveType(tokens[2], 2);
1150 Item item = (Item) context.getPointers().getVariable(
1151 tokens[1]).getValue();
1152 String stringColor = context.getPrimitives().getVariable(
1153 tokens[2]).stringValue();
1154 item.setBackgroundColor((Color) Conversion.Convert(
1155 Color.class, stringColor));
1156 } else if (tokens[0].equals("setitemcolor")) {
1157 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1158 // assertPrimitiveType(tokens[2], 2);
1159 Item item = (Item) context.getPointers().getVariable(
1160 tokens[1]).getValue();
1161 String stringColor = context.getPrimitives().getVariable(
1162 tokens[2]).stringValue();
1163 item.setColor((Color) Conversion.Convert(Color.class,
1164 stringColor, item.getColor()));
1165 } else if (tokens[0].equals("setitemtext")) {
1166 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1167 // assertPrimitiveType(tokens[2], 2);
1168 String newText = context.getPrimitives().getVariable(
1169 tokens[2]).stringValue();
1170 Text textItem = (Text) context.getPointers().getVariable(
1171 tokens[1]).getValue();
1172 textItem.setText(newText, true);
1173 } else
1174 throw new Exception("Unsupported setItem command: "
1175 + code.toString());
1176 } else if (tokens[0].equals("setstrchar")) {
1177 assertExactParametreCount(tokens, 3);
1178 StringBuffer s = new StringBuffer(context.getPrimitives()
1179 .getStringValue(tokens[1]));
1180 int pos = (int) context.getPrimitives().getIntegerValue(
1181 tokens[2]);
1182 char newChar = context.getPrimitives().getCharacterValue(
1183 tokens[3]);
1184 while (pos > s.length()) {
1185 s.append(newChar);
1186 }
1187 s.setCharAt(pos - 1, newChar);
1188
1189 context.getPrimitives().setValue(tokens[1],
1190 new SString(s.toString()));
1191 } else if (tokens[0].equals("setcharinitem")) {
1192 assertExactParametreCount(tokens, 4);
1193 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1194
1195 int row = (int) context.getPrimitives().getIntegerValue(
1196 tokens[3]) - 1;
1197 int col = (int) context.getPrimitives().getIntegerValue(
1198 tokens[4]) - 1;
1199 char newChar = context.getPrimitives().getCharacterValue(
1200 tokens[2]);
1201 Text item = (Text) context.getPointers().getVariable(tokens[1])
1202 .getValue();
1203 List<String> itemText = item.getTextList();
1204
1205 while (row >= itemText.size()) {
1206 StringBuffer sb = new StringBuffer();
1207 for (int i = 0; i <= col; i++)
1208 sb.append(newChar);
1209 itemText.add(sb.toString());
1210 }
1211 StringBuffer sb = new StringBuffer(itemText.get(row));
1212 while (sb.length() <= col)
1213 sb.append(newChar);
1214 sb.setCharAt(col, newChar);
1215
1216 // set the modified string
1217 itemText.set(row, sb.toString());
1218 item.setTextList(itemText);
1219 }
1220 } else if (tokens[0].startsWith("assert")) {
1221 if (tokens[0].equals("asserttrue")) {
1222 assertExactParametreCount(tokens, 1);
1223 if (!context.getPrimitives().getBooleanValue(tokens[1]))
1224 throw new UnitTestFailedException("true", "false");
1225 } else if (tokens[0].equals("assertfalse")) {
1226 assertExactParametreCount(tokens, 1);
1227 if (context.getPrimitives().getBooleanValue(tokens[1]))
1228 throw new UnitTestFailedException("false", "true");
1229 } else if (tokens[0].equals("assertfail")) {
1230 assertExactParametreCount(tokens, 0);
1231 throw new UnitTestFailedException("pass", "fail");
1232 } else if (tokens[0].equals("assertnull")) {
1233 assertExactParametreCount(tokens, 1);
1234 if (!context.isNull(tokens[1]))
1235 throw new UnitTestFailedException("null", "not null");
1236 } else if (tokens[0].equals("assertnotnull")) {
1237 assertExactParametreCount(tokens, 1);
1238 if (context.isNull(tokens[1]))
1239 throw new UnitTestFailedException("not null", "null");
1240 } else if (tokens[0].equals("assertdefined")) {
1241 assertExactParametreCount(tokens, 1);
1242 if (!context.isDefined(tokens[1]))
1243 throw new UnitTestFailedException("defined", "not defined");
1244 } else if (tokens[0].equals("assertnotdefined")) {
1245 assertExactParametreCount(tokens, 1);
1246 if (context.isDefined(tokens[1]))
1247 throw new UnitTestFailedException("defined", "not defined");
1248 } else if (tokens[0].equals("assertequals")) {
1249 assertExactParametreCount(tokens, 2);
1250 if (!context.getPrimitives().equalValues(tokens[1], tokens[2]))
1251 throw new UnitTestFailedException(context.getPrimitives()
1252 .getStringValue(tokens[1]), context.getPrimitives()
1253 .getStringValue(tokens[2]));
1254 } else if (tokens[0].equals("assertequalframes")) {
1255 assertExactParametreCount(tokens, 2);
1256 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1257 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1258 Frame frame1 = (Frame) context.getPointers().getVariable(
1259 tokens[1]).getValue();
1260 Frame frame2 = (Frame) context.getPointers().getVariable(
1261 tokens[2]).getValue();
1262 frame1.assertEquals(frame2);
1263 } else if (tokens[0].equals("assertdefined")) {
1264 assertExactParametreCount(tokens, 1);
1265 if (!context.isDefined(tokens[1])) {
1266 throw new UnitTestFailedException(tokens[1] + " exists",
1267 "not defined");
1268 }
1269 } else {
1270 throw new RuntimeException("Invalid Assert statement");
1271 }
1272 } else if (tokens[0].startsWith("goto")) {
1273 String frameNameVar = DEFAULT_STRING;
1274 if (tokens.length > 1) {
1275 assertExactParametreCount(tokens, 1);
1276 frameNameVar = tokens[1];
1277 }
1278 String frameName = context.getPrimitives().getStringValue(
1279 frameNameVar);
1280 Navigation.Goto(frameName);
1281 } else if (tokens[0].startsWith("get")) {
1282 if (tokens[0].startsWith("getframe")) {
1283 if (tokens[0].equals("getframevalue")) {
1284 assertMinParametreCount(tokens, 3);
1285 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1286
1287 // Get the attribute to be searched for on the target frame
1288 Frame targetFrame = (Frame) context.getPointers()
1289 .getVariable(tokens[1]).getValue();
1290 String targetAttribute = context.getPrimitives()
1291 .getStringValue(tokens[2]).toLowerCase()
1292 + ":";
1293 Boolean found = false;
1294 String value = "";
1295 Text attributeItem = null;
1296 Item valueItem = null;
1297 // Begin the search
1298 for (Text text : targetFrame.getTextItems()) {
1299 String s = text.getText().toLowerCase();
1300 if (s.startsWith(targetAttribute)) {
1301 attributeItem = text;
1302 value = new AttributeValuePair(s).getValue();
1303 if (value.length() > 0) {
1304 found = true;
1305 }
1306 break;
1307 }
1308 }
1309 // Keep looking for a matching value nearby if we found an
1310 // attribute without the value in the same item
1311 if (!found && attributeItem != null) {
1312 Point2D.Float endPoint = attributeItem
1313 .getParagraphEndPosition();
1314
1315 for (Text text : targetFrame.getTextItems()) {
1316 Point startPoint = text.getPosition();
1317 if (Math.abs(startPoint.y - endPoint.y) < 10
1318 && Math.abs(startPoint.x - endPoint.x) < 20) {
1319 found = true;
1320 valueItem = text;
1321 value = text.getText();
1322 break;
1323 }
1324 }
1325 }
1326
1327 // Set the values of the output parametres
1328 context.getPrimitives().setValue(tokens[3],
1329 new SString(value));
1330 if (tokens.length > 4) {
1331 context.getPrimitives().setValue(tokens[4],
1332 new SBoolean(found));
1333 if (tokens.length > 5) {
1334 context.getPointers().setObject(tokens[5],
1335 attributeItem);
1336 if (tokens.length > 6) {
1337 context.getPointers().setObject(tokens[6],
1338 valueItem);
1339 }
1340 }
1341 }
1342 } else if (tokens[0].startsWith("getframename")) {
1343 String frameNameVar = DEFAULT_STRING;
1344 String frameVar = DEFAULT_FRAME;
1345
1346 if (tokens.length > 1) {
1347 assertExactParametreCount(tokens, 2);
1348 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1349 frameNameVar = tokens[2];
1350 frameVar = tokens[1];
1351 }
1352 Frame frame = (Frame) context.getPointers().getVariable(
1353 frameVar).getValue();
1354 context.getPrimitives().setValue(frameNameVar,
1355 frame.getName());
1356 } else if (tokens[0].startsWith("getframetitle")) {
1357 String frameTitleVar = DEFAULT_ITEM;
1358 String frameVar = DEFAULT_FRAME;
1359
1360 if (tokens.length > 1) {
1361 assertExactParametreCount(tokens, 2);
1362 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1363 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1364 frameTitleVar = tokens[2];
1365 frameVar = tokens[1];
1366 }
1367 Frame frame = (Frame) context.getPointers().getVariable(
1368 frameVar).getValue();
1369 context.getPointers().setObject(frameTitleVar,
1370 frame.getTitleItem());
1371 } else if (tokens[0].startsWith("getframefilepath")) {
1372 assertExactParametreCount(tokens, 2);
1373 String frameName = context.getPrimitives().getStringValue(
1374 tokens[1]);
1375 String path = FrameIO.LoadFrame(frameName).getPath();
1376 String filePath = FrameIO.getFrameFullPathName(path,
1377 frameName);
1378 context.getPrimitives().setValue(tokens[2], filePath);
1379 } else if (tokens[0].equals("getframelog")) {
1380 assertExactParametreCount(tokens, 1);
1381 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1382
1383 String log = SessionStats.getFrameEventList();
1384 Text t;
1385
1386 t = (Text) context.getPointers().getVariable(tokens[1])
1387 .getValue();
1388 t.setText(log, true);
1389 } else if (tokens[0].equals("getframeitemcount")) {
1390 String frameVar = DEFAULT_FRAME;
1391 String countVar = DEFAULT_INTEGER;
1392 if (tokens.length > 1) {
1393 assertExactParametreCount(tokens, 2);
1394 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1395 frameVar = tokens[1];
1396 countVar = tokens[2];
1397 }
1398 Frame frame = (Frame) context.getPointers().getVariable(
1399 frameVar).getValue();
1400 Integer count = frame.getItems(true).size();
1401 context.getPrimitives().setValue(countVar,
1402 new SInteger(count));
1403 } else {
1404 executeAction(tokens, context);
1405 }
1406 } else if (tokens[0].equals("getassociation")) {
1407 assertMinParametreCount(tokens, 3);
1408 Map map = (Map) context.getPointers().getVariable(tokens[1])
1409 .getValue();
1410 String attribute = context.getPrimitives().getStringValue(
1411 tokens[2]);
1412 String newValue = map.get(attribute).toString();
1413 context.getPrimitives().setValue(tokens[3], newValue);
1414 } else if (tokens[0].startsWith("getcurrent")) {
1415 if (tokens[0].equals("getcurrentframe")) {
1416 assertMinParametreCount(tokens, 1);
1417 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1418
1419 Frame currentFrame = DisplayIO.getCurrentFrame();
1420 context.getPointers().setObject(tokens[1], currentFrame);
1421
1422 // check if the user is also after the frameName
1423 if (tokens.length > 2) {
1424 context.getPrimitives().setValue(tokens[2],
1425 new SString(currentFrame.getName()));
1426 }
1427 } else if (tokens[0].equals("getcurrentitem")) {
1428 assertMinParametreCount(tokens, 1);
1429 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1430
1431 Item currentItem = FrameUtils.getCurrentItem();
1432
1433 context.getPointers().setObject(tokens[1], currentItem);
1434
1435 // check if the user is also after line position
1436 if (currentItem != null && currentItem instanceof Text
1437 && tokens.length > 2) {
1438 Text text = (Text) currentItem;
1439 int cursorLinePos = text
1440 .getLinePosition(FrameMouseActions.getY());
1441 context.getPrimitives().setValue(tokens[2],
1442 new SInteger(cursorLinePos + 1));
1443 if (tokens.length > 3) {
1444 int cursorCharPos = text.getCharPosition(
1445 cursorLinePos, DisplayIO.getMouseX())
1446 .getCharIndex();
1447 context.getPrimitives().setValue(tokens[3],
1448 new SInteger(cursorCharPos + 1));
1449 }
1450 }
1451 }
1452 } else if (tokens[0].startsWith("getitem")) {
1453 if (tokens[0].equals("getitemposition")) {
1454 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1455 // assertPrimitiveType(tokens[2], 2);
1456 // assertPrimitiveType(tokens[3], 3);
1457 Point pos = ((Item) context.getPointers().getVariable(
1458 tokens[1]).getValue()).getPosition();
1459 Integer x = pos.x;
1460 Integer y = pos.y;
1461 context.getPrimitives()
1462 .setValue(tokens[2], new SInteger(x));
1463 context.getPrimitives()
1464 .setValue(tokens[3], new SInteger(y));
1465 } else if (tokens[0].equals("getitemthickness")) {
1466 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1467 // assertPrimitiveType(tokens[2], 2);
1468 Float thickness = ((Item) context.getPointers()
1469 .getVariable(tokens[1]).getValue()).getThickness();
1470 context.getPrimitives().setValue(tokens[2],
1471 new SReal(thickness));
1472 } else if (tokens[0].equals("getitemwidth")) {
1473 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1474 // assertPrimitiveType(tokens[2], 2);
1475 Integer width = ((Item) context.getPointers().getVariable(
1476 tokens[1]).getValue()).getWidth();
1477 context.getPrimitives().setValue(tokens[2],
1478 new SInteger(width));
1479 } else if (tokens[0].equals("getitemsize")) {
1480 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1481 // assertPrimitiveType(tokens[2], 2);
1482 Integer size = (int) ((Item) context.getPointers()
1483 .getVariable(tokens[1]).getValue()).getSize();
1484 context.getPrimitives().setValue(tokens[2],
1485 new SInteger(size));
1486 } else if (tokens[0].equals("getitemlink")) {
1487 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1488 // assertPrimitiveType(tokens[2], 2);
1489 String link = ((Item) context.getPointers().getVariable(
1490 tokens[1]).getValue()).getAbsoluteLink();
1491 context.getPrimitives().setValue(tokens[2],
1492 new SString(link));
1493 } else if (tokens[0].equals("getitemdata")) {
1494 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1495 Collection<String> dataList = ((Item) context.getPointers()
1496 .getVariable(tokens[1]).getValue()).getData();
1497 String data = "";
1498 if (dataList.size() > 0)
1499 data = dataList.iterator().next();
1500 context.getPrimitives().setValue(tokens[2],
1501 new SString(data));
1502 } else if (tokens[0].equals("getitemaction")) {
1503 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1504 Collection<String> dataList = ((Item) context.getPointers()
1505 .getVariable(tokens[1]).getValue()).getAction();
1506 String action = "";
1507 if (dataList.size() > 0)
1508 action = dataList.iterator().next();
1509 context.getPrimitives().setValue(tokens[2],
1510 new SString(action));
1511 } else if (tokens[0].equals("getitemfillcolor")) {
1512 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1513 // assertPrimitiveType(tokens[2], 2);
1514 Color itemColor = ((Item) context.getPointers()
1515 .getVariable(tokens[1]).getValue())
1516 .getPaintBackgroundColor();
1517 String color = itemColor.getRed() + " "
1518 + itemColor.getGreen() + " " + itemColor.getBlue();
1519 context.getPrimitives().setValue(tokens[2],
1520 new SString(color));
1521 } else if (tokens[0].equals("getitemcolor")) {
1522 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1523 // assertPrimitiveType(tokens[2], 2);
1524 Color itemColor = ((Item) context.getPointers()
1525 .getVariable(tokens[1]).getValue()).getPaintColor();
1526 String color = itemColor.getRed() + " "
1527 + itemColor.getGreen() + " " + itemColor.getBlue();
1528 context.getPrimitives().setValue(tokens[2],
1529 new SString(color));
1530 } else if (tokens[0].equals("getitemtext")) {
1531 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1532 Item item = ((Item) context.getPointers().getVariable(
1533 tokens[1]).getValue());
1534 context.getPrimitives().setValue(tokens[2],
1535 new SString(item.getText()));
1536 } else
1537 throw new Exception("Unsupported getItem command: "
1538 + code.toString());
1539 } else if (tokens[0].equals("getstrchar")) {
1540 assertExactParametreCount(tokens, 3);
1541 String s = context.getPrimitives().getStringValue(tokens[1]);
1542 int pos = (int) context.getPrimitives().getIntegerValue(
1543 tokens[2]);
1544
1545 context.getPrimitives().setValue(tokens[3],
1546 new SCharacter(s.charAt(pos - 1)));
1547 } else if (tokens[0].equals("getstrlength")) {
1548 assertExactParametreCount(tokens, 2);
1549 String s = context.getPrimitives().getStringValue(tokens[1]);
1550
1551 context.getPrimitives().setValue(tokens[2],
1552 new SInteger(s.length()));
1553 } else if (tokens[0].equals("getelapsedtime")) {
1554 assertExactParametreCount(tokens, 1);
1555 context.getPrimitives().setValue(tokens[1],
1556 new SInteger(AgentStats.getMilliSecondsElapsed()));
1557 } else if (tokens[0].equals("getlastnumberinframeset")) {
1558 String framesetNameVar = DEFAULT_STRING;
1559 String countVar = DEFAULT_INTEGER;
1560 if (tokens.length > 1) {
1561 assertMinParametreCount(tokens, 2);
1562 framesetNameVar = tokens[1];
1563 countVar = tokens[2];
1564 }
1565 String frameset = context.getPrimitives().getStringValue(
1566 framesetNameVar);
1567 long count = FrameIO.getLastNumber(frameset);
1568 context.getPrimitives().setValue(countVar, new SInteger(count));
1569 } else if (tokens[0].equals("getlistofframesets")) {
1570 String stringVar = DEFAULT_ITEM;
1571 if (tokens.length > 1) {
1572 assertMinParametreCount(tokens, 1);
1573 stringVar = tokens[1];
1574 }
1575 context.getPrimitives().setValue(stringVar,
1576 FrameIO.getFramesetList());
1577 } else if (tokens[0].equals("getsessionstats")) {
1578 assertExactParametreCount(tokens, 1);
1579 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1580
1581 String stats = SessionStats.getCurrentStats();
1582 Text t = (Text) context.getPointers().getVariable(tokens[1])
1583 .getValue();
1584 t.setText(stats);
1585 } else if (tokens[0].equals("getrandominteger")) {
1586 assertExactParametreCount(tokens, 3);
1587 int lowerBound = (int) context.getPrimitives().getIntegerValue(
1588 tokens[1]);
1589 int upperBound = (int) context.getPrimitives().getIntegerValue(
1590 tokens[2]);
1591 Random random = new Random();
1592 long result = Math.abs(random.nextInt())
1593 % (upperBound - lowerBound) + lowerBound;
1594 context.getPrimitives().setValue(tokens[3],
1595 new SInteger(result));
1596 } else if (tokens[0].equals("getrandomreal")) {
1597 assertExactParametreCount(tokens, 3);
1598 double lowerBound = context.getPrimitives().getDoubleValue(
1599 tokens[1]);
1600 double upperBound = context.getPrimitives().getDoubleValue(
1601 tokens[2]);
1602 Random random = new Random();
1603 double result = random.nextDouble() * (upperBound - lowerBound)
1604 + lowerBound;
1605 context.getPrimitives().setValue(tokens[3], new SReal(result));
1606 } else if (tokens[0].equals("getrandomtextitem")) {
1607 assertExactParametreCount(tokens, 2);
1608 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1609 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1610 List<Text> items = ((Frame) context.getPointers().getVariable(
1611 tokens[1]).getValue()).getBodyTextItems(false);
1612 Random random = new Random();
1613 int itemIndex = random.nextInt(items.size());
1614 context.getPointers()
1615 .setObject(tokens[2], items.get(itemIndex));
1616 } else {
1617 executeAction(tokens, context);
1618 }
1619 } else if (tokens[0].equals("or")) {
1620 for (int i = 1; i < tokens.length - 1; i++) {
1621 if (Primitives.isPrimitive(tokens[i])) {
1622 if (context.getPrimitives().getBooleanValue(tokens[i])) {
1623 context.getPrimitives().setValue(
1624 tokens[tokens.length - 1], new SBoolean(true));
1625 return Status.OK;
1626 }
1627 }
1628 }
1629 context.getPrimitives().setValue(tokens[tokens.length - 1],
1630 new SBoolean(false));
1631 } else if (tokens[0].equals("and")) {
1632 for (int i = 1; i < tokens.length - 1; i++) {
1633 if (Primitives.isPrimitive(tokens[i])) {
1634 if (!context.getPrimitives().getBooleanValue(tokens[i])) {
1635 context.getPrimitives().setValue(
1636 tokens[tokens.length - 1], new SBoolean(false));
1637 return Status.OK;
1638 }
1639 }
1640 }
1641 context.getPrimitives().setValue(tokens[tokens.length - 1],
1642 new SBoolean(true));
1643 } else if (tokens[0].equals("messagelnitem")
1644 || tokens[0].equals("messagelineitem")) {
1645 String itemVar = DEFAULT_ITEM;
1646
1647 if (tokens.length > 1) {
1648 assertExactParametreCount(tokens, 1);
1649 itemVar = tokens[1];
1650 assertVariableType(itemVar, 1, SPointer.itemPrefix);
1651 }
1652 Item message = (Item) context.getPointers().getVariable(itemVar)
1653 .getValue();
1654 try {
1655 MessageBay.displayMessage(((Text) message).copy());
1656 } catch (NullPointerException e) {
1657 MessageBay.displayMessage("null");
1658 } catch (ClassCastException e) {
1659 // Just ignore not text items!
1660 MessageBay.displayMessage(message.toString());
1661 } catch (Exception e) {
1662 // Just ignore other errors
1663 }
1664 } else if (tokens[0].equals("messageln")
1665 || tokens[0].equals("messageline")
1666 || tokens[0].equals("messagelnnospaces")
1667 || tokens[0].equals("messagelinenospaces")
1668 || tokens[0].equals("errorln") || tokens[0].equals("errorline")) {
1669 String message = getMessage(tokens, context, code.toString(),
1670 tokens[0].endsWith("nospaces") ? "" : " ", 1);
1671
1672 if (tokens[0].equals("errorln") || tokens[0].equals("errorline"))
1673 MessageBay.errorMessage(message);
1674 else
1675 MessageBay.displayMessageAlways(message);
1676 } else if (tokens[0].equals("typeatrate")) {
1677 assertMinParametreCount(tokens, 1);
1678 double delay = context.getPrimitives().getDoubleValue(tokens[1]);
1679 String s = getMessage(tokens, context, code.toString(), " ", 2);
1680 DisplayIO.typeStringDirect(delay, s);
1681 } else if (tokens[0].equals("type") || tokens[0].equals("typenospaces")) {
1682
1683 String s = getMessage(tokens, context, code.toString(), tokens[0]
1684 .equals("type") ? " " : "", 1);
1685
1686 DisplayIO.typeStringDirect(0.025, s);
1687 } else if (tokens[0].equals("runstring")) {
1688 String codeText = getMessage(tokens, context, code.toString(), " ",
1689 1);
1690 Text dynamicCode = new Text(codeText);
1691 RunItem(dynamicCode, context, Status.OK);
1692 } else if (tokens[0].equals("runoscommand")) {
1693 String command = getMessage(tokens, context, code.toString(), " ",
1694 1);
1695 Runtime.getRuntime().exec(command);
1696 } else if (tokens[0].equals("executeoscommand")) {
1697 String command = getMessage(tokens, context, code.toString(), " ",
1698 1);
1699 try {
1700 Process p = Runtime.getRuntime().exec(command);
1701 MessageBay.displayMessage(command, Color.darkGray);
1702
1703 BufferedReader stdInput = new BufferedReader(
1704 new InputStreamReader(p.getInputStream()));
1705 BufferedReader stdError = new BufferedReader(
1706 new InputStreamReader(p.getErrorStream()));
1707 String message = "";
1708 while ((message = stdInput.readLine()) != null) {
1709 MessageBay.displayMessage(message);
1710 }
1711 while ((message = stdError.readLine()) != null) {
1712 MessageBay.errorMessage(message);
1713 }
1714 } catch (Exception e) {
1715 throw new RuntimeException(e.getMessage());
1716 }
1717 } else if (tokens[0].startsWith("else")) {
1718 // if the if statement was false then run the else statement
1719 if (lastItemStatus == Status.FalseIf) {
1720 // check if it is a one line if statment
1721 if (tokens.length > 1) {
1722 // put together the one line statement
1723 StringBuilder statement = new StringBuilder();
1724 for (int i = 1; i < tokens.length; i++)
1725 statement.append(tokens[i]).append(' ');
1726 // create a copy of the code item to run
1727 Text copiedCode = code.copy();
1728 copiedCode.setText(statement.toString());
1729 return RunItem(copiedCode, context, Status.OK);
1730 } else {
1731 return RunFrameAndReportError(code, context);
1732 }
1733 } else if (lastItemStatus == Status.TrueIf) {
1734 return Status.OK;
1735 }
1736 throw new RuntimeException("Else without matching If statement");
1737 } else if (tokens[0].startsWith("if")) {
1738 Boolean result = null;
1739 int parametres = 1;
1740 String variable = DEFAULT_ITEM;
1741 String ifStatement = tokens[0];
1742 // Set the default variable
1743 if (tokens.length == 1) {
1744 if (ifStatement.equals("if") || ifStatement.equals("ifnot"))
1745 variable = DEFAULT_STRING;
1746 else if (ifStatement.equals("ifzero")
1747 || ifStatement.equals("ifnotzero"))
1748 variable = DEFAULT_INTEGER;
1749 } else {
1750 variable = tokens[1];
1751 }
1752
1753 if (ifStatement.equals("if")) {
1754 result = context.getPrimitives().getBooleanValue(variable);
1755 } else if (ifStatement.equals("ifnot")) {
1756 result = !context.getPrimitives().getBooleanValue(variable);
1757 } else if (ifStatement.equals("ifdefined")) {
1758 result = context.isDefined(tokens[1]);
1759 } else if (ifStatement.equals("ifnotdefined")) {
1760 result = !context.isDefined(tokens[1]);
1761 } else if (ifStatement.equals("ifzero")) {
1762 result = context.getPrimitives().getIntegerValue(variable) == 0;
1763 } else if (ifStatement.equals("ifnotzero")) {
1764 result = context.getPrimitives().getIntegerValue(variable) != 0;
1765 } else if (tokens[0].equals("ifeq")) {
1766 result = context.equalValues(tokens[1], tokens[2]);
1767 parametres = 2;
1768 } else if (tokens[0].equals("ifeqnocase")) {
1769 result = context.getPrimitives().equalValuesNoCase(tokens[1],
1770 tokens[2]);
1771 parametres = 2;
1772 } else if (tokens[0].equals("ifnoteqnocase")) {
1773 result = !context.getPrimitives().equalValuesNoCase(tokens[1],
1774 tokens[2]);
1775 parametres = 2;
1776 } else if (tokens[0].equals("ifnoteq")) {
1777 result = !context.equalValues(tokens[1], tokens[2]);
1778 parametres = 2;
1779 } else if (tokens[0].equals("ifless")) {
1780 result = context.getPrimitives().compareValues(tokens[1],
1781 tokens[2]) < 0;
1782 parametres = 2;
1783 } else if (tokens[0].equals("ifgtr")) {
1784 result = context.getPrimitives().compareValues(tokens[1],
1785 tokens[2]) > 0;
1786 parametres = 2;
1787 } else if (tokens[0].equals("ifgeq")) {
1788 result = context.getPrimitives().compareValues(tokens[1],
1789 tokens[2]) >= 0;
1790 parametres = 2;
1791 } else if (tokens[0].equals("ifleq")) {
1792 result = context.getPrimitives().compareValues(tokens[1],
1793 tokens[2]) <= 0;
1794 parametres = 2;
1795 } else if (tokens[0].equals("ifexistingframe")) {
1796 result = FrameIO.canAccessFrame(context.getPrimitives()
1797 .getStringValue(tokens[1]));
1798 } else if (tokens[0].equals("ifexistingframeset")) {
1799 String framesetName = context.getPrimitives().getStringValue(
1800 tokens[1]);
1801 result = FrameIO.canAccessFrameset(framesetName);
1802 } else {
1803 // assertVariableType(variable, 1, SPointer.itemPrefix);
1804 if (ifStatement.equals("ifannotation")) {
1805 result = ((Item) context.getPointers()
1806 .getVariable(variable).getValue()).isAnnotation();
1807 } else if (ifStatement.equals("iflinked")) {
1808 result = ((Item) context.getPointers()
1809 .getVariable(variable).getValue()).getLink() != null;
1810 } else if (ifStatement.equals("ifactioned")) {
1811 result = ((Item) context.getPointers()
1812 .getVariable(variable).getValue()).hasAction();
1813 } else if (ifStatement.equals("ifnotactioned")) {
1814 result = !((Item) context.getPointers().getVariable(
1815 variable).getValue()).hasAction();
1816 } else if (ifStatement.equals("ifbodytext")) {
1817 Item i = (Item) context.getPointers().getVariable(variable)
1818 .getValue();
1819 result = i instanceof Text && !i.isFrameName()
1820 && !i.isFrameTitle();
1821 } else if (ifStatement.equals("ifnotannotation")) {
1822 result = !((Item) context.getPointers().getVariable(
1823 variable).getValue()).isAnnotation();
1824 } else if (ifStatement.equals("ifnotlinked")) {
1825 result = ((Item) context.getPointers()
1826 .getVariable(variable).getValue()).getLink() == null;
1827 } else if (ifStatement.equals("ifnotbodytext")) {
1828 Item i = (Item) context.getPointers().getVariable(variable)
1829 .getValue();
1830 result = !(i instanceof Text) || i.isFrameName()
1831 || i.isFrameTitle();
1832 }
1833 }
1834
1835 if (result == null)
1836 throw new RuntimeException("Invalid If statement");
1837 // Now check if we need to run the code
1838 else if (result) {
1839 Status status;
1840 // check if it is a one line if statment
1841 if (tokens.length > parametres + 1) {
1842 // put together the one line statement
1843 StringBuilder statement = new StringBuilder();
1844 for (int i = parametres + 1; i < tokens.length; i++)
1845 statement.append(tokens[i]).append(' ');
1846 // create a copy of the code item to run
1847 Text copiedCode = code.copy();
1848 copiedCode.setText(statement.toString());
1849 status = RunItem(copiedCode, context, Status.OK);
1850 } else {
1851 status = RunFrameAndReportError(code, context);
1852 }
1853 if (status == Status.OK) {
1854 return Status.TrueIf;
1855 } else {
1856 return status;
1857 }
1858 }
1859 return Status.FalseIf;
1860 } // Look for variable length methods
1861 else if (tokens[0].equals("attachitemtocursor")) {
1862 String itemVar = DEFAULT_ITEM;
1863
1864 if (tokens.length > 1) {
1865 assertExactParametreCount(tokens, 1);
1866 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1867 itemVar = tokens[1];
1868 }
1869 Item item = (Item) context.getPointers().getVariable(itemVar)
1870 .getValue();
1871 item
1872 .setPosition(FrameMouseActions.MouseX,
1873 FrameMouseActions.MouseY);
1874 FrameMouseActions.pickup(item);
1875 } else if (tokens[0].equals("attachstrtocursor")) {
1876 String stringVar = DEFAULT_STRING;
1877
1878 if (tokens.length > 1) {
1879 assertExactParametreCount(tokens, 1);
1880 stringVar = tokens[1];
1881 }
1882 String s = context.getPrimitives().getStringValue(stringVar);
1883 Frame frame = DisplayIO.getCurrentFrame();
1884 Item item = frame.createNewText(s);
1885 item
1886 .setPosition(FrameMouseActions.MouseX,
1887 FrameMouseActions.MouseY);
1888 FrameMouseActions.pickup(item);
1889 } else if (tokens[0].equals("additemtoframe")) {
1890 String itemVar = DEFAULT_ITEM;
1891 String frameVar = DEFAULT_FRAME;
1892
1893 if (tokens.length > 1) {
1894 assertExactParametreCount(tokens, 2);
1895 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1896 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1897 itemVar = tokens[2];
1898 frameVar = tokens[1];
1899 }
1900 Frame frame = (Frame) context.getPointers().getVariable(frameVar)
1901 .getValue();
1902 Item item = (Item) context.getPointers().getVariable(itemVar)
1903 .getValue();
1904 frame.addItem(item);
1905 } else if (tokens[0].equals("connectdots")) {
1906 assertMinParametreCount(tokens, 2);
1907 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1908 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1909 Item dot1 = null;
1910 Item dot2 = null;
1911 try {
1912 dot1 = (Item) context.getPointers().getVariable(tokens[1])
1913 .getValue();
1914 } catch (Exception e) {
1915 throw new IncorrectTypeException("Dot", 1);
1916 }
1917 try {
1918 dot2 = (Item) context.getPointers().getVariable(tokens[2])
1919 .getValue();
1920 } catch (Exception e) {
1921 throw new IncorrectTypeException("Dot", 2);
1922 }
1923 Frame frame = dot1.getParent();
1924 frame.addItem(new Line(dot1, dot2, frame.getNextItemID()));
1925 } else if (tokens[0].equals("createitem")
1926 || tokens[0].equals("createtext")) {
1927 assertMinParametreCount(tokens, 4);
1928 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1929 assertVariableType(tokens[4], 4, SPointer.itemPrefix);
1930 Frame frame = (Frame) context.getPointers().getVariable(tokens[1])
1931 .getValue();
1932 Item newItem;
1933 int x = (int) context.getPrimitives().getIntegerValue(tokens[2]);
1934 int y = (int) context.getPrimitives().getIntegerValue(tokens[3]);
1935 // check for the option text and action for the new item
1936 if (tokens.length > 5) {
1937 String newText = context.getPrimitives().getStringValue(
1938 tokens[5]);
1939 String newAction = null;
1940 if (tokens.length > 6) {
1941 newAction = context.getPrimitives().getStringValue(
1942 tokens[6]);
1943 }
1944 newItem = frame.addText(x, y, newText, newAction);
1945 } else {
1946 if (tokens[0].equals("createtext")) {
1947 newItem = frame.createNewText();
1948 newItem.setPosition(x, y);
1949 } else {
1950 // create a point if the optional params are not provided
1951 newItem = frame.addDot(x, y);
1952 }
1953 }
1954 context.getPointers().setObject(tokens[4], newItem);
1955 } else if (tokens[0].equals("deleteitem")) {
1956 assertMinParametreCount(tokens, 1);
1957 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1958 Item item = (Item) context.getPointers().getVariable(tokens[1])
1959 .getValue();
1960 item.delete();
1961 } else if (tokens[0].equals("deleteframe")) {
1962 assertMinParametreCount(tokens, 1);
1963 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1964 Frame frame = (Frame) context.getPointers().getVariable(tokens[1])
1965 .getValue();
1966 String errorMessage = "Error deleting " + frame.getName();
1967 boolean success = false;
1968 try {
1969 success = FrameIO.DeleteFrame(frame) != null;
1970 if (!success && _verbose)
1971 MessageBay.warningMessage(errorMessage);
1972 } catch (Exception e) {
1973 // If an exception is thrown then success is false
1974 if (_verbose) {
1975 MessageBay.warningMessage(errorMessage
1976 + (e.getMessage() != null ? ". " + e.getMessage()
1977 : ""));
1978 }
1979 }
1980 if (tokens.length > 2) {
1981 context.getPrimitives().setValue(tokens[2],
1982 new SBoolean(success));
1983 }
1984 } else if (tokens[0].equals("deleteframeset")) {
1985 assertMinParametreCount(tokens, 1);
1986 String framesetName = context.getPrimitives().getStringValue(
1987 tokens[1]);
1988 boolean success = FrameIO.deleteFrameset(framesetName);
1989 if (!success && _verbose) {
1990 MessageBay.warningMessage("Error deleting " + framesetName);
1991 }
1992 if (tokens.length > 2) {
1993 context.getPrimitives().setValue(tokens[2],
1994 new SBoolean(success));
1995 }
1996 } else if (tokens[0].equals("copyitem")) {
1997 assertMinParametreCount(tokens, 2);
1998 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1999 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
2000 Item item = (Item) context.getPointers().getVariable(tokens[1])
2001 .getValue();
2002 Item copy = item.copy();
2003 context.getPointers().setObject(tokens[2], copy);
2004 } else if (tokens[0].equals("copyframeset")) {
2005 assertMinParametreCount(tokens, 2);
2006 String framesetToCopy = context.getPrimitives().getStringValue(
2007 tokens[1]);
2008 String copiedFrameset = context.getPrimitives().getStringValue(
2009 tokens[2]);
2010 boolean success = FrameIO.CopyFrameset(framesetToCopy,
2011 copiedFrameset);
2012 if (!success && _verbose)
2013 MessageBay.warningMessage("Error copying " + framesetToCopy);
2014 if (tokens.length > 3) {
2015 context.getPrimitives().setValue(tokens[3],
2016 new SBoolean(success));
2017 }
2018 } else if (tokens[0].equals("copyframe")) {
2019 assertMinParametreCount(tokens, 2);
2020 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2021 assertVariableType(tokens[2], 2, SPointer.framePrefix);
2022 Frame frameToCopy = (Frame) context.getPointers().getVariable(
2023 tokens[1]).getValue();
2024 FrameIO.SuspendCache();
2025 Frame freshCopy = FrameIO.LoadFrame(frameToCopy.getName());
2026 // Change the frameset if one was provided
2027 if (tokens.length > 3) {
2028 String destinationFrameset = context.getPrimitives()
2029 .getStringValue(tokens[3]);
2030 freshCopy.setFrameset(destinationFrameset);
2031 }// Otherwise add it to the end of this frameset
2032 int nextNumber = FrameIO.getLastNumber(freshCopy.getFramesetName()) + 1;
2033 // if the frameset doesnt already exist then create it
2034 if (nextNumber <= 0) {
2035 try {
2036 FrameIO.CreateFrameset(freshCopy.getFramesetName(),
2037 frameToCopy.getPath());
2038 nextNumber = 1;
2039 } catch (Exception e) {
2040 }
2041 } else {
2042 Frame zero = FrameIO.LoadFrame(freshCopy.getFramesetName()
2043 + "0");
2044 freshCopy.setPath(zero.getPath());
2045 }
2046 boolean success = false;
2047 if (nextNumber > 0) {
2048 freshCopy.setFrameNumber(nextNumber);
2049 context.getPointers().setObject(tokens[2], freshCopy);
2050 String fileContents = FrameIO.ForceSaveFrame(freshCopy);
2051 success = fileContents != null;
2052 }
2053 FrameIO.ResumeCache();
2054 if (success) {
2055 // Need to add the new copy to the cache in case it is edited by
2056 // other simple statements
2057 FrameIO.addToCache(freshCopy);
2058 }
2059 if (!success && _verbose)
2060 MessageBay.warningMessage("Error copying "
2061 + frameToCopy.getName());
2062 if (tokens.length > 4) {
2063 context.getPrimitives().setValue(tokens[4],
2064 new SBoolean(success));
2065 }
2066 } else if (tokens[0].equals("createframe")) {
2067
2068 String framesetName = DEFAULT_STRING;
2069 String frameVar = DEFAULT_FRAME;
2070
2071 if (tokens.length > 1) {
2072 assertMinParametreCount(tokens, 2);
2073 assertVariableType(tokens[2], 2, SPointer.framePrefix);
2074 framesetName = tokens[1];
2075 frameVar = tokens[2];
2076 }
2077
2078 if (tokens.length > 3) {
2079 context.createFrame(framesetName, frameVar, tokens[3]);
2080 } else
2081 context.createFrame(framesetName, frameVar, null);
2082 } else if (tokens[0].equals("closeframe")) {
2083 String frameVar = DEFAULT_FRAME;
2084
2085 if (tokens.length > 1) {
2086 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2087 frameVar = tokens[1];
2088 }
2089
2090 if (tokens.length > 2) {
2091 // assertPrimitiveType(tokens[3], 3);
2092 context.closeFrame(frameVar, tokens[3]);
2093 } else
2094 context.closeFrame(frameVar, null);
2095 } else if (tokens[0].equals("readframe")
2096 || tokens[0].equals("openframe")) {
2097
2098 String frameName = DEFAULT_STRING;
2099 String frameVar = DEFAULT_FRAME;
2100
2101 if (tokens.length > 1) {
2102 assertMinParametreCount(tokens, 2);
2103 assertVariableType(tokens[2], 2, SPointer.framePrefix);
2104 frameName = tokens[1];
2105 frameVar = tokens[2];
2106 // assertPrimitiveType(frameName, 1);
2107 }
2108
2109 if (tokens.length > 3) {
2110 // assertPrimitiveType(tokens[3], 3);
2111 context.readFrame(frameName, frameVar, tokens[3]);
2112 } else
2113 context.readFrame(frameName, frameVar, null);
2114 } else if (tokens[0].equals("exitexpeditee")) {
2115 Browser._theBrowser.exit();
2116 } else if (tokens[0].equals("readkbdcond")) {
2117
2118 String nextCharVarName = DEFAULT_CHAR;
2119 String wasCharVarName = DEFAULT_BOOLEAN;
2120
2121 if (tokens.length > 1) {
2122 assertMinParametreCount(tokens, 2);
2123 assertVariableType(tokens[2], 2, SPointer.framePrefix);
2124 nextCharVarName = tokens[1];
2125 wasCharVarName = tokens[2];
2126 }
2127
2128 Character nextChar = _KeyStrokes.poll();
2129 boolean hasChar = nextChar != null;
2130 context.getPrimitives().setValue(wasCharVarName,
2131 new SBoolean(hasChar));
2132 if (hasChar)
2133 context.getPrimitives().setValue(nextCharVarName,
2134 new SCharacter(nextChar));
2135 } else if (tokens[0].equals("createassociation")) {
2136
2137 String associationVar = DEFAULT_ASSOCIATION;
2138
2139 if (tokens.length > 0) {
2140 assertVariableType(tokens[1], 2, SPointer.associationPrefix);
2141 associationVar = tokens[1];
2142 }
2143 Map<String, String> newMap = new HashMap<String, String>();
2144 context.getPointers().setObject(associationVar, newMap);
2145 } else if (tokens[0].equals("deleteassociation")) {
2146
2147 String associationVar = DEFAULT_ASSOCIATION;
2148
2149 if (tokens.length > 0) {
2150 assertVariableType(tokens[1], 2, SPointer.associationPrefix);
2151 associationVar = tokens[1];
2152 }
2153 context.getPointers().delete(associationVar);
2154 } else if (tokens[0].equals("openreadfile")) {
2155 assertVariableType(tokens[1], 1, SString.prefix);
2156 assertVariableType(tokens[2], 2, SPointer.filePrefix);
2157
2158 if (tokens.length > 3) {
2159 assertVariableType(tokens[3], 3, SBoolean.prefix);
2160 context.openReadFile(tokens[1], tokens[2], tokens[3]);
2161 } else
2162 context.openReadFile(tokens[1], tokens[2]);
2163 } else if (tokens[0].equals("readlinefile")
2164 || tokens[0].equals("readlnfile")) {
2165 assertVariableType(tokens[1], 1, SPointer.filePrefix);
2166
2167 if (tokens.length > 3) {
2168 assertVariableType(tokens[3], 3, SBoolean.prefix);
2169 context.readLineFile(tokens[1], tokens[2], tokens[3]);
2170 } else
2171 context.readLineFile(tokens[1], tokens[2]);
2172 } else if (tokens[0].equals("readitemfile")) {
2173 assertVariableType(tokens[1], 1, SPointer.filePrefix);
2174 assertVariableType(tokens[2], 1, SPointer.itemPrefix);
2175
2176 if (tokens.length > 3) {
2177 assertVariableType(tokens[3], 3, SBoolean.prefix);
2178 context.readItemFile(tokens[1], tokens[2], tokens[3]);
2179 } else
2180 context.readItemFile(tokens[1], tokens[2]);
2181 } else if (tokens[0].equals("openwritefile")) {
2182 assertVariableType(tokens[1], 1, SString.prefix);
2183 assertVariableType(tokens[2], 2, SPointer.filePrefix);
2184
2185 if (tokens.length > 3) {
2186 assertVariableType(tokens[3], 3, SBoolean.prefix);
2187 context.openWriteFile(tokens[1], tokens[2], tokens[3]);
2188 } else
2189 context.openWriteFile(tokens[1], tokens[2]);
2190 } else if (tokens[0].equals("writefile")
2191 || tokens[0].equals("writelinefile")
2192 || tokens[0].equals("writelnfile")) {
2193 assertVariableType(tokens[1], 1, SPointer.filePrefix);
2194
2195 StringBuffer textToWrite = new StringBuffer();
2196 if (tokens.length == 1) {
2197 textToWrite.append(context.getPrimitives().getVariable(
2198 DEFAULT_STRING).stringValue()
2199 + " ");
2200 } else {
2201 for (int i = 2; i < tokens.length; i++) {
2202 if (Primitives.isPrimitive(tokens[i])) {
2203 textToWrite.append(context.getPrimitives().getVariable(
2204 tokens[i]).stringValue());
2205 } else
2206 throw new Exception("Illegal parametre: " + tokens[i]
2207 + " in " + code.toString());
2208 }
2209 }
2210
2211 if (!tokens[0].equals("writefile"))
2212 textToWrite.append(Text.LINE_SEPARATOR);
2213 context.writeFile(tokens[1], textToWrite.toString());
2214 } else if (tokens[0].equals("displayframeset")) {
2215 assertMinParametreCount(tokens, 1);
2216 String framesetName = context.getPrimitives().getStringValue(
2217 tokens[1]);
2218 int lastFrameNo = FrameIO.getLastNumber(framesetName);
2219 int firstFrameNo = 0;
2220 double pause = 0.0;
2221 // get the first and last frames to display if they were proided
2222 if (tokens.length > 2) {
2223 firstFrameNo = (int) context.getPrimitives().getIntegerValue(
2224 tokens[2]);
2225 if (tokens.length > 3) {
2226 lastFrameNo = (int) context.getPrimitives()
2227 .getIntegerValue(tokens[3]);
2228 if (tokens.length > 4) {
2229 pause = context.getPrimitives().getDoubleValue(
2230 tokens[4]);
2231 }
2232 }
2233 }
2234 Runtime runtime = Runtime.getRuntime();
2235 // Display the frames
2236 for (int i = firstFrameNo; i <= lastFrameNo; i++) {
2237 Frame frame = FrameIO.LoadFrame(framesetName + i);
2238 if (frame != null) {
2239 double thisFramesPause = pause;
2240 // check for change in delay for this frame only
2241 Item pauseItem = ItemUtils.FindTag(frame.getItems(),
2242 "@DisplayFramePause:");
2243 if (pauseItem != null) {
2244 try {
2245 // attempt to read in the delay value
2246 thisFramesPause = Double.parseDouble(ItemUtils
2247 .StripTag(
2248 ((Text) pauseItem).getFirstLine(),
2249 "@DisplayFramePause"));
2250 } catch (NumberFormatException nfe) {
2251 }
2252 }
2253 DisplayIO.setCurrentFrame(frame, false);
2254 pause(thisFramesPause);
2255
2256 long freeMemory = runtime.freeMemory();
2257 if (freeMemory < DisplayTree.GARBAGE_COLLECTION_THRESHOLD) {
2258 runtime.gc();
2259 MessageBay.displayMessage("Force Garbage Collection!");
2260 }
2261 }
2262 }
2263 } else if (tokens[0].equals("createframeset")) {
2264 String framesetName = DEFAULT_STRING;
2265 String successVar = null;
2266 if (tokens.length > 1) {
2267 framesetName = tokens[1];
2268 if (tokens.length > 2)
2269 successVar = tokens[2];
2270 }
2271 context.createFrameset(framesetName, successVar);
2272 } else if (tokens[0].equals("writetree")) {
2273 assertMinParametreCount(tokens, 3);
2274 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2275 Frame source = (Frame) context.getPointers().getVariable(tokens[1])
2276 .getValue();
2277 String format = context.getPrimitives().getStringValue(tokens[2]);
2278 String fileName = context.getPrimitives().getStringValue(tokens[3]);
2279 WriteTree wt = new WriteTree(format, fileName);
2280 if (wt.initialise(source, null)) {
2281 _agent = wt;
2282 wt.run();
2283 _agent = null;
2284 }
2285 } else if (tokens[0].equals("concatstr")) {
2286 assertMinParametreCount(tokens, 3);
2287 String resultVar = tokens[tokens.length - 1];
2288
2289 StringBuilder sb = new StringBuilder();
2290 // loop through all the strings concatenating them
2291 for (int i = 1; i < tokens.length - 1; i++) {
2292 // assertPrimitiveType(tokens[i], i);
2293 sb.append(context.getPrimitives().getStringValue(tokens[i]));
2294 }
2295 context.getPrimitives().setValue(resultVar,
2296 new SString(sb.toString()));
2297 } else if (tokens[0].equals("convstrlower")) {
2298 assertExactParametreCount(tokens, 1);
2299 // assertPrimitiveType(tokens[1], 1);
2300 context.getPrimitives().setValue(
2301 tokens[1],
2302 new SString(context.getPrimitives().getStringValue(
2303 tokens[1]).toLowerCase()));
2304 } else if (tokens[0].equals("convstrupper")) {
2305 assertExactParametreCount(tokens, 1);
2306 // assertPrimitiveType(tokens[1], 1);
2307 context.getPrimitives().setValue(
2308 tokens[1],
2309 new SString(context.getPrimitives().getStringValue(
2310 tokens[1]).toUpperCase()));
2311 } else if (tokens[0].equals("countcharsinstr")) {
2312 assertExactParametreCount(tokens, 3);
2313 String s = context.getPrimitives().getStringValue(tokens[1]);
2314 String pattern = context.getPrimitives().getStringValue(tokens[2]);
2315 int count = countCharsInString(s, pattern);
2316 context.getPrimitives().setValue(tokens[3], new SInteger(count));
2317 } else if (tokens[0].equals("countcharsinitem")) {
2318 assertExactParametreCount(tokens, 3);
2319 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
2320 Item item = (Item) context.getPointers().getVariable(tokens[1])
2321 .getValue();
2322 String pattern = context.getPrimitives().getStringValue(tokens[2]);
2323 int count = 0;
2324 if (item instanceof Text)
2325 count = countCharsInString(((Text) item).getText(), pattern);
2326 context.getPrimitives().setValue(tokens[3], new SInteger(count));
2327 } else if (tokens[0].equals("clearframe")) {
2328 String frameVar = DEFAULT_FRAME;
2329 if (tokens.length > 1) {
2330 assertMinParametreCount(tokens, 1);
2331 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2332 frameVar = tokens[1];
2333 }
2334 boolean success = true;
2335 try {
2336 Frame frameToClear = (Frame) context.getPointers().getVariable(
2337 frameVar).getValue();
2338 frameToClear.clear(false);
2339 assert (frameToClear.getItems().size() <= 1);
2340 } catch (Exception e) {
2341 success = false;
2342 }
2343 if (tokens.length > 2) {
2344 assertExactParametreCount(tokens, 2);
2345 context.getPrimitives().setValue(tokens[2],
2346 new SBoolean(success));
2347 }
2348 } else if (tokens[0].equals("parseframename")) {
2349 assertExactParametreCount(tokens, 4);
2350 String frameName = context.getPrimitives()
2351 .getStringValue(tokens[1]);
2352 String frameSet = "";
2353 int frameNo = -1;
2354 boolean success = true;
2355 try {
2356 frameSet = Conversion.getFramesetName(frameName, false);
2357 frameNo = Conversion.getFrameNumber(frameName);
2358 } catch (Exception e) {
2359 success = false;
2360 if (_verbose)
2361 MessageBay.warningMessage("Error parsing " + frameName);
2362 }
2363 // assertPrimitiveType(tokens[2], 2);
2364 context.getPrimitives().setValue(tokens[2], new SBoolean(success));
2365
2366 // assertPrimitiveType(tokens[3], 3);
2367 context.getPrimitives().setValue(tokens[3], new SString(frameSet));
2368
2369 // assertPrimitiveType(tokens[4], 4);
2370 context.getPrimitives().setValue(tokens[4], new SInteger(frameNo));
2371 } else if (tokens[0].equals("parsestr")) {
2372 assertMinParametreCount(tokens, 2);
2373 // assertPrimitiveType(tokens[1], 1);
2374 // assertPrimitiveType(tokens[2], 2);
2375
2376 String s = context.getPrimitives().getStringValue(tokens[1]);
2377
2378 String separator = context.getPrimitives()
2379 .getStringValue(tokens[2]);
2380
2381 String[] split = s.split(separator, tokens.length - 4);
2382
2383 if (tokens.length > 3) {
2384 // assertPrimitiveType(tokens[3], 3);
2385 int count = split.length;
2386 // if the string is not blank and its got a remainder then
2387 // decrease the count by 1 to account for the remainder
2388 if (split.length != 0 && split.length > tokens.length - 5)
2389 count--;
2390
2391 context.getPrimitives()
2392 .setValue(tokens[3], new SInteger(count));
2393
2394 if (tokens.length > 4) {
2395 // Set the remainder string
2396 // assertPrimitiveType(tokens[4], 4);
2397 if (split.length < tokens.length - 4)
2398 context.getPrimitives().setValue(tokens[4],
2399 new SString());
2400 else
2401 context.getPrimitives().setValue(tokens[4],
2402 new SString(split[split.length - 1]));
2403
2404 // Set the strings for each of the vars
2405 if (tokens.length > 5) {
2406 for (int i = 5; i < tokens.length; i++) {
2407 // assertPrimitiveType(tokens[i], i);
2408 if (split.length < i - 4)
2409 context.getPrimitives().setValue(tokens[i],
2410 new SString());
2411 else
2412 context.getPrimitives().setValue(tokens[i],
2413 new SString(split[i - 5]));
2414 }
2415 }
2416 }
2417 }
2418 } else if (tokens[0].equals("stripstr")) {
2419 assertExactParametreCount(tokens, 2);
2420 String s = context.getPrimitives().getStringValue(tokens[1]);
2421 String charsToStrip = context.getPrimitives().getStringValue(
2422 tokens[2]);
2423 for (int i = 0; i < charsToStrip.length(); i++)
2424 s = s.replaceAll(charsToStrip.substring(i, i + 1), "");
2425 context.getPrimitives().setValue(tokens[1], new SString(s));
2426 } else if (tokens[0].equals("subststr")) {
2427 assertExactParametreCount(tokens, 3);
2428 String oldString = context.getPrimitives()
2429 .getStringValue(tokens[2]);
2430 String newString = context.getPrimitives()
2431 .getStringValue(tokens[3]);
2432 String result = context.getPrimitives().getStringValue(tokens[1]);
2433 result = result.replaceAll(oldString, newString);
2434 context.getPrimitives().setValue(tokens[1], new SString(result));
2435 } else if (tokens[0].equals("substr")) {
2436 assertExactParametreCount(tokens, 4);
2437 int startPos = (int) context.getPrimitives().getIntegerValue(
2438 tokens[2]) - 1;
2439 int length = (int) context.getPrimitives().getIntegerValue(
2440 tokens[3]);
2441 String s = context.getPrimitives().getStringValue(tokens[1]);
2442 String result;
2443 if (startPos + length < s.length())
2444 result = s.substring(startPos, startPos + length);
2445 else
2446 result = s.substring(startPos);
2447 context.getPrimitives().setValue(tokens[4], new SString(result));
2448 } else if (tokens[0].equals("pause")) {
2449 String lengthVar = DEFAULT_REAL;
2450
2451 if (tokens.length > 1) {
2452 assertExactParametreCount(tokens, 1);
2453 lengthVar = tokens[1];
2454 }
2455
2456 pause(context.getPrimitives().getDoubleValue(lengthVar));
2457 } else if (tokens[0].equals("waitforagent")) {
2458 while(DefaultAgent.isAgentRunning()){
2459 Thread.sleep(100);
2460 }
2461 }else if (tokens[0].equals("glidecursorto")) {
2462 assertMinParametreCount(tokens, 2);
2463 int finalX = (int) context.getPrimitives().getIntegerValue(
2464 tokens[1]);
2465 int finalY = (int) context.getPrimitives().getIntegerValue(
2466 tokens[2]);
2467 int milliseconds = 1000;
2468 if (tokens.length > 3)
2469 milliseconds = (int) (context.getPrimitives().getDoubleValue(
2470 tokens[3]) * 1000);
2471
2472 int initialX = DisplayIO.getMouseX();
2473 int initialY = FrameMouseActions.getY();
2474
2475 final int timeInterval = 40;
2476
2477 int deltaX = (int) (finalX - initialX);
2478 int deltaY = (int) (finalY - initialY);
2479
2480 int intervals = milliseconds / timeInterval;
2481 for (double i = 0; i < intervals; i++) {
2482 int newX = initialX + (int) (deltaX * i / intervals);
2483 int newY = initialY + (int) (deltaY * i / intervals);
2484 Thread.yield();
2485 Thread.sleep(timeInterval);
2486 DisplayIO.setCursorPosition(newX, newY);
2487 // DisplayIO.repaint();
2488 }
2489 // Thread.yield();
2490 Thread.sleep(milliseconds % timeInterval);
2491 DisplayIO.setCursorPosition(finalX, finalY);
2492 } else if (tokens[0].equals("glideitemto")) {
2493 assertMinParametreCount(tokens, 3);
2494 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
2495 Item item = (Item) context.getPointers().getVariable(tokens[1])
2496 .getValue();
2497 int finalX = (int) context.getPrimitives().getIntegerValue(
2498 tokens[2]);
2499 int finalY = (int) context.getPrimitives().getIntegerValue(
2500 tokens[3]);
2501
2502 // DisplayIO.setCursorPosition(item.getX(), item.getY());
2503 // FrameMouseActions.pickup(item);
2504
2505 int milliseconds = 1000;
2506 if (tokens.length > 4)
2507 milliseconds = (int) (context.getPrimitives().getDoubleValue(
2508 tokens[4]) * 1000);
2509
2510 int initialX = item.getX();
2511 int initialY = item.getY();
2512 // int initialX = DisplayIO.getMouseX();
2513 // int initialY = DisplayIO.getMouseY();
2514
2515 final int timeInterval = 40;
2516
2517 int deltaX = (int) (finalX - initialX);
2518 int deltaY = (int) (finalY - initialY);
2519
2520 int intervals = milliseconds / timeInterval;
2521 for (double i = 0; i < intervals; i++) {
2522 int newX = initialX + (int) (deltaX * i / intervals);
2523 int newY = initialY + (int) (deltaY * i / intervals);
2524 Thread.yield();
2525 Thread.sleep(timeInterval);
2526 // DisplayIO.setCursorPosition(newX, newY);
2527
2528 item.setPosition(newX, newY);
2529 FrameGraphics.Repaint();
2530 }
2531 // Thread.yield();
2532 Thread.sleep(milliseconds % timeInterval);
2533 item.setPosition(finalX, finalY);
2534 // DisplayIO.setCursorPosition(finalX, finalY);
2535 FrameMouseActions.anchor(item);
2536 FreeItems.getInstance().clear();
2537 FrameGraphics.Repaint();
2538 // FrameMouseActions.updateCursor();
2539 }
2540 // Now look for fixed parametre statements
2541 else if (tokens[0].equals(EXIT_TEXT)) {
2542 return Status.Exit;
2543 } else if (tokens[0].equals(LOOP_TEXT)) {
2544 Status status = Status.OK;
2545 // Check if its a counter loop
2546 if (tokens.length > 1) {
2547 // Get the number of times to repeat the loop
2548 long finalCount = context.getPrimitives().getIntegerValue(
2549 tokens[1]);
2550 String counterVar = tokens.length > 2 ? tokens[2] : null;
2551 long count = 0;
2552 while ((status == Status.OK || status == Status.Continue)
2553 && (count < finalCount)) {
2554 count++;
2555 // Update the counter variable
2556 if (counterVar != null) {
2557 context.getPrimitives().setValue(counterVar,
2558 new SInteger(count));
2559 }
2560 status = RunFrameAndReportError(code, context);
2561 pause(code);
2562 }
2563 } else {
2564 // Keep looping until break or exit occurs
2565 while (status == Status.OK || status == Status.Continue) {
2566 status = RunFrameAndReportError(code, context);
2567 pause(code);
2568 }
2569 }
2570 if (status == Status.Continue || status == Status.Break)
2571 status = Status.OK;
2572 return status;
2573 } else if (tokens[0].equals(CONTINUE_TEXT)
2574 || tokens[0].equals(CONTINUE2_TEXT)) {
2575 return Status.Continue;
2576 } else if (tokens[0].equals(BREAK_TEXT)
2577 || tokens[0].equals(BREAK2_TEXT)) {
2578 return Status.Break;
2579 } else if (tokens[0].equals(RETURN_TEXT)) {
2580 return Status.Return;
2581 } else if (tokens[0].equals("pressleftbutton")) {
2582 assertExactParametreCount(tokens, 0);
2583 DisplayIO.pressMouse(InputEvent.BUTTON1_MASK);
2584 } else if (tokens[0].equals("pressmiddlebutton")) {
2585 assertExactParametreCount(tokens, 0);
2586 DisplayIO.pressMouse(InputEvent.BUTTON2_MASK);
2587 } else if (tokens[0].equals("pressrightbutton")) {
2588 assertExactParametreCount(tokens, 0);
2589 DisplayIO.pressMouse(InputEvent.BUTTON3_MASK);
2590 } else if (tokens[0].equals("releaseleftbutton")) {
2591 assertExactParametreCount(tokens, 0);
2592 DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK);
2593 } else if (tokens[0].equals("releasemiddlebutton")) {
2594 assertExactParametreCount(tokens, 0);
2595 DisplayIO.releaseMouse(InputEvent.BUTTON2_MASK);
2596 } else if (tokens[0].equals("releaserightbutton")) {
2597 assertExactParametreCount(tokens, 0);
2598 DisplayIO.releaseMouse(InputEvent.BUTTON3_MASK);
2599 } else if (tokens[0].equals("clickleftbutton")) {
2600 assertExactParametreCount(tokens, 0);
2601 FrameMouseActions.leftButton();
2602 // DisplayIO.clickMouse(InputEvent.BUTTON1_MASK);
2603 } else if (tokens[0].equals("clickmiddlebutton")) {
2604 assertExactParametreCount(tokens, 0);
2605 FrameMouseActions.middleButton();
2606 // DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
2607 } else if (tokens[0].equals("clickrightbutton")) {
2608 assertExactParametreCount(tokens, 0);
2609 FrameMouseActions.rightButton();
2610 // DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
2611 } else if (tokens[0].equals("repaint")) {
2612 assertExactParametreCount(tokens, 0);
2613 // FrameGraphics.Repaint();
2614 FrameGraphics.requestRefresh(true);
2615 } else if (tokens[0].equals("add")) {
2616 assertMaxParametreCount(tokens, 3);
2617 switch (tokens.length) {
2618 case 1:
2619 context.getPrimitives().add(DEFAULT_INTEGER);
2620 break;
2621 case 2:
2622 context.getPrimitives().add(tokens[1]);
2623 break;
2624 case 3:
2625 context.getPrimitives().add(tokens[2], tokens[1]);
2626 break;
2627 case 4:
2628 context.getPrimitives().add(tokens[1], tokens[2], tokens[3]);
2629 break;
2630 default:
2631 assert (false);
2632 }
2633 } else if (tokens[0].equals("subtract")) {
2634 assertMaxParametreCount(tokens, 3);
2635 switch (tokens.length) {
2636 case 1:
2637 context.getPrimitives().subtract(DEFAULT_INTEGER);
2638 break;
2639 case 2:
2640 context.getPrimitives().subtract(tokens[1]);
2641 break;
2642 case 3:
2643 context.getPrimitives().subtract(tokens[2], tokens[1]);
2644 break;
2645 case 4:
2646 context.getPrimitives().subtract(tokens[1], tokens[2],
2647 tokens[3]);
2648 break;
2649 default:
2650 assert (false);
2651 }
2652 } else if (tokens[0].equals("multiply")) {
2653 assertMinParametreCount(tokens, 2);
2654 assertMaxParametreCount(tokens, 3);
2655 switch (tokens.length) {
2656 case 3:
2657 context.getPrimitives().multiply(tokens[2], tokens[1]);
2658 break;
2659 case 4:
2660 context.getPrimitives().multiply(tokens[1], tokens[2],
2661 tokens[3]);
2662 break;
2663 default:
2664 assert (false);
2665 }
2666 } else if (tokens[0].equals("divide")) {
2667 assertMinParametreCount(tokens, 2);
2668 assertMaxParametreCount(tokens, 3);
2669 switch (tokens.length) {
2670 case 3:
2671 context.getPrimitives().divide(tokens[2], tokens[1]);
2672 break;
2673 case 4:
2674 context.getPrimitives().divide(tokens[1], tokens[2], tokens[3]);
2675 break;
2676 default:
2677 assert (false);
2678 }
2679 } else if (tokens[0].equals("modulo")) {
2680 assertExactParametreCount(tokens, 3);
2681 context.getPrimitives().modulo(tokens[1], tokens[2], tokens[3]);
2682 } else if (tokens[0].equals("power")) {
2683 assertExactParametreCount(tokens, 3);
2684 context.getPrimitives().power(tokens[1], tokens[2], tokens[3]);
2685 } else if (tokens[0].equals("not")) {
2686 assertExactParametreCount(tokens, 2);
2687 context.getPrimitives().not(tokens[1], tokens[2]);
2688 } else if (tokens[0].equals("exp")) {
2689 assertExactParametreCount(tokens, 2);
2690 context.getPrimitives().exp(tokens[1], tokens[2]);
2691 } else if (tokens[0].equals("log")) {
2692 assertExactParametreCount(tokens, 2);
2693 context.getPrimitives().log(tokens[2], tokens[2]);
2694 } else if (tokens[0].equals("log10")) {
2695 assertExactParametreCount(tokens, 2);
2696 context.getPrimitives().log10(tokens[1], tokens[2]);
2697 } else if (tokens[0].equals("sqrt")) {
2698 assertExactParametreCount(tokens, 2);
2699 context.getPrimitives().sqrt(tokens[1], tokens[2]);
2700 } else if (tokens[0].equals("closewritefile")) {
2701 assertVariableType(tokens[1], 1, SPointer.filePrefix);
2702 context.closeWriteFile(tokens[1]);
2703 } else if (tokens[0].equals("closereadfile")) {
2704 assertVariableType(tokens[1], 1, SPointer.filePrefix);
2705 context.closeReadFile(tokens[1]);
2706 } else if (tokens[0].startsWith("foreach")) {
2707 if (tokens[0].equals("foreachassociation")) {
2708 assertExactParametreCount(tokens, 3);
2709 assertVariableType(tokens[1], 1, SPointer.associationPrefix);
2710 Map<String, String> map = (Map<String, String>) context
2711 .getPointers().getVariable(tokens[1]).getValue();
2712 for (Map.Entry entry : map.entrySet()) {
2713 String value = entry.getValue().toString();
2714 String key = entry.getKey().toString();
2715 context.getPrimitives().setValue(tokens[2], key);
2716 context.getPrimitives().setValue(tokens[3], value);
2717 Status status = RunFrameAndReportError(code, context);
2718 pause(code);
2719 // check if we need to exit this loop because of
2720 // statements in the code that was run
2721 if (status == Status.Exit || status == Status.Return)
2722 return status;
2723 else if (status == Status.Break)
2724 break;
2725 }
2726 } else {
2727 Class itemType = Object.class;
2728 String type = tokens[0].substring("foreach".length());
2729 // Check the type of foreach loop
2730 // and set the item type to iterate over
2731 if (type.equals("dot")) {
2732 itemType = Dot.class;
2733 } else if (type.equals("text")) {
2734 itemType = Text.class;
2735 } else if (type.equals("line")) {
2736 itemType = Line.class;
2737 } else if (type.equals("item") || type.equals("")) {
2738 itemType = Object.class;
2739 } else {
2740 throw new RuntimeException("Invalid ForEach loop type");
2741 }
2742
2743 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
2744 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2745 Frame currFrame = (Frame) context.getPointers().getVariable(
2746 tokens[1]).getValue();
2747 // Create the ip variable
2748 Item frameTitle = currFrame.getTitleItem();
2749
2750 for (Item i : currFrame.getVisibleItems()) {
2751 if (i == frameTitle)
2752 continue;
2753 if (!(itemType.isInstance(i)))
2754 continue;
2755
2756 context.getPointers().setObject(tokens[2], i);
2757 Status status = RunFrameAndReportError(code, context);
2758 pause(code);
2759 // check if we need to exit this loop because of
2760 // statements in the code that was run
2761 if (status == Status.Exit || status == Status.Return)
2762 return status;
2763 else if (status == Status.Break)
2764 return Status.OK;
2765 }
2766 }
2767 } else if (tokens[0].equals("movecursorto")) {
2768 assertExactParametreCount(tokens, 2);
2769 int x = (int) context.getPrimitives().getIntegerValue(tokens[1]);
2770 int y = (int) context.getPrimitives().getIntegerValue(tokens[2]);
2771 DisplayIO.setCursorPosition(x, y);
2772 } else {
2773 // Check the available actions
2774 if (!executeAction(tokens, context)) {
2775 throw new RuntimeException("Unknown statement");
2776 }
2777 }
2778 return Status.OK;
2779 }
2780
2781 /**
2782 * This method is the backstop if the main SIMPLE parser did not recognise.
2783 * the statement TODO make it so it passes the vars rather than a string
2784 * with all the vars in order to improve efficiency.
2785 *
2786 * @param tokens
2787 * @param context
2788 * @return
2789 * @throws Exception
2790 */
2791 private static boolean executeAction(String[] tokens, Context context)
2792 throws Exception {
2793 StringBuffer command = new StringBuffer();
2794 command.append(tokens[0]);
2795 int param = 1;
2796
2797 Frame source = null;
2798 // Check if the first param is a frame
2799 if (param < tokens.length
2800 && tokens[param].startsWith(SPointer.framePrefix)) {
2801 source = (Frame) context.getPointers().getVariable(tokens[param])
2802 .getValue();
2803 param++;
2804 }
2805 // Check if the next param is an item
2806 Item launcher = null;
2807 if (param < tokens.length
2808 && tokens[param].startsWith(SPointer.itemPrefix)) {
2809 try {
2810 launcher = (Item) context.getPointers().getVariable(
2811 tokens[param]).getValue();
2812 param++;
2813 } catch (Exception e) {
2814 // If the variable does not exist it could be for a return value
2815 }
2816 }
2817
2818 if (source == null)
2819 source = DisplayIO.getCurrentFrame();
2820 int lastParam = tokens.length - 1;
2821 String resultVarName = null;
2822 if (tokens[lastParam].startsWith(SPointer.itemPrefix)) {
2823 resultVarName = tokens[lastParam];
2824 lastParam--;
2825 }
2826
2827 // Finally add the rest of the params as Strings
2828 for (int i = param; i <= lastParam; i++) {
2829 command.append(' ').append(
2830 context.getPrimitives().getStringValue(tokens[i]));
2831 }
2832
2833 Object returnValue = Actions.PerformAction(source, launcher, command
2834 .toString());
2835 if (returnValue != null) {
2836 if (resultVarName != null) {
2837 if (!(returnValue instanceof Item)) {
2838 try {
2839 Item item = ((Item) context.getPointers().getVariable(
2840 resultVarName).getValue());
2841 item.setText(returnValue.toString());
2842 returnValue = item;
2843 } catch (Exception e) {
2844 // If the itemVariable does not exist then create one
2845 returnValue = source.getStatsTextItem(returnValue
2846 .toString());
2847 }
2848 }
2849 context.getPointers().setObject(resultVarName, returnValue);
2850 } else {
2851 FreeItems.getInstance().clear();
2852 if (returnValue instanceof Item) {
2853 Misc.attachToCursor((Item) returnValue);
2854 } else {
2855 Misc.attachStatsToCursor(returnValue.toString());
2856 }
2857 }
2858 }
2859
2860 return true;
2861 }
2862
2863 public static int countCharsInString(String s, String pattern) {
2864 String newString = s;
2865 int count = -1;
2866 do {
2867 count++;
2868 s = newString;
2869 newString = s.replaceFirst(pattern, "");
2870 } while (s.length() != newString.length());
2871
2872 return count;
2873 }
2874
2875 public static void assertVariableType(String varName, int no, String type)
2876 throws Exception {
2877 if (!varName.startsWith(type))
2878 throw new IncorrectTypeException(type, no);
2879 }
2880
2881 /*
2882 * public static void assertPrimitiveType(String varName, int no) throws
2883 * Exception { if (!Primitives.isPrimitive(varName)) throw new
2884 * IncorrectTypeException("primitive", no); }
2885 */
2886
2887 public static void assertMinParametreCount(String[] tokens,
2888 int minParametres) throws Exception {
2889 if (tokens.length - 1 < minParametres)
2890 throw new BelowMinParametreCountException(minParametres);
2891 }
2892
2893 public static void assertExactParametreCount(String[] tokens,
2894 int parametreCount) throws Exception {
2895 if (tokens.length - 1 != parametreCount)
2896 throw new IncorrectParametreCountException(parametreCount);
2897 }
2898
2899 public static void assertMaxParametreCount(String[] tokens,
2900 int parametreCount) throws Exception {
2901 if (tokens.length - 1 > parametreCount)
2902 throw new AboveMaxParametreCountException(parametreCount);
2903 }
2904
2905 private static String getMessage(String[] tokens, Context context,
2906 String code, String separator, int firstStringIndex)
2907 throws Exception {
2908 StringBuilder message = new StringBuilder();
2909 if (tokens.length == firstStringIndex) {
2910 message.append(context.getPrimitives().getVariable(DEFAULT_STRING)
2911 .stringValue());
2912 } else {
2913 for (int i = firstStringIndex; i < tokens.length; i++) {
2914 if (Primitives.isPrimitive(tokens[i])) {
2915 message.append(context.getPrimitives().getVariable(
2916 tokens[i]).stringValue()
2917 + separator);
2918 } else
2919 throw new Exception("Illegal parametre: [" + tokens[i]
2920 + "] in line " + code);
2921 }
2922 }
2923 return message.toString();
2924 }
2925
2926 public static void stop() {
2927 _stop = true;
2928 if (_agent != null) {
2929 _agent.stop();
2930 }
2931 }
2932
2933 public static void nextStatement() {
2934 _nextStatement = true;
2935 }
2936
2937 public static void ProgramStarted() {
2938 _programsRunning++;
2939 AgentStats.reset();
2940 MessageBay.displayMessage("Running SimpleProgram...", Color.BLUE);
2941 }
2942
2943 public static boolean isVerbose() {
2944 return _verbose;
2945 }
2946}
Note: See TracBrowser for help on using the repository browser.