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;
22  
23  import net.sf.jour.instrumentor.Instrumentor;
24  
25  import javassist.*;
26  
27  /***
28   * TODO add docs.
29   *
30   * Created on 02.10.2004
31   *
32   * Contributing Author(s):
33   *
34   *   Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
35   *   Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
36   * 
37   * @author michaellif
38   * @version $Revision: 1.5 $ ($Author: vlads $) $Date: 2004/12/13 06:19:10 $
39   */
40  public class Interceptor {
41      /***   DOCUMENT ME!   */
42      ClassPool pool;
43  
44      /***   DOCUMENT ME!   */
45      String className;
46  
47      /***   DOCUMENT ME!   */
48      Instrumentor[] instrumentors;
49      
50      private long countMethods;
51      
52      private long countCounstructors;
53      /***
54       * Flag any modification to class.
55       */
56      boolean modified;
57  
58      /***
59       * Creates a new Interceptor object.
60       *
61       * @param pool DOCUMENT ME!
62       * @param className DOCUMENT ME!
63       * @param instrumentors DOCUMENT ME!
64       *
65       * @throws InterceptorException DOCUMENT ME!
66       */
67      public Interceptor(ClassPool pool, String className,
68          Instrumentor[] instrumentors) throws InterceptorException {
69          if ((instrumentors == null) || (instrumentors.length == 0)) {
70              throw new InterceptorException(
71                  "Should be at least one instrumentor");
72          }
73  
74          this.pool = pool;
75          this.className = className;
76          this.instrumentors = instrumentors;
77      }
78  
79      /***
80       * DOCUMENT ME!
81       *
82       * @param bytes DOCUMENT ME!
83       *
84       * @return DOCUMENT ME!
85       *
86       * @throws InterceptorException DOCUMENT ME!
87       */
88      public byte[] instrument(byte[] bytes) throws InterceptorException {
89          try {
90              pool.insertClassPath(new ByteArrayClassPath(className, bytes));
91  
92              try {
93                  return instrument().toBytecode();
94              } catch (InterceptorException ie) {
95                  throw ie;
96              } catch (Exception e) {
97                  e.printStackTrace();
98                  throw new InterceptorException(
99                      "Profiling error @instrumentClass@setSerialVersionUID. " +
100                     e);
101             }
102         } catch (InterceptorException e) {
103             System.out.println("instrument error " + e + " for class : " +
104                 className);
105             e.printStackTrace();
106         }
107 
108         return bytes;
109     }
110 
111     /***
112      * DOCUMENT ME!
113      *
114      * @return DOCUMENT ME!
115      *
116      * @throws InterceptorException DOCUMENT ME!
117      */
118     public CtClass instrument() throws InterceptorException {
119         CtClass clazz = null;
120 
121         try {
122             clazz = pool.get(className);
123         } catch (NotFoundException nfe) {
124             nfe.printStackTrace();
125             throw new InterceptorException("Class " + className +
126                 " is not found in class pool." + nfe);
127         }
128 
129         if ((clazz != null) && !clazz.isInterface() && !clazz.isModified()) {
130             try {
131                 SerialVersionUID.setSerialVersionUID(clazz);
132 				this.modified = false;
133                 for (int i = 0; i < instrumentors.length; i++) {
134                     //instrumentor has a total running count per instance
135                     //interceptor should return currently modified count
136                     long p_countCounstructors = instrumentors[i].getCountCounstructors();
137                     long p_countMethods = instrumentors[i].getCountMethods();
138                     
139                     //Go to actual instrumentation
140                     this.modified = instrumentors[i].instrument(clazz) || this.modified;
141                     
142                     this.countCounstructors += instrumentors[i].getCountCounstructors() - p_countCounstructors;
143         	        this.countMethods += instrumentors[i].getCountMethods() - p_countMethods;
144                 }
145             } catch (Exception e) {
146                 e.printStackTrace();
147                 throw new InterceptorException(
148                     "Profiling error @instrumentClass@setSerialVersionUID. " +
149                     e);
150             }
151         }
152 
153         return clazz;
154     }
155     /***
156      * @return Returns true if any modification has been made to the class.
157      */
158     public boolean isModified() {
159         return modified;
160     }
161 
162     /***
163      * @return Returns the countCounstructors.
164      */
165     public long getCountCounstructors() {
166         return countCounstructors;
167     }
168     /***
169      * @return Returns the countMethods.
170      */
171     public long getCountMethods() {
172         return countMethods;
173     }
174 }