001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2004 Jennifer Lhotak
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package soot.toolkits.graph.interaction;
021:
022: import soot.*;
023: import soot.toolkits.graph.*;
024: import soot.jimple.toolkits.annotation.callgraph.*;
025: import java.util.*;
026: import soot.options.*;
027:
028: public class InteractionHandler {
029:
030: public InteractionHandler(Singletons.Global g) {
031: }
032:
033: public static InteractionHandler v() {
034: return G.v()
035: .soot_toolkits_graph_interaction_InteractionHandler();
036: }
037:
038: private ArrayList<Object> stopUnitList;
039:
040: public ArrayList<Object> getStopUnitList() {
041: return stopUnitList;
042: }
043:
044: public void addToStopUnitList(Object elem) {
045: if (stopUnitList == null) {
046: stopUnitList = new ArrayList<Object>();
047: }
048: stopUnitList.add(elem);
049: }
050:
051: public void removeFromStopUnitList(Object elem) {
052: if (stopUnitList.contains(elem)) {
053: stopUnitList.remove(elem);
054: }
055: }
056:
057: public void handleNewAnalysis(Transform t, Body b) {
058: // here save current phase name and only send if actual data flow analysis exists
059: if (PhaseOptions.getBoolean(PhaseOptions.v().getPhaseOptions(
060: t.getPhaseName()), "enabled")) {
061: String name = t.getPhaseName() + " for method: "
062: + b.getMethod().getName();
063: currentPhaseName(name);
064: currentPhaseEnabled(true);
065: doneCurrent(false);
066: } else {
067: currentPhaseEnabled(false);
068: setInteractThisAnalysis(false);
069: }
070: }
071:
072: public void handleCfgEvent(DirectedGraph g) {
073: if (currentPhaseEnabled()) {
074: G.v().out.println("Analyzing: " + currentPhaseName());
075: doInteraction(new InteractionEvent(
076: IInteractionConstants.NEW_ANALYSIS,
077: currentPhaseName()));
078: }
079: if (isInteractThisAnalysis()) {
080: doInteraction(new InteractionEvent(
081: IInteractionConstants.NEW_CFG, g));
082: }
083: }
084:
085: public void handleStopAtNodeEvent(Object u) {
086: if (isInteractThisAnalysis()) {
087: doInteraction(new InteractionEvent(
088: IInteractionConstants.STOP_AT_NODE, u));
089: }
090: }
091:
092: public void handleBeforeAnalysisEvent(Object beforeFlow) {
093: if (isInteractThisAnalysis()) {
094: if (autoCon()) {
095: doInteraction(new InteractionEvent(
096: IInteractionConstants.NEW_BEFORE_ANALYSIS_INFO_AUTO,
097: beforeFlow));
098: } else {
099: doInteraction(new InteractionEvent(
100: IInteractionConstants.NEW_BEFORE_ANALYSIS_INFO,
101: beforeFlow));
102: }
103: }
104: }
105:
106: public void handleAfterAnalysisEvent(Object afterFlow) {
107: if (isInteractThisAnalysis()) {
108: if (autoCon()) {
109: doInteraction(new InteractionEvent(
110: IInteractionConstants.NEW_AFTER_ANALYSIS_INFO_AUTO,
111: afterFlow));
112: } else {
113: doInteraction(new InteractionEvent(
114: IInteractionConstants.NEW_AFTER_ANALYSIS_INFO,
115: afterFlow));
116: }
117: }
118: }
119:
120: public void handleTransformDone(Transform t, Body b) {
121: doneCurrent(true);
122: if (isInteractThisAnalysis()) {
123: doInteraction(new InteractionEvent(
124: IInteractionConstants.DONE, null));
125: }
126: }
127:
128: public void handleCallGraphStart(Object info,
129: CallGraphGrapher grapher) {
130: setGrapher(grapher);
131: doInteraction(new InteractionEvent(
132: IInteractionConstants.CALL_GRAPH_START, info));
133: if (!isCgReset()) {
134: handleCallGraphNextMethod();
135: } else {
136: setCgReset(false);
137: handleReset();
138: }
139: }
140:
141: public void handleCallGraphNextMethod() {
142: if (!cgDone()) {
143: getGrapher().setNextMethod(getNextMethod());
144: getGrapher().handleNextMethod();
145: }
146: }
147:
148: private boolean cgReset = false;
149:
150: public void setCgReset(boolean v) {
151: cgReset = v;
152: }
153:
154: public boolean isCgReset() {
155: return cgReset;
156: }
157:
158: public void handleReset() {
159: if (!cgDone()) {
160: getGrapher().reset();
161: }
162: }
163:
164: public void handleCallGraphPart(Object info) {
165: doInteraction(new InteractionEvent(
166: IInteractionConstants.CALL_GRAPH_PART, info));
167: if (!isCgReset()) {
168: handleCallGraphNextMethod();
169: } else {
170: setCgReset(false);
171: handleReset();
172: }
173: }
174:
175: private CallGraphGrapher grapher;
176:
177: private void setGrapher(CallGraphGrapher g) {
178: grapher = g;
179: }
180:
181: private CallGraphGrapher getGrapher() {
182: return grapher;
183: }
184:
185: private SootMethod nextMethod;
186:
187: public void setNextMethod(SootMethod m) {
188: nextMethod = m;
189: }
190:
191: private SootMethod getNextMethod() {
192: return nextMethod;
193: }
194:
195: private synchronized void doInteraction(InteractionEvent event) {
196: getInteractionListener().setEvent(event);
197: getInteractionListener().handleEvent();
198:
199: }
200:
201: public synchronized void waitForContinue() {
202: try {
203: this .wait();
204: } catch (InterruptedException e) {
205: }
206:
207: }
208:
209: private boolean interactThisAnalysis;
210:
211: public void setInteractThisAnalysis(boolean b) {
212: interactThisAnalysis = b;
213: }
214:
215: public boolean isInteractThisAnalysis() {
216: return interactThisAnalysis;
217: }
218:
219: private boolean interactionCon;
220:
221: public synchronized void setInteractionCon() {
222: this .notify();
223: }
224:
225: public boolean isInteractionCon() {
226: return interactionCon;
227: }
228:
229: private IInteractionListener interactionListener;
230:
231: public void setInteractionListener(IInteractionListener listener) {
232: interactionListener = listener;
233: }
234:
235: public IInteractionListener getInteractionListener() {
236: return interactionListener;
237: }
238:
239: private String currentPhaseName;
240:
241: public void currentPhaseName(String name) {
242: currentPhaseName = name;
243: }
244:
245: public String currentPhaseName() {
246: return currentPhaseName;
247: }
248:
249: private boolean currentPhaseEnabled;
250:
251: public void currentPhaseEnabled(boolean b) {
252: currentPhaseEnabled = b;
253: }
254:
255: public boolean currentPhaseEnabled() {
256: return currentPhaseEnabled;
257: }
258:
259: private boolean cgDone = false;
260:
261: public void cgDone(boolean b) {
262: cgDone = b;
263: }
264:
265: public boolean cgDone() {
266: return cgDone;
267: }
268:
269: private boolean doneCurrent;
270:
271: public void doneCurrent(boolean b) {
272: doneCurrent = b;
273: }
274:
275: public boolean doneCurrent() {
276: return doneCurrent;
277: }
278:
279: private boolean autoCon;
280:
281: public void autoCon(boolean b) {
282: autoCon = b;
283: }
284:
285: public boolean autoCon() {
286: return autoCon;
287: }
288:
289: public void stopInteraction(boolean b) {
290: Options.v().set_interactive_mode(false);
291: }
292:
293: }
|