KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > test > coverage > Coverage


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.test.coverage;
6
7 import java.io.BufferedReader JavaDoc;
8 import java.io.BufferedWriter JavaDoc;
9 import java.io.File JavaDoc;
10 import java.io.FileReader JavaDoc;
11 import java.io.FileWriter JavaDoc;
12 import java.io.Reader JavaDoc;
13 import java.io.Writer JavaDoc;
14 import java.util.ArrayList JavaDoc;
15
16 /**
17  * Tool to instrument java files with profiler calls. The tool can be used for
18  * profiling an application and for coverage testing. This class is not used at
19  * runtime of the tested application.
20  */

21 public class Coverage {
22     static final String JavaDoc IMPORT = "import " + Coverage.class.getPackage().getName() + ".Profile";
23     ArrayList JavaDoc files = new ArrayList JavaDoc();
24     ArrayList JavaDoc exclude = new ArrayList JavaDoc();
25     Tokenizer tokenizer;
26     Writer JavaDoc writer;
27     Writer JavaDoc data;
28     String JavaDoc token = "";
29     String JavaDoc add = "";
30     String JavaDoc file;
31     int index;
32     int indent;
33     int line;
34     String JavaDoc last;
35     String JavaDoc word, function;
36     boolean perClass;
37     boolean perFunction = true;
38
39     void printUsage() {
40         System.out
41                 .println("Usage:\n"
42                         + "- copy all your source files to another directory\n"
43                         + " (be carefull, they will be modified - don't take originals!)\n"
44                         + "- java " + getClass().getName() + " <directory>\n"
45                         + " this will modified the source code and create 'profile.txt'\n"
46                         + "- compile the modified source files\n"
47                         + "- run your main application\n"
48                         + "- after the application exits, a file 'notcovered.txt' is created,\n"
49                         + " which contains the class names, function names and line numbers\n"
50                         + " of code that has not been covered\n\n"
51                         + "Options:\n"
52                         + "-r recurse all subdirectories\n"
53                         + "-e exclude files\n"
54                         + "-c coverage on a per-class basis\n"
55                         + "-f coverage on a per-function basis\n"
56                         + "<dir> directory name (. for current directory)");
57     }
58
59     public static void main(String JavaDoc[] arg) {
60         (new Coverage()).run(arg);
61     }
62
63     void run(String JavaDoc[] arg) {
64         if (arg.length == 0 || arg[0].equals("-?")) {
65             printUsage();
66             return;
67         }
68         Coverage c = new Coverage();
69         int recurse = 1;
70         for (int i = 0; i < arg.length; i++) {
71             String JavaDoc s = arg[i];
72             if (s.equals("-r")) {
73                 // maximum recurse is 100 subdirectories, that should be enough
74
recurse = 100;
75             } else if (s.equals("-c")) {
76                 c.perClass = true;
77             } else if (s.equals("-f")) {
78                 c.perFunction = true;
79             } else if (s.equals("-e")) {
80                 c.addExclude(arg[++i]);
81             } else {
82                 c.addDir(s, recurse);
83             }
84         }
85         try {
86             c.data = new BufferedWriter JavaDoc(new FileWriter JavaDoc("profile.txt"));
87             c.processAll();
88             c.data.close();
89         } catch (Exception JavaDoc e) {
90             e.printStackTrace();
91         }
92     }
93     
94     void addExclude(String JavaDoc file) {
95         exclude.add(file);
96     }
97     
98     boolean isExcluded(String JavaDoc s) {
99         for(int i=0; i<exclude.size(); i++) {
100             if(s.startsWith(exclude.get(i).toString())) {
101                 return true;
102             }
103         }
104         return false;
105     }
106
107     void addDir(String JavaDoc path, int recurse) {
108         File JavaDoc f = new File JavaDoc(path);
109         if (f.isFile() && path.endsWith(".java")) {
110             if(!isExcluded(path)) {
111                 files.add(path);
112             }
113         } else if (f.isDirectory() && recurse > 0) {
114             String JavaDoc[] list = f.list();
115             for (int i = 0; i < list.length; i++) {
116                 addDir(path + "/" + list[i], recurse - 1);
117             }
118         }
119     }
120
121     void processAll() {
122         int len = files.size();
123         long time = System.currentTimeMillis();
124         for (int i = 0; i < len; i++) {
125             long t2 = System.currentTimeMillis();
126             if (t2 - time > 1000 || i >= len - 1) {
127                 System.out.println((i + 1) + " of " + len + " " + (100 * i / len) + "%");
128                 time = t2;
129             }
130             String JavaDoc fileName = (String JavaDoc) files.get(i);
131             processFile(fileName);
132         }
133     }
134
135     void processFile(String JavaDoc name) {
136         file = name;
137         int i;
138         i = file.lastIndexOf('.');
139         if (i != -1) {
140             file = file.substring(0, i);
141         }
142         while(true) {
143             i = file.indexOf('/');
144             if(i < 0) {
145                 i = file.indexOf('\\');
146             }
147             if(i<0) {
148                 break;
149             }
150             file = file.substring(0, i) + "." +file.substring(i+1);
151         }
152         if (name.endsWith("Coverage.java") || name.endsWith("Tokenizer.java")
153                 || name.endsWith("Profile.java")) {
154             return;
155         }
156         File JavaDoc f = new File JavaDoc(name);
157         File JavaDoc fnew = new File JavaDoc(name + ".new");
158         try {
159             writer = new BufferedWriter JavaDoc(new FileWriter JavaDoc(fnew));
160             Reader JavaDoc r = new BufferedReader JavaDoc(new FileReader JavaDoc(f));
161             tokenizer = new Tokenizer(r);
162             indent = 0;
163             try {
164                 process();
165             } catch (Exception JavaDoc e) {
166                 r.close();
167                 writer.close();
168                 e.printStackTrace();
169                 printError(e.getMessage());
170                 throw e;
171             }
172             r.close();
173             writer.close();
174             File JavaDoc fbak = new File JavaDoc(name + ".bak");
175             fbak.delete();
176             f.renameTo(fbak);
177             File JavaDoc fcopy = new File JavaDoc(name);
178             fnew.renameTo(fcopy);
179             if (perClass) {
180                 nextDebug();
181             }
182         } catch (Exception JavaDoc e) {
183             e.printStackTrace();
184             printError(e.getMessage());
185         }
186     }
187
188     void read() throws Exception JavaDoc {
189         last = token;
190         String JavaDoc write = token;
191         token = null;
192         tokenizer.initToken();
193         int i = tokenizer.nextToken();
194         if (i != Tokenizer.TYPE_EOF) {
195             token = tokenizer.getString();
196             if (token == null) {
197                 token = "" + ((char) i);
198             } else if (i == '\'') {
199                 //mToken="'"+getEscape(mToken)+"'";
200
token = tokenizer.getToken();
201             } else if (i == '\"') {
202                 //mToken="\""+getEscape(mToken)+"\"";
203
token = tokenizer.getToken();
204             } else {
205                 if (write == null) {
206                     write = "";
207                 } else {
208                     write = write + " ";
209                 }
210             }
211         }
212         if (write == null
213                 || (!write.equals("else ") && !write.equals("else")
214                         && !write.equals("super ") && !write.equals("super")
215                         && !write.equals("this ") && !write.equals("this")
216                         && !write.equals("} ") && !write.equals("}"))) {
217             if (add != null && !add.equals("")) {
218                 writeLine();
219                 write(add);
220                 if (!perClass) {
221                     nextDebug();
222                 }
223             }
224         }
225         add = "";
226         if (write != null) {
227             write(write);
228         }
229     }
230
231     void readThis(String JavaDoc s) throws Exception JavaDoc {
232         if (!token.equals(s)) {
233             throw new Exception JavaDoc("Expected: " + s + " got:" + token);
234         }
235         read();
236     }
237
238     void process() throws Exception JavaDoc {
239         boolean imp = false;
240         read();
241         do {
242             while (true) {
243                 if (token == null || token.equals("{")) {
244                     break;
245                 } else if (token.equals(";")) {
246                     if (!imp) {
247                         write(";" + IMPORT);
248                         imp = true;
249                     }
250                 }
251                 read();
252             }
253             processClass();
254         } while (token != null);
255     }
256
257     void processInit() throws Exception JavaDoc {
258         do {
259             if (token.equals("{")) {
260                 read();
261                 processInit();
262             } else if (token.equals("}")) {
263                 read();
264                 return;
265             } else {
266                 read();
267             }
268         } while (true);
269     }
270
271     void processClass() throws Exception JavaDoc {
272         int type = 0;
273         while (true) {
274             if (token == null) {
275                 break;
276             } else if (token.equals("class")) {
277                 read();
278                 type = 1;
279             } else if (token.equals("=")) {
280                 read();
281                 type = 2;
282             } else if (token.equals("static")) {
283                 word = "static";
284                 read();
285                 type = 3;
286             } else if (token.equals("(")) {
287                 word = last + "(";
288                 read();
289                 if (!token.equals(")")) {
290                     word = word + token;
291                 }
292                 type = 3;
293             } else if (token.equals(",")) {
294                 read();
295                 word = word + "," + token;
296             } else if (token.equals(")")) {
297                 word = word + ")";
298                 read();
299             } else if (token.equals(";")) {
300                 read();
301                 type = 0;
302             } else if (token.equals("{")) {
303                 read();
304                 if (type == 1) {
305                     processClass();
306                 } else if (type == 2) {
307                     processInit();
308                 } else if (type == 3) {
309                     writeLine();
310                     setLine();
311                     processFunction();
312                     writeLine();
313                 }
314             } else if (token.equals("}")) {
315                 read();
316                 break;
317             } else {
318                 read();
319             }
320         }
321     }
322
323     void processBraket() throws Exception JavaDoc {
324         do {
325             if (token.equals("(")) {
326                 read();
327                 processBraket();
328             } else if (token.equals(")")) {
329                 read();
330                 return;
331             } else {
332                 read();
333             }
334         } while (true);
335     }
336
337     void processFunction() throws Exception JavaDoc {
338         function = word;
339         writeLine();
340         do {
341             processStatement();
342         } while (!token.equals("}"));
343         read();
344         writeLine();
345     }
346
347     void processBlockOrStatement() throws Exception JavaDoc {
348         if (!token.equals("{")) {
349             write("{ //++");
350             writeLine();
351             setLine();
352             processStatement();
353             write("} //++");
354             writeLine();
355         } else {
356             read();
357             setLine();
358             processFunction();
359         }
360     }
361
362     void processStatement() throws Exception JavaDoc {
363         while (true) {
364             if (token.equals("while") || token.equals("for")
365                     || token.equals("synchronized")) {
366                 read();
367                 readThis("(");
368                 processBraket();
369                 indent++;
370                 processBlockOrStatement();
371                 indent--;
372                 return;
373             } else if (token.equals("if")) {
374                 read();
375                 readThis("(");
376                 processBraket();
377                 indent++;
378                 processBlockOrStatement();
379                 indent--;
380                 if (token.equals("else")) {
381                     read();
382                     indent++;
383                     processBlockOrStatement();
384                     indent--;
385                 }
386                 return;
387             } else if (token.equals("try")) {
388                 read();
389                 indent++;
390                 processBlockOrStatement();
391                 indent--;
392                 while (true) {
393                     if (token.equals("catch")) {
394                         read();
395                         readThis("(");
396                         processBraket();
397                         indent++;
398                         processBlockOrStatement();
399                         indent--;
400                     } else if (token.equals("finally")) {
401                         read();
402                         indent++;
403                         processBlockOrStatement();
404                         indent--;
405                     } else {
406                         break;
407                     }
408                 }
409                 return;
410             } else if (token.equals("{")) {
411                 if (last.equals(")")) {
412                     // process anonymous inner classes (this is a hack)
413
read();
414                     processClass();
415                     return;
416                 } else if (last.equals("]")) {
417                     // process object array initialization (another hack)
418
while (!token.equals("}")) {
419                         read();
420                     }
421                     read();
422                     return;
423                 }
424                 indent++;
425                 processBlockOrStatement();
426                 indent--;
427                 return;
428             } else if (token.equals("do")) {
429                 read();
430                 indent++;
431                 processBlockOrStatement();
432                 readThis("while");
433                 readThis("(");
434                 processBraket();
435                 readThis(";");
436                 setLine();
437                 indent--;
438                 return;
439             } else if (token.equals("case")) {
440                 add = "";
441                 read();
442                 while (!token.equals(":")) {
443                     read();
444                 }
445                 read();
446                 setLine();
447             } else if (token.equals("default")) {
448                 add = "";
449                 read();
450                 readThis(":");
451                 setLine();
452             } else if (token.equals("switch")) {
453                 read();
454                 readThis("(");
455                 processBraket();
456                 indent++;
457                 processBlockOrStatement();
458                 indent--;
459                 return;
460             } else if (token.equals("class")) {
461                 read();
462                 processClass();
463                 return;
464             } else if (token.equals("(")) {
465                 read();
466                 processBraket();
467             } else if (token.equals("=")) {
468                 read();
469                 if (token.equals("{")) {
470                     read();
471                     processInit();
472                 }
473             } else if (token.equals(";")) {
474                 read();
475                 setLine();
476                 return;
477             } else if (token.equals("}")) {
478                 return;
479             } else {
480                 read();
481             }
482         }
483     }
484
485     void setLine() throws Exception JavaDoc {
486         add += "Profile.visit(" + index + ");";
487         line = tokenizer.getLine();
488     }
489
490     void nextDebug() throws Exception JavaDoc {
491         if (perFunction) {
492             int i = function.indexOf("(");
493             String JavaDoc func = i<0 ? function : function.substring(0, i);
494             String JavaDoc fileLine = file + "." + func +"(";
495             i = file.lastIndexOf('.');
496             String JavaDoc fil = i<0 ? file : file.substring(i+1);
497             fileLine += fil + ".java:" + line + ")";
498             data.write(fileLine + " " + last + "\r\n");
499         } else {
500             data.write(file + " " + line + "\r\n");
501         }
502         index++;
503     }
504
505     void writeLine() throws Exception JavaDoc {
506         write("\r\n");
507         for (int i = 0; i < indent; i++) {
508             writer.write(' ');
509         }
510     }
511
512     void write(String JavaDoc s) throws Exception JavaDoc {
513         writer.write(s);
514         //System.out.print(s);
515
}
516
517     void printError(String JavaDoc error) {
518         System.out.println("");
519         System.out.println("File:" + file);
520         System.out.println("ERROR: " + error);
521     }
522 }
523
524
Popular Tags