org.mozilla.javascript

## Class ContextFactory

- java.lang.Object
- - org.mozilla.javascript.ContextFactory

-     public class ContextFactory
      extends java.lang.Object

  Factory class that Rhino runtime uses to create new `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
       {

           // 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();
               // 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_PROPERTIES:
                       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,
                                     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);
           }

       }

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static interface` | `ContextFactory.GlobalSetter`
    `static interface` | `ContextFactory.Listener` Listener of `Context` creation and release events.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `ContextFactory()`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addListener(ContextFactory.Listener listener)`
    `java.lang.Object` | `call(ContextAction 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.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### ContextFactory

          public ContextFactory()

  - ### Method Detail

    - #### getGlobal

          public static ContextFactory getGlobal()

      Get global ContextFactory.
      See Also:
        `hasExplicitGlobal()`, `initGlobal(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.
      See Also:
        `getGlobal()`, `initGlobal(ContextFactory)`

    - #### initGlobal

          public static void initGlobal(ContextFactory factory)

      Set global ContextFactory. The method can only be called once.
      See Also:
        `getGlobal()`, `hasExplicitGlobal()`

    - #### getGlobalSetter

          public static ContextFactory.GlobalSetter getGlobalSetter()

    - #### 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.

    - #### 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.

    - #### getE4xImplementationFactory

          protected XMLLib.Factory getE4xImplementationFactory()

      Provides a default `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.

    - #### createClassLoader

          protected GeneratedClassLoader createClassLoader(java.lang.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.

    - #### getApplicationClassLoader

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

    - #### initApplicationClassLoader

          public final void initApplicationClassLoader(java.lang.ClassLoader loader)

      Set explicit class loader to use when searching for Java classes.
      See Also:
        `getApplicationClassLoader()`

    - #### doTopCall

          protected java.lang.Object doTopCall(Callable callable,
                                   Context cx,
                                   Scriptable scope,
                                   Scriptable thisObj,
                                   java.lang.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.

    - #### 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)

    - #### addListener

          public final void addListener(ContextFactory.Listener listener)

    - #### removeListener

          public final void removeListener(ContextFactory.Listener listener)

    - #### isSealed

          public final boolean isSealed()

      Checks if this is a sealed ContextFactory.
      See Also:
        `seal()`

    - #### 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()`

    - #### checkNotSealed

          protected final void checkNotSealed()

    - #### call

          public final java.lang.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)`.
      See Also:
        `call(ContextAction)`, `Context.call(ContextFactory factory, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)`

    - #### enterContext

          public Context enterContext()

      Get a context associated with the current thread, creating one if need be. The Context stores the execution state of the JavaScript engine, so it is required that the context be entered before execution may begin. Once a thread has entered a Context, then getCurrentContext() may be called to find the context that is associated with the current thread.

      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;
                    }
                });

      Returns:
        a Context associated with the current thread
      See Also:
        `Context.getCurrentContext()`, `Context.exit()`, `call(ContextAction)`

    - #### enter

          public final Context enter()

      Deprecated. use `enterContext()` instead
      Returns:
        a Context associated with the current thread

    - #### exit

          public final void exit()

      Deprecated. Use `Context.exit()` instead.

    - #### enterContext

          public final Context enterContext(Context cx)

      Get a Context associated with the current thread, using the given Context if need be.

      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.

      Parameters:
        `cx` - a Context to associate with the thread if possible
      Returns:
        a Context associated with the current thread
      Throws:
        `java.lang.IllegalStateException` - if `cx` is already associated with a different thread
      See Also:
        `enterContext()`, `call(ContextAction)`