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

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