package com.nvarghese.beowulf.common.cobra.html.js;
import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Scriptable;
public class CustomContextFactory extends ContextFactory {
// Custom Context to store execution time.
private static class CustomContext extends Context {
long startTime;
}
static {
// Initialize GlobalFactory with custom factory
ContextFactory.initGlobal(new CustomContextFactory());
}
// Override makeContext()
protected Context makeContext() {
CustomContext cx = new CustomContext();
// Use pure interpreter mode to allow for
// observeInstructionCount(Context, int) to work
cx.setOptimizationLevel(-1);
// 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_PROPRTIES:
return false;
}
return super.hasFeature(cx, featureIndex);
}
// Override observeInstructionCount(Context, int)
protected void observeInstructionCount(Context cx, int instructionCount) {
CustomContext mcx = (CustomContext) cx;
long currentTime = System.currentTimeMillis();
if (currentTime - mcx.startTime > 20 * 1000) {
// More then 20 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 scope, Scriptable
// thisObj, Object[] args)
protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
CustomContext mcx = (CustomContext) cx;
mcx.startTime = System.currentTimeMillis();
return super.doTopCall(callable, cx, scope, thisObj, args);
}
}