KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cobertura > instrument > ClassInstrumenter


1 /*
2  * Cobertura - http://cobertura.sourceforge.net/
3  *
4  * Copyright (C) 2005 Mark Doliner <thekingant@users.sourceforge.net>
5  *
6  * Cobertura is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2 of the License,
9  * or (at your option) any later version.
10  *
11  * Cobertura is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Cobertura; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  */

21
22 package net.sourceforge.cobertura.instrument;
23
24 import java.util.Collection JavaDoc;
25
26 import net.sourceforge.cobertura.coveragedata.ClassData;
27 import net.sourceforge.cobertura.coveragedata.ProjectData;
28
29 import org.apache.log4j.Logger;
30 import org.objectweb.asm.ClassAdapter;
31 import org.objectweb.asm.ClassVisitor;
32 import org.objectweb.asm.MethodVisitor;
33 import org.objectweb.asm.Opcodes;
34
35 class ClassInstrumenter extends ClassAdapter
36 {
37
38     private static final Logger logger = Logger
39             .getLogger(ClassInstrumenter.class);
40
41     private final static String JavaDoc hasBeenInstrumented = "net/sourceforge/cobertura/coveragedata/HasBeenInstrumented";
42
43     private Collection JavaDoc ignoreRegexs;
44
45     private ProjectData projectData;
46
47     private ClassData classData;
48
49     private String JavaDoc myName;
50
51     private boolean instrument = false;
52
53     public String JavaDoc getClassName()
54     {
55         return this.myName;
56     }
57
58     public boolean isInstrumented()
59     {
60         return instrument;
61     }
62
63     public ClassInstrumenter(ProjectData projectData, final ClassVisitor cv,
64             final Collection JavaDoc ignoreRegexs)
65     {
66         super(cv);
67         this.projectData = projectData;
68         this.ignoreRegexs = ignoreRegexs;
69     }
70
71     private boolean arrayContains(Object JavaDoc[] array, Object JavaDoc key)
72     {
73         for (int i = 0; i < array.length; i++)
74         {
75             if (array[i].equals(key))
76                 return true;
77         }
78
79         return false;
80     }
81
82     /**
83      * @param name In the format
84      * "net/sourceforge/cobertura/coverage/ClassInstrumenter"
85      */

86     public void visit(int version, int access, String JavaDoc name, String JavaDoc signature,
87             String JavaDoc superName, String JavaDoc[] interfaces)
88     {
89         this.myName = name.replace('/', '.');
90         this.classData = this.projectData.getOrCreateClassData(this.myName);
91         this.classData.setContainsInstrumentationInfo();
92
93         // Do not attempt to instrument interfaces or classes that
94
// have already been instrumented
95
if (((access & Opcodes.ACC_INTERFACE) != 0)
96                 || arrayContains(interfaces, hasBeenInstrumented))
97         {
98             super.visit(version, access, name, signature, superName,
99                             interfaces);
100         }
101         else
102         {
103             instrument = true;
104
105             // Flag this class as having been instrumented
106
String JavaDoc[] newInterfaces = new String JavaDoc[interfaces.length + 1];
107             System.arraycopy(interfaces, 0, newInterfaces, 0,
108                             interfaces.length);
109             newInterfaces[newInterfaces.length - 1] = hasBeenInstrumented;
110
111             super.visit(version, access, name, signature, superName,
112                     newInterfaces);
113         }
114     }
115
116     /**
117      * @param source In the format "ClassInstrumenter.java"
118      */

119     public void visitSource(String JavaDoc source, String JavaDoc debug)
120     {
121         super.visitSource(source, debug);
122         classData.setSourceFileName(source);
123     }
124
125     public MethodVisitor visitMethod(final int access, final String JavaDoc name,
126             final String JavaDoc desc, final String JavaDoc signature,
127             final String JavaDoc[] exceptions)
128     {
129         MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
130                 exceptions);
131
132         if (!instrument)
133             return mv;
134
135         return mv == null ? null : new MethodInstrumenter(classData, mv,
136                 this.myName, name, desc, ignoreRegexs);
137     }
138
139     public void visitEnd()
140     {
141         if (instrument && classData.getNumberOfValidLines() == 0)
142             logger.warn("No line number information found for class "
143                     + this.myName
144                     + ". Perhaps you need to compile with debug=true?");
145     }
146
147 }
148
Popular Tags