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

Last change on this file since 429 was 429, checked in by ra33, 15 years ago

Fixed problems with ghost items being created when ranging

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