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

Last change on this file since 947 was 947, checked in by bln4, 9 years ago

Removed usused imports

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
36//import 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.