/*
* Copyright 2008-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mozilla.javascript;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.concurrent.ThreadSafe;
import org.mozilla.javascript.regexp.RegExpImpl;
import org.mozilla.javascript.tools.debugger.Main;
import com.nominanuda.zen.common.Check;
import com.nominanuda.zen.stereotype.Initializable;
@ThreadSafe
public class RhinoEmbedding extends ContextFactory implements Initializable, MethodArgCoercer {
private static final AtomicBoolean exclusiveContextMaker = new AtomicBoolean(false);
private boolean debug = false;
@SuppressWarnings("unused")
private Object securityDomain = null;
private RegExpProxy regExpProxy = new HtmlUnitRegExpProxy(new RegExpImpl());
public void installAsGlobalContextFactory() {
ContextFactory.initGlobal(this);
}
public void init() {
wrapFactory.setJavaPrimitiveWrap(javaPrimitiveWrap);
}
@Override
protected Context makeContext() {
Context cx = super.makeContext();
cx.setWrapFactory(wrapFactory);
cx.setLanguageVersion(languageVersion);
if(regExpProxy != null) {
ScriptRuntime.setRegExpProxy(cx, regExpProxy);
}
if(debug) {
getDebugger();
}
// //cx.setOptimizationLevel(-1);//disallow compilation
// cx.setGeneratingDebug(true);
// //cx.setWrapFactory(WrapFactory wrapFactory);
// cx.setGeneratingSource(true);
// cx.setErrorReporter(new ToolErrorReporter(true));
return cx;
}
@Override
protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
return super.doTopCall(callable, cx, scope, thisObj, args);
}
public static void setExclusiveJvmContextMaker() {
if(! exclusiveContextMaker.getAndSet(true)) {
ContextFactory.getGlobal().addListener(new Listener() {
public void contextReleased(Context cx) {
}
public void contextCreated(Context cx) {
Check.illegalstate.assertTrue(
cx.getFactory() instanceof RhinoEmbedding);
}
});
}
}
public void setRegExpProxy(RegExpProxy regExpProxy) {
this.regExpProxy = regExpProxy;
}
public void setSecurityDomain(Object securityDomain) {
this.securityDomain = securityDomain;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
///// Java <--> Javascript conversions
private MethodArgCoercer methodArgsCoercer = new PluggableMethodArgCoercer();
private boolean javaPrimitiveWrap = false;
private WrapFactory wrapFactory = new PluggableWrapFactory(this);
public void setWrapFactory(WrapFactory wf) {
this.wrapFactory = wf;
}
public void setMethodArgCoercer(MethodArgCoercer coercer) {
this.methodArgsCoercer = coercer;
}
public int getConversionWeight(Object value, Class<?> type) {
return methodArgsCoercer.getConversionWeight(value, type);
}
public Object coerceTypeImpl(Class<?> type, Object value) {
return methodArgsCoercer.coerceTypeImpl(type, value);
}
/**
* @see {@link WrapFactory#setJavaPrimitiveWrap(boolean)}.
*/
public void setJavaPrimitiveWrap(
boolean wrapFactoryWrapJavaPrimitives) {
this.javaPrimitiveWrap = wrapFactoryWrapJavaPrimitives;
}
// Language Settings
private int languageVersion = Context.VERSION_1_7;
private boolean featureMemberAsFunctionName = true;
/**FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER Control if reserved keywords are treated as identifiers.*/
private boolean featureReservedKeywordAsIdentifier = false;
//FEATURE_DYNAMIC_SCOPE Control if dynamic scope should be used for name access.
private boolean featureDynamicScope = true;
//FEATURE_STRICT_VARS Control if strict variable mode is enabled.
private boolean featureStrictVars = true;
//FEATURE_E4X Control if support for E4X(ECMAScript for XML) extension is available.
private boolean featureE4X = true;
//FEATURE_ENHANCED_JAVA_ACCESS Enables enhanced access to Java.
private boolean featureEnhancedJavaAccess = true;
//FEATURE_LOCATION_INFORMATION_IN_ERROR When the feature is on Rhino will add
//a "fileName" and "lineNumber" properties to Error objects automatically.
private boolean featureLocationInformationInError = true;
//FEATURE_NON_ECMA_GET_YEAR Controls behaviour of Date.prototype.getYear().
private boolean featureNonEcmaGetYear = false;
//FEATURE_PARENT_PROTO_PROPERTIES Control if properties __proto__ and __parent__ are treated specially.
private boolean featureParentProtoProperties = false;
//FEATURE_STRICT_EVAL Control if strict eval mode is enabled.
private boolean featureStrictEval = true;
//FEATURE_STRICT_MODE Controls whether JS 1.5 'strict mode' is enabled.
private boolean featureStrictMode = false;
//FEATURE_TO_STRING_AS_SOURCE Control if toString() should returns
//the same result as toSource() when applied to objects and arrays.
private boolean featureToStringAsSource = true;
//FEATURE_WARNING_AS_ERROR Controls whether a warning should be treated as an error.
private boolean featureWarningAsError = true;
@Override
protected boolean hasFeature(Context cx, int featureIndex) {
switch (featureIndex) {
case Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER:
return featureReservedKeywordAsIdentifier;
case Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME:
return featureMemberAsFunctionName;
case Context.FEATURE_DYNAMIC_SCOPE:
return featureDynamicScope;
case Context.FEATURE_STRICT_VARS:
return featureStrictVars;
case Context.FEATURE_E4X:
return featureE4X;
case Context.FEATURE_ENHANCED_JAVA_ACCESS:
return featureEnhancedJavaAccess;
case Context.FEATURE_LOCATION_INFORMATION_IN_ERROR:
return featureLocationInformationInError;
case Context.FEATURE_NON_ECMA_GET_YEAR:
return featureNonEcmaGetYear;
case Context.FEATURE_PARENT_PROTO_PROPERTIES:
return featureParentProtoProperties;
case Context.FEATURE_STRICT_EVAL:
return featureStrictEval;
case Context.FEATURE_STRICT_MODE:
return featureStrictMode;
case Context.FEATURE_TO_STRING_AS_SOURCE:
return featureToStringAsSource;
case Context.FEATURE_WARNING_AS_ERROR:
return featureWarningAsError;
}
return super.hasFeature(cx, featureIndex);
}
public void setFeatureReservedKeywordAsIdentifier(boolean featureReservedKeywordAsIdentifier) {
this.featureReservedKeywordAsIdentifier = featureReservedKeywordAsIdentifier;
}
public void setFeatureMemberAsFunctionName(boolean featureMemberAsFunctionName) {
this.featureMemberAsFunctionName = featureMemberAsFunctionName;
}
public void setFeatureDynamicScope(boolean featureDynamicScope) {
this.featureDynamicScope = featureDynamicScope;
}
public void setFeatureStrictVars(boolean featureStrictVars) {
this.featureStrictVars = featureStrictVars;
}
public void setFeatureE4X(boolean featureE4X) {
this.featureE4X = featureE4X;
}
public void setLanguageVersion(int languageVersion) {
this.languageVersion = languageVersion;
}
public void setFeatureEnhancedJavaAccess(boolean featureEnhancedJavaAccess) {
this.featureEnhancedJavaAccess = featureEnhancedJavaAccess;
}
public void setFeatureLocationInformationInError(boolean featureLocationInformationInError) {
this.featureLocationInformationInError = featureLocationInformationInError;
}
public void setFeatureNonEcmaGetYear(boolean featureNonEcmaGetYear) {
this.featureNonEcmaGetYear = featureNonEcmaGetYear;
}
public void setFeatureParentProtoProperties(boolean featureParentProtoProperties) {
this.featureParentProtoProperties = featureParentProtoProperties;
}
public void setFeatureStrictEval(boolean featureStrictEval) {
this.featureStrictEval = featureStrictEval;
}
public void setFeatureStrictMode(boolean featureStrictMode) {
this.featureStrictMode = featureStrictMode;
}
public void setFeatureToStringAsSource(boolean featureToStringAsSource) {
this.featureToStringAsSource = featureToStringAsSource;
}
public void setFeatureWarningAsError(boolean featureWarningAsError) {
this.featureWarningAsError = featureWarningAsError;
}
///////// DEBUGGER STUFF
private Main _debugger;
private Main getDebugger() {
if (_debugger == null) {
_debugger = new Main("rhino debugger");
_debugger.attachTo(ContextFactory.getGlobal());
_debugger.setExitAction(new Runnable() {
public void run() {
debug = false;
_debugger.detach();
_debugger = null;
}
});
_debugger.pack();
_debugger.setSize(600, 460);
_debugger.setVisible(true);
}
return _debugger;
}
}