001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.drjava.model.repl;
038:
039: import edu.rice.cs.drjava.DrJavaTestCase;
040: import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
041: import edu.rice.cs.drjava.model.repl.newjvm.MainJVM;
042: import edu.rice.cs.drjava.model.FileSaveSelector;
043:
044: import edu.rice.cs.util.FileOpenSelector;
045: import edu.rice.cs.util.Log;
046: import edu.rice.cs.util.OperationCanceledException;
047: import edu.rice.cs.util.StringOps;
048: import edu.rice.cs.util.text.ConsoleDocument;
049: import edu.rice.cs.util.text.EditDocumentException;
050:
051: import java.io.File;
052: import java.io.IOException;
053:
054: import java.rmi.RemoteException;
055:
056: /** Tests the functionality of an InteractionsModel.
057: * @version $Id: InteractionsModelTest.java 4255 2007-08-28 19:17:37Z mgricken $
058: */
059: public final class InteractionsModelTest extends DrJavaTestCase {
060:
061: private static Log _log = new Log("InteractionsModelTest.txt",
062: false);
063: protected InteractionsDJDocument _adapter;
064: protected InteractionsModel _model;
065:
066: public InteractionsModelTest(String name) {
067: super (name);
068: _adapter = new InteractionsDJDocument();
069: _model = new TestInteractionsModel(_adapter);
070: }
071:
072: public void tearDown() throws Exception {
073: // dispose the the AbstractMasterJVM supervising the MainJVM if it exists
074: if (_model instanceof IncompleteInputInteractionsModel)
075: ((IncompleteInputInteractionsModel) _model).dispose();
076: _model = null;
077: _adapter = null;
078: super .tearDown();
079: }
080:
081: /** Asserts that the given string typed by the user is processed to become the given expected string for an
082: * interpretation.
083: * @param typed A string typed by the user
084: * @param expected What the processor should return
085: */
086: protected void _assertProcessedContents(String typed,
087: String expected) throws EditDocumentException {
088: assertTrue(_model instanceof TestInteractionsModel);
089: TestInteractionsModel model = (TestInteractionsModel) _model;
090: InteractionsDocument doc = model.getDocument();
091: doc.reset("This is a test");
092: doc.append(typed, InteractionsDocument.DEFAULT_STYLE);
093: model.interpretCurrentInteraction();
094: assertEquals("processed output should match expected",
095: expected, model.toEval);
096: }
097:
098: /** Asserts that the given string typed by the user of the form "java classname" is transformed to the given
099: * expected main method invocation.
100: * @param typed the "java classname args ..." typed by the user
101: * @param expected the expected main class call
102: */
103: protected void _assertMainTransformation(String typed,
104: String expected) {
105: assertEquals("main transformation should match expected",
106: expected, TestInteractionsModel._testClassCall(typed));
107: }
108:
109: /** Tests that the correct text is returned when interpreting. */
110: public void testInterpretCurrentInteraction()
111: throws EditDocumentException {
112: assertTrue(_model instanceof TestInteractionsModel);
113: TestInteractionsModel model = (TestInteractionsModel) _model;
114: String code = "int x = 3;";
115: InteractionsDocument doc = model.getDocument();
116: model.interpretCurrentInteraction();
117: // pretend the call completed
118: model.replReturnedVoid();
119: assertEquals("string being interpreted", "", model.toEval);
120:
121: // Insert text and evaluate
122: doc.append(code, InteractionsDocument.DEFAULT_STYLE);
123: model.interpretCurrentInteraction();
124: // pretend the call completed
125: model.replReturnedVoid();
126: assertEquals("string being interpreted", code, model.toEval);
127: }
128:
129: // Why do we create a new model (and slave JVM) for each of this trivial tests?
130: public void testInterpretCurrentInteractionWithIncompleteInput()
131: throws EditDocumentException, InterruptedException,
132: RemoteException {
133: _log
134: .log("testInterpretCurrentInteractionWithIncompleteInput started");
135: _model = new IncompleteInputInteractionsModel(_adapter); // override the one initialized in setUp()
136: assertReplThrewContinuationException("void m() {");
137: assertReplThrewContinuationException("void m() {;");
138: assertReplThrewContinuationException("1+");
139: assertReplThrewContinuationException("(1+2");
140: assertReplThrewSyntaxException("(1+2;");
141: assertReplThrewContinuationException("for (;;");
142: }
143:
144: protected void assertReplThrewContinuationException(String code)
145: throws EditDocumentException, InterruptedException {
146: assertTrue(_model instanceof IncompleteInputInteractionsModel);
147: IncompleteInputInteractionsModel model = (IncompleteInputInteractionsModel) _model;
148: InteractionsDocument doc = model.getDocument();
149: doc.reset("This is a test");
150: doc.append(code, InteractionsDocument.DEFAULT_STYLE);
151: model._logInteractionStart();
152: model.interpretCurrentInteraction();
153: _log.log("Waiting for InteractionDone()");
154: model._waitInteractionDone();
155: assertTrue(
156: "Code '"
157: + code
158: + "' should generate a continuation exception but not a syntax exception",
159: (model.isContinuationException() == true)
160: && (model.isSyntaxException() == false));
161: }
162:
163: protected void assertReplThrewSyntaxException(String code)
164: throws EditDocumentException, InterruptedException {
165: assertTrue(_model instanceof IncompleteInputInteractionsModel);
166: IncompleteInputInteractionsModel model = (IncompleteInputInteractionsModel) _model;
167: InteractionsDocument doc = model.getDocument();
168: doc.reset("This is a test");
169: doc.append(code, InteractionsDocument.DEFAULT_STYLE);
170: model._logInteractionStart();
171: model.interpretCurrentInteraction();
172: model._waitInteractionDone();
173: assertTrue(
174: "Code '"
175: + code
176: + "' should generate a syntax exception but not a continuation exception",
177: (model.isSyntaxException() == true)
178: && (model.isContinuationException() == false));
179: }
180:
181: /** Tests that "java Classname [args]" runs the class's main method, with simple delimited arguments. */
182: public void testInterpretJavaArguments() {
183: // java Foo a b c
184: // Foo.main(new String[]{"a", "b", "c"});
185: _assertMainTransformation("java Foo a b c",
186: "Foo.main(new String[]{\"a\",\"b\",\"c\"});");
187: // java Foo "a b c"
188: // Foo.main(new String[]{"a b c"});
189: _assertMainTransformation("java Foo \"a b c\"",
190: "Foo.main(new String[]{\"a b c\"});");
191: // java Foo "a b"c d
192: // Foo.main(new String[]{"a bc", "d"});
193: // This is different behavior than Unix or DOS, but it's more
194: // intuitive to the user (and easier to implement).
195: _assertMainTransformation("java Foo \"a b\"c d",
196: "Foo.main(new String[]{\"a bc\",\"d\"});");
197:
198: // java Foo c:\\file.txt
199: // Foo.main("c:\\file.txt");
200: _assertMainTransformation("java Foo c:\\\\file.txt",
201: "Foo.main(new String[]{\"c:\\\\file.txt\"});");
202:
203: // java Foo /home/user/file
204: // Foo.main("/home/user/file");
205: _assertMainTransformation("java Foo /home/user/file",
206: "Foo.main(new String[]{\"/home/user/file\"});");
207: }
208:
209: /** Tests that escaped characters just return the character itself. Escaped whitespace is considered a character,
210: * not a delimiter. (This is how Unix behaves.)
211: *
212: * not currently enforcing any behavior for a simple implementation using a StreamTokenizer
213: */
214: public void testInterpretJavaEscapedArgs() {
215: // java Foo \j
216: // Foo.main(new String[]{"j"});
217: _assertMainTransformation("java Foo \\j",
218: "Foo.main(new String[]{\"j\"});");
219: // java Foo \"
220: // Foo.main(new String[]{"\""});
221: _assertMainTransformation("java Foo \\\"",
222: "Foo.main(new String[]{\"\\\"\"});");
223: // java Foo \\
224: // Foo.main(new String[]{"\\"});
225: _assertMainTransformation("java Foo \\\\",
226: "Foo.main(new String[]{\"\\\\\"});");
227: // java Foo a\ b
228: // Foo.main(new String[]{"a b"});
229: _assertMainTransformation("java Foo a\\ b",
230: "Foo.main(new String[]{\"a b\"});");
231: }
232:
233: /** Tests that within a quote, everything is correctly escaped.
234: * (Special characters are passed to the program correctly.)
235: */
236: public void testInterpretJavaQuotedEscapedArgs() {
237: // java Foo "a \" b"
238: // Foo.main(new String[]{"a \" b"});
239: _assertMainTransformation("java Foo \"a \\\" b\"",
240: "Foo.main(new String[]{\"a \\\" b\"});");
241: // java Foo "\'"
242: // Foo.main(new String[]{"\\'"});
243: _assertMainTransformation("java Foo \"\\'\"",
244: "Foo.main(new String[]{\"\\\\'\"});");
245: // java Foo "\\"
246: // Foo.main(new String[]{"\\"});
247: _assertMainTransformation("java Foo \"\\\\\"",
248: "Foo.main(new String[]{\"\\\\\"});");
249: // java Foo "\" \d"
250: // Foo.main(new String[]{"\" \\d"});
251: _assertMainTransformation("java Foo \"\\\" \\d\"",
252: "Foo.main(new String[]{\"\\\" \\\\d\"});");
253: // java Foo "\n"
254: // Foo.main(new String[]{"\n"});
255: /* _assertMainTransformation("java Foo \"\\n\"",
256: "Foo.main(new String[]{\"\\n\"});");
257: // java Foo "\t"
258: // Foo.main(new String[]{"\t"});
259: _assertMainTransformation("java Foo \"\\t\"",
260: "Foo.main(new String[]{\"\\t\"});");
261: // java Foo "\r"
262: // Foo.main(new String[]{"\r"});
263: _assertMainTransformation("java Foo \"\\r\"",
264: "Foo.main(new String[]{\"\\r\"});");
265: // java Foo "\f"
266: // Foo.main(new String[]{"\f"});
267: _assertMainTransformation("java Foo \"\\f\"",
268: "Foo.main(new String[]{\"\\f\"});");
269: // java Foo "\b"
270: // Foo.main(new String[]{"\b"});
271: _assertMainTransformation("java Foo \"\\b\"",
272: "Foo.main(new String[]{\"\\b\"});"); */
273: }
274:
275: /** Tests that single quotes can be used as argument delimiters. */
276: public void testInterpretJavaSingleQuotedArgs() {
277:
278: // java Foo 'asdf'
279: _assertMainTransformation("java Foo 'asdf'",
280: "Foo.main(new String[]{\"asdf\"});");
281:
282: // java Foo 'a b c'
283: _assertMainTransformation("java Foo 'a b c'",
284: "Foo.main(new String[]{\"a b c\"});");
285:
286: // java Foo 'a b'c
287: _assertMainTransformation("java Foo 'a b'c",
288: "Foo.main(new String[]{\"a bc\"});");
289: }
290:
291: //public void testLoadHistory();
292: // TO DO: test that the correct history is returned (careful of last newline)
293:
294: /** Tests that a debug port can be generated. */
295: public void testDebugPort() throws IOException {
296: int port = _model.getDebugPort();
297: assertTrue("generated debug port", port != -1);
298:
299: // Resetting after startUp should change the port
300: _model.setWaitingForFirstInterpreter(false);
301: _model.interpreterResetting();
302: int newPort = _model.getDebugPort();
303: assertTrue("debug port should change", newPort != port);
304:
305: // Set port
306: _model.setDebugPort(5);
307: assertEquals("manually set debug port", 5, _model
308: .getDebugPort());
309:
310: // Port should stay -1 after setting it
311: _model.setDebugPort(-1);
312: assertEquals("debug port should be -1", -1, _model
313: .getDebugPort());
314: }
315:
316: /** Tests that an interactions history can be loaded in as a script. */
317: public void testScriptLoading() throws IOException,
318: OperationCanceledException {
319: assertTrue(_model instanceof TestInteractionsModel);
320: TestInteractionsModel model = (TestInteractionsModel) _model;
321: // Set up a sample history
322: String line1 = "System.out.println(\"hi\")";
323: String line2 = "System.out.println(\"bye\")";
324: // String delim = History.INTERACTION_SEPARATOR + StringOps.EOL;
325: final File temp = File.createTempFile("drjava-test", ".hist")
326: .getCanonicalFile();
327: temp.deleteOnExit();
328: History history = new History(5);
329: history.add(line1);
330: history.add(line2);
331: history.writeToFile(new FileSaveSelector() {
332: public File getFile() {
333: return temp;
334: }
335:
336: public boolean warnFileOpen(File f) {
337: return true;
338: }
339:
340: public boolean verifyOverwrite() {
341: return true;
342: }
343:
344: public boolean shouldSaveAfterFileMoved(
345: OpenDefinitionsDocument doc, File oldFile) {
346: return true;
347: }
348: });
349:
350: // Load the history as a script
351: InteractionsScriptModel ism = model
352: .loadHistoryAsScript(new FileOpenSelector() {
353: public File[] getFiles() {
354: return new File[] { temp };
355: }
356: });
357: InteractionsDocument doc = model.getDocument();
358:
359: // Should not be able to get the previous interaction
360: assertTrue("Should have no previous", !ism.hasPrevInteraction());
361: try {
362: ism.prevInteraction();
363: fail("Should not have been able to get previous interaction!");
364: } catch (IllegalStateException ise) {
365: // good, continue
366: }
367:
368: // Get the next (first) interaction
369: assertTrue("Should have next", ism.hasNextInteraction());
370: ism.nextInteraction();
371: assertEquals(
372: "Should have put the first line into the document.",
373: line1, doc.getCurrentInteraction());
374:
375: // Still should not be able to get the previous interaction
376: assertTrue("Should have no previous", !ism.hasPrevInteraction());
377: try {
378: ism.prevInteraction();
379: fail("Should not have been able to get previous interaction!");
380: } catch (IllegalStateException ise) {
381: // good, continue
382: }
383:
384: // Skip it; get the next (second) interaction
385: assertTrue("Should have next", ism.hasNextInteraction());
386: ism.nextInteraction();
387: assertEquals(
388: "Should have put the second line into the document.",
389: line2, doc.getCurrentInteraction());
390:
391: // Now we should be able to get the previous interaction
392: assertTrue("Should have previous", ism.hasPrevInteraction());
393: ism.prevInteraction();
394: assertEquals(
395: "Should have put the first line into the document.",
396: line1, doc.getCurrentInteraction());
397:
398: // Go back to the second line and execute it
399: ism.nextInteraction();
400: ism.executeInteraction();
401: assertEquals(
402: "Should have \"executed\" the second interaction.",
403: line2, model.toEval);
404: // pretend the call completed
405: model.replReturnedVoid();
406:
407: // Should not be able to get the next interaction, since we're at the end
408: assertTrue("Should have no next", !ism.hasNextInteraction());
409: try {
410: ism.nextInteraction();
411: fail("Should not have been able to get next interaction!");
412: } catch (IllegalStateException ise) {
413: // good, continue
414: }
415:
416: // Get Previous should return the most recently executed interaction
417: assertTrue("Should have previous", ism.hasPrevInteraction());
418: ism.prevInteraction();
419: assertEquals(
420: "Should have put the second line into the document.",
421: line2, doc.getCurrentInteraction());
422:
423: // Get Previous should now return the first interaction
424: assertTrue("Should have previous", ism.hasPrevInteraction());
425: ism.prevInteraction();
426: assertEquals(
427: "Should have put the first line into the document.",
428: line1, doc.getCurrentInteraction());
429:
430: // Should have no more previous
431: assertTrue("Should have no previous", !ism.hasPrevInteraction());
432:
433: // Now execute the first interaction
434: ism.executeInteraction();
435: assertEquals("Should have \"executed\" the first interaction.",
436: line1, model.toEval);
437: // pretend the call completed
438: model.replReturnedVoid();
439:
440: // Get Previous should return the most recent (first) interaction
441: assertTrue("Should have previous", ism.hasPrevInteraction());
442: ism.prevInteraction();
443: assertEquals(
444: "Should have put the first line into the document.",
445: line1, doc.getCurrentInteraction());
446:
447: // Should not be able to get the previous interaction this time
448: assertTrue("Should have no previous", !ism.hasPrevInteraction());
449: try {
450: ism.prevInteraction();
451: fail("Should not have been able to get previous interaction!");
452: } catch (IllegalStateException ise) {
453: // good, continue
454: }
455: }
456:
457: /** Tests that setting and changing an input listener works correctly. */
458: public void testSetChangeInputListener() {
459: InputListener listener1 = new InputListener() {
460: public String getConsoleInput() {
461: return "input1";
462: }
463: };
464:
465: InputListener listener2 = new InputListener() {
466: public String getConsoleInput() {
467: return "input2";
468: }
469: };
470:
471: try {
472: _model.getConsoleInput();
473: fail("Should not have allowed getting input before a listener is installed!");
474: } catch (IllegalStateException ise) {
475: assertEquals("Should have thrown the correct exception.",
476: "No input listener installed!", ise.getMessage());
477: }
478:
479: _model.setInputListener(listener1);
480: assertEquals(
481: "First input listener should return correct input",
482: "input1", _model.getConsoleInput());
483: _model.changeInputListener(listener1, listener2);
484: assertEquals(
485: "Second input listener should return correct input",
486: "input2", _model.getConsoleInput());
487: }
488:
489: /** Tests that the interactions history is stored correctly. See bug # 992455 */
490: public void testInteractionsHistoryStoredCorrectly()
491: throws EditDocumentException {
492: final Object _lock = new Object();
493: String code = "public class A {\n";
494:
495: InteractionsDocument doc = _model.getDocument();
496:
497: // Insert text and evaluate
498: doc.insertText(doc.getLength(), code,
499: InteractionsDocument.DEFAULT_STYLE);
500:
501: _model.interpretCurrentInteraction();
502: //Simulate result
503: _model.replReturnedSyntaxError(
504: "Encountered Unexpected \"<EOF>\"",
505: "public class A {\n", -1, -1, -1, -1);
506:
507: String expected = "public class A {\n" + "\n"; // last term was StringOps.EOL but Swing uses '\n' for newLIne
508: String result = doc.getCurrentInteraction();
509: // System.err.println("expected = '" + expected + "' length = " + expected.length());
510: // System.err.println("result = '" + result + "' length = " + result.length());
511: assertEquals(
512: "Current interaction should still be there - should not have interpreted",
513: expected, result);
514: History h = doc.getHistory();
515: assertEquals("History should be empty", 0, h.size());
516:
517: code = "}\n";
518:
519: doc.insertText(doc.getLength(), code,
520: InteractionsDocument.DEFAULT_STYLE);
521:
522: synchronized (_lock) {
523: _model.interpretCurrentInteraction();
524: _model.replReturnedVoid();
525: }
526:
527: synchronized (_lock) {
528: assertEquals(
529: "Current interaction should not be there - should have interpreted",
530: "", doc.getCurrentInteraction());
531: assertEquals("History should contain one interaction", 1, h
532: .size());
533: }
534: }
535:
536: /** A generic InteractionsModel for testing purposes. (Used here and in InteractionsPaneTest.) */
537: public static class TestInteractionsModel extends InteractionsModel {
538: String toEval = null;
539: String addedClass = null;
540:
541: /** Constructs a new InteractionsModel. */
542: public TestInteractionsModel(InteractionsDJDocument adapter) {
543: // Adapter, history size, write delay
544: super (adapter, new File(System.getProperty("user.dir")),
545: 1000, 25);
546: }
547:
548: protected void _interpret(String toEval) {
549: this .toEval = toEval;
550: }
551:
552: public String getVariableToString(String var) {
553: fail("cannot getVariableToString in a test");
554: return null;
555: }
556:
557: public String getVariableClassName(String var) {
558: fail("cannot getVariableClassName in a test");
559: return null;
560: }
561:
562: public void addProjectClassPath(File path) {
563: fail("cannot add to classpath in a test");
564: }
565:
566: public void addBuildDirectoryClassPath(File path) {
567: fail("cannot add to classpath in a test");
568: }
569:
570: public void addProjectFilesClassPath(File path) {
571: fail("cannot add to classpath in a test");
572: }
573:
574: public void addExternalFilesClassPath(File path) {
575: fail("cannot add to classpath in a test");
576: }
577:
578: public void addExtraClassPath(File path) {
579: fail("cannot add to classpath in a test");
580: }
581:
582: protected void _resetInterpreter(File wd) {
583: fail("cannot reset interpreter in a test");
584: }
585:
586: protected void _notifyInteractionStarted() {
587: }
588:
589: protected void _notifyInteractionEnded() {
590: }
591:
592: protected void _notifySyntaxErrorOccurred(int offset, int length) {
593: }
594:
595: protected void _notifyInterpreterExited(int status) {
596: }
597:
598: protected void _notifyInterpreterResetting() {
599: }
600:
601: protected void _notifyInterpreterResetFailed(Throwable t) {
602: }
603:
604: public void _notifyInterpreterReady(File wd) {
605: }
606:
607: protected void _interpreterResetFailed(Throwable t) {
608: }
609:
610: protected void _notifyInteractionIncomplete() {
611: }
612:
613: protected void _notifySlaveJVMUsed() {
614: }
615:
616: public ConsoleDocument getConsoleDocument() {
617: return null;
618: }
619: }
620:
621: /** This test model includes a slave JVM, just like a DefaultGlobalModel. It must be disposed before it is
622: * deallocated to kill the slave JVM. TODO: the mutation in this class is disgusting -- Corky 2 June 06.
623: */
624: private static class IncompleteInputInteractionsModel extends
625: RMIInteractionsModel {
626: boolean continuationException; // This appears to be the negation of syntaxException making it redundant!
627: boolean syntaxException;
628:
629: private volatile boolean _interactionDone = false;
630: private final Object _interactionLock = new Object();
631:
632: public void _logInteractionStart() {
633: _interactionDone = false;
634: }
635:
636: public void _waitInteractionDone() throws InterruptedException {
637: synchronized (_interactionLock) {
638: while (!_interactionDone)
639: _interactionLock.wait();
640: }
641: }
642:
643: /** Constructs a new IncompleteInputInteractionsModel. */
644: public IncompleteInputInteractionsModel(
645: InteractionsDJDocument adapter) throws RemoteException {
646: // MainJVM, Adapter, history size, write delay
647: super (new MainJVM(null), adapter, new File(System
648: .getProperty("user.dir")), 1000, 25);
649: _jvm.setInteractionsModel(this ); // _jvm is set to MainJVM(null) by super call;
650: _jvm.startInterpreterJVM();
651: continuationException = false;
652: syntaxException = false;
653: }
654:
655: protected void _notifyInteractionStarted() {
656: }
657:
658: protected void _notifyInteractionEnded() {
659: _log.log("_notifyInteractionEnded called.");
660: synchronized (_interactionLock) {
661: _interactionDone = true;
662: _interactionLock.notify();
663: }
664: }
665:
666: protected void _notifySyntaxErrorOccurred(int offset, int length) {
667: }
668:
669: protected void _notifyInterpreterExited(int status) {
670: }
671:
672: protected void _notifyInterpreterResetting() {
673: }
674:
675: protected void _notifyInterpreterResetFailed(Throwable t) {
676: }
677:
678: public void _notifyInterpreterReady(File wd) {
679: }
680:
681: protected void _interpreterResetFailed(Throwable t) {
682: }
683:
684: protected void _notifyInteractionIncomplete() {
685: _notifyInteractionEnded();
686: }
687:
688: protected void _notifyInterpreterChanged(boolean inProgress) {
689: }
690:
691: protected void _notifySlaveJVMUsed() {
692: }
693:
694: public void dispose() throws RemoteException {
695: _jvm.dispose();
696: }
697:
698: public ConsoleDocument getConsoleDocument() {
699: return null;
700: }
701:
702: public void replThrewException(String exceptionClass,
703: String message, String stackTrace, String shortMessage) {
704: _log.log("replThrewException called");
705: if (shortMessage != null) {
706: if (shortMessage.endsWith("<EOF>\"")) {
707: continuationException = true;
708: syntaxException = false;
709: _interactionIsOver();
710: return;
711: }
712: }
713: syntaxException = true;
714: continuationException = false;
715: _interactionIsOver();
716: }
717:
718: public void replReturnedSyntaxError(String errorMessage,
719: String interaction, int startRow, int startCol,
720: int endRow, int endCol) {
721: _log.log("replReturnedSyntaxError called");
722: if (errorMessage != null) {
723: if (errorMessage.endsWith("<EOF>\"")) {
724: continuationException = true;
725: syntaxException = false;
726: _interactionIsOver();
727: return;
728: }
729: }
730: syntaxException = true;
731: continuationException = false;
732: _interactionIsOver();
733: }
734:
735: public boolean isContinuationException() {
736: return continuationException;
737: }
738:
739: public boolean isSyntaxException() {
740: return syntaxException;
741: }
742: }
743:
744: // public class TestInteractionsListener extends DummyInteractionsListener {
745: // private volatile boolean _interactionDone = false; // records when the interaction is done
746: // private final Object _interactionLock = new Object(); // lock for _interactionDone
747: //
748: // /** Relying on the default constructor. */
749: //
750: // public void interactionEnded() {
751: // synchronized(_interactionLock) {
752: // _interactionDone = true;
753: // _interactionLock.notify();
754: // }
755: // }
756: // public void logInteractionStart() { _interactionDone = false; }
757: //
758: // public void waitInteractionDone() throws InterruptedException {
759: // synchronized(_interactionLock) { while (! _interactionDone) _interactionLock.wait(); }
760: // }
761: // }
762: }
|