Intercepting access to a java object field in Rhino

Is it possible to intercept access to Java objects (and the method) in JavaScript executable code? Just like the delegate in AOKoa, which allows you to handle access to properties and methods.

+6
source share
2 answers

You can use Context.setWrapFactory to specify how to transfer Java objects. Here are wrappers that print field access and method invocation:

InterceptWrapFactory.java

import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.WrapFactory; public class InterceptWrapFactory extends WrapFactory{ @Override public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class<?> staticType) { return new InterceptNativeObject(scope, javaObject, staticType); } } 

InterceptNativeObject.java

 import org.mozilla.javascript.NativeJavaMethod; import org.mozilla.javascript.NativeJavaObject; import org.mozilla.javascript.Scriptable; public class InterceptNativeObject extends NativeJavaObject { @Override public Object get(String name, Scriptable start) { Object res = super.get(name, start); System.out.println("Field get name="+name+" result="+res); if (res instanceof NativeJavaMethod) { NativeJavaMethod method = (NativeJavaMethod) res; return new JavaMethodWrapper(method); } return res; } public InterceptNativeObject(Scriptable scope, Object javaObject, Class<?> staticType) { super(scope, javaObject, staticType); } } 

JavaMethodWrapper.java

 import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.NativeJavaMethod; import org.mozilla.javascript.Scriptable; public class JavaMethodWrapper implements Function { NativeJavaMethod method; public JavaMethodWrapper(NativeJavaMethod method) { this.method = method; } public boolean hasInstance(Scriptable instance) { return method.hasInstance(instance); } public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { System.out.println("Call method: "+method); return method.call(cx, scope, thisObj, args); } public boolean has(int index, Scriptable start) { return method.has(index, start); } public Scriptable construct(Context cx, Scriptable scope, Object[] args) { return method.construct(cx, scope, args); } public void put(int index, Scriptable start, Object value) { method.put(index, start, value); } public void delete(int index) { method.delete(index); } public Scriptable createObject(Context cx, Scriptable scope) { return method.createObject(cx, scope); } public boolean has(String name, Scriptable start) { return method.has(name, start); } public void defineConst(String name, Scriptable start) { method.defineConst(name, start); } public void put(String name, Scriptable start, Object value) { method.put(name, start, value); } public void delete(String name) { method.delete(name); } public Scriptable getPrototype() { return method.getPrototype(); } public void setPrototype(Scriptable m) { method.setPrototype(m); } public Scriptable getParentScope() { return method.getParentScope(); } public void setParentScope(Scriptable m) { method.setParentScope(m); } public Object[] getIds() { return method.getIds(); } public Object get(int index, Scriptable start) { return method.get(index, start); } public Object get(String name, Scriptable start) { return method.get(name, start); } public String getClassName() { return method.getClassName(); } public Object getDefaultValue(Class<?> typeHint) { return method.getDefaultValue(typeHint); } } 

And this is the test code:

 import java.util.Vector; import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; public class InterceptTest { public static void main(String[] args) { Context cx=Context.enter(); cx.setWrapFactory(new InterceptWrapFactory()); Scriptable root=cx.initStandardObjects(); ScriptableObject.putProperty(root,"v", new Vector<String>()); cx.evaluateString(root, "v.add('foo'); v.get(0)", "src", 1, null); } } 
+5
source

As an alternative to the hog1e3 clause, it is also possible to implement a Scriptable interface to intercept calls to class methods / fields.

0
source

Source: https://habr.com/ru/post/915087/


All Articles