Factory class that Rhino runtime use to create new
Context
instances or to notify about Context execution.
When Rhino runtime needs to create new
Context
instance during
execution of
Context.enter()
or
Context
, it will call
makeContext()
of the current global ContextFactory.
See
getGlobal()
and
initGlobal(ContextFactory)
.
It is also possible to use explicit ContextFactory instances for Context
creation. This is useful to have a set of independent Rhino runtime
instances under single JVM. See
call(ContextAction)
.
The following example demonstrates Context customization to terminate
scripts running more then 10 seconds and to provide better compatibility
with JavaScript code using MSIE-specific features.
import org.mozilla.javascript.*;
class MyFactory extends ContextFactory
{
// Custom Context
to store execution time.
private static class MyContext extends Context
{
long startTime;
}
static {
// Initialize GlobalFactory with custom factory
ContextFactory.initGlobal(new MyFactory());
}
// Override makeContext()
protected Context makeContext()
{
MyContext cx = new MyContext();
// Use pure interpreter mode to allow for
// observeInstructionCount(Context,int)
to work
cx.setOptimizationLevel(-1);
// Make Rhino runtime to call observeInstructionCount
// each 10000 bytecode instructions
cx.setInstructionObserverThreshold(10000);
return cx;
}
// Override hasFeature(Context,int)
public boolean hasFeature(Context cx, int featureIndex)
{
// Turn on maximum compatibility with MSIE scripts
switch (featureIndex) {
case Context.FEATURE_NON_ECMA_GET_YEAR
:
return true;
case Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME
:
return true;
case Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER
:
return true;
case Context.FEATURE_PARENT_PROTO_PROPRTIES
:
return false;
}
return super.hasFeature(cx, featureIndex);
}
// Override observeInstructionCount(Context,int)
protected void observeInstructionCount(Context cx, int instructionCount)
{
MyContext mcx = (MyContext)cx;
long currentTime = System.currentTimeMillis();
if (currentTime - mcx.startTime > 10*1000) {
// More then 10 seconds from Context creation time:
// it is time to stop the script.
// Throw Error instance to ensure that script will never
// get control back through catch or finally.
throw new Error();
}
}
// Override doTopCall(Callable, Context, Scriptable scope, Scriptable thisObj, Object[] args)
protected Object doTopCall(Callable callable,
Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
MyContext mcx = (MyContext)cx;
mcx.startTime = System.currentTimeMillis();
return super.doTopCall(callable, cx, scope, thisObj, args);
}
}
call
public final Object call(ContextAction action)
Call
ContextAction.run(Context cx)
using the
Context
instance associated with the current thread.
If no Context is associated with the thread, then
makeContext()
will be called to construct
new Context instance. The instance will be temporary associated
with the thread during call to
ContextAction.run(Context)
.
call(ContextAction)
, Context.call(ContextFactory factory, Callable callable,
Scriptable scope, Scriptable thisObj,
Object[] args)
checkNotSealed
protected final void checkNotSealed()
createClassLoader
protected GeneratedClassLoader createClassLoader(ClassLoader parent)
Create class loader for generated classes.
This method creates an instance of the default implementation
of
GeneratedClassLoader
. Rhino uses this interface to load
generated JVM classes when no
SecurityController
is installed.
Application can override the method to provide custom class loading.
doTopCall
protected Object doTopCall(Callable callable,
Context cx,
Scriptable scope,
Scriptable thisObj,
Object[] args)
Execute top call to script or function.
When the runtime is about to execute a script or function that will
create the first stack frame with scriptable code, it calls this method
to perform the real call. In this way execution of any script
happens inside this function.
getApplicationClassLoader
public final ClassLoader getApplicationClassLoader()
Get ClassLoader to use when searching for Java classes.
Unless it was explicitly initialized with
initApplicationClassLoader(ClassLoader)
the method returns
null to indicate that Thread.getContextClassLoader() should be used.
getGlobal
public static ContextFactory getGlobal()
Get global ContextFactory.
hasExplicitGlobal
public static boolean hasExplicitGlobal()
Check if global factory was set.
Return true to indicate that
initGlobal(ContextFactory)
was
already called and false to indicate that the global factory was not
explicitly set.
hasFeature
protected boolean hasFeature(Context cx,
int featureIndex)
Implementation of
Context.hasFeature(int featureIndex)
.
This can be used to customize
Context
without introducing
additional subclasses.
initApplicationClassLoader
public final void initApplicationClassLoader(ClassLoader loader)
Set explicit class loader to use when searching for Java classes.
initGlobal
public static void initGlobal(ContextFactory factory)
Set global ContextFactory.
The method can only be called once.
isSealed
public final boolean isSealed()
Checks if this is a sealed ContextFactory.
makeContext
protected Context makeContext()
Create new
Context
instance to be associated with the current
thread.
This is a callback method used by Rhino to create
Context
instance when it is necessary to associate one with the current
execution thread.
makeContext() is allowed to call
Context.seal(Object)
on the result to prevent
Context
changes by hostile scripts or applets.
observeInstructionCount
protected void observeInstructionCount(Context cx,
int instructionCount)
Implementation of
Context.observeInstructionCount(int instructionCount)
.
This can be used to customize
Context
without introducing
additional subclasses.
onContextCreated
protected void onContextCreated(Context cx)
onContextReleased
protected void onContextReleased(Context cx)
seal
public final void seal()
Seal this ContextFactory so any attempt to modify it like to add or
remove its listeners will throw an exception.