001
014
015 package com.liferay.portal.spring.aop;
016
017 import com.liferay.portal.kernel.util.MethodTargetClassKey;
018
019 import java.lang.annotation.Annotation;
020 import java.lang.reflect.Method;
021
022 import java.util.Map;
023 import java.util.concurrent.ConcurrentHashMap;
024
025 import org.aopalliance.intercept.MethodInvocation;
026
027
031 public abstract class AnnotationChainableMethodAdvice<T extends Annotation>
032 extends ChainableMethodAdvice {
033
034 public AnnotationChainableMethodAdvice() {
035 _nullAnnotation = getNullAnnotation();
036 _annotationType = _nullAnnotation.annotationType();
037 }
038
039 public abstract T getNullAnnotation();
040
041 protected MethodTargetClassKey buildMethodTargetClassKey(
042 MethodInvocation methodInvocation) {
043
044 Method method = methodInvocation.getMethod();
045
046 Class<?> targetClass = null;
047
048 Object thisObject = methodInvocation.getThis();
049
050 if (thisObject != null) {
051 targetClass = thisObject.getClass();
052 }
053
054 return new MethodTargetClassKey(method, targetClass);
055 }
056
057 protected T findAnnotation(MethodTargetClassKey methodTargetClassKey){
058 Annotation[] annotations = _annotations.get(methodTargetClassKey);
059
060 if (annotations != null) {
061 return getAnnotation(annotations);
062 }
063
064 Method method = methodTargetClassKey.getMethod();
065
066 Method targetMethod = methodTargetClassKey.getTargetMethod();
067
068 if (targetMethod != null) {
069 annotations = targetMethod.getAnnotations();
070 }
071
072 if ((annotations == null) || (annotations.length == 0)) {
073 annotations = method.getAnnotations();
074 }
075
076 if ((annotations == null) || (annotations.length == 0)) {
077 annotations = _emptyAnnotations;
078 }
079
080 _annotations.put(methodTargetClassKey, annotations);
081
082 return getAnnotation(annotations);
083 }
084
085 protected T getAnnotation(Annotation[] annotations) {
086 for(Annotation annotation : annotations) {
087 if (annotation.annotationType() == _annotationType) {
088 return (T)annotation;
089 }
090 }
091
092 return _nullAnnotation;
093 }
094
095 private static Map<MethodTargetClassKey, Annotation[]> _annotations =
096 new ConcurrentHashMap<MethodTargetClassKey, Annotation[]>();
097 private static Annotation[] _emptyAnnotations = new Annotation[0];
098
099 private Class<? extends Annotation> _annotationType;
100 private T _nullAnnotation;
101
102 }