1 /*
2 ~ Copyright 2006-2007 Nicolas De Loof.
3 ~
4 ~ Licensed under the Apache License, Version 2.0 (the "License");
5 ~ you may not use this file except in compliance with the License.
6 ~ You may obtain a copy of the License at
7 ~
8 ~ http://www.apache.org/licenses/LICENSE-2.0
9 ~
10 ~ Unless required by applicable law or agreed to in writing, software
11 ~ distributed under the License is distributed on an "AS IS" BASIS,
12 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ~ See the License for the specific language governing permissions and
14 ~ limitations under the License.
15 */
16 package org.jmonit.support.aop;
17
18 import org.aopalliance.intercept.MethodInterceptor;
19 import org.aopalliance.intercept.MethodInvocation;
20 import org.jmonit.Monitor;
21 import org.jmonit.Monitoring;
22 import org.jmonit.Repository;
23 import org.jmonit.Stopwatch;
24
25 /**
26 * AOP-alliance interceptor to evaluate component performances using an
27 * intercpetor. Typically used with spring-aop.
28 *
29 * @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
30 */
31 public class PerformanceInterceptor
32 implements MethodInterceptor
33 {
34 /** The jMonit repository */
35 private Repository repository;
36
37 /**
38 * {@inheritDoc}
39 *
40 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
41 */
42 public final Object invoke( MethodInvocation invocation )
43 throws Throwable
44 {
45 String name = getMonitorName( invocation );
46 if ( name == null )
47 {
48 return invocation.proceed();
49 }
50 Monitor monitor = getRepository().getMonitor( name );
51 Stopwatch stopwatch = Stopwatch.start( monitor );
52
53 Throwable error = null;
54 try
55 {
56 return invocation.proceed();
57 }
58 catch ( Throwable t )
59 {
60 error = t;
61 throw t;
62 }
63 finally
64 {
65 beforeReturning( monitor, error, stopwatch.getElapsedTime() );
66 }
67 }
68
69 /**
70 * @param monitor the monitor associated to the method invocation
71 * @param error Throwable trowed by the method invocation if any
72 * @param duration the duration of the method invocation
73 */
74 private void beforeReturning( Monitor monitor, Throwable error, long duration )
75 {
76 Monitor detail;
77 if ( error != null )
78 {
79 detail = getFailureMonitor( monitor, error );
80 }
81 else
82 {
83 detail = getSuccessMonitor( monitor );
84 }
85 if ( detail != null )
86 {
87 detail.add( duration );
88 }
89 }
90
91 /**
92 * Select a monitor for successful method invocations. Application can
93 * override this method for custom usage.
94 *
95 * @param monitor the monitor associated to this mehod invocation
96 * @return a monitor, or <code>null</code> if no monitoring is expected
97 */
98 protected Monitor getSuccessMonitor( Monitor monitor )
99 {
100 String name = monitor.getName() + "~" + "success";
101 return getRepository().getMonitor( name );
102 }
103
104 /**
105 * Select a monitor for method invocation failures. Application can override
106 * this method for custom usage.
107 *
108 * @param monitor the monitor associated to this mehod invocation
109 * @return a monitor, or <code>null</code> if no monitoring is expected
110 */
111 protected Monitor getFailureMonitor( Monitor monitor, Throwable error )
112 {
113 String name = monitor.getName() + "~" + error.getClass().getSimpleName();
114 return getRepository().getMonitor( name );
115 }
116
117 /**
118 * Compute the monitor name associated to this mehod invocation
119 *
120 * @param invocation method beeing invoked
121 * @return monitor name. If <code>null</code>, nothing will be monitored
122 */
123 protected String getMonitorName( MethodInvocation invocation )
124 {
125 return invocation.getClass().getSimpleName() + "." + invocation.getMethod().getName();
126 }
127
128 /**
129 * Set a custom application-defined repository
130 *
131 * @param repository
132 */
133 public void setRepository( Repository repository )
134 {
135 this.repository = repository;
136 }
137
138 /**
139 * Get the current repository
140 *
141 * @return
142 */
143 protected Repository getRepository()
144 {
145 if ( repository == null )
146 {
147 return Monitoring.getRepository();
148 }
149 return repository;
150 }
151
152 }