package jj.engine; import java.util.Set; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import jj.event.Publisher; import jj.logging.Emergency; import jj.script.RhinoContext; import org.mozilla.javascript.RhinoException; import org.mozilla.javascript.ScriptableObject; /** * component that sources a prepared rhino context for script execution. * @author jason * */ @Singleton class EngineAPIImpl implements EngineAPI { private final ScriptableObject global; private final Publisher publisher; @Inject EngineAPIImpl( final Provider<RhinoContext> contextProvider, final Set<HostObject> hostObjects, final Publisher publisher ) { try (RhinoContext context = contextProvider.get()) { global = initializeGlobalScope(context, hostObjects); this.publisher = publisher; } } @Override public ScriptableObject global() { return global; } private ScriptableObject initializeGlobalScope(final RhinoContext context, final Set<HostObject> hostObjects) { final ScriptableObject global = context.initStandardObjects(true); // make sure all the Rhino objects are available context.evaluateString(global , "RegExp; getClass; java; Packages; JavaAdapter;", "lazyLoad"); context.evaluateString(global, "var global=this;", "jj-internal"); context.evaluateString( global, "global['" + PROP_CONVERT_ARGS + "'] = function(args){var out = [];Array.forEach(args,function(arg){out.push(arg);});return JSON.stringify(out);}", "jj-internal" ); for (final HostObject hostObject : hostObjects) { int flags = ScriptableObject.EMPTY; if (hostObject.constant()) { flags |= ScriptableObject.CONST; } else { if (hostObject.readonly()) flags |= ScriptableObject.READONLY; if (hostObject.permanent()) flags |= ScriptableObject.PERMANENT; } if (hostObject.dontenum()) flags |= ScriptableObject.DONTENUM; global.defineProperty(hostObject.name(), hostObject, flags); if (hostObject instanceof ContributesScript) { final String script = ((ContributesScript)hostObject).script(); try { context.evaluateString(global, script, hostObject.name()); } catch (RhinoException re) { publisher.publish(new Emergency("trouble evaluating host object {} script {}", hostObject.getClass().getName(), script)); throw new AssertionError("bad host object!", re); } } } global.sealObject(); return global; } }