|
19 | 19 | package net.php;
|
20 | 20 |
|
21 | 21 | import java.lang.reflect.*;
|
22 |
| -import java.util.ResourceBundle; |
| 22 | +import java.util.*; |
23 | 23 | import java.beans.*;
|
24 | 24 |
|
25 | 25 | class reflect {
|
@@ -114,29 +114,111 @@ public static void CreateObject(String name, Object args[], long result) {
|
114 | 114 | }
|
115 | 115 | }
|
116 | 116 |
|
| 117 | + // |
| 118 | + // Select the best match from a list of methods |
| 119 | + // |
| 120 | + private static Method select(Vector methods, Object args[]) { |
| 121 | + if (methods.size() == 1) return (Method) methods.firstElement(); |
| 122 | + |
| 123 | + Method selected = null; |
| 124 | + int best = Integer.MAX_VALUE; |
| 125 | + |
| 126 | + for (Enumeration e = methods.elements(); e.hasMoreElements(); ) { |
| 127 | + Method method = (Method)e.nextElement(); |
| 128 | + int weight=0; |
| 129 | + Class parms[] = method.getParameterTypes(); |
| 130 | + for (int i=0; i<parms.length; i++) { |
| 131 | + if (parms[i].isInstance(args[i])) { |
| 132 | + for (Class c=parms[i]; (c=c.getSuperclass()) != null; ) { |
| 133 | + if (!c.isInstance(args[i])) break; |
| 134 | + weight++; |
| 135 | + } |
| 136 | + } else if (parms[i].isPrimitive()) { |
| 137 | + Class c=parms[i]; |
| 138 | + if (args[i] instanceof Number) { |
| 139 | + if (c==Boolean.TYPE) weight+=5; |
| 140 | + if (c==Character.TYPE) weight+=4; |
| 141 | + if (c==Byte.TYPE) weight+=3; |
| 142 | + if (c==Short.TYPE) weight+=2; |
| 143 | + if (c==Integer.TYPE) weight++; |
| 144 | + if (c==Float.TYPE) weight++; |
| 145 | + } else if (args[i] instanceof Boolean) { |
| 146 | + if (c!=Boolean.TYPE) weight+=9999; |
| 147 | + } else if (args[i] instanceof String) { |
| 148 | + if (c== Character.TYPE || ((String)args[i]).length()>0) |
| 149 | + weight+=((String)args[i]).length(); |
| 150 | + else |
| 151 | + weight+=9999; |
| 152 | + } else { |
| 153 | + weight+=9999; |
| 154 | + } |
| 155 | + } else { |
| 156 | + weight+=9999; |
| 157 | + } |
| 158 | + } |
| 159 | + |
| 160 | + if (weight < best) { |
| 161 | + if (weight == 0) return method; |
| 162 | + best = weight; |
| 163 | + selected = method; |
| 164 | + } |
| 165 | + } |
| 166 | + |
| 167 | + return selected; |
| 168 | + } |
| 169 | + |
| 170 | + // |
| 171 | + // Select the best match from a list of methods |
| 172 | + // |
| 173 | + private static Object[] coerce(Method method, Object args[]) { |
| 174 | + Object result[] = args; |
| 175 | + Class parms[] = method.getParameterTypes(); |
| 176 | + for (int i=0; i<args.length; i++) { |
| 177 | + if (parms[i].isInstance(args[i])) continue; |
| 178 | + if (args[i] instanceof Number && parms[i].isPrimitive()) { |
| 179 | + if (result==args) result=(Object[])result.clone(); |
| 180 | + Class c = parms[i]; |
| 181 | + Number n = (Number)args[i]; |
| 182 | + if (c == Boolean.TYPE) result[i]=new Boolean(0.0!=n.floatValue()); |
| 183 | + if (c == Byte.TYPE) result[i]=new Byte(n.byteValue()); |
| 184 | + if (c == Short.TYPE) result[i]=new Short(n.shortValue()); |
| 185 | + if (c == Integer.TYPE) result[i]=new Integer(n.intValue()); |
| 186 | + if (c == Float.TYPE) result[i]=new Float(n.floatValue()); |
| 187 | + if (c == Long.TYPE && !(n instanceof Long)) |
| 188 | + result[i]=new Long(n.longValue()); |
| 189 | + } |
| 190 | + } |
| 191 | + return result; |
| 192 | + } |
| 193 | + |
117 | 194 | //
|
118 | 195 | // Invoke a method on a given object
|
119 | 196 | //
|
120 | 197 | public static void Invoke
|
121 | 198 | (Object object, String method, Object args[], long result)
|
122 | 199 | {
|
123 | 200 | try {
|
| 201 | + Vector matches = new Vector(); |
124 | 202 |
|
| 203 | + // gather |
125 | 204 | for (Class jclass = object.getClass();;jclass=(Class)object) {
|
126 | 205 | Method methods[] = jclass.getMethods();
|
127 | 206 | for (int i=0; i<methods.length; i++) {
|
128 | 207 | if (methods[i].getName().equalsIgnoreCase(method) &&
|
129 | 208 | methods[i].getParameterTypes().length == args.length) {
|
130 |
| - setResult(result, methods[i].invoke(object, args)); |
131 |
| - return; |
| 209 | + matches.addElement(methods[i]); |
132 | 210 | }
|
133 | 211 | }
|
134 | 212 |
|
135 | 213 | // try a second time with the object itself, if it is of type Class
|
136 |
| - if (!(jclass instanceof Class) || (jclass==object)) break; |
| 214 | + if (!(object instanceof Class) || (jclass==object)) break; |
137 | 215 | }
|
138 | 216 |
|
139 |
| - throw new NoSuchMethodException(method); |
| 217 | + Method selected = select(matches, args); |
| 218 | + if (selected == null) throw new NoSuchMethodException(method); |
| 219 | + |
| 220 | + Object coercedArgs[] = coerce(selected, args); |
| 221 | + setResult(result, selected.invoke(object, coercedArgs)); |
140 | 222 |
|
141 | 223 | } catch (Exception e) {
|
142 | 224 | setException(result, e);
|
@@ -180,7 +262,7 @@ public static void CreateObject(String name, Object args[], long result) {
|
180 | 262 | }
|
181 | 263 |
|
182 | 264 | // try a second time with the object itself, if it is of type Class
|
183 |
| - if (!(jclass instanceof Class) || (jclass==object)) break; |
| 265 | + if (!(object instanceof Class) || (jclass==object)) break; |
184 | 266 | }
|
185 | 267 |
|
186 | 268 | } catch (Exception e) {
|
|
0 commit comments