📄 javamembers.java
字号:
if (member instanceof NativeJavaMethod && ((NativeJavaMethod)member).methods.length > 1 ) { NativeJavaMethod fun = new NativeJavaMethod(methodOrCtor, name); fun.setPrototype(prototype); ht.put(name, fun); member = fun; } } } return member; } /** * Retrieves mapping of methods to accessible methods for a class. * In case the class is not public, retrieves methods with same * signature as its public methods from public superclasses and * interfaces (if they exist). Basically upcasts every method to the * nearest accessible method. */ private static Method[] discoverAccessibleMethods(Class clazz, boolean includeProtected, boolean includePrivate) { Map map = new HashMap(); discoverAccessibleMethods(clazz, map, includeProtected, includePrivate); return (Method[])map.values().toArray(new Method[map.size()]); } private static void discoverAccessibleMethods(Class clazz, Map map, boolean includeProtected, boolean includePrivate) { if (Modifier.isPublic(clazz.getModifiers()) || includePrivate) { try { if (includeProtected || includePrivate) { while (clazz != null) { try { Method[] methods = clazz.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; int mods = method.getModifiers(); if (Modifier.isPublic(mods) || Modifier.isProtected(mods) || includePrivate) { if (includePrivate) method.setAccessible(true); map.put(new MethodSignature(method), method); } } clazz = clazz.getSuperclass(); } catch (SecurityException e) { // Some security settings (i.e., applets) disallow // access to Class.getDeclaredMethods. Fall back to // Class.getMethods. Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; MethodSignature sig = new MethodSignature(method); if (map.get(sig) == null) map.put(sig, method); } break; // getMethods gets superclass methods, no // need to loop any more } } } else { Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; MethodSignature sig = new MethodSignature(method); map.put(sig, method); } } return; } catch (SecurityException e) { Context.reportWarning( "Could not discover accessible methods of class " + clazz.getName() + " due to lack of privileges, " + "attemping superclasses/interfaces."); // Fall through and attempt to discover superclass/interface // methods } } Class[] interfaces = clazz.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { discoverAccessibleMethods(interfaces[i], map, includeProtected, includePrivate); } Class superclass = clazz.getSuperclass(); if (superclass != null) { discoverAccessibleMethods(superclass, map, includeProtected, includePrivate); } } private static final class MethodSignature { private final String name; private final Class[] args; private MethodSignature(String name, Class[] args) { this.name = name; this.args = args; } MethodSignature(Method method) { this(method.getName(), method.getParameterTypes()); } public boolean equals(Object o) { if(o instanceof MethodSignature) { MethodSignature ms = (MethodSignature)o; return ms.name.equals(name) && Arrays.equals(args, ms.args); } return false; } public int hashCode() { return name.hashCode() ^ args.length; } } private void reflect(Scriptable scope, boolean includeProtected) { // We reflect methods first, because we want overloaded field/method // names to be allocated to the NativeJavaMethod before the field // gets in the way. Method[] methods = discoverAccessibleMethods(cl, includeProtected, includePrivate); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; int mods = method.getModifiers(); boolean isStatic = Modifier.isStatic(mods); Hashtable ht = isStatic ? staticMembers : members; String name = method.getName(); Object value = ht.get(name); if (value == null) { ht.put(name, method); } else { ObjArray overloadedMethods; if (value instanceof ObjArray) { overloadedMethods = (ObjArray)value; } else { if (!(value instanceof Method)) Kit.codeBug(); // value should be instance of Method as at this stage // staticMembers and members can only contain methods overloadedMethods = new ObjArray(); overloadedMethods.add(value); ht.put(name, overloadedMethods); } overloadedMethods.add(method); } } // replace Method instances by wrapped NativeJavaMethod objects // first in staticMembers and then in members for (int tableCursor = 0; tableCursor != 2; ++tableCursor) { boolean isStatic = (tableCursor == 0); Hashtable ht = (isStatic) ? staticMembers : members; Enumeration e = ht.keys(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); MemberBox[] methodBoxes; Object value = ht.get(name); if (value instanceof Method) { methodBoxes = new MemberBox[1]; methodBoxes[0] = new MemberBox((Method)value); } else { ObjArray overloadedMethods = (ObjArray)value; int N = overloadedMethods.size(); if (N < 2) Kit.codeBug(); methodBoxes = new MemberBox[N]; for (int i = 0; i != N; ++i) { Method method = (Method)overloadedMethods.get(i); methodBoxes[i] = new MemberBox(method); } } NativeJavaMethod fun = new NativeJavaMethod(methodBoxes); if (scope != null) { ScriptRuntime.setFunctionProtoAndParent(fun, scope); } ht.put(name, fun); } } // Reflect fields. Field[] fields = getAccessibleFields(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; String name = field.getName(); int mods = field.getModifiers(); if (!includePrivate && !Modifier.isPublic(mods)) { continue; } try { boolean isStatic = Modifier.isStatic(mods); Hashtable ht = isStatic ? staticMembers : members; Object member = ht.get(name); if (member == null) { ht.put(name, field); } else if (member instanceof NativeJavaMethod) { NativeJavaMethod method = (NativeJavaMethod) member; FieldAndMethods fam = new FieldAndMethods(scope, method.methods, field); Hashtable fmht = isStatic ? staticFieldAndMethods : fieldAndMethods; if (fmht == null) { fmht = new Hashtable(4); if (isStatic) { staticFieldAndMethods = fmht; } else { fieldAndMethods = fmht; } } fmht.put(name, fam); ht.put(name, fam); } else if (member instanceof Field) { Field oldField = (Field) member; // If this newly reflected field shadows an inherited field, // then replace it. Otherwise, since access to the field // would be ambiguous from Java, no field should be // reflected. // For now, the first field found wins, unless another field // explicitly shadows it. if (oldField.getDeclaringClass(). isAssignableFrom(field.getDeclaringClass())) { ht.put(name, field); } } else { // "unknown member type" Kit.codeBug(); } } catch (SecurityException e) { // skip this field Context.reportWarning("Could not access field " + name + " of class " + cl.getName() + " due to lack of privileges."); } } // Create bean propeties from corresponding get/set methods first for // static members and then for instance members for (int tableCursor = 0; tableCursor != 2; ++tableCursor) { boolean isStatic = (tableCursor == 0); Hashtable ht = (isStatic) ? staticMembers : members; Hashtable toAdd = new Hashtable(); // Now, For each member, make "bean" properties. for (Enumeration e = ht.keys(); e.hasMoreElements(); ) { // Is this a getter? String name = (String) e.nextElement(); boolean memberIsGetMethod = name.startsWith("get"); boolean memberIsSetMethod = name.startsWith("set"); boolean memberIsIsMethod = name.startsWith("is"); if (memberIsGetMethod || memberIsIsMethod || memberIsSetMethod) { // Double check name component. String nameComponent = name.substring(memberIsIsMethod ? 2 : 3); if (nameComponent.length() == 0) continue; // Make the bean property name. String beanPropertyName = nameComponent; char ch0 = nameComponent.charAt(0); if (Character.isUpperCase(ch0)) { if (nameComponent.length() == 1) { beanPropertyName = nameComponent.toLowerCase(); } else { char ch1 = nameComponent.charAt(1); if (!Character.isUpperCase(ch1)) { beanPropertyName = Character.toLowerCase(ch0) +nameComponent.substring(1); } } } // If we already have a member by this name, don't do this // property. if (ht.containsKey(beanPropertyName) || toAdd.containsKey(beanPropertyName)) { continue; } // Find the getter method, or if there is none, the is- // method. MemberBox getter = null; getter = findGetter(isStatic, ht, "get", nameComponent); // If there was no valid getter, check for an is- method. if (getter == null) { getter = findGetter(isStatic, ht, "is", nameComponent); } // setter MemberBox setter = null; NativeJavaMethod setters = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -