On Sep 23, 4:14 am, tlrobinson <[EMAIL PROTECTED]> wrote:
> I'm trying to create Rhino context (in JS code running in Rhino) with
> a scope object that reports to me whenever a property is set or
> accessed. I've tried a number of things, but can't seem to find the
> right combination.
>
> Here's what I was hoping would work, but I couldn't find any way to
> call a Java superclass's method from within a JavaAdapter's method
> implementation. Is it possible?

Yes, use super$methodName() to invoke super methods. This should be
documented at
http://www.mozilla.org/rhino/ScriptingJava.html#javaAdapter

>     var cx = Packages.org.mozilla.javascript.Context.enter();

Note that you don't need to call Context.enter() as you are already
running in a rhino context. You may just use
Context.getCurrentContext() instead.

>     var scope = new Packages.org.mozilla.javascript.ScriptableObject({
>         className : function() {
>             return "HookedScriptableObject";
>         },
>         put : function(name, start, value) {
>             java.lang.System.out.println("putting: " + name);
>             // need equivalent to "super.put(name, start, value)"
>         }
>     });
>     scope = cx.initStandardObjects(scope);

Neat idea, but it won't work that way, as the JavaAdapter will be
wrapped as java object.

> I also tried subclassing ScriptableObject directly in Java. This sort
> of worked when I just instantiated it directly:
>
>         js> a = new Packages.HookedScriptableObject()
>         Default for class java.lang.String
>         test4567
>         js> a.asdf = "1234"
>         Putting: asdf => 1234
>         1234
>         js> a.asdf
>         Getting: asdf
>         1234
>
> But when calling initStandardObjects I get "Can't find method
> org.mozilla.javascript.Context.initStandardObjects(object)":
>
>     var cx = Packages.org.mozilla.javascript.Context.enter();
>     scope = cx.initStandardObjects(new
> Packages.HookedScriptableObject());

This is a bug in the java method lookup code. I filed a bug for this:
https://bugzilla.mozilla.org/show_bug.cgi?id=456546

> Here's HookedScriptableObject.java:
>
>     import org.mozilla.javascript.Scriptable;
>     import org.mozilla.javascript.ScriptableObject;
>
>     class HookedScriptableObject extends ScriptableObject
>     {
>         public HookedScriptableObject()
>         {
>             super();
>         }
>
>         public String getClassName()
>         {
>             return "test1234";
>         }
>
>         public Object getDefaultValue(Class typeHint)
>         {
>             System.out.println("Default for " + typeHint);
>             return "test4567";
>         }
>
>         public Object get(int index, Scriptable start)
>         {
>             System.out.println("Getting index: " + index);
>             return super.get(index, start);
>         }
>
>         public Object get(String name, Scriptable start)
>         {
>             System.out.println("Getting: " + name);
>             return super.get(name, start);
>         }
>
>         public void put(String name, Scriptable start, Object value)
>         {
>             System.out.println("Putting: " + name + " => " + value);
>             super.put(name, start, value);
>         }
>
>         public void put(int index, Scriptable start, Object value)
>         {
>             System.out.println("Putting index: " + index + " => " +
> value);
>             super.put(index,start, value);
>         }
>     }
>
> I feel like there must be a way to do this pretty easily, I'm just
> missing something...
>
> Ideally the code would be entirely in JavaScript, but  some Java is
> ok. This portion of the code should be in JavaScript, if possible:
>
>     var cx = Packages.org.mozilla.javascript.Context.enter();
>     scope = cx.initStandardObjects(whatever);
>
> Thanks in advance.

The following will work (with the fix for bug 456546 above):

var rhino = org.mozilla.javascript;
var cx = rhino.Context.currentContext;

var scope = new JavaAdapter(rhino.NativeObject, {
    getClassName: function() { return "Foo"; },
    put: function(name, start, value) {
        this.super$put(name, this, value);
    },
});

scope = rhino.Context.currentContext.jsToJava(scope,
rhino.Scriptable);
scope.__proto__ = Object.prototype;
cx.initStandardObjects(scope);


Be careful not to calling value.toString() in the put function, as it
will dive into infinite recursion while the scope is being
initialized.

hannes

> -Tom

_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

Reply via email to