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

Last change on this file since 919 was 919, checked in by jts21, 10 years ago

Added license headers to all files, added full GPL3 license file, moved license header generator script to dev/bin/scripts

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