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 javassist.ByteArrayClassPath;
24  import javassist.ClassPool;
25  import javassist.CtClass;
26  import javassist.NotFoundException;
27  import javassist.SerialVersionUID;
28  import net.sf.jour.instrumentor.Instrumentor;
29  import net.sf.jour.instrumentor.InstrumentorResults;
30  import net.sf.jour.instrumentor.InstrumentorResultsImpl;
31  
32  /**
33   * 
34   * Created on 02.10.2004
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: 25 $ ($Author: vlads $) $Date: 2006-12-14 13:53:25 -0500 (Thu, 14 Dec 2006) $
43   */
44  public class Interceptor {
45  
46  	ClassPool pool;
47  
48  	String className;
49  
50  	Instrumentor[] instrumentors;
51  
52  	private Config config;
53  
54  	/**
55  	 * Flag any modification to class.
56  	 */
57  	private InstrumentorResults results;
58  	
59  	/**
60  	 * Creates a new Interceptor object.
61  	 */
62  	public Interceptor(Config config, ClassPool pool, String className, Instrumentor[] instrumentors) throws InterceptorException {
63  		if ((instrumentors == null) || (instrumentors.length == 0)) {
64  			throw new InterceptorException("Should be at least one instrumentor");
65  		}
66  
67  		this.pool = pool;
68  		this.className = className;
69  		this.instrumentors = instrumentors;
70  		this.config = config;
71  		this.results = InstrumentorResultsImpl.NOT_MODIFIED; 
72  	}
73  
74  	public byte[] instrument(byte[] bytes) throws InterceptorException {
75  		try {
76  			pool.insertClassPath(new ByteArrayClassPath(className, bytes));
77  
78  			try {
79  				return instrument().toBytecode();
80  			} catch (InterceptorException ie) {
81  				throw ie;
82  			} catch (Exception e) {
83  				e.printStackTrace();
84  				throw new InterceptorException("Profiling error @instrumentClass@setSerialVersionUID. " + e);
85  			}
86  		} catch (InterceptorException e) {
87  			System.out.println("instrument error " + e + " for class : " + className);
88  			e.printStackTrace();
89  		}
90  
91  		return bytes;
92  	}
93  
94  	public CtClass instrument() throws InterceptorException {
95  		CtClass clazz = null;
96  
97  		try {
98  			clazz = pool.get(className);
99  		} catch (NotFoundException nfe) {
100 			nfe.printStackTrace();
101 			throw new InterceptorException("Class " + className + " is not found in class pool." + nfe);
102 		}
103 
104 		if ((clazz != null) && !clazz.isInterface() && !clazz.isModified()) {
105 			try {
106 				if (config.isSetSerialVersionUID()) {
107 					SerialVersionUID.setSerialVersionUID(clazz);
108 				}
109 				for (int i = 0; i < instrumentors.length; i++) {
110 					// Go to actual instrumentation
111 					InstrumentorResults rc = instrumentors[i].instrument(clazz);
112 					if (rc.isModified()) {
113 						this.results = new InstrumentorResultsImpl(this.results, rc);
114 					}
115 				}
116 			} catch (Exception e) {
117 				e.printStackTrace();
118 				throw new InterceptorException("Profiling error @instrumentClass@setSerialVersionUID. " + e);
119 			}
120 		}
121 
122 		return clazz;
123 	}
124 
125 	/**
126 	 * @return Returns the Results.
127 	 */
128 	public InstrumentorResults getInstrumentorResults() {
129 		return this.results;
130 	}
131 }