001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-10-4
005     * Time: 16:54:10
006     * To change template for new class use 
007     * Code Style | Class Templates options (Tools | IDE Options).
008     */
009    package EVolve.util;
010    
011    import java.util.*;
012    
013    public class MethodInvokingTrace {
014        private ArrayList trace, stack;
015        private int invocationNum;
016        //private ReferenceDimension xAxis;
017    
018        public MethodInvokingTrace() {
019            trace = new ArrayList();
020            stack = new ArrayList();
021            invocationNum = 0;
022        }
023    
024        public void updateMethodTrace(int calleeId, boolean methodEntry) {
025        int[] methodFootprint = new int[2];
026    
027            methodFootprint[0] = calleeId;
028            methodFootprint[1] = methodEntry ? 1 : 0; // 1 means a entry event, 0 means exit event
029            if (!methodEntry && (trace.size() == 0)) return;
030    
031            if (methodEntry) invocationNum++;
032            trace.add(methodFootprint);
033        }
034    
035        public void updateMethodTrace2(int calleeId) {
036            trace.add(new Integer(calleeId));
037        }
038    
039        public ArrayList getCallerChains(int callerId,int calleeId) {
040            ArrayList returnVal = new ArrayList();
041            ArrayList callerChain;
042            int footprint[];
043    
044            stack.clear();
045            for (int i = 0; i<trace.size(); i++) {
046                footprint = (int[])trace.get(i);
047            
048                if (footprint[1] == 0) {// method exit
049                    if (stack.size() != 0) stack.remove(stack.size()-1);
050                }
051                else {
052                    stack.add(new Integer(footprint[0]));
053                    if ((stack.size()>=2) &&
054                        (((Integer)stack.get(stack.size()-1)).intValue() == calleeId) &&
055                        (((Integer)stack.get(stack.size()-2)).intValue() == callerId)) {
056                        callerChain = (ArrayList)stack.clone();
057                        callerChain.remove(callerChain.size()-1);
058                        returnVal.add(callerChain);
059                    }
060                }
061    
062            }
063    
064            // remove duplicates
065            ArrayList temp = new ArrayList(), tempReturnVal = new ArrayList();
066            for (int i = 1; i< returnVal.size(); i++) {
067                temp = (ArrayList)returnVal.get(i-1);
068                boolean found = false;
069                for (int j=i; j<returnVal.size(); j++) {
070                    callerChain = (ArrayList)returnVal.get(j);
071                    if (temp.size() != callerChain.size())
072                        continue;
073                    for (int k=0; k< temp.size(); k++) {
074                        if (((Integer)temp.get(k)).intValue() != ((Integer)callerChain.get(k)).intValue()) {
075                            found = false;
076                            break;
077                        }
078                        found = true;
079                    }
080                    if (found) break;
081                }
082                if (!found)
083                    tempReturnVal.add(temp);
084            }
085            if (tempReturnVal.size()>0)
086                returnVal = tempReturnVal;
087            return returnVal;
088        }
089        
090        public ArrayList getCallerChain(int callerId, int calleeId) {
091            ArrayList callerChain = new ArrayList();
092            int[] footprint;
093    
094            callerChain.add(new Integer(callerId));
095            stack.clear();
096            for (int i = 0; i<trace.size(); i++) {
097                footprint = (int[])trace.get(i);
098    
099                if (footprint[1] == 0) { // method exit event
100                    if (stack.size() != 0) stack.remove(stack.size()-1);
101                } else {
102                    stack.add(new Integer(footprint[0]));
103                    if ((stack.size()>=2) &&
104                        (((Integer)stack.get(stack.size()-1)).intValue() == calleeId) &&
105                        (((Integer)stack.get(stack.size()-2)).intValue() == callerId)) {
106                        callerChain = (ArrayList)stack.clone();
107                        callerChain.remove(callerChain.size()-1);
108                        break;
109                    }
110                }
111            }
112    
113            return callerChain;
114        }
115    
116        public ArrayList getCallees(int callerId, int calleeId) {
117            ArrayList callees = new ArrayList();
118            int footprint[],i;
119    
120            stack.clear();
121            for (i = 0; i<trace.size(); i++) {
122                footprint = (int[])trace.get(i);
123    
124                if (footprint[1] == 0) { // method exit event
125                    if (stack.size() != 0) stack.remove(stack.size()-1);
126                } else {
127                    stack.add(new Integer(footprint[0]));
128                    if ((stack.size()>=3) &&
129                        (((Integer)stack.get(stack.size()-2)).intValue() == calleeId) &&
130                        (((Integer)stack.get(stack.size()-3)).intValue() == callerId)) {
131                        callees.add(new Integer(footprint[0]));
132                    }
133                }
134            }
135    
136            // remove duplicates
137            ArrayList temp = new ArrayList();
138            for (i=0; i<callees.size();i++) {
139                int value = ((Integer)callees.get(i)).intValue();
140                boolean found = false;
141                if (i==0) {
142                    temp.add(new Integer(value));
143                    continue;
144                }
145                for (int j=0; j<temp.size();j++) {
146                    if (value == ((Integer)temp.get(j)).intValue()) {
147                        found = true;
148                        break;
149                    }
150                }
151                if (!found)
152                    temp.add(new Integer(value));
153            }
154            callees = temp;
155            return callees;
156        }
157    
158        public int size() {
159            return trace.size();
160        }
161    
162        public ArrayList getMethodTrace() {
163            return trace;
164        }
165    }