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

Last change on this file since 1415 was 1415, checked in by bln4, 5 years ago

Renamed Frame.getItems() to Frame.getSortedItems() to better represent its functionality.

-> org.apollo.ApolloGestureActions
-> org.apollo.ApolloSystem
-> org.expeditee.actions.Actions
-> org.expeditee.actions.Debug
-> org.expeditee.actions.ExploratorySearchActions
-> org.expeditee.actions.JfxBrowserActions
-> org.expeditee.actions.Misc
-> org.expeditee.actions.Navigation
-> org.expeditee.actions.ScriptBase
-> org.expeditee.actions.Simple
-> org.expeditee.agents.ComputeTree
-> org.expeditee.agents.CopyTree
-> org.expeditee.agents.DisplayComet
-> org.expeditee.agents.DisplayTree
-> org.expeditee.agents.DisplayTreeLeaves
-> org.expeditee.agents.GraphFramesetLinks
-> org.expeditee.agents.TreeProcessor
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.DisplayController
-> org.expeditee.gui.FrameCreator
-> org.expeditee.gui.FrameIO
-> org.expeditee.io.DefaultTreeWriter
-> org.expeditee.io.JavaWriter
-> org.expeditee.io.PDF2Writer
-> org.expeditee.io.TXTWriter
-> org.expeditee.io.WebParser
-> org.expeditee.io.flowlayout.XGroupItem
-> org.expeditee.items.Dot
-> org.expeditee.items.Item
-> org.expeditee.items.ItemUtils
-> org.expeditee.network.FrameShare
-> org.expeditee.stats.TreeStats


Created ItemsList class to wrap ArrayList<Item>. Frames now use this new class to store its body list (used for display) as well as its primaryBody and surrogateBody.

-> org.expeditee.agents.Format
-> org.expeditee.agents.HFormat
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.Frame
-> org.expeditee.gui.FrameUtils


Refactorted Frame.setResort(bool) to Frame.invalidateSorted() to better function how it is intended to with a more accurate name.

-> org.expeditee.agents.Sort


When writing out .exp files and getting attributes to respond to LEFT + RIGHT click, boolean items are by default true. This has always been the case. An ammendment to this is that defaults can now be established.
Also added 'EnterClick' functionality. If cursored over a item with this property and you press enter, it acts as if you have clicked on it instead.

-> org.expeditee.assets.resources-public.framesets.authentication.1.exp to 6.exp
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gio.input.KBMInputEvent
-> org.expeditee.gio.javafx.JavaFXConversions
-> org.expeditee.gio.swing.SwingConversions
-> org.expeditee.gui.AttributeUtils
-> org.expeditee.io.Conversion
-> org.expeditee.io.DefaultFrameWriter
-> org.expeditee.items.Item


Fixed a bug caused by calling Math.abs on Integer.MIN_VALUE returning unexpected result. Due to zero being a thing, you cannot represent Math.abs(Integer.MIN_VALUE) in a Integer object. The solution is to use Integer.MIN_VALUE + 1 instead of Integer.MIN_VALUE.

-> org.expeditee.core.bounds.CombinationBounds
-> org.expeditee.io.flowlayout.DimensionExtent


Recoded the contains function in EllipticalBounds so that intersection tests containing circles work correctly.

-> org.expeditee.core.bounds.EllipticalBounds


Added toString() to PolygonBounds to allow for useful printing during debugging.

-> org.expeditee.core.bounds.PolygonBounds

Implemented Surrogate Mode!

-> org.expeditee.encryption.io.EncryptedExpReader
-> org.expeditee.encryption.io.EncryptedExpWriter
-> org.expeditee.encryption.items.surrogates.EncryptionDetail
-> org.expeditee.encryption.items.surrogates.Label
-> org.expeditee.gui.FrameUtils
-> org.expeditee.gui.ItemsList
-> org.expeditee.items.Item
-> org.expeditee.items.Text


???? Use Integer.MAX_VALUE cast to a float instead of Float.MAX_VALUE. This fixed some bug which I cannot remember.

-> org.expeditee.gio.TextLayoutManager
-> org.expeditee.gio.swing.SwingTextLayoutManager


Improved solution for dealing with the F10 key taking focus away from Expeditee due to it being a assessibility key.

-> org.expeditee.gio.swing.SwingInputManager


Renamed variable visibleItems in FrameGraphics.paintFrame to itemsToPaintCanditates to better represent functional intent.

-> org.expeditee.gui.FrameGraphics


Improved checking for if personal resources exist before recreating them

-> org.expeditee.gui.FrameIO


Repeated messages to message bay now have a visual feedback instead of just a beep. This visual feedback is in the form of a count of the amount of times it has repeated.

-> org.expeditee.gui.MessageBay


Updated comment on the Vector class to explain what vectors are.

-> org.expeditee.gui.Vector


Added constants to represent all of the property keys in DefaultFrameReader and DefaultFrameWriter.

-> org.expeditee.io.DefaultFrameReader
-> org.expeditee.io.DefaultFrameWriter


Updated the KeyList setting to be more heirarcial with how users will store their Secrets.

-> org.expeditee.settings.identity.secrets.KeyList

File size: 105.8 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.getY() - endPoint.getY()) < 10
1132 && Math.abs(startPoint.getX() - endPoint.getX()) < 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.getY() - endPoint.getY()) < 10
1383 && Math.abs(startPoint.getX() - endPoint.getX()) < 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.getSortedItems(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.getX();
1594 Integer y = pos.getY();
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.getSortedItems(),
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.getSortedItems().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(), null);
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.