I'm having a strange error happen when using rhino with my own
WrapFactory implementation from within a Servlet Container.  If I run
the application outside the servlet container everything works
fine.    I added my own WrapFactory so that I could make Java
collections more closely mimic Javascript Arrays and Objects.  Problem
is when an script is executed for the first time it can't find
the .length parameter on a Java Collection.  After it errors out that
one time it starts working without a problem.  In the debugger I can
see that Rhino is using the custom WrapFactory, and the
NativeJavaObject extension is being created for that java.util.List.
However, the get() method is never called which is where the extension
to add the ".length" parameter support is.  As I said if I take it out
of the container get() method is called as expected, but within the
servlet container it doesn't do it the first time.  Any ideas what's
going on?  I'm using the latest stable release of Rhino.

Here's my code:

public class EnhancedWrapFactory extends WrapFactory {

    private boolean scriptableJavaObjects = false;

    public EnhancedWrapFactory() {
        setJavaPrimitiveWrap(false);
    }

    public EnhancedWrapFactory( boolean scriptableJavaObjects ) {
        this();
        this.scriptableJavaObjects = scriptableJavaObjects;
    }

    public Scriptable wrapAsJavaObject(Context cx, Scriptable scope,
Object javaObject, Class staticType) {
        if (javaObject instanceof Map) {
            return new NativeMapAdapter(cx, scope, javaObject,
staticType);
        } else if (javaObject instanceof List) {
            return new NativeListAdapter(cx, scope, javaObject,
staticType);
        } else if( scriptableJavaObjects ) {
            return new
ScriptableNativeJavaObject(scope,javaObject,staticType);
        } else {
            return new NativeJavaObject(scope, javaObject,
staticType);
        }
    }
}

public class NativeListAdapter extends NativeJavaObject {

    public NativeListAdapter(Context cx, Scriptable scope, Object
javaObject, Class staticType) {
        super(scope, javaObject, staticType);
        Scriptable scriptable = (Scriptable) cx.evaluateString( scope,
"Array.prototype", "internal" , 1, null);
        setPrototype(scriptable);
    }

    private List getList() {
        return (List) javaObject;
    }

    @Override
    public Object get(String name, Scriptable start) {
        if( name.equals("length") ) return getList().size();
        return super.get(name, start);
    }

    public void delete(int index) {
        try {
            getList().remove(index);
        } catch (RuntimeException e) {
            throw Context.throwAsScriptRuntimeEx(e);
        }
    }

    public Object get(int index, Scriptable start) {
        Context cx = Context.getCurrentContext();
        try {
            int s = getList().size();
            if( index >= 0 && index < s ) {
                return cx.getWrapFactory().wrap(cx, this,
getList().get(index), null);
            } else {
                return Context.getUndefinedValue();
            }
        } catch (RuntimeException e) {
            throw Context.throwAsScriptRuntimeEx(e);
        }
    }

    public String getClassName() {
        return "NativeListAdapter";
    }

    public Object[] getIds() {
        int size = getList().size();
        Integer[] ids = new Integer[size];
        for (int i = 0; i < size; ++i) {
            ids[i] = i;
        }
        return ids;
    }

    public boolean has(int index, Scriptable start) {
        return index >= 0 && index < getList().size();
    }

    public void put(int index, Scriptable start, Object value) {
        try {
            getList().set(index, Context.jsToJava(value,
org.mozilla.javascript.ScriptRuntime.ObjectClass));
        } catch (RuntimeException e) {
            Context.throwAsScriptRuntimeEx(e);
        }
    }

    @Override
    public boolean hasInstance(Scriptable value) {
        return true;
    }

    public String toString() {
        return javaObject.toString();
    }
}
_______________________________________________
dev-tech-js-engine-rhino mailing list
dev-tech-js-engine-rhino@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

Reply via email to