1 57 58 package org.apache.soap.util; 59 60 import java.util.*; 61 import java.io.*; 62 import java.beans.*; 63 import java.lang.reflect.*; 64 65 72 public class MethodUtils { 73 74 76 98 static private Object getEntryPoint(Class targetClass, 99 String methodName, 100 Class [] argTypes, 101 boolean isStaticReference) 102 throws SecurityException , NoSuchMethodException 103 { 104 Object m=null; 106 107 110 try { 112 if(methodName!=null) 113 { 114 m=targetClass.getMethod (methodName, argTypes); 115 if(isStaticReference && 116 !Modifier.isStatic(entryGetModifiers(m)) ) 117 { 118 throw 119 new NoSuchMethodException (callToString (targetClass, 120 methodName, 121 argTypes, 122 isStaticReference)+ 123 " resolved to instance " + m); 124 } 125 return m; 126 } 127 else 128 return targetClass.getConstructor (argTypes); 129 130 } catch (NoSuchMethodException e) { 131 if(argTypes==null || argTypes.length==0) 133 { 134 throw 135 new NoSuchMethodException (callToString (targetClass, 136 methodName, 137 argTypes, 138 isStaticReference)+ 139 " not found."); 140 } 141 } 143 144 147 Object [] methods; 150 if(methodName!=null) 151 { 152 methods=targetClass.getMethods(); 153 } 154 else 155 { 156 methods=targetClass.getConstructors(); 157 } 158 if(0==methods.length) 159 { 160 throw new NoSuchMethodException ("No methods!"); 161 } 162 163 MoreSpecific best=new MoreSpecific(); 164 for(int i=0;i<methods.length;++i) 165 { 166 Object mi=methods[i]; 167 if ( 168 Modifier.isPublic(entryGetModifiers(mi)) 170 && 171 (methodName==null || entryGetName(mi).equals(methodName) ) 173 && 174 areMethodConvertable(entryGetParameterTypes(mi),argTypes) 176 ) 177 best.addItem(mi); 179 } 180 181 m=best.getMostSpecific(targetClass,methodName,argTypes,isStaticReference); 184 185 if(m==null) 193 { 194 throw new NoSuchMethodException (callToString(targetClass, 195 methodName, 196 argTypes, 197 isStaticReference)+ 198 " -- no signature match"); 199 } 200 201 if( methodName!=null && 202 isStaticReference && 203 !Modifier.isStatic(entryGetModifiers(m)) ) 204 { 205 throw new NoSuchMethodException (callToString(targetClass, 206 methodName, 207 argTypes, 208 isStaticReference)+ 209 " resolved to instance: "+m); 210 } 211 212 return m; 213 } 214 215 216 219 private static String callToString(Class targetClass,String methodName, 220 Class [] argTypes,boolean isStaticReference) 221 { 222 StringBuffer buf = new StringBuffer (); 223 if(isStaticReference) 224 buf.append("static "); 225 buf.append(StringUtils.getClassName(targetClass)); 226 if(methodName!=null) 227 buf.append(".").append(methodName); 228 buf.append("("); 229 if (argTypes != null && argTypes.length>0) { 230 if(false) 231 { 232 } 235 else 236 { 237 buf.append(StringUtils.getClassName(argTypes[0])); 238 for (int i = 1; i < argTypes.length; i++) { 239 buf.append(",").append(StringUtils.getClassName(argTypes[i])); 240 } 241 } 242 } 243 else 244 buf.append("[none]"); 245 buf.append(")"); 246 return buf.toString(); 247 } 248 249 266 static private boolean isMethodConvertable(Class parm, Class arg) 267 { 268 if (parm.equals(arg)) return true; 270 271 if (arg == null) 273 { 274 return !parm.isPrimitive(); 275 } 276 277 while(parm.isArray()) 281 { 282 if(!arg.isArray()) 283 return false; else 285 { 286 parm=parm.getComponentType(); 287 arg=arg.getComponentType(); 288 } 289 } 290 if(arg.isArray()) 291 return false; 293 if(parm.isAssignableFrom(arg)) 302 return true; 303 304 309 if(parm.equals(Void.TYPE) || parm.equals(Boolean.TYPE) || 310 arg.equals(Void.TYPE) || arg.equals(Boolean.TYPE)) 311 return false; 312 313 Class [] primTypes={ Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, 314 Long.TYPE, Float.TYPE, Double.TYPE }; 315 int parmscore,argscore; 316 317 for(parmscore=0;parmscore<primTypes.length;++parmscore) 318 if (parm.equals(primTypes[parmscore])) 319 break; 320 if(parmscore>=primTypes.length) 321 return false; 323 for(argscore=0;argscore<primTypes.length;++argscore) 324 if (arg.equals(primTypes[argscore])) 325 break; 326 if(argscore>=primTypes.length) 327 return false; 329 return (argscore<parmscore && (argscore!=0 || parmscore>2) ); 331 } 332 333 334 344 static private boolean isAssignmentConvertable(Class parm,Class arg) 345 { 346 return 347 (arg.equals(Integer.TYPE) && 348 (parm.equals(Byte.TYPE) || 349 parm.equals(Short.TYPE) || 350 parm.equals(Character.TYPE) 351 ) 352 ) || 353 isMethodConvertable(parm,arg); 354 } 355 356 357 360 static private boolean areMethodConvertable(Class [] parms,Class [] args) 361 { 362 if(parms.length!=args.length) 363 return false; 364 365 for(int i=0;i<parms.length;++i) 366 if(!isMethodConvertable(parms[i],args[i])) 367 return false; 368 369 return true; 370 } 371 372 394 private static class MoreSpecific 395 extends Vector 396 { 397 403 void addItem (Object newEntry) 404 { 405 if(size()==0) 406 addElement(newEntry); 407 else 408 { 409 Class [] newargs=entryGetParameterTypes(newEntry); 410 boolean keep=true; 411 for (Enumeration e = elements(); 412 keep & e.hasMoreElements() ; 413 ) 414 { 415 Object oldEntry=e.nextElement(); 416 Class [] oldargs=entryGetParameterTypes(oldEntry); 418 if(areMethodConvertable(oldargs,newargs)) 419 removeElement(oldEntry); else if(areMethodConvertable(newargs,oldargs)) 421 keep=false; } 424 if(keep) 425 addElement(newEntry); 426 } 427 } 428 429 435 Object getMostSpecific(Class targetClass,String methodName, 436 Class [] argTypes,boolean isStaticReference) 437 throws NoSuchMethodException 438 { 439 if(size()==1) 440 return firstElement(); 441 if(size()>1) 442 { 443 StringBuffer buf=new StringBuffer (); 444 Enumeration e=elements(); 445 buf.append(e.nextElement()); 446 while(e.hasMoreElements()) 447 buf.append(" and ").append(e.nextElement()); 448 throw new NoSuchMethodException (callToString(targetClass, 449 methodName, 450 argTypes, 451 isStaticReference)+ 452 " is ambiguous. It matches "+ 453 buf.toString()); 454 } 455 return null; 456 } 457 } 458 459 468 470 static String entryGetName(Object entry) 471 { 472 return (entry instanceof Method) 473 ? ((Method)entry).getName() 474 : ((Constructor)entry).getName(); 475 } 476 478 static int entryGetModifiers(Object entry) 479 { 480 return (entry instanceof Method) 481 ? ((Method)entry).getModifiers() 482 : ((Constructor)entry).getModifiers(); 483 } 484 486 static Class [] entryGetParameterTypes(Object entry) 487 { 488 return (entry instanceof Method) 489 ? ((Method)entry).getParameterTypes() 490 : ((Constructor)entry).getParameterTypes(); 491 } 492 494 static String entryToString(Object entry) 495 { 496 return (entry instanceof Method) 497 ? ((Method)entry).toString() 498 : ((Constructor)entry).toString(); 499 } 500 501 503 523 static public Method getMethod(Object target,String methodName, 524 Class [] argTypes) 525 throws SecurityException , NoSuchMethodException 526 { 527 boolean staticRef=target instanceof Class ; 528 return getMethod( staticRef ? (Class )target : target.getClass(), 529 methodName,argTypes,staticRef); 530 } 531 532 534 544 static public Method getMethod(Class target,String methodName, 545 Class [] argTypes,boolean isStaticReference) 546 throws SecurityException , NoSuchMethodException 547 { 548 return (Method)getEntryPoint(target,methodName,argTypes,isStaticReference); 549 } 550 551 553 563 static public Constructor getConstructor(Class targetClass, Class [] argTypes) 564 throws SecurityException , NoSuchMethodException 565 { 566 return (Constructor) getEntryPoint(targetClass,null,argTypes,true); 567 } 568 } 569 | Popular Tags |