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 java.io.*;
24  import java.util.*;
25  
26  import javassist.*;
27  import net.sf.jour.instrumentor.*;
28  
29  import org.apache.log4j.Logger;
30  
31  import net.sf.jour.util.PropertiesBase;
32  import net.sf.jour.util.FileUtil;
33  import net.sf.jour.rt.agent.InstrumentationMap;
34  
35  /***
36   * TODO add docs.
37   *
38   * Created on 02.10.2004
39   *
40   * Contributing Author(s):
41   *
42   *   Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
43   *   Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
44   * 
45   * @author michaellif
46   * @version $Revision: 1.13 $ ($Author: vlads $) $Date: 2004/12/13 06:19:10 $
47   */
48  public class PreProcessor {
49      
50  	protected static final Logger log = Logger.getLogger(PreProcessor.class);
51  	
52      public static long startTime = new Date().getTime();
53  	
54      public long savedClasses;
55      private long countMethods;
56      private long countCounstructors;
57      
58      /***   DOCUMENT ME!   */
59      private static final char FILE_SEPARATOR = System.getProperty(
60              "file.separator").charAt(0);
61  
62  	private PropertiesBase properties;
63  	
64      /***   DOCUMENT ME!   */
65      private File startFile;
66      
67  	private File classList;
68  
69      /***   DOCUMENT ME!   */
70      private String outDir;
71  
72      /***
73       * Creates a new PreProcessor object.
74       *
75       * @param f DOCUMENT ME!
76       * @param o DOCUMENT ME!
77       */
78      public PreProcessor(PropertiesBase properties) {
79      	this.properties = properties;
80  		
81      	log.info("java.class.path = " + System.getProperty("java.class.path"));
82      	
83      	File out = properties.getFolder("dst", true);
84  		if (out == null) {
85  			throw new Error("-dst DIR Output folder expected");
86  		}
87  		
88          String classlist = properties.getProperty("classlist");
89          if (classlist != null) {
90              this.classList = properties.getFile("classlist", true);
91              if (this.classList == null) {
92                  throw new Error("-classlist fileName Input file expected");
93              }
94          } else {
95              File f = properties.getFolder("src", false);
96              if (f == null) {
97                  throw new Error("-src DIR Input folder expected");
98              }
99              this.startFile = f;
100         }
101 
102         System.out.println("Start Processor");
103 
104 		this.outDir = out.getAbsolutePath();
105     }
106 
107     /***
108      * DOCUMENT ME!
109      *
110      * @throws Exception DOCUMENT ME!
111      */
112     public void process() throws Exception {
113 		
114 		InstrumentationMap map = InstrumentationMap.instance();
115 		String mapFile = properties.getProperty("imap", 
116 			outDir + File.separator + InstrumentationMap.DEFULAT_FILE_NAME);
117 		
118 		if (new File(mapFile).canRead()) {
119 			map.load(new File(mapFile));
120     	}	
121 		
122     	if (this.startFile != null) {
123 	        process(this.startFile);
124     	} else if (this.classList != null) {
125 			processList(this.classList);
126     	}
127     	
128     	if (map.isUpdated()) {
129     		if (map.save(mapFile)) {
130     			log.info("Map saved " + mapFile);
131     		}
132     	}
133     	log.info("Map size " + map.size());
134 		log.info("Altered Counstructors " + this.countCounstructors);
135 		log.info("Altered Methods " + this.countMethods);
136 		log.info("Saved Classes " + savedClasses);
137     }
138 
139     /***
140      * DOCUMENT ME!
141      *
142      * @param f DOCUMENT ME!
143      *
144      * @throws Exception DOCUMENT ME!
145      */
146     public void process(File f) throws Exception {
147         if (f.isFile()) {
148             processFile(f);
149         } else if (f.isDirectory()) {
150             processDirectory(f);
151         }
152     }
153 
154     /***
155      * DOCUMENT ME!
156      *
157      * @param f DOCUMENT ME!
158      *
159      * @throws Exception DOCUMENT ME!
160      */
161     void processDirectory(File f) throws Exception {
162         String[] flist = f.list();
163         String initPath = f.getCanonicalPath();
164 		log.debug(f);
165         for (int i = 0; i < flist.length; i++) {
166             String path = initPath;
167 
168             if (path.charAt(path.length() - 1) != FILE_SEPARATOR) {
169                 path += FILE_SEPARATOR;
170             }
171 
172             path += flist[i];
173 
174             File f1 = new File(path);
175             process(f1);
176         }
177     }
178 
179     /***
180      * DOCUMENT ME!
181      *
182      * @param f DOCUMENT ME!
183      *
184      * @throws Exception DOCUMENT ME!
185      */
186     void processFile(File f) throws Exception {
187         //log.debug(f);
188         String className = fileName2Class(f);
189         if (className != null) {
190 			processClass(className);
191         }
192     }
193     
194 	private void processList(File f) throws Exception {
195 		HashSet list = FileUtil.readTextFile(f);
196 		if (list == null) {
197 			return;
198 		}
199 		for (Iterator i = list.iterator(); i.hasNext(); ) {
200 			String className = (String) i.next();
201 			processClass(className);
202 		}
203 	}
204 
205     void processClass(String className) throws Exception {
206         log.debug("className " + className);
207         ClassPool pool = ClassPool.getDefault();
208         Instrumentor[] instrumentors = Config.getInstrumentors(className);
209         if (instrumentors.length > 0) {
210             log.debug("intercepting class " + className);
211             Interceptor interceptor = new Interceptor(pool, className, instrumentors);
212             CtClass cc = interceptor.instrument();
213             log.debug("intercepted methods " + interceptor.getCountMethods());
214             if (interceptor.isModified()) {
215 	            cc.writeFile(outDir);
216     	        this.savedClasses ++;
217     	        this.countCounstructors += interceptor.getCountCounstructors();
218     	        this.countMethods += interceptor.getCountMethods();
219             }
220         }
221     }
222     /***
223      * DOCUMENT ME!
224      *
225      * @param f DOCUMENT ME!
226      *
227      * @return DOCUMENT ME!
228      */
229     String fileName2Class(File f) {
230         String className = null;
231 
232         try {
233             if (f.getName().endsWith(".class")) {
234             	String baseName = startFile.getCanonicalPath();
235             	String fileName = f.getCanonicalPath();
236                 int idx = fileName.indexOf(baseName);
237                 if (idx == -1) {
238             		log.debug("base:" + baseName);
239             		log.debug("file:" + fileName);
240                 	return null;
241                 }
242             	idx = baseName.length() + 1;
243                     
244                 className = fileName.substring(idx).replace(FILE_SEPARATOR, '.');
245                 className = className.substring(0,
246                         className.length() - ".class".length());
247             }
248         } catch (IOException e) {
249             log.error("File name rrror ", e);
250             return null;
251         }
252 
253         return className;
254     }
255 
256     /***
257      * DOCUMENT ME!
258      *
259      * @param classname DOCUMENT ME!
260      *
261      * @return DOCUMENT ME!
262      */
263     String class2FileName(String classname) {
264         return startFile.getAbsolutePath() + FILE_SEPARATOR +
265         classname.replace('.', FILE_SEPARATOR) + ".class";
266     }
267 
268     /***
269      * DOCUMENT ME!
270      *
271      * @param args DOCUMENT ME!
272      */
273     public static void main(String[] args) {
274         if (args.length < 1) {
275             System.out.println("Usage:java net.sf.jour.PreProcessor " 
276             + " -dst outDir \n"
277             + " (-src targetDir | -classlist fileName.txt)"
278             + " [-imap mapFileName]");
279             System.exit(1);
280         }
281 
282         try {
283 			PropertiesBase pargs = new PropertiesBase();
284 			pargs.loadArgs(args);
285 			
286             PreProcessor pp = new PreProcessor(pargs);
287             pp.process();
288         } catch (Exception e) {
289             e.printStackTrace();
290             System.exit(1);
291         }
292     }
293 }