summaryrefslogtreecommitdiff
path: root/java/jdk14/files/patch-javascript_ReflectUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/jdk14/files/patch-javascript_ReflectUtil.java')
-rw-r--r--java/jdk14/files/patch-javascript_ReflectUtil.java312
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);
++ }
++ }
++}
++
++