001package org.javasimon.spring; 002 003import java.lang.reflect.Method; 004 005import org.javasimon.aop.Monitored; 006 007import org.springframework.aop.ClassFilter; 008import org.springframework.aop.MethodMatcher; 009import org.springframework.aop.Pointcut; 010import org.springframework.aop.support.AopUtils; 011import org.springframework.core.annotation.AnnotationUtils; 012import org.springframework.util.ClassUtils; 013 014/** 015 * Pointcut that identifies methods/classes with the {@link Monitored} annotation. 016 * 017 * @author Erik van Oosten 018 * @author <a href="mailto:virgo47@gmail.com">Richard "Virgo" Richter</a> 019 */ 020public final class MonitoredMeasuringPointcut implements Pointcut { 021 /** 022 * Returns a class filter that lets all class through. 023 * 024 * @return a class filter that lets all class through 025 */ 026 @Override 027 public ClassFilter getClassFilter() { 028 return ClassFilter.TRUE; 029 } 030 031 /** 032 * Returns a method matcher that matches any method that has the {@link Monitored} annotation, 033 * or is in a class with the {@link Monitored} annotation or is in a subclass of such a class or interface. 034 * 035 * @return method matcher matching {@link Monitored} methods 036 */ 037 @Override 038 public MethodMatcher getMethodMatcher() { 039 return MonitoredMethodMatcher.INSTANCE; 040 } 041 042 private enum MonitoredMethodMatcher implements MethodMatcher { 043 INSTANCE; 044 045 @Override 046 public boolean matches(Method method, Class targetClass) { 047 return !ClassUtils.isCglibProxyClass(targetClass) && isMonitoredAnnotationOnClassOrMethod(method, targetClass); 048 } 049 050 private boolean isMonitoredAnnotationOnClassOrMethod(Method method, Class targetClass) { 051 return AnnotationUtils.findAnnotation(targetClass, Monitored.class) != null 052 || AnnotationUtils.findAnnotation(AopUtils.getMostSpecificMethod(method, targetClass), Monitored.class) != null; 053 } 054 055 @Override 056 public boolean isRuntime() { 057 return false; 058 } 059 060 @Override 061 public boolean matches(Method method, Class targetClass, Object[] args) { 062 throw new UnsupportedOperationException("This is not a runtime method matcher"); 063 } 064 } 065}