edu.rice.cs.drjava.model.repl
Class InteractionsModel

java.lang.Object
  extended by edu.rice.cs.drjava.model.repl.InteractionsModel
All Implemented Interfaces:
InteractionsModelCallback
Direct Known Subclasses:
InteractionsModelTest.TestInteractionsModel, RMIInteractionsModel, SimpleInteractionsModel

public abstract class InteractionsModel
extends Object
implements InteractionsModelCallback

A Swing specific model for the DrJava InteractionsPane. It glues together an InteractionsDocument, an InteractionsPane and a JavaInterpreter. This abstract class provides common functionality for all such models. The methods in this class generally can be executed only in the event thread once the model has been constructed.

Version:
$Id: InteractionsModel.java 4694 2008-12-08 20:47:26Z dlsmith $

Field Summary
protected  ConsoleDocumentInterface _cDoc
          The embedded interactions document (a SwingDocument in native DrJava)
protected  InteractionsDocument _document
          InteractionsDocument containing the commands and history.
protected  InputListener _inputListener
          The input listener to listen for requests to System.in.
protected  String _lastError
          Last error, or null if successful.
protected  InteractionsEventNotifier _notifier
          Keeps track of any listeners to the model.
 InteractionsPane _pane
          The interactions pane bundled with this document.
protected  String _secondToLastError
           
protected  boolean _waitingForFirstInterpreter
          Whether we are waiting for the interpreter to register for the first time.
protected  File _workingDirectory
          The working directory for the current interpreter.
 Object _writerLock
          A lock object to prevent print calls to System.out or System.err from flooding the JVM, ensuring the UI remains responsive.
static String BANNER_PREFIX
          Banner prefix.
 
Constructor Summary
InteractionsModel(ConsoleDocumentInterface cDoc, File wd, int historySize, int writeDelay)
          Constructs an InteractionsModel.
 
Method Summary
 void _addNewline()
          Appends a newLine to _document assuming that the Write Lock is already held.
protected  void _createNewDebugPort()
          Generates an available port for use with the debugger.
protected static String _deleteSemiColon(String s)
          Deletes the last character of a string.
protected static ArrayList<String> _getHistoryText(FileOpenSelector selector)
          Opens the files chosen in the given file selector, and returns an ArrayList with one history string for each selected file.
 void _interactionIsOver()
          Performs the common behavior when an interaction ends.
protected abstract  void _interpret(String toEval)
          Interprets the given command.
protected abstract  void _interpreterResetFailed(Throwable t)
          Any extra action to perform (beyond notifying listeners) when the interpreter fails to reset.
protected abstract  void _notifyInteractionEnded()
          Notifies listeners that an interaction has ended.
protected abstract  void _notifyInteractionIncomplete()
          Notifies the view that the current interaction is incomplete.
abstract  void _notifyInteractionStarted()
          Notifies listeners that an interaction has started.
protected abstract  void _notifyInterpreterExited(int status)
          Notifies listeners that the interpreter has exited unexpectedly.
abstract  void _notifyInterpreterReady(File wd)
          Notifies listeners that the interpreter is ready.
protected abstract  void _notifyInterpreterResetFailed(Throwable t)
          Notifies listeners that the interpreter reset failed.
protected abstract  void _notifyInterpreterResetting()
          Notifies listeners that the interpreter is resetting.
protected abstract  void _notifySlaveJVMUsed()
          Notifies listeners that the slave JVM has been used.
protected abstract  void _notifySyntaxErrorOccurred(int offset, int length)
          Handles a syntax error being returned from an interaction
protected static ArrayList<String> _removeSeparators(String text)
          Removes the interaction-separator comments from a history, so that they will not appear when executing the history.
protected abstract  void _resetInterpreter(File wd)
          Resets the Java interpreter.
protected static String _testClassCall(String s)
          Assumes a trimmed String.
 void _writerDelay()
          Waits for a small amount of time on a shared writer lock.
abstract  void addBuildDirectoryClassPath(File f)
          These add the given path to the build directory classpaths used in the interpreter.
abstract  void addExternalFilesClassPath(File f)
          These add the given path to the external files classpaths used in the interpreter.
abstract  void addExtraClassPath(File f)
          These add the given path to the extra classpaths used in the interpreter.
 void addListener(InteractionsListener listener)
          Adds an InteractionsListener to the model.
abstract  void addProjectClassPath(File f)
          These add the given path to the classpaths used in the interpreter.
abstract  void addProjectFilesClassPath(File f)
          These add the given path to the project files classpaths used in the interpreter.
 void append(String s, String styleName)
          Appends a string to the given document using a named style.
 void changeInputListener(InputListener oldListener, InputListener newListener)
          Changes the input listener.
 String getBanner()
           
static String getBanner(File wd)
           
abstract  ConsoleDocument getConsoleDocument()
          Gets the console tab document for this interactions model
 String getConsoleInput()
          Returns a line of text entered by the user at the equivalent of System.in.
 int getDebugPort()
          Returns the port number to use for debugging the interactions JVM.
 InteractionsDocument getDocument()
          Returns the InteractionsDocument stored by this model.
 String getLastError()
          Return the last error, or null if successful.
 String getSecondToLastError()
          Return the second to last error, or null if successful.
 String getStartUpBanner()
           
abstract  String getVariableToString(String var)
          Gets the string representation of the value of a variable in the current interpreter.
abstract  String getVariableType(String var)
          Gets the class name of a variable in the current interpreter.
 File getWorkingDirectory()
          Returns the working directory for the current interpreter.
 void interactionContinues()
           
 void interpret(String toEval)
          Interprets the given command.
 void interpretCurrentInteraction()
          Interprets the current given text at the prompt in the interactions doc.
 void interpreterReady(File wd)
          Called when a new Java interpreter has registered and is ready for use.
 void interpreterResetFailed(Throwable t)
          This method is called by the Main JVM if the Interpreter JVM cannot be exited
 void interpreterResetting()
          Called when the interpreter starts to reset.
 void loadHistory(FileOpenSelector selector)
          Interprets the files selected in the FileOpenSelector.
 InteractionsScriptModel loadHistoryAsScript(FileOpenSelector selector)
           
 void removeAllInteractionListeners()
          Removes all InteractionsListeners from this model.
 String removeLastFromHistory()
          Returns the last history item and then removes it, or returns null if the history is empty.
 void removeListener(InteractionsListener listener)
          Removea an InteractionsListener from the model.
 void replCalledSystemExit(int status)
          Signifies that the most recent interpretation contained a call to System.exit.
 void replReturnedResult(String result, String style)
          Appends the returned result to the interactions document, inserts a prompt in the interactions document, and advances the caret in the interactions pane.
 void replReturnedSyntaxError(String errorMessage, String interaction, int startRow, int startCol, int endRow, int endCol)
          Signifies that the most recent interpretation was preempted by a syntax error.
 void replReturnedVoid()
          Signifies that the most recent interpretation completed successfully, returning no value.
 void replSystemErrPrint(String s)
          Called when the repl prints to System.err.
 void replSystemOutPrint(String s)
          Called when the repl prints to System.out.
 void replThrewException(String message)
          Signifies that the most recent interpretation was ended due to an exception being thrown.
 void resetInterpreter(File wd)
          Resets the Java interpreter with working directry wd.
 void resetLastErrors()
          Reset the information about the last and second to last error.
protected  void scrollToCaret()
           
 void setDebugPort(int port)
          Sets the port number to use for debugging the interactions JVM.
 void setInputListener(InputListener listener)
          Sets the listener for any type of single-source input event.
 void setUpPane(InteractionsPane pane)
          Sets the _pane field and initializes the caret position in the pane.
 void setWaitingForFirstInterpreter(boolean waiting)
          Sets this model's notion of whether it is waiting for the first interpreter to connect.
 void slaveJVMUsed()
          Called when the slave JVM has been used for interpretation or unit testing.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

BANNER_PREFIX

public static final String BANNER_PREFIX
Banner prefix.

See Also:
Constant Field Values

_notifier

protected final InteractionsEventNotifier _notifier
Keeps track of any listeners to the model.


_document

protected volatile InteractionsDocument _document
InteractionsDocument containing the commands and history. This field is volatile rather than final because its initialization is deferred until after the interactions pane is created. The InteractionsDocument constructor indirectly accesses the pane generating a NullPointerException if _pane is uninitialized.


_waitingForFirstInterpreter

protected volatile boolean _waitingForFirstInterpreter
Whether we are waiting for the interpreter to register for the first time.


_workingDirectory

protected volatile File _workingDirectory
The working directory for the current interpreter.


_writerLock

public final Object _writerLock
A lock object to prevent print calls to System.out or System.err from flooding the JVM, ensuring the UI remains responsive. Only public for testing purposes.


_inputListener

protected volatile InputListener _inputListener
The input listener to listen for requests to System.in.


_cDoc

protected final ConsoleDocumentInterface _cDoc
The embedded interactions document (a SwingDocument in native DrJava)


_pane

public volatile InteractionsPane _pane
The interactions pane bundled with this document. In contrast to a standard MVC decomposition, where the model and the view are independent components, an interactions model inherently includes a prompt and a cursor marking where the next input expression (in progress) begins and where the cursor is within that expression. In Swing, the view contains the cursor. Our InteractionsDocument (a form of ConsoleDocument) contains the prompt. Public only for testing purposes; otherwise protected. TODO: The Eclipse plug-in doesn't use Swing, and so has no InteractionsPane. In that case, _pane is always null. This should be redesigned to eliminate the strong coupling with Swing.


_lastError

protected volatile String _lastError
Last error, or null if successful.


_secondToLastError

protected volatile String _secondToLastError
Constructor Detail

InteractionsModel

public InteractionsModel(ConsoleDocumentInterface cDoc,
                         File wd,
                         int historySize,
                         int writeDelay)
Constructs an InteractionsModel. The InteractionsPane is created later by the InteractionsController. As a result, the posting of a banner at the top of InteractionsDocument must be deferred until after the InteracationsPane has been set up.

Parameters:
cDoc - document to use in the InteractionsDocument
wd - Working directory for the interpreter
historySize - Number of lines to store in the history
writeDelay - Number of milliseconds to wait after each println
Method Detail

setUpPane

public void setUpPane(InteractionsPane pane)
Sets the _pane field and initializes the caret position in the pane. Called in the InteractionsController.


addListener

public void addListener(InteractionsListener listener)
Adds an InteractionsListener to the model.

Parameters:
listener - a listener that reacts to Interactions events.

removeListener

public void removeListener(InteractionsListener listener)
Removea an InteractionsListener from the model. If the listener is not currently listening to this model, this method has no effect.

Parameters:
listener - a listener that reacts to Interactions events

removeAllInteractionListeners

public void removeAllInteractionListeners()
Removes all InteractionsListeners from this model.


getDocument

public InteractionsDocument getDocument()
Returns the InteractionsDocument stored by this model.


interactionContinues

public void interactionContinues()

setWaitingForFirstInterpreter

public void setWaitingForFirstInterpreter(boolean waiting)
Sets this model's notion of whether it is waiting for the first interpreter to connect. The interactionsReady event is not fired for the first interpreter.


interpretCurrentInteraction

public void interpretCurrentInteraction()
Interprets the current given text at the prompt in the interactions doc. May run outside the event thread.


_addNewline

public void _addNewline()
Appends a newLine to _document assuming that the Write Lock is already held. Must run in the event thread.


interpret

public final void interpret(String toEval)
Interprets the given command.

Parameters:
toEval - command to be evaluated.

_interpret

protected abstract void _interpret(String toEval)
Interprets the given command. This should only be called from interpret, never directly.

Parameters:
toEval - command to be evaluated

_notifyInteractionIncomplete

protected abstract void _notifyInteractionIncomplete()
Notifies the view that the current interaction is incomplete.


_notifyInteractionStarted

public abstract void _notifyInteractionStarted()
Notifies listeners that an interaction has started. (Subclasses must maintain listeners.)


getVariableToString

public abstract String getVariableToString(String var)
Gets the string representation of the value of a variable in the current interpreter.

Parameters:
var - the name of the variable
Returns:
A string representation of the value, or null if the variable is not defined.

getVariableType

public abstract String getVariableType(String var)
Gets the class name of a variable in the current interpreter.

Parameters:
var - the name of the variable

resetInterpreter

public final void resetInterpreter(File wd)
Resets the Java interpreter with working directry wd.


_resetInterpreter

protected abstract void _resetInterpreter(File wd)
Resets the Java interpreter. This should only be called from resetInterpreter, never directly.


getWorkingDirectory

public File getWorkingDirectory()
Returns the working directory for the current interpreter.


addProjectClassPath

public abstract void addProjectClassPath(File f)
These add the given path to the classpaths used in the interpreter.

Parameters:
f - the path to add

addBuildDirectoryClassPath

public abstract void addBuildDirectoryClassPath(File f)
These add the given path to the build directory classpaths used in the interpreter.

Parameters:
f - the path to add

addProjectFilesClassPath

public abstract void addProjectFilesClassPath(File f)
These add the given path to the project files classpaths used in the interpreter.

Parameters:
f - the path to add

addExternalFilesClassPath

public abstract void addExternalFilesClassPath(File f)
These add the given path to the external files classpaths used in the interpreter.

Parameters:
f - the path to add

addExtraClassPath

public abstract void addExtraClassPath(File f)
These add the given path to the extra classpaths used in the interpreter.

Parameters:
f - the path to add

_notifySyntaxErrorOccurred

protected abstract void _notifySyntaxErrorOccurred(int offset,
                                                   int length)
Handles a syntax error being returned from an interaction

Parameters:
offset - the first character of the error in the InteractionsDocument
length - the length of the error.

loadHistory

public void loadHistory(FileOpenSelector selector)
                 throws IOException
Interprets the files selected in the FileOpenSelector. Assumes all strings have no trailing whitespace. Interprets the array all at once so if there are any errors, none of the statements after the first erroneous one are processed. Only runs in the event thread.

Throws:
IOException

_getHistoryText

protected static ArrayList<String> _getHistoryText(FileOpenSelector selector)
                                            throws IOException,
                                                   OperationCanceledException
Opens the files chosen in the given file selector, and returns an ArrayList with one history string for each selected file.

Parameters:
selector - A file selector supporting multiple file selection
Returns:
a list of histories (one for each selected file)
Throws:
IOException
OperationCanceledException

loadHistoryAsScript

public InteractionsScriptModel loadHistoryAsScript(FileOpenSelector selector)
                                            throws IOException,
                                                   OperationCanceledException
Throws:
IOException
OperationCanceledException

_removeSeparators

protected static ArrayList<String> _removeSeparators(String text)
Removes the interaction-separator comments from a history, so that they will not appear when executing the history.

Parameters:
text - The full, formatted text of an interactions history (obtained from _getHistoryText)
Returns:
A list of strings representing each interaction in the history. If no separators are present, the entire history is treated as one interaction.

getDebugPort

public int getDebugPort()
                 throws IOException
Returns the port number to use for debugging the interactions JVM. Generates an available port if one has not been set manually.

Specified by:
getDebugPort in interface InteractionsModelCallback
Throws:
IOException - if unable to get a valid port number.

_createNewDebugPort

protected void _createNewDebugPort()
                            throws IOException
Generates an available port for use with the debugger.

Throws:
IOException - if unable to get a valid port number.

setDebugPort

public void setDebugPort(int port)
Sets the port number to use for debugging the interactions JVM.

Parameters:
port - Port to use to debug the interactions JVM

replSystemOutPrint

public void replSystemOutPrint(String s)
Called when the repl prints to System.out. Includes a delay to prevent flooding the interactions document. This method can safely be called from outside the event thread.

Specified by:
replSystemOutPrint in interface InteractionsModelCallback
Parameters:
s - String to print

replSystemErrPrint

public void replSystemErrPrint(String s)
Called when the repl prints to System.err. Includes a delay to prevent flooding the interactions document. This method can safely be called from outside the event thread.

Specified by:
replSystemErrPrint in interface InteractionsModelCallback
Parameters:
s - String to print

getConsoleInput

public String getConsoleInput()
Returns a line of text entered by the user at the equivalent of System.in. Only executes in the event thread.

Specified by:
getConsoleInput in interface InteractionsModelCallback
Returns:
the input given to System.in

setInputListener

public void setInputListener(InputListener listener)
Sets the listener for any type of single-source input event. The listener can only be changed with the changeInputListener method.except in testing code which needs to install a different listener after the interactiona controller has been created (method testConsoleInput in GlobalModelIOTest).

Specified by:
setInputListener in interface InteractionsModelCallback
Parameters:
listener - a listener that reacts to input requests
Throws:
IllegalStateException - if the input listener is locked

changeInputListener

public void changeInputListener(InputListener oldListener,
                                InputListener newListener)
Changes the input listener. Takes in the old listener to ensure that the owner of the original listener is aware that it is being changed. It is therefore important NOT to include a public accessor to the input listener on the model. Only used in a single thread in unit tests, so synchronization is unnecessary.

Specified by:
changeInputListener in interface InteractionsModelCallback
Parameters:
oldListener - the listener that was installed
newListener - the listener to be installed

_interactionIsOver

public void _interactionIsOver()
Performs the common behavior when an interaction ends. Subclasses might want to additionally notify listeners here. (Do this after calling super()). Access is public for testing purposes.


_notifyInteractionEnded

protected abstract void _notifyInteractionEnded()
Notifies listeners that an interaction has ended. (Subclasses must maintain listeners.)


append

public void append(String s,
                   String styleName)
Appends a string to the given document using a named style.

Parameters:
s - String to append to the end of the document
styleName - Name of the style to use for s

_writerDelay

public void _writerDelay()
Waits for a small amount of time on a shared writer lock.


replReturnedVoid

public void replReturnedVoid()
Signifies that the most recent interpretation completed successfully, returning no value.

Specified by:
replReturnedVoid in interface InteractionsModelCallback

replReturnedResult

public void replReturnedResult(String result,
                               String style)
Appends the returned result to the interactions document, inserts a prompt in the interactions document, and advances the caret in the interactions pane.

Specified by:
replReturnedResult in interface InteractionsModelCallback
Parameters:
result - The .toString-ed version of the value that was returned by the interpretation. We must return the String form because returning the Object directly would require the data type to be serializable.

replThrewException

public void replThrewException(String message)
Signifies that the most recent interpretation was ended due to an exception being thrown.

Specified by:
replThrewException in interface InteractionsModelCallback
Parameters:
message - The exception's message

replReturnedSyntaxError

public void replReturnedSyntaxError(String errorMessage,
                                    String interaction,
                                    int startRow,
                                    int startCol,
                                    int endRow,
                                    int endCol)
Signifies that the most recent interpretation was preempted by a syntax error. The integer parameters support future error highlighting.

Specified by:
replReturnedSyntaxError in interface InteractionsModelCallback
Parameters:
errorMessage - The syntax error message
startRow - The starting row of the error
startCol - The starting column of the error
endRow - The end row of the error param endCol The end column of the error
endCol - The end column of the error

replCalledSystemExit

public void replCalledSystemExit(int status)
Signifies that the most recent interpretation contained a call to System.exit.

Specified by:
replCalledSystemExit in interface InteractionsModelCallback
Parameters:
status - The exit status that will be returned.

_notifyInterpreterExited

protected abstract void _notifyInterpreterExited(int status)
Notifies listeners that the interpreter has exited unexpectedly. (Subclasses must maintain listeners.)

Parameters:
status - Status code of the dead process

interpreterResetting

public void interpreterResetting()
Called when the interpreter starts to reset.

Specified by:
interpreterResetting in interface InteractionsModelCallback

_notifyInterpreterResetting

protected abstract void _notifyInterpreterResetting()
Notifies listeners that the interpreter is resetting. (Subclasses must maintain listeners.)


interpreterResetFailed

public void interpreterResetFailed(Throwable t)
This method is called by the Main JVM if the Interpreter JVM cannot be exited

Specified by:
interpreterResetFailed in interface InteractionsModelCallback
Parameters:
t - The Throwable thrown by System.exit

_interpreterResetFailed

protected abstract void _interpreterResetFailed(Throwable t)
Any extra action to perform (beyond notifying listeners) when the interpreter fails to reset.

Parameters:
t - The Throwable thrown by System.exit

_notifyInterpreterResetFailed

protected abstract void _notifyInterpreterResetFailed(Throwable t)
Notifies listeners that the interpreter reset failed. (Subclasses must maintain listeners.)

Parameters:
t - Throwable explaining why the reset failed.

getBanner

public String getBanner()

getStartUpBanner

public String getStartUpBanner()

getBanner

public static String getBanner(File wd)

scrollToCaret

protected void scrollToCaret()

interpreterReady

public void interpreterReady(File wd)
Called when a new Java interpreter has registered and is ready for use.

Specified by:
interpreterReady in interface InteractionsModelCallback

_notifyInterpreterReady

public abstract void _notifyInterpreterReady(File wd)
Notifies listeners that the interpreter is ready. (Subclasses must maintain listeners.)


slaveJVMUsed

public void slaveJVMUsed()
Called when the slave JVM has been used for interpretation or unit testing.

Specified by:
slaveJVMUsed in interface InteractionsModelCallback

_notifySlaveJVMUsed

protected abstract void _notifySlaveJVMUsed()
Notifies listeners that the slave JVM has been used. (Subclasses must maintain listeners.)


_testClassCall

protected static String _testClassCall(String s)
Assumes a trimmed String. Returns a string of the main call that the interpretor can use.


_deleteSemiColon

protected static String _deleteSemiColon(String s)
Deletes the last character of a string. Assumes semicolon at the end, but does not check. Helper for _testClassCall(String).

Parameters:
s - the String containing the semicolon
Returns:
a substring of s with one less character

getConsoleDocument

public abstract ConsoleDocument getConsoleDocument()
Gets the console tab document for this interactions model


getLastError

public String getLastError()
Return the last error, or null if successful.


getSecondToLastError

public String getSecondToLastError()
Return the second to last error, or null if successful.


resetLastErrors

public void resetLastErrors()
Reset the information about the last and second to last error.


removeLastFromHistory

public String removeLastFromHistory()
Returns the last history item and then removes it, or returns null if the history is empty.