001
014
015 package com.liferay.portal.spring.aop;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018
019 import java.lang.annotation.Annotation;
020
021 import java.util.ArrayList;
022 import java.util.HashMap;
023 import java.util.Map;
024 import java.util.concurrent.ConcurrentHashMap;
025
026 import org.aopalliance.intercept.MethodInterceptor;
027 import org.aopalliance.intercept.MethodInvocation;
028
029
032 public class ServiceBeanAopCacheManager {
033
034 public static <T> T getAnnotation(
035 MethodInvocation methodInvocation,
036 Class<? extends Annotation> annotationType, T defaultValue) {
037
038 Annotation[] annotations = _annotations.get(methodInvocation);
039
040 if (annotations == _nullAnnotations) {
041 return defaultValue;
042 }
043
044 if (annotations == null) {
045 return null;
046 }
047
048 for (Annotation annotation : annotations) {
049 if (annotation.annotationType() == annotationType) {
050 return (T)annotation;
051 }
052 }
053
054 return defaultValue;
055 }
056
057 public static void putAnnotations(
058 MethodInvocation methodInvocation, Annotation[] annotations) {
059
060 if (ArrayUtil.isEmpty(annotations)) {
061 annotations = _nullAnnotations;
062 }
063
064 if (methodInvocation instanceof ServiceBeanMethodInvocation) {
065 ServiceBeanMethodInvocation serviceBeanMethodInvocation =
066 (ServiceBeanMethodInvocation)methodInvocation;
067
068 methodInvocation = serviceBeanMethodInvocation.toCacheKeyModel();
069 }
070
071 _annotations.put(methodInvocation, annotations);
072 }
073
074 public MethodInterceptorsBag getMethodInterceptorsBag(
075 MethodInvocation methodInvocation) {
076
077 return _methodInterceptorBags.get(methodInvocation);
078 }
079
080 public Map
081 <Class<? extends Annotation>, AnnotationChainableMethodAdvice<?>[]>
082 getRegisteredAnnotationChainableMethodAdvices() {
083
084 return _annotationChainableMethodAdvices;
085 }
086
087 public boolean isRegisteredAnnotationClass(
088 Class<? extends Annotation> annotationClass) {
089
090 return _annotationChainableMethodAdvices.containsKey(annotationClass);
091 }
092
093 public void putMethodInterceptorsBag(
094 MethodInvocation methodInvocation,
095 MethodInterceptorsBag methodInterceptorsBag) {
096
097 _methodInterceptorBags.put(methodInvocation, methodInterceptorsBag);
098 }
099
100 public void registerAnnotationChainableMethodAdvice(
101 Class<? extends Annotation> annotationClass,
102 AnnotationChainableMethodAdvice<?> annotationChainableMethodAdvice) {
103
104 AnnotationChainableMethodAdvice<?>[] annotationChainableMethodAdvices =
105 _annotationChainableMethodAdvices.get(annotationClass);
106
107 if (annotationChainableMethodAdvices == null) {
108 annotationChainableMethodAdvices =
109 new AnnotationChainableMethodAdvice<?>[1];
110
111 annotationChainableMethodAdvices[0] =
112 annotationChainableMethodAdvice;
113 }
114 else {
115 annotationChainableMethodAdvices = ArrayUtil.append(
116 annotationChainableMethodAdvices,
117 annotationChainableMethodAdvice);
118 }
119
120 _annotationChainableMethodAdvices.put(
121 annotationClass, annotationChainableMethodAdvices);
122 }
123
124 public void removeMethodInterceptor(
125 MethodInvocation methodInvocation,
126 MethodInterceptor methodInterceptor) {
127
128 if (!(methodInvocation instanceof ServiceBeanMethodInvocation)) {
129 return;
130 }
131
132 ServiceBeanMethodInvocation serviceBeanMethodInvocation =
133 (ServiceBeanMethodInvocation)methodInvocation;
134
135 MethodInterceptorsBag methodInterceptorsBag =
136 _methodInterceptorBags.get(serviceBeanMethodInvocation);
137
138 if (methodInterceptorsBag == null) {
139 return;
140 }
141
142 ArrayList<MethodInterceptor> methodInterceptors = new ArrayList<>(
143 methodInterceptorsBag.getMergedMethodInterceptors());
144
145 methodInterceptors.remove(methodInterceptor);
146
147 MethodInterceptorsBag newMethodInterceptorsBag = null;
148
149 if (methodInterceptors.equals(
150 methodInterceptorsBag.getClassLevelMethodInterceptors())) {
151
152 newMethodInterceptorsBag = new MethodInterceptorsBag(
153 methodInterceptorsBag.getClassLevelMethodInterceptors(),
154 methodInterceptorsBag.getClassLevelMethodInterceptors());
155 }
156 else {
157 methodInterceptors.trimToSize();
158
159 newMethodInterceptorsBag = new MethodInterceptorsBag(
160 methodInterceptorsBag.getClassLevelMethodInterceptors(),
161 methodInterceptors);
162 }
163
164 _methodInterceptorBags.put(
165 serviceBeanMethodInvocation.toCacheKeyModel(),
166 newMethodInterceptorsBag);
167 }
168
169 public void reset() {
170 _annotations.clear();
171 _methodInterceptorBags.clear();
172 }
173
174 private static final Map<MethodInvocation, Annotation[]> _annotations =
175 new ConcurrentHashMap<>();
176 private static final Annotation[] _nullAnnotations = new Annotation[0];
177
178 private
179 Map<Class<? extends Annotation>, AnnotationChainableMethodAdvice<?>[]>
180 _annotationChainableMethodAdvices = new HashMap
181 <Class<? extends Annotation>,
182 AnnotationChainableMethodAdvice<?>[]>();
183 private final Map<MethodInvocation, MethodInterceptorsBag>
184 _methodInterceptorBags = new ConcurrentHashMap<>();
185
186 }