diff options
Diffstat (limited to 'java/jdk14/files/patch-javascript_ReflectUtil.java')
-rw-r--r-- | java/jdk14/files/patch-javascript_ReflectUtil.java | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/java/jdk14/files/patch-javascript_ReflectUtil.java b/java/jdk14/files/patch-javascript_ReflectUtil.java new file mode 100644 index 000000000000..827bd0c666ce --- /dev/null +++ b/java/jdk14/files/patch-javascript_ReflectUtil.java @@ -0,0 +1,312 @@ +$FreeBSD$ + +--- ../../deploy/src/plugin/src/share/classes/sun/plugin/javascript/ReflectUtil.java 1 Jan 1970 00:00:00 -0000 ++++ ../../deploy/src/plugin/src/share/classes/sun/plugin/javascript/ReflectUtil.java 3 Dec 2004 03:56:58 -0000 1.1 +@@ -0,0 +1,307 @@ ++/* ++ * @(#)ReflectUtil.java 1.1 04/06/20 ++ * ++ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. ++ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. ++ */ ++package sun.plugin.javascript; ++ ++import java.lang.reflect.Method; ++import java.lang.reflect.Field; ++import java.lang.reflect.Modifier; ++import java.lang.reflect.InvocationTargetException; ++import java.util.HashMap; ++import java.util.ArrayList; ++import java.util.List; ++import java.util.Map; ++import java.util.Iterator; ++import sun.plugin.javascript.JSClassLoader; ++ ++public class ReflectUtil { ++ /* ++ * Discover the public methods on public classes ++ * and interfaces accessible to the calling ++ * JavaScript code. ++ */ ++ public static Method[] getJScriptMethods(Class cls) { ++ List m = new ArrayList(); /* the valid methods we find */ ++ ++ /* ++ * Temporary map of method signatures when we decide ++ * that a simple call to target.getMethods() returns ++ * inaccessible methods and we must search for alternative ++ * supermethods that might be accessible. We can toss ++ * this when we're done searching. ++ */ ++ Map sigs = new HashMap(); ++ ++ while (cls != null) { ++ boolean done = getPublicMethods(cls, m, sigs); ++ if (done) { ++ break; ++ } ++ getJScriptInterfaceMethods(cls, m, sigs); ++ cls = cls.getSuperclass(); ++ } ++ return (Method[]) m.toArray(new Method[m.size()]); ++ } ++ ++ /* ++ * Process the immediate interfaces of this class or interface. ++ */ ++ private static void getJScriptInterfaceMethods(Class cls, List m, Map sigs) { ++ Class[] intfs = cls.getInterfaces(); ++ for (int i=0; i < intfs.length; i++) { ++ Class intf = intfs[i]; ++ boolean done = getPublicMethods(intf, m, sigs); ++ if (!done) { ++ getJScriptInterfaceMethods(intf, m, sigs); ++ } ++ } ++ } ++ ++ /* ++ * ++ * Process the methods in this class or interface ++ */ ++ private static boolean getPublicMethods(Class cls, List m, Map sigs) { ++ Method[] methods = null; ++ try { ++ ++ /* ++ * This class or interface is non-public so we ++ * can't use any of it's methods. Go back and ++ * try again with a superclass or superinterface. ++ */ ++ if (!Modifier.isPublic(cls.getModifiers())) { ++ return false; ++ } ++ ++ if (!JSClassLoader.isPackageAccessible(cls)) { ++ return false; ++ } ++ ++ methods = cls.getMethods(); ++ } catch (SecurityException se) { ++ return false; ++ } ++ ++ /* ++ * Check for inherited methods with non-public ++ * declaring classes. They might override and hide ++ * methods from their superclasses or ++ * superinterfaces. ++ */ ++ boolean done = true; ++ for (int i=0; i < methods.length; i++) { ++ Class dc = methods[i].getDeclaringClass(); ++ if (!Modifier.isPublic(dc.getModifiers())) { ++ done = false; ++ break; ++ } ++ } ++ ++ /* ++ * Belatedly initialize the signature map if ++ * this is not the first time here. ++ */ ++ if (sigs.isEmpty() && !m.isEmpty()) { ++ initSignatureMap(m, sigs); ++ } ++ ++ if (done) { ++ /* ++ * We're done. Spray all the methods into ++ * the list and then we're out of here. ++ */ ++ for (int i=0; i < methods.length; i++) { ++ addMethod(m, sigs, methods[i]); ++ } ++ } else { ++ /* ++ * Simulate cls.getDeclaredMethods() by ++ * stripping away inherited methods. ++ */ ++ for (int i=0; i < methods.length; i++) { ++ Class dc = methods[i].getDeclaringClass(); ++ if (cls.equals(dc)) { ++ addMethod(m, sigs, methods[i]); ++ } ++ } ++ } ++ return done; ++ } ++ ++ private static void initSignatureMap(List m, Map sigs) { ++ Iterator i = m.iterator(); ++ while (i.hasNext()) { ++ Method entry = (Method) i.next(); ++ sigs.put(getSignature(entry), entry); ++ } ++ } ++ ++ private static void addMethod(List m, Map sigs, Method method) { ++ /* ++ * Avoid work. We ignore the signature matching ++ * until the map is initialized in initSignatureMap. ++ * This has the effect of avoiding the signature ++ * work for the first call of getPublicMethods(). ++ */ ++ if (sigs.isEmpty()) { ++ m.add(method); ++ return; ++ } ++ ++ /* ++ * Avoid adding duplicate accessible methods on ++ * the list. ++ */ ++ String signature = getSignature(method); ++ if (!sigs.containsKey(signature)) { ++ m.add(method); ++ sigs.put(signature, method); ++ } ++ } ++ ++ /* ++ * Return a canonical method signature for the method. ++ * We care only about the simple method name and the ++ * the number, type and order of the parameters. ++ * Exception declarations are not part of a method ++ * signature nor is the return type. ++ */ ++ private static String getSignature(Method method) { ++ StringBuffer sb = new StringBuffer(); ++ ++ sb.append(method.getName()); ++ Class[] params = method.getParameterTypes(); ++ sb.append('('); ++ if (params.length > 0) { ++ sb.append(params[0].getName()); ++ } ++ for (int i=1; i < params.length; i++) { ++ sb.append(','); ++ sb.append(params[i].getName()); ++ } ++ sb.append(')'); ++ ++ return sb.toString(); ++ } ++ ++ /* ++ * Discover the public fields on public classes ++ * and interfaces accessible to the calling ++ * JavaScript code. ++ */ ++ public static Field[] getJScriptFields(Class cls) { ++ List m = new ArrayList(); /* the valid fields we find */ ++ ++ /* ++ * Temporary map of field name when we decide ++ * that a simple call to target.getFields() returns ++ * inaccessible fields and we must search for alternative ++ * supermethods that might be accessible. We can toss ++ * this when we're done searching. ++ */ ++ Map names = new HashMap(); ++ ++ while (cls != null) { ++ boolean done = getPublicFields(cls, m, names); ++ if (done) { ++ break; ++ } ++ getJScriptInterfaceFields(cls, m, names); ++ cls = cls.getSuperclass(); ++ } ++ return (Field[]) m.toArray(new Field[m.size()]); ++ } ++ ++ /* ++ * Process the immediate interfaces of this class or interface. ++ */ ++ private static void getJScriptInterfaceFields(Class cls, List m, Map names) { ++ Class[] intfs = cls.getInterfaces(); ++ for (int i=0; i < intfs.length; i++) { ++ Class intf = intfs[i]; ++ boolean done = getPublicFields(intf, m, names); ++ if (!done) { ++ getJScriptInterfaceFields(intf, m, names); ++ } ++ } ++ } ++ ++ /* ++ * ++ * Process the fields in this class or interface ++ */ ++ private static boolean getPublicFields(Class cls, List m, Map names) { ++ Field[] fields = null; ++ try { ++ ++ /* ++ * This class or interface is non-public so we ++ * can't use any of it's fields. Go back and ++ * try again with a superclass or superinterface. ++ */ ++ if (!Modifier.isPublic(cls.getModifiers())) { ++ return false; ++ } ++ ++ if (!JSClassLoader.isPackageAccessible(cls)) { ++ return false; ++ } ++ fields = cls.getFields(); ++ } catch (SecurityException se) { ++ return false; ++ } ++ ++ /* ++ * Check for inherited fields with non-public ++ * declaring classes. They might hide ++ * fields from public classes or interfaces. ++ */ ++ boolean done = true; ++ for (int i=0; i < fields.length; i++) { ++ Class dc = fields[i].getDeclaringClass(); ++ if (!Modifier.isPublic(dc.getModifiers())) { ++ done = false; ++ break; ++ } ++ } ++ if (done) { ++ /* ++ * We're done. Spray all the fields into ++ * the list and then we're out of here. ++ */ ++ for (int i=0; i < fields.length; i++) { ++ addField(m, names, fields[i]); ++ } ++ } else { ++ /* ++ * Simulate cls.getDeclaredFields() by ++ * stripping away inherited fields. ++ */ ++ for (int i=0; i < fields.length; i++) { ++ Class dc = fields[i].getDeclaringClass(); ++ if (cls.equals(dc)) { ++ addField(m, names, fields[i]); ++ } ++ } ++ } ++ return done; ++ } ++ ++ private static void addField(List m, Map names, Field field) { ++ /* ++ * Avoid adding duplicate accessible fields on ++ * the list. ++ */ ++ String name = field.getName(); ++ if (!names.containsKey(name)) { ++ m.add(field); ++ names.put(name, field); ++ } ++ } ++} ++ ++ |