org.mozilla.javascript

Class ContextFactory

public class ContextFactory extends Object

Factory class that Rhino runtime use to create new {@link Context} instances or to notify about Context execution.

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
interfaceContextFactory.Listener
Listener of {@link Context} creation and release events.
Method Summary
voidaddListener(ContextFactory.Listener listener)
Objectcall(ContextAction action)
Call {@link ContextAction#run(Context cx)} using the {@link Context} instance associated with the current thread.
protected voidcheckNotSealed()
protected GeneratedClassLoadercreateClassLoader(ClassLoader parent)
Create class loader for generated classes.
protected ObjectdoTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
Execute top call to script or function.
Contextenter()
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.
Contextenter(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.
voidexit()
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}.
ClassLoadergetApplicationClassLoader()
Get ClassLoader to use when searching for Java classes.
static ContextFactorygetGlobal()
Get global ContextFactory.
static booleanhasExplicitGlobal()
Check if global factory was set.
protected booleanhasFeature(Context cx, int featureIndex)
Implementation of {@link Context#hasFeature(int featureIndex)}.
voidinitApplicationClassLoader(ClassLoader loader)
Set explicit class loader to use when searching for Java classes.
static voidinitGlobal(ContextFactory factory)
Set global ContextFactory.
booleanisSealed()
Checks if this is a sealed ContextFactory.
protected ContextmakeContext()
Create new {@link Context} instance to be associated with the current thread.
protected voidobserveInstructionCount(Context cx, int instructionCount)
Implementation of {@link Context#observeInstructionCount(int instructionCount)}.
protected voidonContextCreated(Context cx)
protected voidonContextReleased(Context cx)
voidremoveListener(ContextFactory.Listener listener)
voidseal()
Seal this ContextFactory so any attempt to modify it like to add or remove its listeners will throw an exception.

Method Detail

addListener

public final void addListener(ContextFactory.Listener listener)

call

public final Object call(ContextAction action)
Call {@link ContextAction#run(Context cx)} using the {@link Context} instance associated with the current thread. If no Context is associated with the thread, then {@link #makeContext()} will be called to construct new Context instance. The instance will be temporary associated with the thread during call to {@link ContextAction#run(Context)}.

See Also: 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 {@link GeneratedClassLoader}. Rhino uses this interface to load generated JVM classes when no {@link 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.

enter

public final 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.

Returns: a Context associated with the current thread

enter

public final 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.

Returns: a Context associated with the current thread

exit

public final 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}.

getApplicationClassLoader

public final ClassLoader getApplicationClassLoader()
Get ClassLoader to use when searching for Java classes. Unless it was explicitly initialized with {@link #initApplicationClassLoader(ClassLoader)} the method returns null to indicate that Thread.getContextClassLoader() should be used.

getGlobal

public static ContextFactory getGlobal()
Get global ContextFactory.

See Also: hasExplicitGlobal initGlobal

hasExplicitGlobal

public static boolean hasExplicitGlobal()
Check if global factory was set. Return true to indicate that {@link #initGlobal(ContextFactory)} was already called and false to indicate that the global factory was not explicitly set.

See Also: getGlobal initGlobal

hasFeature

protected boolean hasFeature(Context cx, int featureIndex)
Implementation of {@link Context#hasFeature(int featureIndex)}. This can be used to customize {@link Context} without introducing additional subclasses.

initApplicationClassLoader

public final void initApplicationClassLoader(ClassLoader loader)
Set explicit class loader to use when searching for Java classes.

See Also: getApplicationClassLoader

initGlobal

public static void initGlobal(ContextFactory factory)
Set global ContextFactory. The method can only be called once.

See Also: getGlobal hasExplicitGlobal

isSealed

public final boolean isSealed()
Checks if this is a sealed ContextFactory.

See Also: seal

makeContext

protected Context makeContext()
Create new {@link Context} instance to be associated with the current thread. This is a callback method used by Rhino to create {@link Context} instance when it is necessary to associate one with the current execution thread. makeContext() is allowed to call {@link Context#seal(Object)} on the result to prevent {@link Context} changes by hostile scripts or applets.

observeInstructionCount

protected void observeInstructionCount(Context cx, int instructionCount)
Implementation of {@link Context#observeInstructionCount(int instructionCount)}. This can be used to customize {@link Context} without introducing additional subclasses.

onContextCreated

protected void onContextCreated(Context cx)

onContextReleased

protected void onContextReleased(Context cx)

removeListener

public final void removeListener(ContextFactory.Listener listener)

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.

See Also: isSealed