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

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

Adding networking stuff for peer to peer sharing of frames

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