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 java.util.Arrays;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Vector;
28  
29  import javassist.CtClass;
30  import javassist.CtConstructor;
31  import javassist.CtMethod;
32  import net.sf.jour.InterceptorException;
33  import net.sf.jour.filter.Pointcut;
34  import net.sf.jour.filter.PointcutListFilter;
35  import net.sf.jour.log.Logger;
36  
37  /**
38   *
39   * Contributing Author(s):
40   *
41   *   Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
42   *   Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
43   *
44   * @author michaellif
45   * @version $Revision: 46 $ ($Author: vlads $) $Date: 2007-08-28 14:30:40 -0400 (Tue, 28 Aug 2007) $
46   */
47  public abstract class AbstractInstrumentor implements Instrumentor {
48  
49  	protected static final Logger log = Logger.getLogger();
50  
51  	protected PointcutListFilter pointcuts;
52  
53  	List createdClasses;
54  	
55  	protected AbstractInstrumentor() {
56  		log.debug("AbstractInstrumentor Created");
57  	}
58  
59  	public InstrumentorResults instrument(CtClass clazz) throws InterceptorException {
60  		if (clazz.isInterface()) {
61  			return InstrumentorResultsImpl.NOT_MODIFIED;
62  		}
63  		boolean modified = false;
64  		
65  		long countCounstructors = 0;
66  
67  		long countMethods = 0;
68  		
69  		createdClasses = new Vector();
70  		
71  		HashMap instrumented = new HashMap();
72  		
73  		//log.debug("Start instrumenting:" + clazz.getName());
74  		
75  		for (Iterator i = pointcuts.iterator(); i.hasNext();) {
76  			Pointcut pointcut = (Pointcut) i.next();
77  
78  			if (pointcut.acceptClass(clazz)) {
79  				
80  				if (!instrumented.containsKey(clazz)) {
81  					log.debug("instrumenting class:" + clazz.getName());
82  					modified = instrumentClass(clazz) || modified;
83  					instrumented.put(clazz, null);
84  				}
85  
86  				Iterator methods = Arrays.asList(clazz.getDeclaredMethods()).iterator();
87  				while (methods.hasNext()) {
88  					CtMethod method = (CtMethod) methods.next();
89  					if (!instrumented.containsKey(method) && pointcut.acceptMethod(method)
90  					// This will check the pointcut exceptions.
91  							&& pointcuts.match(method)) {
92  						
93  						log.debug("instrumenting method:" + clazz.getName() + "." + method.getName() + "(" + method.getSignature() + ")");
94  						
95  						if (instrumentMethod(clazz, method)) {
96  							countMethods++;
97  							modified = true;
98  						}
99  						instrumented.put(method, null);
100 					}
101 				}
102 
103 				Iterator constructors = Arrays.asList(clazz.getConstructors()).iterator();
104 				while (constructors.hasNext()) {
105 					CtConstructor constructor = (CtConstructor) constructors.next();
106 					//TODO check to process static constructors
107 					if (!constructor.isClassInitializer() && pointcut.acceptConstr(constructor)
108 							&& !instrumented.containsKey(constructor)) {
109 						log.debug("instrumenting constructor:" + clazz.getName() + "." + constructor.getName() + "(" + constructor.getSignature() + ")");
110 						if (instrumentConstructor(clazz, constructor)) {
111 							countCounstructors++;
112 							modified = true;
113 						}
114 						instrumented.put(constructor, null);
115 					}
116 				}
117 			}
118 		}
119 		log.debug("End instrumenting:" + clazz.getName());
120 		if (modified) {
121 			return new InstrumentorResultsImpl(countCounstructors, countMethods, createdClasses);
122 		} else {
123 			return InstrumentorResultsImpl.NOT_MODIFIED;
124 		}
125 	}
126 
127 	public void setPointcuts(PointcutListFilter pointcuts) {
128 		this.pointcuts = pointcuts;
129 	}
130 
131 	protected void classCreated(CtClass clazz) {
132 		createdClasses.add(clazz);
133 	}
134 	
135 	public abstract boolean instrumentClass(CtClass clazz) throws InterceptorException;
136 
137 	public abstract boolean instrumentMethod(CtClass clazz, CtMethod method) throws InterceptorException;
138 
139 	public abstract boolean instrumentConstructor(CtClass clazz, CtConstructor constructor) throws InterceptorException;
140 }