in modules/implementation-script/src/main/java/org/apache/tuscany/sca/implementation/script/engines/TuscanyJRubyScriptEngine.java [327:466]
private void setGlobalVariables(final ScriptContext ctx) {
ctx.setAttribute("context", ctx, ScriptContext.ENGINE_SCOPE);
setGlobalVariables(new GlobalVariables(runtime) {
GlobalVariables parent = runtime.getGlobalVariables();
@Override
public void define(String name, IAccessor accessor) {
assert name != null;
assert accessor != null;
assert name.startsWith("$");
synchronized (ctx) {
Bindings engineScope = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.put(name, new GlobalVariable(accessor));
}
}
@Override
public void defineReadonly(String name, IAccessor accessor) {
assert name != null;
assert accessor != null;
assert name.startsWith("$");
synchronized (ctx) {
Bindings engineScope = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.put(name, new GlobalVariable(new
ReadonlyAccessor(name, accessor)));
}
}
@Override
public boolean isDefined(String name) {
assert name != null;
assert name.startsWith("$");
synchronized (ctx) {
String modifiedName = name.substring(1);
boolean defined = ctx.getAttributesScope(modifiedName) != -1;
return defined ? true : parent.isDefined(name);
}
}
@Override
public void alias(String name, String oldName) {
assert name != null;
assert oldName != null;
assert name.startsWith("$");
assert oldName.startsWith("$");
if (runtime.getSafeLevel() >= 4) {
throw runtime.newSecurityError("Insecure: can't alias global variable");
}
synchronized (ctx) {
int scope = ctx.getAttributesScope(name);
if (scope == -1) {
scope = ScriptContext.ENGINE_SCOPE;
}
IRubyObject value = get(oldName);
ctx.setAttribute(name, rubyToJava(value), scope);
}
}
@Override
public IRubyObject get(String name) {
assert name != null;
assert name.startsWith("$");
synchronized (ctx) {
// skip '$' and try
String modifiedName = name.substring(1);
int scope = ctx.getAttributesScope(modifiedName);
if (scope == -1) {
return parent.get(name);
}
Object obj = ctx.getAttribute(modifiedName, scope);
if (obj instanceof IAccessor) {
return ((IAccessor)obj).getValue();
} else {
return javaToRuby(obj);
}
}
}
@Override
public IRubyObject set(String name, IRubyObject value) {
assert name != null;
assert name.startsWith("$");
if (runtime.getSafeLevel() >= 4) {
throw runtime.newSecurityError("Insecure: can't change global variable value");
}
synchronized (ctx) {
// skip '$' and try
String modifiedName = name.substring(1);
int scope = ctx.getAttributesScope(modifiedName);
if (scope == -1) {
scope = ScriptContext.ENGINE_SCOPE;
}
IRubyObject oldValue = get(name);
Object obj = ctx.getAttribute(modifiedName, scope);
if (obj instanceof IAccessor) {
((IAccessor)obj).setValue(value);
} else {
ctx.setAttribute(modifiedName, rubyToJava(value), scope);
if ("KCODE".equals(modifiedName)) {
setKCode((String)rubyToJava(value));
} else if ("stdout".equals(modifiedName)) {
equalOutputs((RubyObject)value);
}
}
return oldValue;
}
}
@Override
public Set<String> getNames() {
HashSet set = new HashSet();
synchronized (ctx) {
for (Object scope : ctx.getScopes()) {
Bindings b = ctx.getBindings((Integer)scope);
if (b != null) {
for (Object key: b.keySet()) {
set.add(key);
}
}
}
}
for (Iterator<String> names = parent.getNames().iterator(); names.hasNext();) {
set.add(names.next());
}
return Collections.unmodifiableSet(set);
}
@Override
public IRubyObject getDefaultSeparator() {
return parent.getDefaultSeparator();
}
});
}