org.mozilla.javascript
public class ContextFactory extends Object
When Rhino runtime needs to create new {@link Context} instance during execution of {@link Context#enter()} or {@link Context}, it will call {@link #makeContext()} of the current global ContextFactory. See {@link #getGlobal()} and {@link #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 {@link #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 {@link Context} to store execution time. private static class MyContext extends Context { long startTime; } static { // Initialize GlobalFactory with custom factory ContextFactory.initGlobal(new MyFactory()); } // Override {@link #makeContext()} protected Context makeContext() { MyContext cx = new MyContext(); // Use pure interpreter mode to allow for // {@link #observeInstructionCount(Context, int)} to work cx.setOptimizationLevel(-1); // Make Rhino runtime to call observeInstructionCount // each 10000 bytecode instructions cx.setInstructionObserverThreshold(10000); return cx; } // Override {@link #hasFeature(Context, int)} public boolean hasFeature(Context cx, int featureIndex) { // Turn on maximum compatibility with MSIE scripts switch (featureIndex) { case {@link Context#FEATURE_NON_ECMA_GET_YEAR}: return true; case {@link Context#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME}: return true; case {@link Context#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER}: return true; case {@link Context#FEATURE_PARENT_PROTO_PROPRTIES}: return false; } return super.hasFeature(cx, featureIndex); } // Override {@link #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 {@link #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); } }
Nested Class Summary | |
---|---|
interface | ContextFactory.Listener
Listener of {@link Context} creation and release events. |
Method Summary | |
---|---|
void | addListener(ContextFactory.Listener listener) |
Object | call(ContextAction action)
Call {@link ContextAction#run(Context cx)}
using the {@link Context} instance associated with the current thread.
|
protected void | checkNotSealed() |
protected GeneratedClassLoader | createClassLoader(ClassLoader parent)
Create class loader for generated classes.
|
protected Object | doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
Execute top call to script or function.
|
Context | enter()
Same as {@link Context#enter()} with the difference that if a new context
needs to be created, then this context factory is used to create it
instead of the global context factory. |
Context | enter(Context cx)
Same as {@link Context#enter(Context)} with the difference that if a new
context needs to be created, then this context factory is used to create
it instead of the global context factory. |
void | exit()
Same as {@link Context#exit()}, although if you used {@link #enter()} or
{@link #enter(Context)} methods on this object, you should use this exit
method instead of the static one in {@link Context}. |
ClassLoader | getApplicationClassLoader()
Get ClassLoader to use when searching for Java classes.
|
static ContextFactory | getGlobal()
Get global ContextFactory.
|
static boolean | hasExplicitGlobal()
Check if global factory was set.
|
protected boolean | hasFeature(Context cx, int featureIndex)
Implementation of {@link Context#hasFeature(int featureIndex)}.
|
void | initApplicationClassLoader(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 {@link Context} instance to be associated with the current
thread.
|
protected void | observeInstructionCount(Context cx, int instructionCount)
Implementation of
{@link 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. |
See Also: call (ContextFactory factory, Callable callable,
Scriptable scope, Scriptable thisObj,
Object[] args)
Returns: a Context associated with the current thread
Returns: a Context associated with the current thread
See Also: hasExplicitGlobal initGlobal
See Also: getGlobal initGlobal
See Also: getApplicationClassLoader
See Also: getGlobal hasExplicitGlobal
See Also: seal
See Also: isSealed