View Javadoc

1   /*
2    * Jour - java profiler and monitoring library
3    *
4    * Copyright (C) 2004 Jour team
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Library General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Library General Public License for more details.
15   *
16   * You should have received a copy of the GNU Library General Public
17   * License along with this library; if not, write to the
18   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   * Boston, MA  02111-1307, USA.
20   */
21  package net.sf.jour.instrumentor;
22  
23  import javassist.CtClass;
24  import javassist.CtConstructor;
25  import javassist.CtMethod;
26  import javassist.CtNewMethod;
27  import net.sf.jour.InterceptorException;
28  
29  /**
30   *
31   * Contributing Author(s):
32   *
33   *   Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
34   *   Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
35   *
36   * @author vlads
37   * @version $Revision: 46 $ ($Author: vlads $) $Date: 2007-08-28 14:30:40 -0400 (Tue, 28 Aug 2007) $
38   */
39  public class MethodExecutionTimeInstrumentor extends AbstractInstrumentor implements
40          InstrumentorConsts {
41  
42  	public boolean instrumentClass(CtClass clazz) throws InterceptorException {
43  		return false;
44      }
45  
46      public boolean instrumentMethod(CtClass clazz, CtMethod method) throws InterceptorException {
47          addTiming(clazz, method);
48  		return true;
49      }
50  
51      public boolean instrumentConstructor(CtClass clazz, CtConstructor constructor)
52              throws InterceptorException {
53           return false;
54      }
55  
56      private static void addTiming(CtClass clazz, CtMethod method) throws InterceptorException {
57          try {
58          String mname = method.getName();
59          //  rename old method to synthetic name, then duplicate the
60          //  method with original name for use as interceptor
61          String nname = "jour$"+ mname + "$impl";
62          method.setName(nname);
63          CtMethod mnew = CtNewMethod.copy(method, mname, clazz, null);
64  
65          //  start the body text generation by saving the start time
66          //  to a local variable, then call the timed method; the
67          //  actual code generated needs to depend on whether the
68          //  timed method returns a value
69          String type = method.getReturnType().getName();
70          StringBuffer body = new StringBuffer();
71          body.append("{\nlong start = System.currentTimeMillis();\n");
72          if (!"void".equals(type)) {
73              body.append(type + " result = ");
74          }
75          body.append(nname + "($$);\n");
76  
77          //  finish body text generation with call to print the timing
78          //  information, and return saved value (if not void)
79          //body.append("net.sf.jour.rt.agent.Elog.logEvent(new net.sf.jour.rt.agent.MethodExecutionTimeEvent(\"" + mname + "\", System.currentTimeMillis()-start));\n");
80          body.append("System.out.println(\"" + mname + "\" + System.currentTimeMillis()-start));\n");
81          if (!"void".equals(type)) {
82              body.append("return result;\n");
83          }
84          body.append("}");
85  
86          //  replace the body of the interceptor method with generated
87          //  code block and add it to class
88          mnew.setBody(body.toString());
89          clazz.addMethod(mnew);
90          } catch (Exception e) {
91              e.printStackTrace();
92              throw new InterceptorException("Failed to add timing to method " + method.getName());
93          }
94      }
95  }