| 
68
 | 
     1 package fschmidt.util.java;
 | 
| 
 | 
     2 
 | 
| 
 | 
     3 import java.lang.reflect.Method;
 | 
| 
 | 
     4 import java.util.Arrays;
 | 
| 
 | 
     5 import java.util.HashMap;
 | 
| 
 | 
     6 import java.util.Map;
 | 
| 
 | 
     7 import java.util.WeakHashMap;
 | 
| 
 | 
     8 
 | 
| 
 | 
     9 
 | 
| 
 | 
    10 public final class ClassUtils {
 | 
| 
 | 
    11 
 | 
| 
 | 
    12 	private ClassUtils() {}  // never
 | 
| 
 | 
    13 
 | 
| 
 | 
    14 	private static final class Key {
 | 
| 
 | 
    15 		private final String name;
 | 
| 
 | 
    16 		private final Class[] parameterTypes;
 | 
| 
 | 
    17 
 | 
| 
 | 
    18 		private Key(Method m) {
 | 
| 
 | 
    19 			this(m.getName(),m.getParameterTypes());
 | 
| 
 | 
    20 		}
 | 
| 
 | 
    21 
 | 
| 
 | 
    22 		private Key(String name,Class[] parameterTypes) {
 | 
| 
 | 
    23 			this.name = name;
 | 
| 
 | 
    24 			this.parameterTypes = parameterTypes;
 | 
| 
 | 
    25 		}
 | 
| 
 | 
    26 
 | 
| 
 | 
    27 		public boolean equals(Object obj) {
 | 
| 
 | 
    28 			if( !(obj instanceof Key) )
 | 
| 
 | 
    29 				return false;
 | 
| 
 | 
    30 			Key key = (Key)obj;
 | 
| 
 | 
    31 			return key.name.equals(name) && Arrays.equals(key.parameterTypes,parameterTypes);
 | 
| 
 | 
    32 		}
 | 
| 
 | 
    33 
 | 
| 
 | 
    34 		public int hashCode() {
 | 
| 
 | 
    35 			return name.hashCode()+31*Arrays.hashCode(parameterTypes);
 | 
| 
 | 
    36 		}
 | 
| 
 | 
    37 	}
 | 
| 
 | 
    38 
 | 
| 
 | 
    39 	private static final Map<Class,FutureValue<Map<Key,Method>>> cache = new WeakHashMap<Class,FutureValue<Map<Key,Method>>>();
 | 
| 
 | 
    40 
 | 
| 
 | 
    41 	// return null if not found
 | 
| 
 | 
    42 	public static Method getMethod(final Class cls,String name,Class... parameterTypes) {
 | 
| 
 | 
    43 		FutureValue<Map<Key,Method>> ft;
 | 
| 
 | 
    44 		synchronized(cache) {
 | 
| 
 | 
    45 			ft = cache.get(cls);
 | 
| 
 | 
    46 			if( ft==null ) {
 | 
| 
 | 
    47 				ft = new FutureValue<Map<Key,Method>>() {
 | 
| 
 | 
    48 					protected Map<Key,Method> compute() {
 | 
| 
 | 
    49 						Map<Key,Method> map = new HashMap<Key,Method>();
 | 
| 
 | 
    50 						for( Method m : cls.getMethods() ) {
 | 
| 
 | 
    51 							Method m2 = map.put(new Key(m),m);
 | 
| 
 | 
    52 							if( m2 != null )
 | 
| 
 | 
    53 								throw new RuntimeException("duplicate methods "+m+" and "+m2);
 | 
| 
 | 
    54 						}
 | 
| 
 | 
    55 						return map;
 | 
| 
 | 
    56 					}
 | 
| 
 | 
    57 				};
 | 
| 
 | 
    58 				cache.put(cls,ft);
 | 
| 
 | 
    59 			}
 | 
| 
 | 
    60 		}
 | 
| 
 | 
    61 		Key key = new Key(name,parameterTypes);
 | 
| 
 | 
    62 		return ft.get().get(key);
 | 
| 
 | 
    63 	}
 | 
| 
 | 
    64 
 | 
| 
 | 
    65 }
 |