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

Last change on this file since 442 was 442, checked in by davidb, 12 years ago

Fixed syntax error in the code.

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