⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 javaadapter.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Patrick Beard *   Norris Boyd *   Igor Bukanov *   Mike McCabe *   Matthias Radestock *   Andi Vajda *   Andrew Wason *   Kemal Bayram * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript;import org.mozilla.classfile.*;import java.lang.reflect.*;import java.io.*;import java.security.*;import java.util.*;public final class JavaAdapter implements IdFunctionCall{    /**     * Provides a key with which to distinguish previously generated     * adapter classes stored in a hash table.     */    static class JavaAdapterSignature    {        Class superClass;        Class[] interfaces;        ObjToIntMap names;        JavaAdapterSignature(Class superClass, Class[] interfaces,                             ObjToIntMap names)        {            this.superClass = superClass;            this.interfaces = interfaces;            this.names = names;        }        public boolean equals(Object obj)        {            if (!(obj instanceof JavaAdapterSignature))                return false;            JavaAdapterSignature sig = (JavaAdapterSignature) obj;            if (superClass != sig.superClass)                return false;            if (interfaces != sig.interfaces) {                if (interfaces.length != sig.interfaces.length)                    return false;                for (int i=0; i < interfaces.length; i++)                    if (interfaces[i] != sig.interfaces[i])                        return false;            }            if (names.size() != sig.names.size())                return false;            ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(names);            for (iter.start(); !iter.done(); iter.next()) {                String name = (String)iter.getKey();                int arity = iter.getValue();                if (arity != names.get(name, arity + 1))                    return false;            }            return true;        }        public int hashCode()        {            return superClass.hashCode()                | (0x9e3779b9 * (names.size() | (interfaces.length << 16)));        }    }    public static void init(Context cx, Scriptable scope, boolean sealed)    {        JavaAdapter obj = new JavaAdapter();        IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_JavaAdapter,                                                     "JavaAdapter", 1, scope);        ctor.markAsConstructor(null);        if (sealed) {            ctor.sealObject();        }        ctor.exportAsScopeProperty();    }    public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,                             Scriptable thisObj, Object[] args)    {        if (f.hasTag(FTAG)) {            if (f.methodId() == Id_JavaAdapter) {                return js_createAdapter(cx, scope, args);            }        }        throw f.unknown();    }    public static Object convertResult(Object result, Class c)    {        if (result == Undefined.instance &&            (c != ScriptRuntime.ObjectClass &&             c != ScriptRuntime.StringClass))        {            // Avoid an error for an undefined value; return null instead.            return null;        }        return Context.jsToJava(result, c);    }    public static Scriptable createAdapterWrapper(Scriptable obj,                                                  Object adapter)    {        Scriptable scope = ScriptableObject.getTopLevelScope(obj);        NativeJavaObject res = new NativeJavaObject(scope, adapter, null, true);        res.setPrototype(obj);        return res;    }    public static Object getAdapterSelf(Class adapterClass, Object adapter)        throws NoSuchFieldException, IllegalAccessException    {        Field self = adapterClass.getDeclaredField("self");        return self.get(adapter);    }    static Object js_createAdapter(Context cx, Scriptable scope, Object[] args)    {        int N = args.length;        if (N == 0) {            throw ScriptRuntime.typeError0("msg.adapter.zero.args");        }        Class superClass = null;        Class[] intfs = new Class[N - 1];        int interfaceCount = 0;        for (int i = 0; i != N - 1; ++i) {            Object arg = args[i];            if (!(arg instanceof NativeJavaClass)) {                throw ScriptRuntime.typeError2("msg.not.java.class.arg",                                               String.valueOf(i),                                               ScriptRuntime.toString(arg));            }            Class c = ((NativeJavaClass) arg).getClassObject();            if (!c.isInterface()) {                if (superClass != null) {                    throw ScriptRuntime.typeError2("msg.only.one.super",                              superClass.getName(), c.getName());                }                superClass = c;            } else {                intfs[interfaceCount++] = c;            }        }        if (superClass == null)            superClass = ScriptRuntime.ObjectClass;        Class[] interfaces = new Class[interfaceCount];        System.arraycopy(intfs, 0, interfaces, 0, interfaceCount);        Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]);        Class adapterClass = getAdapterClass(scope, superClass, interfaces,                                             obj);        Class[] ctorParms = {            ScriptRuntime.ContextFactoryClass,            ScriptRuntime.ScriptableClass        };        Object[] ctorArgs = { cx.getFactory(), obj };        try {            Object adapter = adapterClass.getConstructor(ctorParms).                                 newInstance(ctorArgs);            return getAdapterSelf(adapterClass, adapter);        } catch (Exception ex) {            throw Context.throwAsScriptRuntimeEx(ex);        }    }    // Needed by NativeJavaObject serializer    public static void writeAdapterObject(Object javaObject,                                          ObjectOutputStream out)        throws IOException    {        Class cl = javaObject.getClass();        out.writeObject(cl.getSuperclass().getName());        Class[] interfaces = cl.getInterfaces();        String[] interfaceNames = new String[interfaces.length];        for (int i=0; i < interfaces.length; i++)            interfaceNames[i] = interfaces[i].getName();        out.writeObject(interfaceNames);        try {            Object delegee = cl.getField("delegee").get(javaObject);            out.writeObject(delegee);            return;        } catch (IllegalAccessException e) {        } catch (NoSuchFieldException e) {        }        throw new IOException();    }    // Needed by NativeJavaObject de-serializer    public static Object readAdapterObject(Scriptable self,                                           ObjectInputStream in)        throws IOException, ClassNotFoundException    {        ContextFactory factory;        Context cx = Context.getCurrentContext();        if (cx != null) {            factory = cx.getFactory();        } else {            factory = null;        }        Class superClass = Class.forName((String)in.readObject());        String[] interfaceNames = (String[])in.readObject();        Class[] interfaces = new Class[interfaceNames.length];        for (int i=0; i < interfaceNames.length; i++)            interfaces[i] = Class.forName(interfaceNames[i]);        Scriptable delegee = (Scriptable)in.readObject();        Class adapterClass = getAdapterClass(self, superClass, interfaces,                                             delegee);        Class[] ctorParms = {            ScriptRuntime.ContextFactoryClass,            ScriptRuntime.ScriptableClass,            ScriptRuntime.ScriptableClass        };        Object[] ctorArgs = { factory, delegee, self };        try {            return adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);        } catch(InstantiationException e) {        } catch(IllegalAccessException e) {        } catch(InvocationTargetException e) {        } catch(NoSuchMethodException e) {        }        throw new ClassNotFoundException("adapter");    }    private static ObjToIntMap getObjectFunctionNames(Scriptable obj)    {        Object[] ids = ScriptableObject.getPropertyIds(obj);        ObjToIntMap map = new ObjToIntMap(ids.length);        for (int i = 0; i != ids.length; ++i) {            if (!(ids[i] instanceof String))                continue;            String id = (String) ids[i];            Object value = ScriptableObject.getProperty(obj, id);            if (value instanceof Function) {                Function f = (Function)value;                int length = ScriptRuntime.toInt32(                                 ScriptableObject.getProperty(f, "length"));                if (length < 0) {                    length = 0;                }                map.put(id, length);            }        }        return map;    }    private static Class getAdapterClass(Scriptable scope, Class superClass,                                         Class[] interfaces, Scriptable obj)    {        ClassCache cache = ClassCache.get(scope);        Map<JavaAdapterSignature,Class<?>> generated            = cache.getInterfaceAdapterCacheMap();        ObjToIntMap names = getObjectFunctionNames(obj);        JavaAdapterSignature sig;        sig = new JavaAdapterSignature(superClass, interfaces, names);        Class<?> adapterClass = generated.get(sig);        if (adapterClass == null) {            String adapterName = "adapter"                                 + cache.newClassSerialNumber();            byte[] code = createAdapterCode(names, adapterName,                                            superClass, interfaces, null);            adapterClass = loadAdapterClass(adapterName, code);            if (cache.isCachingEnabled()) {                generated.put(sig, adapterClass);            }        }        return adapterClass;    }    public static byte[] createAdapterCode(ObjToIntMap functionNames,                                           String adapterName,                                           Class superClass,                                           Class[] interfaces,                                           String scriptClassName)    {        ClassFileWriter cfw = new ClassFileWriter(adapterName,                                                  superClass.getName(),                                                  "<adapter>");        cfw.addField("factory", "Lorg/mozilla/javascript/ContextFactory;",                     (short) (ClassFileWriter.ACC_PUBLIC |                              ClassFileWriter.ACC_FINAL));        cfw.addField("delegee", "Lorg/mozilla/javascript/Scriptable;",                     (short) (ClassFileWriter.ACC_PUBLIC |                              ClassFileWriter.ACC_FINAL));        cfw.addField("self", "Lorg/mozilla/javascript/Scriptable;",                     (short) (ClassFileWriter.ACC_PUBLIC |                              ClassFileWriter.ACC_FINAL));        int interfacesCount = interfaces == null ? 0 : interfaces.length;        for (int i=0; i < interfacesCount; i++) {            if (interfaces[i] != null)                cfw.addInterface(interfaces[i].getName());        }        String superName = superClass.getName().replace('.', '/');        generateCtor(cfw, adapterName, superName);        generateSerialCtor(cfw, adapterName, superName);        if (scriptClassName != null)            generateEmptyCtor(cfw, adapterName, superName, scriptClassName);        ObjToIntMap generatedOverrides = new ObjToIntMap();        ObjToIntMap generatedMethods = new ObjToIntMap();        // generate methods to satisfy all specified interfaces.        for (int i = 0; i < interfacesCount; i++) {            Method[] methods = interfaces[i].getMethods();            for (int j = 0; j < methods.length; j++) {                Method method = methods[j];                int mods = method.getModifiers();                if (Modifier.isStatic(mods) || Modifier.isFinal(mods)) {                    continue;                }                String methodName = method.getName();                Class[] argTypes = method.getParameterTypes();                if (!functionNames.has(methodName)) {                    try {                        superClass.getMethod(methodName, argTypes);                        // The class we're extending implements this method and                        // the JavaScript object doesn't have an override. See                        // bug 61226.                        continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -