1 23 24 package com.sun.ejb.containers.util; 25 26 import java.util.Map ; 27 import java.util.HashMap ; 28 import java.util.Set ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 import java.lang.reflect.Method ; 32 33 51 public final class MethodMap extends HashMap { 52 53 private static final int DEFAULT_BUCKET_MULTIPLIER = 20; 56 57 private int numBuckets_; 58 59 private MethodInfo[] methodInfo_; 68 69 public MethodMap(Map methodMap) { 70 super(methodMap); 71 72 numBuckets_ = methodMap.size() * DEFAULT_BUCKET_MULTIPLIER; 73 74 buildLookupTable(methodMap); 75 } 76 77 public MethodMap(Map methodMap, int numBuckets) { 78 super(methodMap); 79 80 if( numBuckets <= 0 ) { 81 throw new IllegalArgumentException 82 ("Invalid value of numBuckets = " + numBuckets); 83 } 84 85 numBuckets_ = numBuckets; 86 buildLookupTable(methodMap); 87 } 88 89 public Object put(Object key, Object value) { 90 throw new UnsupportedOperationException (); 91 } 92 public void putAll(Map t) { 93 throw new UnsupportedOperationException (); 94 } 95 public Object remove(Object key) { 96 throw new UnsupportedOperationException (); 97 } 98 99 public Object get(Object key) { 100 101 if( key instanceof Method ) { 102 Method m = (Method ) key; 103 Class [] paramTypes = m.getParameterTypes(); 104 return get(m, paramTypes.length); 105 } 106 107 return null; 108 } 109 110 public Object get(Method m, int numParams) { 111 112 if( methodInfo_ == null ) { 113 return null; 114 } else if( numParams < 0 ) { 115 throw new IllegalStateException 116 ("invalid numParams = " + numParams); 117 } 118 119 Object value = null; 120 121 MethodInfo methodInfo = methodInfo_[getBucket(m, numParams)]; 122 123 if( methodInfo != null) { 124 if(methodInfo.declaringClass == m.getDeclaringClass()) { 126 value = methodInfo.value; 127 } 128 } 129 130 return (value != null) ? value : super.get(m); 131 132 } 133 134 public void clear() { 135 136 if( methodInfo_ != null ) { 137 methodInfo_ = null; 138 super.clear(); 139 } 140 141 } 142 143 private void buildLookupTable(Map methodMap) { 144 145 methodInfo_ = new MethodInfo[numBuckets_]; 146 147 Set methods = methodMap.keySet(); 148 Set occupied = new HashSet (); 149 150 for(Iterator iter = methods.iterator(); iter.hasNext();) { 151 Object nextObj = iter.next(); 152 Method next = null; 153 154 if( nextObj == null ) { 155 throw new IllegalStateException ("null keys not supported"); 156 } else if( nextObj instanceof Method ) { 157 next = (Method ) nextObj; 158 } else { 159 throw new IllegalStateException 160 ("invalid key type = " + nextObj.getClass() + 161 " key must be of type java.lang.reflect.Method"); 162 } 163 164 int bucket = getBucket(next); 165 166 if( !occupied.contains(new Integer (bucket)) ) { 167 168 MethodInfo methodInfo = new MethodInfo(); 169 methodInfo.key = next; 170 methodInfo.value = methodMap.get(next); 171 172 methodInfo.declaringClass = next.getDeclaringClass(); 175 176 methodInfo_[bucket] = methodInfo; 177 178 occupied.add(new Integer (bucket)); 179 180 } else { 181 methodInfo_[bucket] = null; 184 } 185 } 186 } 187 188 private final int getBucket(Method m) { 189 190 Class [] paramTypes = m.getParameterTypes(); 193 194 return getBucket(m, paramTypes.length); 195 } 196 197 private final int getBucket(Method m, int numParams) { 198 199 String methodName = m.getName(); 200 201 220 int hashCode = methodName.hashCode(); 221 222 hashCode = (hashCode >= 0) ? hashCode : (hashCode * -1); 224 hashCode = (hashCode > numParams) ? 225 (hashCode - numParams) : (hashCode + numParams); 226 return (hashCode % numBuckets_); 227 } 228 229 230 private class MethodInfo { 231 public Class declaringClass; 232 public Method key; 233 public Object value; 234 } 235 } 236 | Popular Tags |