1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 package org.exoplatform.cs.statistics;
34
35 import java.lang.reflect.Method;
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.Map;
39 import java.util.TreeMap;
40 import org.aspectj.lang.JoinPoint;
41 import org.aspectj.lang.annotation.After;
42 import org.aspectj.lang.annotation.Aspect;
43 import org.aspectj.lang.annotation.Before;
44 import org.aspectj.lang.annotation.Pointcut;
45 import org.exoplatform.container.ExoContainer;
46 import org.exoplatform.container.ExoContainerContext;
47 import org.exoplatform.services.jcr.statistics.JCRStatisticsManager;
48 import org.exoplatform.services.jcr.statistics.Statistics;
49 import org.exoplatform.services.log.ExoLogger;
50 import org.exoplatform.services.log.Log;
51
52
53
54
55
56
57
58
59
60 @Aspect
61 public abstract class JCRAPIAspect
62 {
63
64
65
66
67 private static final Log LOG = ExoLogger.getLogger(JCRAPIAspect.class);
68
69
70
71
72 private static final Statistics UNKNOWN = new Statistics(null, "?");
73
74
75
76
77 private static volatile boolean INITIALIZED;
78
79
80
81
82 private static Class<?>[] TARGET_INTERFACES;
83
84
85
86
87 private static volatile Map<String, Statistics> MAPPING = Collections.unmodifiableMap(new HashMap<String, Statistics>());
88
89
90
91
92 private final static Map<String, Map<String, Statistics>> ALL_STATISTICS = new HashMap<String, Map<String, Statistics>>();
93
94
95
96
97 private static String getStatisticsName(Method m)
98 {
99 StringBuilder sb = new StringBuilder();
100 sb.append(m.getName());
101 sb.append('(');
102 Class<?>[] types = m.getParameterTypes();
103 if (types != null)
104 {
105 boolean first = true;
106 for (Class<?> type : types)
107 {
108 if (first)
109 {
110 first = false;
111 }
112 else
113 {
114 sb.append(", ");
115 }
116 sb.append(type.getSimpleName());
117 }
118 }
119 sb.append(')');
120 return sb.toString();
121 }
122
123
124
125
126
127
128
129 private static Statistics getStatistics(Class<?> target, String signature)
130 {
131 initIfNeeded();
132 Statistics statistics = MAPPING.get(signature);
133 if (statistics == null)
134 {
135 synchronized (JCRAPIAspect.class)
136 {
137 Class<?> interfaceClass = findInterface(target);
138 if (interfaceClass != null)
139 {
140 Map<String, Statistics> allStatistics = ALL_STATISTICS.get(interfaceClass.getSimpleName());
141 if (allStatistics != null)
142 {
143 int index1 = signature.indexOf('(');
144 int index = signature.substring(0, index1).lastIndexOf('.');
145 String name = signature.substring(index + 1);
146 statistics = allStatistics.get(name);
147 }
148 }
149 if (statistics == null)
150 {
151 statistics = UNKNOWN;
152 }
153 Map<String, Statistics> tempMapping = new HashMap<String, Statistics>(MAPPING);
154 tempMapping.put(signature, statistics);
155 MAPPING = Collections.unmodifiableMap(tempMapping);
156 }
157 }
158 if (UNKNOWN.equals(statistics))
159 {
160 return null;
161 }
162 return statistics;
163 }
164
165
166
167
168
169
170 private static Class<?> findInterface(Class<?> target)
171 {
172 if (target == null)
173 {
174 return null;
175 }
176 Class<?>[] interfaces = target.getInterfaces();
177 if (interfaces != null)
178 {
179 for (Class<?> c : TARGET_INTERFACES)
180 {
181 for (Class<?> i : interfaces)
182 {
183 if (c.getName().equals(i.getName()))
184 {
185 return c;
186 }
187 }
188 }
189 }
190 return findInterface(target.getSuperclass());
191 }
192
193
194
195
196 private static void initIfNeeded()
197 {
198 if (!INITIALIZED)
199 {
200 synchronized (JCRAPIAspect.class)
201 {
202 if (!INITIALIZED)
203 {
204 ExoContainer container = ExoContainerContext.getTopContainer();
205 JCRAPIAspectConfig config = null;
206 if (container != null)
207 {
208 config = (JCRAPIAspectConfig)container.getComponentInstanceOfType(JCRAPIAspectConfig.class);
209 }
210 if (config == null)
211 {
212 TARGET_INTERFACES = new Class<?>[]{};
213 LOG.warn("No interface to monitor could be found");
214 }
215 else
216 {
217 TARGET_INTERFACES = config.getTargetInterfaces();
218 for (Class<?> c : TARGET_INTERFACES)
219 {
220 Statistics global = new Statistics(null, "global");
221 Map<String, Statistics> statistics = new TreeMap<String, Statistics>();
222 Method[] methods = c.getMethods();
223 for (Method m : methods)
224 {
225 String name = getStatisticsName(m);
226 statistics.put(name, new Statistics(global, name));
227 }
228 JCRStatisticsManager.registerStatistics(c.getSimpleName(), global, statistics);
229 ALL_STATISTICS.put(c.getSimpleName(), statistics);
230 }
231 }
232 INITIALIZED = true;
233 }
234 }
235 }
236 }
237
238 @Pointcut
239 abstract void JCRAPIPointcut();
240
241 @Before("JCRAPIPointcut()")
242 public void begin(JoinPoint thisJoinPoint)
243 {
244 Statistics statistics =
245 getStatistics(thisJoinPoint.getTarget().getClass(), thisJoinPoint.getSignature().toString());
246 if (statistics != null)
247 {
248 statistics.begin();
249 }
250 }
251
252 @After("JCRAPIPointcut()")
253 public void end(JoinPoint thisJoinPoint)
254 {
255 Statistics statistics =
256 getStatistics(thisJoinPoint.getTarget().getClass(), thisJoinPoint.getSignature().toString());
257 if (statistics != null)
258 {
259 statistics.end();
260 }
261 }
262 }