001
014
015 package com.liferay.portal.spring.aop;
016
017 import com.liferay.portal.kernel.annotation.AnnotationLocator;
018
019 import java.lang.annotation.Annotation;
020 import java.lang.reflect.Method;
021
022 import java.util.HashMap;
023 import java.util.HashSet;
024 import java.util.Iterator;
025 import java.util.List;
026 import java.util.Map;
027 import java.util.Set;
028
029 import org.aopalliance.intercept.MethodInvocation;
030
031
035 public abstract class AnnotationChainableMethodAdvice<T extends Annotation>
036 extends ChainableMethodAdvice {
037
038 public static void registerAnnotationClass(
039 Class<? extends Annotation> annotationClass) {
040
041 _annotationChainableMethodAdvices.put(annotationClass, null);
042 }
043
044 public AnnotationChainableMethodAdvice() {
045 _nullAnnotation = getNullAnnotation();
046
047 _annotationClass = _nullAnnotation.annotationType();
048 }
049
050 public void afterPropertiesSet() {
051 _annotationChainableMethodAdvices.put(_annotationClass, this);
052 }
053
054 public Class<? extends Annotation> getAnnotationClass() {
055 return _annotationClass;
056 }
057
058 public abstract T getNullAnnotation();
059
060 protected T findAnnotation(MethodInvocation methodInvocation) {
061 Annotation annotation = ServiceMethodAnnotationCache.get(
062 methodInvocation, _annotationClass, _nullAnnotation);
063
064 if (annotation != null) {
065 return (T)annotation;
066 }
067
068 Object thisObject = methodInvocation.getThis();
069
070 Class<?> targetClass = thisObject.getClass();
071
072 Method method = methodInvocation.getMethod();
073
074 List<Annotation> annotations = AnnotationLocator.locate(
075 method, targetClass);
076
077 Iterator<Annotation> iterator = annotations.iterator();
078
079 while (iterator.hasNext()) {
080 Annotation curAnnotation = iterator.next();
081
082 if (!_annotationChainableMethodAdvices.containsKey(
083 curAnnotation.annotationType())) {
084
085 iterator.remove();
086 }
087 }
088
089 ServiceMethodAnnotationCache.put(
090 methodInvocation,
091 annotations.toArray(new Annotation[annotations.size()]));
092
093 Set<Class<? extends Annotation>> annotationClasses =
094 new HashSet<Class<? extends Annotation>>();
095
096 annotation = _nullAnnotation;
097
098 for (Annotation curAnnotation : annotations) {
099 Class<? extends Annotation> annotationClass =
100 curAnnotation.annotationType();
101
102 if (annotationClass == _annotationClass) {
103 annotation = curAnnotation;
104 }
105
106 annotationClasses.add(annotationClass);
107 }
108
109 for (Map.Entry<Class<? extends Annotation>,
110 AnnotationChainableMethodAdvice<?>> entry :
111 _annotationChainableMethodAdvices.entrySet()) {
112
113 Class<? extends Annotation> annotationClass = entry.getKey();
114 AnnotationChainableMethodAdvice<?> annotationChainableMethodAdvice =
115 entry.getValue();
116
117 if (!annotationClasses.contains(annotationClass) &&
118 (annotationChainableMethodAdvice != null)) {
119
120 ServiceBeanAopProxy.removeMethodInterceptor(
121 methodInvocation, annotationChainableMethodAdvice);
122 }
123 }
124
125 return (T)annotation;
126 }
127
128 private static Map<Class<? extends Annotation>,
129 AnnotationChainableMethodAdvice<?>> _annotationChainableMethodAdvices =
130 new HashMap<Class<? extends Annotation>,
131 AnnotationChainableMethodAdvice<?>>();
132
133 private Class<? extends Annotation> _annotationClass;
134 private T _nullAnnotation;
135
136 }