KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > uka > ipd > coverage > recording > RegisteredMethod


1 /*
2  * Created on 16.08.2004
3  *
4  * written by Matthias Kempka
5  */

6 package de.uka.ipd.coverage.recording;
7
8
9 import java.io.Serializable JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.LinkedList JavaDoc;
12 import java.util.List JavaDoc;
13
14 import org.apache.bcel.classfile.JavaClass;
15 import org.apache.bcel.classfile.Method;
16
17 import de.uka.ipd.coverage.natures.CoverageNatureVisitor;
18 import de.uka.ipd.coverage.utils.StringFormatter;
19
20 /**
21  * Created on 16.08.2004
22  * The class RegisteredMethod is a Wrapper for the class
23  * <code>org.apache.bcel.classfile.Method</code> that knows its BasicBlocks and
24  * the associated methods type. Also, it has a list of
25  * <code>de.uka.ipd.coverage.Path</code> objects, which are created during testing.
26  * Thus, this is the kind of object from where
27  * everything is reachable, everything meaning the test results in BasicBlocks
28  * and also their place in the tested project.
29  *
30  * @author Matthias Kempka
31  */

32 public class RegisteredMethod implements Serializable JavaDoc {
33     
34     private BasicBlock[] basicBlocks = null;
35     private List JavaDoc paths = new LinkedList JavaDoc(); // contains Path objects
36
private Path currentPath;
37     private Method method;
38     private JavaClass jclass;
39     private BasicBlock currentBlock;
40     
41     /**
42      * @param method
43      * @param jclass
44      */

45     public RegisteredMethod(Method method, JavaClass jclass) {
46         this.method = method;
47         this.jclass = jclass;
48     }
49     
50     /**
51      * checks, whether one of the paths for this method covers the given parameter
52      * as path. This is done by calling includes(path) on every object.
53      * @param path
54      */

55     public CoverageState isCovered(Path path) {
56         CoverageState result = CoverageState.NO_COVERAGE;
57         for (Iterator JavaDoc iter = paths.iterator(); iter.hasNext();) {
58             Path cPath = (Path) iter.next();
59             CoverageState elementResult = cPath.includes(path);
60             if (elementResult.isGreaterThan(result)) {
61                 result = elementResult;
62             }
63         }
64         return result;
65     }
66     
67     public CoverageState isCoveredIgnoreLoops(Path path) {
68         CoverageState result = CoverageState.NO_COVERAGE;
69         for (Iterator JavaDoc iter = paths.iterator(); iter.hasNext();) {
70             Path cPath = (Path) iter.next();
71             CoverageState elementResult = cPath.loopIncludes(path);
72             if (elementResult.isGreaterThan(result)) {
73                 result = elementResult;
74             }
75         }
76         return result;
77     }
78
79     /**
80      * This method is called by the code that is woven by the CoverageClassLoader
81      * instrumenting the ByteCodeModifyer.
82      * It indicates a block entry.
83      */

84     public void triggerEntered(int start, int end) {
85         assert basicBlocks != null : "RegisteredMethod for " + getHashKey() + //$NON-NLS-1$
86
": no BasicBlocks registered but entered"; //$NON-NLS-1$
87
currentBlock = getBasicBlock(start, end);
88         // if the first block in the method was entered we start recording
89
// a new path.
90
if (currentBlock.referencesSameBytecodeAs(basicBlocks[0])) {
91             currentPath = new Path();
92             paths.add(0, currentPath);
93         }
94         
95         assert currentPath != null : "CurrentPath not initialized!"; //$NON-NLS-1$
96

97         // TODO: Schleifen erkennen!
98
currentPath.addEnteredBlock(currentBlock);
99     }
100     
101     /**
102      * This method is called by the code that is woven by the CoverageClassLoader
103      * instrumenting the ByteCodeModifyer.
104      * It indicates a block exit.
105      */

106     public void triggerExited(int start, int end) {
107         assert currentBlock.referencesSameBytecodeAs(getBasicBlock(start, end)) :
108             "Call triggerEntered before calling triggerExited"; //$NON-NLS-1$
109
currentPath.addExitedBlock(currentBlock);
110         currentBlock = null;
111     }
112     
113     private BasicBlock getBasicBlock(int start, int end) {
114         //TODO: evtl Binaersuche oder letzten Block merken
115
for (int i = 0; i < basicBlocks.length; i++) {
116             if (basicBlocks[i].getStartLine() == start
117                     && basicBlocks[i].getEndLine() == end) {
118                 return basicBlocks[i];
119             }
120         }
121         throw new AssertionError JavaDoc("Block requested that is not in the method!"); //$NON-NLS-1$
122
}
123     
124     /**
125      * This method is called by the code that is woven by the CoverageClassLoader
126      * instrumenting the ByteCodeModifyer.
127      * It indicates a method exit.
128      * It is instrumentalized here to remove duplicate paths.
129      */

130     public void leavingMethod() {
131         // if the path that was taken through the method already is
132
// recorded there is no point in holding it.
133
Iterator JavaDoc iter = paths.iterator();
134         if (iter.hasNext()) {
135             iter.next();
136             while (iter.hasNext()) {
137                 if (currentPath.equals(iter.next())) {
138                     paths.remove(0);
139                     return;
140                 }
141             }
142         }
143     }
144
145     public void acceptVisitor(CoverageNatureVisitor visitor) {
146         visitor.visitCode(this, method.getCode());
147     }
148
149     public JavaClass getJavaClass() {
150         return jclass;
151     }
152     
153     public Method getMethod() {
154         return method;
155     }
156     
157     public void setBasicBlocks(BasicBlock[] blocks) {
158         this.basicBlocks = blocks;
159     }
160     
161     public boolean equals(Object JavaDoc obj) {
162         boolean result = false;
163         if (obj instanceof RegisteredMethod) {
164             RegisteredMethod compMethod = (RegisteredMethod) obj;
165             if (this.method.equals(compMethod.method)
166                     && this.jclass.equals(compMethod.jclass)) {
167                 result = true;
168             }
169         }
170         return result;
171     }
172
173     
174     public int hashCode() {
175         return getHashKey().hashCode();
176     }
177     /**
178      * @return returns a unique string for this RegisteredMethod object that
179      * can be used as hash key.
180      */

181     public String JavaDoc getHashKey() {
182         return createHashKey(this.jclass, this.method);
183     }
184     
185     public static String JavaDoc createHashKey(JavaClass jclass, Method method) {
186         return jclass.getClassName() + ":" + method.toString(); //$NON-NLS-1$
187
}
188     
189     public String JavaDoc toString() {
190         String JavaDoc pathString = ""; //$NON-NLS-1$
191
for (Iterator JavaDoc iter = paths.iterator(); iter.hasNext();) {
192             Path element = (Path) iter.next();
193             pathString += "\t" + element.toString() + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
194
}
195         String JavaDoc result = StringFormatter.format(
196                 "Klasse {0}: Methode {1}\n " + //$NON-NLS-1$
197
"Alle Pfade: \n" + //$NON-NLS-1$
198
"{2}", //$NON-NLS-1$
199
new Object JavaDoc[] {this.jclass.getClassName(),
200                               this.method.getName(),
201                               pathString});
202         return result;
203     }
204     
205     public BasicBlock[] getBasicBlocks() {
206         return basicBlocks;
207     }
208     
209     public Path[] getPaths() {
210         return (Path[]) paths.toArray(new Path[paths.size()]);
211     }
212
213 }
214
Popular Tags