/* Soot - a J*va Optimization Framework
* Copyright (C) 2004 Jennifer Lhotak
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package soot.toolkits.graph.interaction;
import soot.*;
import soot.toolkits.graph.*;
import soot.jimple.toolkits.annotation.callgraph.*;
import java.util.*;
import soot.options.*;
public class InteractionHandler {
public InteractionHandler(Singletons.Global g){}
public static InteractionHandler v() { return G.v().soot_toolkits_graph_interaction_InteractionHandler();}
private ArrayList<Object> stopUnitList;
public ArrayList<Object> getStopUnitList(){
return stopUnitList;
}
public void addToStopUnitList(Object elem){
if (stopUnitList == null){
stopUnitList = new ArrayList<Object>();
}
stopUnitList.add(elem);
}
public void removeFromStopUnitList(Object elem){
if (stopUnitList.contains(elem)){
stopUnitList.remove(elem);
}
}
public void handleNewAnalysis(Transform t, Body b){
// here save current phase name and only send if actual data flow analysis exists
if (PhaseOptions.getBoolean(PhaseOptions.v().getPhaseOptions( t.getPhaseName()), "enabled")){
String name = t.getPhaseName()+" for method: "+b.getMethod().getName();
currentPhaseName(name);
currentPhaseEnabled(true);
doneCurrent(false);
}
else {
currentPhaseEnabled(false);
setInteractThisAnalysis(false);
}
}
public void handleCfgEvent(DirectedGraph g){
if (currentPhaseEnabled()){
G.v().out.println("Analyzing: "+currentPhaseName());
doInteraction(new InteractionEvent(IInteractionConstants.NEW_ANALYSIS, currentPhaseName()));
}
if (isInteractThisAnalysis()){
doInteraction(new InteractionEvent(IInteractionConstants.NEW_CFG, g));
}
}
public void handleStopAtNodeEvent(Object u){
if (isInteractThisAnalysis()){
doInteraction(new InteractionEvent(IInteractionConstants.STOP_AT_NODE, u));
}
}
public void handleBeforeAnalysisEvent(Object beforeFlow){
if (isInteractThisAnalysis()){
if (autoCon()){
doInteraction(new InteractionEvent(IInteractionConstants.NEW_BEFORE_ANALYSIS_INFO_AUTO, beforeFlow));
}
else{
doInteraction(new InteractionEvent(IInteractionConstants.NEW_BEFORE_ANALYSIS_INFO, beforeFlow));
}
}
}
public void handleAfterAnalysisEvent(Object afterFlow){
if (isInteractThisAnalysis()){
if (autoCon()){
doInteraction(new InteractionEvent(IInteractionConstants.NEW_AFTER_ANALYSIS_INFO_AUTO, afterFlow));
}
else {
doInteraction(new InteractionEvent(IInteractionConstants.NEW_AFTER_ANALYSIS_INFO, afterFlow));
}
}
}
public void handleTransformDone(Transform t, Body b){
doneCurrent(true);
if (isInteractThisAnalysis()){
doInteraction(new InteractionEvent(IInteractionConstants.DONE, null));
}
}
public void handleCallGraphStart(Object info, CallGraphGrapher grapher){
setGrapher(grapher);
doInteraction(new InteractionEvent(IInteractionConstants.CALL_GRAPH_START, info));
if (!isCgReset()){
handleCallGraphNextMethod();
}
else {
setCgReset(false);
handleReset();
}
}
public void handleCallGraphNextMethod(){
if (!cgDone()){
getGrapher().setNextMethod(getNextMethod());
getGrapher().handleNextMethod();
}
}
private boolean cgReset = false;
public void setCgReset(boolean v){
cgReset = v;
}
public boolean isCgReset(){
return cgReset;
}
public void handleReset(){
if (!cgDone()){
getGrapher().reset();
}
}
public void handleCallGraphPart(Object info){
doInteraction(new InteractionEvent(IInteractionConstants.CALL_GRAPH_PART, info));
if (!isCgReset()){
handleCallGraphNextMethod();
}
else {
setCgReset(false);
handleReset();
}
}
private CallGraphGrapher grapher;
private void setGrapher(CallGraphGrapher g){
grapher = g;
}
private CallGraphGrapher getGrapher(){
return grapher;
}
private SootMethod nextMethod;
public void setNextMethod(SootMethod m){
nextMethod = m;
}
private SootMethod getNextMethod(){
return nextMethod;
}
private synchronized void doInteraction(InteractionEvent event){
getInteractionListener().setEvent(event);
getInteractionListener().handleEvent();
}
public synchronized void waitForContinue(){
try {
this.wait();
}
catch (InterruptedException e){
}
}
private boolean interactThisAnalysis;
public void setInteractThisAnalysis(boolean b){
interactThisAnalysis = b;
}
public boolean isInteractThisAnalysis(){
return interactThisAnalysis;
}
private boolean interactionCon;
public synchronized void setInteractionCon(){
this.notify();
}
public boolean isInteractionCon(){
return interactionCon;
}
private IInteractionListener interactionListener;
public void setInteractionListener(IInteractionListener listener){
interactionListener = listener;
}
public IInteractionListener getInteractionListener(){
return interactionListener;
}
private String currentPhaseName;
public void currentPhaseName(String name){
currentPhaseName = name;
}
public String currentPhaseName(){
return currentPhaseName;
}
private boolean currentPhaseEnabled;
public void currentPhaseEnabled(boolean b){
currentPhaseEnabled = b;
}
public boolean currentPhaseEnabled(){
return currentPhaseEnabled;
}
private boolean cgDone = false;
public void cgDone(boolean b){
cgDone = b;
}
public boolean cgDone(){
return cgDone;
}
private boolean doneCurrent;
public void doneCurrent(boolean b){
doneCurrent = b;
}
public boolean doneCurrent(){
return doneCurrent;
}
private boolean autoCon;
public void autoCon(boolean b){
autoCon = b;
}
public boolean autoCon(){
return autoCon;
}
public void stopInteraction(boolean b){
Options.v().set_interactive_mode(false);
}
}