public class ContextFactory
extends java.lang.Object
Context
instances. A
ContextFactory
can also notify listeners about context creation and release.
When the 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 { // CustomContext
to store execution time. private static class MyContext extends Context { long startTime; } static { // Initialize GlobalFactory with custom factory ContextFactory.initGlobal(new MyFactory()); } // OverridemakeContext()
protected Context makeContext() { MyContext cx = new MyContext(); // Make Rhino runtime to call observeInstructionCount // each 10000 bytecode instructions cx.setInstructionObserverThreshold(10000); return cx; } // OverridehasFeature(Context, int)
public boolean hasFeature(Context cx, int featureIndex) { // Turn on maximum compatibility with MSIE scripts switch (featureIndex) { caseContext.FEATURE_NON_ECMA_GET_YEAR
: return true; caseContext.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME
: return true; caseContext.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER
: return true; caseContext.FEATURE_PARENT_PROTO_PROPERTIES
: return false; } return super.hasFeature(cx, featureIndex); } // OverrideobserveInstructionCount(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(); } } // OverridedoTopCall(Callable, Context, Scriptable, Scriptable, Object[])
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); } }
Modifier and Type | Class and Description |
---|---|
static interface |
ContextFactory.GlobalSetter |
static interface |
ContextFactory.Listener
Listener of
Context creation and release events. |
Constructor and Description |
---|
ContextFactory() |
Modifier and Type | Method and Description |
---|---|
void |
addListener(ContextFactory.Listener listener) |
<T> T |
call(ContextAction<T> action)
Call
ContextAction.run(Context cx) using the Context instance associated with
the current thread. |
protected void |
checkNotSealed() |
protected GeneratedClassLoader |
createClassLoader(java.lang.ClassLoader parent)
Create class loader for generated classes.
|
protected java.lang.Object |
doTopCall(Callable callable,
Context cx,
Scriptable scope,
Scriptable thisObj,
java.lang.Object[] args)
Execute top call to script or function.
|
Context |
enter()
Deprecated.
use
enterContext() instead |
Context |
enterContext()
Get a context associated with the current thread, creating one if need be.
|
Context |
enterContext(Context cx)
Get a Context associated with the current thread, using the given Context if need be.
|
void |
exit()
Deprecated.
Use
Context.exit() instead. |
java.lang.ClassLoader |
getApplicationClassLoader()
Get ClassLoader to use when searching for Java classes.
|
protected XMLLib.Factory |
getE4xImplementationFactory()
Provides a default
XMLLib.Factory to be
used by the Context instances produced by this factory. |
static ContextFactory |
getGlobal()
Get global ContextFactory.
|
static ContextFactory.GlobalSetter |
getGlobalSetter() |
static boolean |
hasExplicitGlobal()
Check if global factory was set.
|
protected boolean |
hasFeature(Context cx,
int featureIndex)
Implementation of
Context.hasFeature(int featureIndex) . |
void |
initApplicationClassLoader(java.lang.ClassLoader loader)
Set explicit class loader to use when searching for Java classes.
|
static void |
initGlobal(ContextFactory factory)
Set global ContextFactory.
|
boolean |
isSealed()
Checks if this is a sealed ContextFactory.
|
protected Context |
makeContext()
Create new
Context instance to be associated with the current thread. |
protected void |
observeInstructionCount(Context cx,
int instructionCount)
Implementation of
Context.observeInstructionCount(int instructionCount) . |
protected void |
onContextCreated(Context cx) |
protected void |
onContextReleased(Context cx) |
void |
removeListener(ContextFactory.Listener listener) |
void |
seal()
Seal this ContextFactory so any attempt to modify it like to add or remove its listeners will
throw an exception.
|
public static ContextFactory getGlobal()
hasExplicitGlobal()
,
initGlobal(ContextFactory)
public static boolean hasExplicitGlobal()
initGlobal(ContextFactory)
was already called and false to indicate that the global factory
was not explicitly set.getGlobal()
,
initGlobal(ContextFactory)
public static void initGlobal(ContextFactory factory)
getGlobal()
,
hasExplicitGlobal()
public static ContextFactory.GlobalSetter getGlobalSetter()
protected Context makeContext()
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.protected boolean hasFeature(Context cx, int featureIndex)
Context.hasFeature(int featureIndex)
. This can be used to customize
Context
without introducing additional subclasses.protected XMLLib.Factory getE4xImplementationFactory()
XMLLib.Factory
to be
used by the Context
instances produced by this factory. See Context.getE4xImplementationFactory()
for details.
May return null, in which case E4X functionality is not supported in Rhino.
The default implementation now prefers the DOM3 E4X implementation.
protected GeneratedClassLoader createClassLoader(java.lang.ClassLoader parent)
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.public final java.lang.ClassLoader getApplicationClassLoader()
initApplicationClassLoader(ClassLoader)
the method returns null to indicate
that Thread.getContextClassLoader() should be used.public final void initApplicationClassLoader(java.lang.ClassLoader loader)
getApplicationClassLoader()
protected java.lang.Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, java.lang.Object[] args)
protected void observeInstructionCount(Context cx, int instructionCount)
Context.observeInstructionCount(int instructionCount)
. This can be
used to customize Context
without introducing additional subclasses.protected void onContextCreated(Context cx)
protected void onContextReleased(Context cx)
public final void addListener(ContextFactory.Listener listener)
public final void removeListener(ContextFactory.Listener listener)
public final boolean isSealed()
seal()
public final void seal()
isSealed()
protected final void checkNotSealed()
public final <T> T call(ContextAction<T> action)
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)
.public Context enterContext()
Calling enterContext()
will return either the Context currently associated
with the thread, or will create a new context and associate it with the current thread. Each
call to enterContext()
must have a matching call to Context.exit()
.
Context cx = contextFactory.enterContext(); try { ... cx.evaluateString(...); } finally { Context.exit(); }Instead of using
enterContext()
, exit()
pair consider using call(ContextAction)
which guarantees proper association of Context instances with the
current thread. With this method the above example becomes:
ContextFactory.call(new ContextAction() { public Object run(Context cx) { ... cx.evaluateString(...); return null; } });
Context.getCurrentContext()
,
Context.exit()
,
call(ContextAction)
@Deprecated public final Context enter()
enterContext()
instead@Deprecated public final void exit()
Context.exit()
instead.public final Context enterContext(Context cx)
The same as enterContext()
except that cx
is associated with the
current thread and returned if the current thread has no associated context and cx
is not associated with any other thread.
cx
- a Context to associate with the thread if possiblejava.lang.IllegalStateException
- if cx
is already associated with a different
threadenterContext()
,
call(ContextAction)