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 net.sf.jour.InterceptorException;
24  import net.sf.jour.filter.*;
25  
26  import java.util.*;
27  
28  import org.apache.log4j.Logger;
29  
30  import javassist.*;
31  import javassist.CtMethod;
32  
33  /***
34   * TODO Add docs
35   *
36   * Contributing Author(s):
37   *
38   *   Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
39   *   Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
40   *
41   * @author michaellif
42   * @version $Revision: 1.6 $ ($Author: vlads $) $Date: 2004/12/13 06:19:10 $
43   */
44  public abstract class AbstractInstrumentor implements Instrumentor {
45  
46      protected static final Logger log = Logger.getLogger(AbstractInstrumentor.class);
47      
48      private PointcutListFilter pointcuts;
49  
50      private long countMethods;
51      private long countCounstructors;
52      
53      /***
54       * Creates a new AbstractInstrumentor object.
55       */
56      protected AbstractInstrumentor() {
57          log.debug("AbstractInstrumentor Created");
58      }
59  
60      /***
61       * DOCUMENT ME!
62       * 
63       * @param clazz
64       *            DOCUMENT ME!
65       * 
66       * @throws InterceptorException
67       *             DOCUMENT ME!
68       */
69      public boolean instrument(CtClass clazz) throws InterceptorException {
70  //        System.out.println("Start instrumenting:" + clazz.getName());
71  //        System.out.println("	time=" + (new Date().getTime() - net.sf.jour.PreProcessor.startTime));
72          if (clazz.isInterface()) {
73              return false;
74          }
75  		boolean modified = false;
76          HashMap instrumented = new HashMap();
77          //for (int i = 0; i < pointcuts.length; i++) {
78              //Pointcut pointcut = pointcuts[i];
79          for (Iterator i = pointcuts.iterator(); i.hasNext();) {
80              Pointcut pointcut = (Pointcut) i.next();
81              
82              if (pointcut.acceptClass(clazz)) {
83                  if (!instrumented.containsKey(clazz)) {
84  //                    System.out.println("instrumenting class:" + clazz.getName());
85  //                    System.out.println("	time=" + (new Date().getTime() - net.sf.jour.PreProcessor.startTime));
86  					modified = instrumentClass(clazz) || modified;
87                      instrumented.put(clazz, null);
88                  }
89  
90                  Iterator methods = Arrays.asList(clazz.getDeclaredMethods()).iterator();
91                  while (methods.hasNext()) {
92                      CtMethod method = (CtMethod) methods.next();
93                      String methodName = method.getName();
94                      if (!instrumented.containsKey(method) 
95                              && pointcut.acceptMethod(method) 
96                              // This will check the pointcut exceptions.
97                              && pointcuts.match(method)) {
98  //                        System.out.println("instrumenting method:" + clazz.getName() + "."
99  //                                + method.getName() + "(" + method.getSignature() + ")");
100 //                        System.out.println("	time=" + (new Date().getTime() - net.sf.jour.PreProcessor.startTime));
101 						if (instrumentMethod(clazz, method)) {
102 						    countMethods ++;
103 						    modified = true;
104 						}
105                         instrumented.put(method, null);
106                     }
107                 }
108 
109                 Iterator constructors = Arrays.asList(clazz.getConstructors()).iterator();
110                 while (constructors.hasNext()) {
111                     CtConstructor constructor = (CtConstructor) constructors.next();
112                    //TODO check to process static constructors
113                     if (!constructor.isClassInitializer() && 
114                             pointcut.acceptConstr(constructor) && 
115                             !instrumented.containsKey(constructor)) {
116 //                        System.out.println("instrumenting constructor:" + clazz.getName() + "."
117 //                                + constructor.getName() + "(" + constructor.getSignature() + ")");
118 //                        System.out.println("	time=" + (new Date().getTime() - net.sf.jour.PreProcessor.startTime));
119                         if (instrumentConstructor(clazz, constructor)) {
120                             countCounstructors ++;
121                             modified = true;
122                         }
123                         instrumented.put(constructor, null);
124                     }
125                 }
126             }
127         }
128 //        System.out.println("End instrumenting:" + clazz.getName());
129 //        System.out.println("	time=" + (new Date().getTime() - net.sf.jour.PreProcessor.startTime));
130 		return modified;
131     }
132 
133     /***
134      * @return Returns the countCounstructors.
135      */
136     public long getCountCounstructors() {
137         return countCounstructors;
138     }
139     /***
140      * @return Returns the countMethods.
141      */
142     public long getCountMethods() {
143         return countMethods;
144     }
145     
146     public void setPointcuts(PointcutListFilter pointcuts) {
147         this.pointcuts = pointcuts;
148     }
149 
150     /***
151      * DOCUMENT ME!
152      * 
153      * @param clazz
154      *            DOCUMENT ME!
155      * 
156      * @throws InterceptorException
157      *             DOCUMENT ME!
158      */
159     abstract boolean instrumentClass(CtClass clazz) throws InterceptorException;
160 
161     /***
162      * DOCUMENT ME!
163      * 
164      * @param clazz
165      *            DOCUMENT ME!
166      * @param method
167      *            DOCUMENT ME!
168      * 
169      * @throws InterceptorException
170      *             DOCUMENT ME!
171      */
172     abstract boolean instrumentMethod(CtClass clazz, CtMethod method) throws InterceptorException;
173 
174     /***
175      * DOCUMENT ME!
176      * 
177      * @param clazz
178      *            DOCUMENT ME!
179      * @param constructor
180      *            DOCUMENT ME!
181      * 
182      * @throws InterceptorException
183      *             DOCUMENT ME!
184      */
185     abstract boolean instrumentConstructor(CtClass clazz, CtConstructor constructor)
186             throws InterceptorException;
187 }