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