Package samples.callgraph

Source Code of samples.callgraph.CallGraphMonitor

package samples.callgraph;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Stack;

import javax.swing.JFrame;

import org.apache.log4j.Category;
import org.apache.log4j.PropertyConfigurator;

import salvo.jesus.graph.DirectedEdgeImpl;
import salvo.jesus.graph.EdgeImpl;
  import salvo.jesus.graph.Graph;
//  import salvo.jesus.graph.GraphImpl;
import salvo.jesus.graph.Tree;
import salvo.jesus.graph.TreeImpl;
import salvo.jesus.graph.Vertex;
import salvo.jesus.graph.visual.GraphEditor;
import salvo.jesus.graph.visual.VisualGraph;
//import salvo.jesus.graph.visual.layout.ForceDirectedLayout;
import salvo.jesus.graph.visual.layout.GraphLayoutManager;
import salvo.jesus.graph.visual.layout.LayeredTreeLayout;
//import salvo.jesus.graph.visual.layout.OrthogonalLineLayout;

import alt.jiapi.InstrumentationContext;
import alt.jiapi.InstrumentationDescriptor;
import alt.jiapi.event.MethodEvent;
import alt.jiapi.event.MethodEventProducer;
import alt.jiapi.event.MethodListener;
import alt.jiapi.reflect.Loader;
import alt.jiapi.util.InstrumentingClassLoader;

public class CallGraphMonitor extends JFrame implements MethodListener {
    private static Category log = Category.getInstance(CallGraphMonitor.class.getName());
   
    private Stack callStack;
    private Map createdClasses;
    private int count = 1;

    //    private Graph graph;
    private Tree tree;
    private VisualGraph visual;
    private GraphEditor editor;
    //private ForceDirectedLayout layout;
    //    private OrthogonalLineLayout layout;
    private GraphLayoutManager layout;

    public CallGraphMonitor(Properties props) throws Exception {
        PropertyConfigurator.configure(props);

        editor = new GraphEditor();
        //        graph = new GraphImpl();
        tree = new TreeImpl();
        visual = editor.getVisualGraph();
        callStack = new Stack();
        createdClasses = new HashMap();

        //        visual.setGraph(graph);
        editor.setGraph(tree);

        this.getContentPane().setLayout(new GridLayout(1,2));
        this.getContentPane().add(editor);

        //layout = new OrthogonalLineLayout(visual);
//          layout = new ForceDirectedLayout(visual);
//          layout.setIncrement(0.001);
        layout = new LayeredTreeLayout(visual);
        editor.setGraphLayoutManager(layout);

        this.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) { System.exit(0); }
            });
       
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = new Dimension(screenSize.width - 80,
                                            screenSize.height - 200);

        this.setSize(frameSize);
        this.setLocation((int)(screenSize.getWidth() - frameSize.getWidth()) / 2, (int)(screenSize.getHeight() - frameSize.getHeight()) / 2);

        //        layout.layout();       
    }


    // MethodListener callbacks
    public void constructorEntered(MethodEvent event) {
    }

    public void constructorExited(MethodEvent event) {
    }

    public void methodEntered(MethodEvent event) {
        enterMethod(event.getClassName(), event.getMethodName());
    }

    public void methodExited(MethodEvent event){
        exitMethod(event.getClassName(), event.getMethodName());
    }

    private void enterMethod(String className, String methodName) {
//           try {
//               Thread.currentThread().sleep(1000);
//           } catch (Exception e) {
//           }
        log.debug(className + "." + methodName + " entered");
        //        ClassVertex classVertex = (ClassVertex) createdClasses.get(className);
        //    if (classVertex == null) {
            //    createdClasses.put(className, classVertex);
//              try {
//                  tree.add(classVertex);
//              } catch (Exception e) {
//                  log.error(e.getMessage(), e);
//              }
            //        }

        ClassVertex classVertex = null;
        if (!callStack.empty()) {
            ClassVertex parent = (ClassVertex) callStack.peek();
            if (parent.hasChild(className)) {
                classVertex = parent.getChild(className);
                MethodEdge edge = parent.getEdge(className);
                edge.addMethodCall(methodName, count);
                // NOTE! A kludge to refresh edge name.
                try {
                    tree.removeEdge(edge);
                    tree.addEdge(edge);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
            else {
                classVertex = new ClassVertex(className);
                MethodEdge edge = null;
                try {
                    tree.add(classVertex);
                    edge = new MethodEdge(parent, classVertex);
                    edge.addMethodCall(methodName, count);
                    tree.addEdge(edge);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }

                parent.addChild(classVertex, edge);
            }
           
            log.debug("added edge from " + parent.getName() +
                      " to " + classVertex.getName());
        }
        else {
            try {
                classVertex = new ClassVertex(className);
                tree.addNode(null, classVertex);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
       
        callStack.push(classVertex);
        count++;
        visual.layout();
    }

    private void exitMethod(String className, String methodName) {
        log.debug(className + "." + methodName + " exited");
        // This cannot be null since it is impossible to exit a method
        // without first entering it.
        //     ClassVertex classVertex = (ClassVertex) createdClasses.get(className);

        try {
            ClassVertex parent = (ClassVertex) callStack.pop();
//              if (parent != null) {
//                  parent.finishMethodCall();
//              }
        } catch (EmptyStackException ese) {
        }
    }

    public static void main(String[] args) throws Exception {
        InputStream config = new BufferedInputStream(new FileInputStream(args[0]));
        Properties props = new Properties();
        props.load(config);

        CallGraphMonitor monitor = new CallGraphMonitor(props);
        monitor.setTitle("CallGraphMonitor");
        monitor.setVisible(true);

        log.debug("created CallGraphMonitor");
        try {
            Thread.currentThread().sleep(1000);
        }
        catch (Exception e) {
        }

        log.debug("creating the InstrumentationDescriptor");
        InstrumentationContext ctx = new InstrumentationContext();
       
        InstrumentationDescriptor id = new InstrumentationDescriptor();
        id.addInclusionRule("test.callgraph");
        MethodEventProducer eventProducer = new MethodEventProducer(id);
        eventProducer.addMethodListener(monitor);
        ctx.addInstrumentationDescriptor(id);

        log.debug("creating a class loader");
        ClassLoader cl = InstrumentingClassLoader.createClassLoader(ctx);
       
        log.debug("loading classes");
        Class clazz = cl.loadClass("test.callgraph.Main");

        log.debug("starting program");
        java.lang.reflect.Method m =
            clazz.getMethod("main", new Class[] {String[].class});

        String []restArgs = new String[args.length - 1];
        for (int i = 1; i < args.length; i++) {
            restArgs[i - 1] = args[i];           
        }

        for (int i = 0; i < restArgs.length; i++) {
            System.out.println(i + ": " + restArgs[i]);
        }

        m.invoke(clazz, new Object[] {restArgs});

        log.debug("main thread dying");
    }
}
TOP

Related Classes of samples.callgraph.CallGraphMonitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.