Class ContextFactory

  • Direct Known Subclasses:
    ShellContextFactory

    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);
         }
    
     }
    
     
    • Constructor Detail

      • ContextFactory

        public ContextFactory()
    • Method Detail

      • 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()
      • 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()
      • 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

        @Deprecated
        public final Context enter()
        Deprecated.
        use enterContext() instead
        Returns:
        a Context associated with the current thread
      • exit

        @Deprecated
        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)