Package org.apache.batik.script.rhino

Source Code of org.apache.batik.script.rhino.EventTargetWrapper$RhinoNativeJavaMethod

/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved.        *
*---------------------------------------------------------------------------*
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in  *
* the LICENSE file.                                                         *
*****************************************************************************/

package org.apache.batik.script.rhino;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.NativeJavaMethod;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.WrappedException;

import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;

import java.lang.reflect.Method;
import java.util.HashMap;

import org.apache.batik.script.Interpreter;
import org.apache.batik.script.InterpreterException;

/**
* A class that wrap an <code>EventTarget</code> instance to expose
* it in the Rhino engine. Then calling <code>addEventListener</code>
* with a Rhino function as parameter should redirect the call to
* <code>addEventListener</code> with a Java function object calling
* the Rhino function.
* @author <a href="mailto:cjolif@ilog.fr">Christophe Jolif</a>
* @version $Id: EventTargetWrapper.java,v 1.3 2001/01/24 14:51:02 cjolif Exp $
*/
class EventTargetWrapper extends NativeJavaObject {

    /**
     * The Java function object calling the Rhino function.
     */
    class RhinoEventListener implements EventListener {
        private Function function;

        RhinoEventListener(Function f) {
            function = f;
        }
        public void handleEvent(Event evt) {
            try {
                interpreter.callHandler(function, evt);
            } catch (JavaScriptException e) {
                // the only simple solution is to forward it as a
                // RuntimeException to be catch by event dispatching
                // in BridgetEventSupport.java
                // another solution will to give UserAgent to interpreters
                throw new WrappedException(e);
            }
        }
    }

    class RhinoNativeJavaMethod extends NativeJavaMethod {
        RhinoNativeJavaMethod(Method method, String name) {
            super(method, name);
        }
        public Object call(Context ctx, Scriptable scope,
                           Scriptable thisObj, Object[] args)
            throws JavaScriptException {
            if (args[1] instanceof Function) {
                if (jsGet_name().equals(ADD_NAME)) {
                    EventListener evtListener =
                        new RhinoEventListener((Function)args[1]);
                    if (listenerMap == null)
                        listenerMap = new HashMap(2);
                    listenerMap.put(args[1], evtListener);
                    // we need to marshall args
                    Class[] paramTypes = { String.class, Function.class,
                                           Boolean.TYPE };
                    for (int i = 0; i < args.length; i++)
                        args[i] = NativeJavaObject.coerceType(paramTypes[i],
                                                              args[i]);
                    ((EventTarget)unwrap()).
                        addEventListener((String)args[0],
                                         evtListener,
                                         ((Boolean)args[2]).booleanValue());
                    return Undefined.instance;
                } else {
                    if (listenerMap != null) {
                        // we need to marshall args
                        Class[] paramTypes = { String.class, Function.class,
                                               Boolean.TYPE };
                        for (int i = 0; i < args.length; i++)
                            args[i] =
                                NativeJavaObject.coerceType(paramTypes[i],
                                                            args[i]);
                        ((EventTarget)unwrap()).
                            removeEventListener((String)args[0],
                                                (EventListener)listenerMap.
                                                remove(args[1]),
                                                ((Boolean)args[2]).
                                                booleanValue());
                    }
                    return Undefined.instance;
                }
            }
            return super.call(ctx, scope, thisObj, args);
        }
    }

    private RhinoInterpreter interpreter;
    private NativeJavaMethod methodadd;
    private NativeJavaMethod methodremove;
    private HashMap listenerMap;

    private final static String ADD_NAME = "addEventListener";
    private final static String REMOVE_NAME = "removeEventListener";
    private final static Class[] ARGS_TYPE = { String.class,
                                               EventListener.class,
                                               Boolean.TYPE };

    EventTargetWrapper(Scriptable scope, EventTarget object,
                       RhinoInterpreter interp) {
        super(scope, object, (Class)null);
        interpreter = interp;
        try {
            methodadd =
                new RhinoNativeJavaMethod(object.getClass().
                                          getMethod(ADD_NAME,
                                                    ARGS_TYPE),
                                          ADD_NAME);
            methodremove =
                new RhinoNativeJavaMethod(object.getClass().
                                          getMethod(REMOVE_NAME,
                                                    ARGS_TYPE),
                                          REMOVE_NAME);
        } catch (NoSuchMethodException e) {
            // should not happened
            // we are sure the method are there as we
            // have an EventTarget in parameter
        }
    }

    /**
     * Overriden Rhino method.
     */
    public Object get(String name, Scriptable start) {
        Object method = null;
        if (name.equals(ADD_NAME))
            method = methodadd;
        else
            if (name.equals(REMOVE_NAME))
                method = methodremove;
            else
                method = super.get(name, start);
        return method;
    }
}
TOP

Related Classes of org.apache.batik.script.rhino.EventTargetWrapper$RhinoNativeJavaMethod

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.