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

Last change on this file since 1102 was 1102, checked in by davidb, 6 years ago

Reworking of the code-base to separate logic from graphics. This version of Expeditee now supports a JFX graphics as an alternative to SWING

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