package be.ac.vub.objectAnnotations.contextCapturing; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import be.ac.vub.objectAnnotations.AnnotationManager; import be.ac.vub.objectAnnotations.ObjectAnnotation; public aspect ContextCapturingMethodArgsAspect { pointcut methodContext(Object receiver) : !cflow(adviceexecution()) && execution(* *.*(..)) && target(receiver); // pointcut excludeOA : !execution(be.ac.vub.objectAnnotations.contextCapturing.*.*(..)); before(Object receiver) : methodContext(receiver) && !execution(* be.ac.vub.objectAnnotations.contextCapturing.*.*(..)){ try { Object[] argValues = thisJoinPoint.getArgs(); Class[] argTypes = new Class[argValues.length]; if(argValues.length == 0) return; // shortcut for (int i = 0; i < argValues.length; i++) { Object object = argValues[i]; argTypes[i] = object.getClass(); } // check that method is annotated w/ object annotation Class declaringClass = thisJoinPointStaticPart.getSignature() .getDeclaringType(); String methodName = thisJoinPointStaticPart.getSignature() .getName(); Method calledMethod = null; //aspectJ, why don't you give me this? -- I know you know this. // Method[] methods = declaringClass.getDeclaredMethods(); Method[] methods = declaringClass.getMethods(); for (int i = 0; i < methods.length && calledMethod == null; i++) { Method method = methods[i]; Class[] methodArgTypes = method.getParameterTypes(); if (methodArgTypes.length == argTypes.length) { boolean typeMatch = true; for (int j = 0; j < methodArgTypes.length && typeMatch; j++) { Class clazz = methodArgTypes[j]; typeMatch &= clazz.isAssignableFrom(argTypes[j]); } if(typeMatch){ calledMethod = method; } } } if(calledMethod == null){ //The method we are checking is not on the declaredType (WTF?) throw new RuntimeException("Method "+ thisJoinPointStaticPart.getSignature().toShortString()+" is not found in "+declaringClass); } //Now I can look for the annotated args Annotation[][] paramAnns = calledMethod.getParameterAnnotations(); List objectAnnotatedParameterValues = new ArrayList(); Map>> annotationsOnParam = new HashMap>>(); for (int i = 0; i < paramAnns.length; i++) { Annotation[] annotations = paramAnns[i]; boolean paramHasAnnotation = false; for (int j = 0; j < annotations.length; j++) { Annotation annotation = annotations[j]; boolean annotationIsObjectAnn = annotation.annotationType().isAnnotationPresent(ObjectAnnotation.class); paramHasAnnotation |= annotationIsObjectAnn; if(annotationIsObjectAnn){ List> annsOnP = annotationsOnParam.get(argValues[i]); if(annsOnP == null){ annsOnP = new ArrayList>(); } annsOnP.add(annotation.annotationType()); annotationsOnParam.put(argValues[i], annsOnP); } } if(paramHasAnnotation){ objectAnnotatedParameterValues.add(argValues[i]); } } // Construct context MethodContext context = new MethodContext(); // Need to get the names of the arguments from somewhere! (arg names // are not kept on byte code) // for now, call them argN for (int i = 0; i < argValues.length; i++) { Object object = argValues[i]; context.addProperty("arg" + i, object); } context.addProperty("receiver",receiver); for (Object objectAnnotated : objectAnnotatedParameterValues) { List> list = annotationsOnParam.get(objectAnnotated); for (Class annType : list) { AnnotationManager.setContext(objectAnnotated, context, annType); } } } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }