edu.rice.cs.drjava.model.repl.newjvm
Class InterpreterJVM

java.lang.Object
  extended by edu.rice.cs.util.newjvm.AbstractSlaveJVM
      extended by edu.rice.cs.drjava.model.repl.newjvm.InterpreterJVM
All Implemented Interfaces:
JUnitModelCallback, InterpreterJVMRemoteI, SlaveRemote, Remote

public class InterpreterJVM
extends AbstractSlaveJVM
implements InterpreterJVMRemoteI, JUnitModelCallback

This is the main class for the interpreter JVM. All public methods except those involving remote calls (callbacks) synchronized (unless synchronization has no effect). This class is loaded in the Interpreter JVM, not the Main JVM. (Do not use DrJava's config framework here.)

Note that this class is specific to DynamicJava. It must be refactored to accommodate other interpreters.

Version:
$Id: InterpreterJVM.java 4691 2008-12-02 23:33:27Z dlsmith $

Field Summary
static InterpreterJVM ONLY
          Singleton instance of this class.
 
Fields inherited from class edu.rice.cs.util.newjvm.AbstractSlaveJVM
_pollMasterThreadName, _quitSlaveThreadName, CHECK_MAIN_VM_ALIVE_SECONDS
 
Method Summary
 void addBuildDirectoryClassPath(File f)
          Adds the given path to the classpath shared by ALL Java interpreters.
 void addExternalFilesClassPath(File f)
          Adds the given path to the classpath shared by ALL Java interpreters.
 void addExtraClassPath(File f)
          Adds the given path to the classpath shared by ALL Java interpreters.
 void addInterpreter(String name)
          Adds a named Interpreter to the list.
 void addInterpreter(String name, Object thisVal, Class<?> thisClass, Object[] localVars, String[] localVarNames, Class<?>[] localVarClasses)
          Adds a named Interpreter in the given environment to the list.
 void addProjectClassPath(File f)
          Adds the given path to the classpath shared by ALL Java interpreters.
 void addProjectFilesClassPath(File f)
          Adds the given path to the classpath shared by ALL Java interpreters.
 void classFileError(ClassFileError e)
          Notifies the main JVM that JUnitTestManager has encountered an illegal class file.
 List<String> findTestClasses(List<String> classNames, List<File> files)
          Sets up a JUnit test suite in the Interpreter JVM and finds which classes are really TestCases classes (by loading them).
 List<File> getClassPath()
          Returns the current class path.
 File getFileForClassName(String className)
          Called when the JUnitTestManager wants to open a file that is not currently open.
 Object[] getVariable(String var)
          Gets the value of the variable with the given name in the current interpreter.
 String getVariableToString(String var)
          Gets the string representation of the value of a variable in the current interpreter.
 String getVariableType(String var)
          Gets the type of a variable in the current interpreter.
protected  void handleStart(MasterRemote mainJVM)
          Actions to perform when this JVM is started (through its superclass, AbstractSlaveJVM).
 InterpretResult interpret(String s)
          Interprets the given string of source code in the active interpreter.
 InterpretResult interpret(String s, String interpreterName)
          Interprets the given string of source code with the given interpreter.
 void junitJVMReady()
          Called when the JVM used for unit tests has registered.
 void nonTestCase(boolean isTestAll)
          Notifies Main JVM that JUnit has been invoked on a non TestCase class.
protected  void quitFailed(Throwable th)
          This method is called if the interpreterJVM cannot be exited (likely because of a modified security manager.
 void removeInterpreter(String name)
          Removes the interpreter with the given name, if it exists.
 boolean runTestSuite()
          Runs JUnit test suite already cached in the Interpreter JVM.
 boolean setActiveInterpreter(String name)
          Sets the current interpreter to be the one specified by the given name
 void setPrivateAccessible(boolean allow)
          Sets the interpreter to allow access to private members.
 void setShowMessageOnResetFailure(boolean show)
           
 boolean setToDefaultInterpreter()
          Sets the default interpreter to be active.
 void testEnded(String testName, boolean wasSuccessful, boolean causedError)
          Notifies that a particular test has ended.
 void testStarted(String testName)
          Notifies that a particular test has started.
 void testSuiteEnded(JUnitError[] errors)
          Notifies that a full suite of tests has finished running.
 void testSuiteStarted(int numTests)
          Notifies that a suite of tests has started running.
 
Methods inherited from class edu.rice.cs.util.newjvm.AbstractSlaveJVM
beforeQuit, quit, start
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface edu.rice.cs.util.newjvm.SlaveRemote
quit, start
 

Field Detail

ONLY

public static final InterpreterJVM ONLY
Singleton instance of this class.

Method Detail

handleStart

protected void handleStart(MasterRemote mainJVM)
Actions to perform when this JVM is started (through its superclass, AbstractSlaveJVM). Contract from superclass mandates that this code does not synchronized on this across a remote call. This method has no synchronization because it can only be called once (part of the superclass contract) and _mainJVM is only assigned (once!) here.

Specified by:
handleStart in class AbstractSlaveJVM

setShowMessageOnResetFailure

public void setShowMessageOnResetFailure(boolean show)
Specified by:
setShowMessageOnResetFailure in interface InterpreterJVMRemoteI
Parameters:
show - Whether to show a message if a reset operation fails.

quitFailed

protected void quitFailed(Throwable th)
This method is called if the interpreterJVM cannot be exited (likely because of a modified security manager.

Overrides:
quitFailed in class AbstractSlaveJVM

interpret

public InterpretResult interpret(String s)
Interprets the given string of source code in the active interpreter. The result is returned to MainJVM via the interpretResult method.

Specified by:
interpret in interface InterpreterJVMRemoteI
Parameters:
s - Source code to interpret.

interpret

public InterpretResult interpret(String s,
                                 String interpreterName)
Interprets the given string of source code with the given interpreter. The result is returned to MainJVM via the interpretResult method.

Parameters:
s - Source code to interpret.
interpreterName - Name of the interpreter to use
Throws:
IllegalArgumentException - if the named interpreter does not exist

getVariable

public Object[] getVariable(String var)
Gets the value of the variable with the given name in the current interpreter. Invoked reflectively by the debugger. To simplify the inter-process exchange, an array here is used as the return type rather than an Option<Object> -- an empty array corresponds to "none," and a singleton array corresponds to a "some."


getVariableToString

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

Specified by:
getVariableToString in interface InterpreterJVMRemoteI
Parameters:
var - the name of the variable
Returns:
null if the variable is not defined, "null" if the value is null; otherwise, its string representation

getVariableType

public String getVariableType(String var)
Gets the type of a variable in the current interpreter.

Specified by:
getVariableType in interface InterpreterJVMRemoteI
Parameters:
var - the name of the variable

addInterpreter

public void addInterpreter(String name)
Adds a named Interpreter to the list.

Specified by:
addInterpreter in interface InterpreterJVMRemoteI
Parameters:
name - the unique name for the interpreter
Throws:
IllegalArgumentException - if the name is not unique

addInterpreter

public void addInterpreter(String name,
                           Object thisVal,
                           Class<?> thisClass,
                           Object[] localVars,
                           String[] localVarNames,
                           Class<?>[] localVarClasses)
Adds a named Interpreter in the given environment to the list. Invoked reflectively by the debugger.

Parameters:
name - The unique name for the interpreter
thisVal - The value of this (may be null, implying this is a static context)
thisClass - The class in whose context the interpreter is to be created
localVars - Values of local variables
localVarNames - Names of the local variables
localVarClasses - Classes of the local variables. To simplify the work callers must do, a value with a primitive type may have a null entry here.
Throws:
IllegalArgumentException - if the name is not unique, or if the local var arrays are not all of the same length

removeInterpreter

public void removeInterpreter(String name)
Removes the interpreter with the given name, if it exists.

Specified by:
removeInterpreter in interface InterpreterJVMRemoteI
Parameters:
name - Name of the interpreter to remove

setActiveInterpreter

public boolean setActiveInterpreter(String name)
Sets the current interpreter to be the one specified by the given name

Specified by:
setActiveInterpreter in interface InterpreterJVMRemoteI
Parameters:
name - the unique name of the interpreter to set active
Returns:
Whether the new interpreter is currently in progress with an interaction

setToDefaultInterpreter

public boolean setToDefaultInterpreter()
Sets the default interpreter to be active.

Specified by:
setToDefaultInterpreter in interface InterpreterJVMRemoteI
Returns:
Whether the new interpreter is currently in progress with an interaction

setPrivateAccessible

public void setPrivateAccessible(boolean allow)
Sets the interpreter to allow access to private members.

Specified by:
setPrivateAccessible in interface InterpreterJVMRemoteI

findTestClasses

public List<String> findTestClasses(List<String> classNames,
                                    List<File> files)
                             throws RemoteException
Sets up a JUnit test suite in the Interpreter JVM and finds which classes are really TestCases classes (by loading them). Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
findTestClasses in interface InterpreterJVMRemoteI
Parameters:
classNames - the class names to run in a test
files - the associated file
Returns:
the class names that are actually test cases
Throws:
RemoteException

runTestSuite

public boolean runTestSuite()
                     throws RemoteException
Runs JUnit test suite already cached in the Interpreter JVM. Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
runTestSuite in interface InterpreterJVMRemoteI
Returns:
false if no test suite is cached; true otherwise
Throws:
RemoteException

nonTestCase

public void nonTestCase(boolean isTestAll)
Notifies Main JVM that JUnit has been invoked on a non TestCase class. Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
nonTestCase in interface JUnitModelCallback
Parameters:
isTestAll - whether or not it was a use of the test all button

classFileError

public void classFileError(ClassFileError e)
Notifies the main JVM that JUnitTestManager has encountered an illegal class file. Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
classFileError in interface JUnitModelCallback
Parameters:
e - the ClassFileError object describing the error on loading the file

testSuiteStarted

public void testSuiteStarted(int numTests)
Notifies that a suite of tests has started running. Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
testSuiteStarted in interface JUnitModelCallback
Parameters:
numTests - The number of tests in the suite to be run.

testStarted

public void testStarted(String testName)
Notifies that a particular test has started. Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
testStarted in interface JUnitModelCallback
Parameters:
testName - The name of the test being started.

testEnded

public void testEnded(String testName,
                      boolean wasSuccessful,
                      boolean causedError)
Notifies that a particular test has ended. Unsynchronized because it contains a remote call.

Specified by:
testEnded in interface JUnitModelCallback
Parameters:
testName - The name of the test that has ended.
wasSuccessful - Whether the test passed or not.
causedError - If not successful, whether the test caused an error or simply failed.

testSuiteEnded

public void testSuiteEnded(JUnitError[] errors)
Notifies that a full suite of tests has finished running. Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
testSuiteEnded in interface JUnitModelCallback
Parameters:
errors - The array of errors from all failed tests in the suite.

getFileForClassName

public File getFileForClassName(String className)
Called when the JUnitTestManager wants to open a file that is not currently open. Unsynchronized because it contains a remote call and does not involve mutable local state.

Specified by:
getFileForClassName in interface JUnitModelCallback
Parameters:
className - the name of the class for which we want to find the file
Returns:
the file associated with the given class

junitJVMReady

public void junitJVMReady()
Description copied from interface: JUnitModelCallback
Called when the JVM used for unit tests has registered.

Specified by:
junitJVMReady in interface JUnitModelCallback

addExtraClassPath

public void addExtraClassPath(File f)
Description copied from interface: InterpreterJVMRemoteI
Adds the given path to the classpath shared by ALL Java interpreters. Only unique paths are added.

Specified by:
addExtraClassPath in interface InterpreterJVMRemoteI
Parameters:
f - Entry to add to the accumulated classpath

addProjectClassPath

public void addProjectClassPath(File f)
Description copied from interface: InterpreterJVMRemoteI
Adds the given path to the classpath shared by ALL Java interpreters. Only unique paths are added.

Specified by:
addProjectClassPath in interface InterpreterJVMRemoteI
Parameters:
f - Entry to add to the accumulated classpath

addBuildDirectoryClassPath

public void addBuildDirectoryClassPath(File f)
Description copied from interface: InterpreterJVMRemoteI
Adds the given path to the classpath shared by ALL Java interpreters. Only unique paths are added.

Specified by:
addBuildDirectoryClassPath in interface InterpreterJVMRemoteI
Parameters:
f - Entry to add to the accumulated classpath

addProjectFilesClassPath

public void addProjectFilesClassPath(File f)
Description copied from interface: InterpreterJVMRemoteI
Adds the given path to the classpath shared by ALL Java interpreters. Only unique paths are added.

Specified by:
addProjectFilesClassPath in interface InterpreterJVMRemoteI
Parameters:
f - Entry to add to the accumulated classpath

addExternalFilesClassPath

public void addExternalFilesClassPath(File f)
Description copied from interface: InterpreterJVMRemoteI
Adds the given path to the classpath shared by ALL Java interpreters. Only unique paths are added.

Specified by:
addExternalFilesClassPath in interface InterpreterJVMRemoteI
Parameters:
f - Entry to add to the accumulated classpath

getClassPath

public List<File> getClassPath()
Description copied from interface: InterpreterJVMRemoteI
Returns the current class path. (List rather than Iterable to avoid conflicts between RMI and Retroweaver.)

Specified by:
getClassPath in interface JUnitModelCallback
Specified by:
getClassPath in interface InterpreterJVMRemoteI