1 22 package org.jboss.aop; 23 24 import gnu.trove.TLongObjectHashMap; 25 26 import java.lang.reflect.Constructor ; 27 import java.lang.reflect.Field ; 28 import java.lang.reflect.Method ; 29 import java.security.AccessController ; 30 import java.security.PrivilegedAction ; 31 import java.security.PrivilegedActionException ; 32 import java.security.PrivilegedExceptionAction ; 33 import java.util.ArrayList ; 34 import java.util.Arrays ; 35 import java.util.HashMap ; 36 import java.util.HashSet ; 37 import java.util.Iterator ; 38 import java.util.Map ; 39 import org.jboss.aop.advice.AdviceBinding; 40 import org.jboss.aop.introduction.AnnotationIntroduction; 41 import org.jboss.aop.pointcut.AnnotationMatcher; 42 import org.jboss.aop.pointcut.PointcutMethodMatch; 43 import org.jboss.aop.proxy.container.InstanceProxyContainer; 44 import org.jboss.aop.util.Advisable; 45 import org.jboss.util.MethodHashing; 46 47 52 public class ReflectiveAspectBinder 53 { 54 protected Class clazz; 55 protected HashSet aspects = new HashSet (); 56 protected HashMap methodAdvices = new HashMap(); 57 protected HashMap constructorAdvices = new HashMap(); 58 protected HashMap fieldReadAdvices = new HashMap(); 59 protected HashMap fieldWriteAdvices = new HashMap(); 60 protected Advisor advisor; 61 protected boolean isInstanceContainer; 62 TLongObjectHashMap methodMap = new TLongObjectHashMap(); 63 64 65 public ReflectiveAspectBinder(Class clazz, Advisor advisor) 66 { 67 this.clazz = clazz; 68 this.advisor = advisor; 69 isInstanceContainer = InstanceProxyContainer.class == advisor.getClass(); 70 bindMethodAdvices(clazz); 71 bindConstructorAdvices(); 72 bindFieldAdvices(); 73 } 74 75 public Class getClazz() 76 { 77 return clazz; 78 } 79 80 public HashSet getAspects() 81 { 82 return aspects; 83 } 84 85 public HashMap getMethodAdvices() 86 { 87 return methodAdvices; 88 } 89 90 public HashMap getConstructorAdvices() 91 { 92 return constructorAdvices; 93 } 94 95 public HashMap getFieldReadAdvices() 96 { 97 return fieldReadAdvices; 98 } 99 100 public HashMap getFieldWriteAdvices() 101 { 102 return fieldWriteAdvices; 103 } 104 105 public void createMethodMap(final Class superClass) 106 { 107 try 108 { 109 if (superClass == null || (superClass == Object .class && !isInstanceContainer)) 110 { 111 return; 112 } 113 createMethodMap(superClass.getSuperclass()); 114 115 Method [] methods = (Method []) AccessController.doPrivileged(new PrivilegedExceptionAction () 116 { 117 public Object run() throws Exception 118 { 119 return superClass.getDeclaredMethods(); 120 } 121 }); 122 for (int i = 0 ; i < methods.length ; i++) 123 { 124 if (!Advisable.isAdvisable(methods[i])) 125 { 126 continue; 127 } 128 129 long hash = MethodHashing.methodHash(methods[i]); 130 methodMap.put(hash, methods[i]); 131 } 132 } 133 catch (PrivilegedActionException e) 134 { 135 throw new RuntimeException (e.getException()); 136 } 137 catch (Exception e) 138 { 139 throw new RuntimeException (e); 140 } 141 } 142 143 protected void bindMethodAdvices(Class superClass) 144 { 145 createMethodMap(superClass); 146 if (methodMap != null) 147 { 148 Object [] methods = methodMap.getValues(); 149 for (int i = 0 ; i < methods.length ; i++) 150 { 151 bindMethodAdvice((Method )methods[i]); 152 } 153 } 154 } 155 156 protected void bindConstructorAdvices() 157 { 158 Constructor [] cons = (Constructor []) AccessController.doPrivileged(new PrivilegedAction () 159 { 160 public Object run() 161 { 162 return clazz.getDeclaredConstructors(); 163 } 164 }); 165 for (int i = 0; i < cons.length; i++) 166 { 167 bindConstructorAdvice(cons[i]); 168 } 169 } 170 171 protected void bindFieldAdvices() 172 { 173 Field [] fields = (Field []) AccessController.doPrivileged(new PrivilegedAction () 174 { 175 public Object run() 176 { 177 return clazz.getDeclaredFields(); 178 } 179 }); 180 for (int i = 0; i < fields.length; i++) 181 { 182 bindFieldGetAdvice(fields[i]); 183 bindFieldSetAdvice(fields[i]); 184 } 185 } 186 187 protected boolean matches(AnnotationIntroduction ai, Object element) 188 { 189 AnnotationMatcher matcher = new AnnotationMatcher(advisor, element); 190 return ((Boolean ) ai.getTarget().jjtAccept(matcher, null)).booleanValue(); 191 } 192 193 protected void bindMethodAdvice(Method mi) 194 { 195 Map repositoryBindings = advisor.getManager().getBindings(); 196 Iterator it = repositoryBindings.values().iterator(); 197 ArrayList advices = (ArrayList )methodAdvices.get(mi); 198 while (it.hasNext()) 199 { 200 201 AdviceBinding binding = (AdviceBinding)it.next(); 202 PointcutMethodMatch pmatch= binding.getPointcut().matchesExecution(advisor, mi); 203 204 if (pmatch != null && pmatch.isMatch()) 205 { 206 if (advices == null) 207 { 208 advices = new ArrayList (); 209 methodAdvices.put(mi, advices); 210 } 211 advices.addAll(Arrays.asList(binding.getInterceptorFactories())); 212 for (int i = 0; i < binding.getInterceptorFactories().length; i++) 213 { 214 aspects.add(binding.getInterceptorFactories()[i].getAspect()); 215 } 216 } 217 } 218 } 219 220 protected void bindConstructorAdvice(Constructor mi) 221 { 222 Map repositoryBindings = advisor.getManager().getBindings(); 223 Iterator it = repositoryBindings.values().iterator(); 224 ArrayList advices = (ArrayList )constructorAdvices.get(mi); 225 while (it.hasNext()) 226 { 227 228 AdviceBinding binding = (AdviceBinding)it.next(); 229 if (binding.getPointcut().matchesExecution(advisor, mi)) 230 { 231 if (advices == null) 232 { 233 advices = new ArrayList (); 234 constructorAdvices.put(mi, advices); 235 } 236 advices.addAll(Arrays.asList(binding.getInterceptorFactories())); 237 for (int i = 0; i < binding.getInterceptorFactories().length; i++) 238 { 239 aspects.add(binding.getInterceptorFactories()[i].getAspect()); 240 } 241 } 242 } 243 } 244 245 protected void bindFieldGetAdvice(Field mi) 246 { 247 Map repositoryBindings = advisor.getManager().getBindings(); 248 Iterator it = repositoryBindings.values().iterator(); 249 ArrayList advices = (ArrayList )fieldReadAdvices.get(mi); 250 while (it.hasNext()) 251 { 252 253 AdviceBinding binding = (AdviceBinding)it.next(); 254 if (binding.getPointcut().matchesGet(advisor, mi)) 255 { 256 if (advices == null) 257 { 258 advices = new ArrayList (); 259 fieldReadAdvices.put(mi, advices); 260 } 261 advices.addAll(Arrays.asList(binding.getInterceptorFactories())); 262 for (int i = 0; i < binding.getInterceptorFactories().length; i++) 263 { 264 aspects.add(binding.getInterceptorFactories()[i].getAspect()); 265 } 266 } 267 } 268 } 269 270 protected void bindFieldSetAdvice(Field mi) 271 { 272 Map repositoryBindings = advisor.getManager().getBindings(); 273 Iterator it = repositoryBindings.values().iterator(); 274 ArrayList advices = (ArrayList )fieldWriteAdvices.get(mi); 275 while (it.hasNext()) 276 { 277 278 AdviceBinding binding = (AdviceBinding)it.next(); 279 if (binding.getPointcut().matchesSet(advisor, mi)) 280 { 281 if (advices == null) 282 { 283 advices = new ArrayList (); 284 fieldWriteAdvices.put(mi, advices); 285 } 286 advices.addAll(Arrays.asList(binding.getInterceptorFactories())); 287 for (int i = 0; i < binding.getInterceptorFactories().length; i++) 288 { 289 aspects.add(binding.getInterceptorFactories()[i].getAspect()); 290 } 291 } 292 } 293 } 294 } 295 | Popular Tags |