alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.test.debugger.Util;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import org.openide.TopManager;
import org.openide.src.ClassElement;
import org.openide.src.MethodElement;
import org.openide.src.ConstructorElement;
import org.openide.debugger.Watch;
import org.openide.debugger.Debugger;
import org.openide.debugger.Breakpoint;
import org.openide.debugger.DebuggerNotFoundException;
import org.openide.debugger.DebuggerInfo;
import org.openide.debugger.DebuggerException;
import org.openide.text.Line;

/**
 * Common methods used in automated test's of debugger. These methods are
 * using only Open API and not API of the debugger modules.
 *
 * @author Jan Stola
 */
public class DebuggerOpenAPI extends Object {
    
    /**
     * Returns default debugger of the IDE.
     *
     * @return default debugger of the IDE or null if there
     * are problems with obtaining that debugger.
     */
    public static Debugger getDebugger() {
        try {
            Debugger d=TopManager.getDefault().getDebugger();
            if (d == null) {
                Common.error="Can not find debugger instance.";
                return null;
            }
            return d;
        } catch (DebuggerNotFoundException e) {
            Common.error="Can not find debugger instance. "+Common.getString(e)+".";
            return null;
        }
    }
    
    /**
     * Starts the debugger. The debugged application is specified by name
     * of its main class.
     *
     * @param className name of the main class of the debugged application.
     * @param argv arguments passed to the debugged application.
     * @param stopClassName name of the class the debugger should stop in.
     * @return true if debugged application was started successfully
     * and the debugger stopped on some breakpoint. Returns false
     * otherwise.
     */
    public static boolean start(String className, String[] argv, String stopClassName) {
        Debugger d=getDebugger();
        DebuggerStateListener pcl=new DebuggerStateListener();
        d.addPropertyChangeListener(pcl);
        synchronized (pcl) {
            DebuggerInfo di = new DebuggerInfo(className, argv, stopClassName);
            try {
                d.startDebugger(di);
            } catch (DebuggerException e) {
                Common.error="Problems with start of the debugger. "+Common.getString(e)+".";
                return false;
            }
            try {
                pcl.wait(30000);
            } catch (InterruptedException e) {
            }
        }
        d.removePropertyChangeListener(pcl);
        return d.getState()==Debugger.DEBUGGER_STOPPED;
    }
    
    /**
     * Finishes debugger.
     *
     * @return true if the debugger was successfully finished.
     * Returns false otherwise.
     */
    public static boolean finish() {
        Debugger d=getDebugger();
        try {
            d.finishDebugger();
        } catch (DebuggerException e) {
            Common.error="Problems with finish of the debugger. "+Common.getString(e)+".";
            return false;
        }
        return true;
    }
    
    /**
     * Continues debugging.
     *
     * @return true if the debugger stopped on some breakpoint.
     * Returns false otherwise.
     */
    public static boolean go() {
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        Debugger d=getDebugger();
        DebuggerStateListener pcl=new DebuggerStateListener();
        d.addPropertyChangeListener(pcl);
        synchronized (pcl) {
            try {
                d.go();
            } catch (DebuggerException e) {
                Common.error="Problems with continue. "+Common.getString(e)+".";
                return false;
            }
            try {
                pcl.wait(30000);
            } catch (InterruptedException e) {
            }
        }
        d.removePropertyChangeListener(pcl);
        return d.getState()==Debugger.DEBUGGER_STOPPED;
    }
    
    /**
     * Steps into.
     *
     * @return true if the debugger succesfully stepped into
     * and didn't finish. Returns false otherwise.
     */
    public static boolean stepInto() {
        Debugger d=getDebugger();
        DebuggerStateListener pcl=new DebuggerStateListener();
        d.addPropertyChangeListener(pcl);
        synchronized (pcl) {
            try {
                d.traceInto();
            } catch (DebuggerException e) {
                Common.error="Problems with step into. "+Common.getString(e)+".";
                return false;
            }
            try {
                pcl.wait(30000);
            } catch (InterruptedException e) {
            }
        }
        d.removePropertyChangeListener(pcl);
        return d.getState()==Debugger.DEBUGGER_STOPPED;
    }
    
    /**
     * Steps over.
     *
     * @return true if the debugger succesfully stepped over
     * and didn't finish. Returns false otherwise.
     */
    public static boolean stepOver() {
        Debugger d=getDebugger();
        DebuggerStateListener pcl=new DebuggerStateListener();
        d.addPropertyChangeListener(pcl);
        synchronized (pcl) {
            try {
                d.traceOver();
            } catch (DebuggerException e) {
                Common.error="Problems with step over. "+Common.getString(e)+".";
                return false;
            }
            try {
                pcl.wait(30000);
            } catch (InterruptedException e) {
            }
        }
        d.removePropertyChangeListener(pcl);
        return d.getState()==Debugger.DEBUGGER_STOPPED;
    }
    
    /**
     * Steps out.
     *
     * @return true if the debugger succesfully stepped out
     * and didn't finish. Returns false otherwise.
     */
    public static boolean stepOut() {
        Debugger d=getDebugger();
        DebuggerStateListener pcl=new DebuggerStateListener();
        d.addPropertyChangeListener(pcl);
        synchronized (pcl) {
            try {
                d.stepOut();
            } catch (DebuggerException e) {
                Common.error="Problems with step out. "+Common.getString(e)+".";
                return false;
            }
            try {
                pcl.wait(30000);
            } catch (InterruptedException e) {
            }
        }
        d.removePropertyChangeListener(pcl);
        return d.getState()==Debugger.DEBUGGER_STOPPED;
    }
    
    /**
     * Adds line breakpoint on the lineNumber in the class
     * specified by className.
     *
     * @param className name of the class the created breakpoint belongs to.
     * @param lineNumber line number of the breakpoint.
     * @return newly created Breakpoint or null
     * if the creation was not successful.
     */
    public static Breakpoint addLineBreakpoint(String className, int lineNumber) {
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        Line l = Common.getLineFor(className, lineNumber);
        if (l == null) {
            Common.error+="Cannot obtain Line object for "+className+":"+lineNumber+".";
            return null;
        }
        Debugger d=getDebugger();
        if (d == null) return null;
        Breakpoint b = d.createBreakpoint(l);
        if (b == null) {
            Common.error="Can not create breakpoint on line.";
            return null;
        }
        //PENDING
        b.setEnabled(false);
        b.setEnabled(true);
        return b;
    }
    
    /**
     * Looks for line breakpoint on given lineNumber in the class
     * of the given className.
     *
     * @param className name of the class the desired breakpoint belongs to.
     * @param lineNumber line number of the desired breakpoint.
     * @return Breakpoint that match the given arguments or
     * null if such breakpoint doesn't exist.
     */
    public static Breakpoint findLineBreakpoint(String className, int lineNumber) {
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        Line l = Common.getLineFor(className, lineNumber);
        if (l == null) return null;
        Debugger d = getDebugger();
        if (d == null) return null;
        return d.findBreakpoint(l);
    }
    
    /**
     * Adds method breakpoint on constructor of the class specified by its
     * className.
     *
     * @param className name of the class the created breakpoint belongs to.
     * @return newly created Breakpoint or null
     * if the creation was not successful.
     */
    public static Breakpoint addConstructorBreakpoint(String className) {
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        ClassElement ce = ClassElement.forName(className);
        if (ce == null) {
            Common.error="Cannot create classElement "+className+".";
            return null;
        }
        ConstructorElement cos[]=ce.getConstructors();
        if ((cos==null)||(cos.length==0)) {
            Common.error="Cannot find constructor in class "+className+".";
            return null;
        }
        Debugger d = getDebugger();
        if (d == null) return null;
        Breakpoint b = d.createBreakpoint(cos[0]);
        if (b == null) {
            Common.error="Can not create breakpoint on initializer.";
            return null;
        }
        //PENDING
        b.setEnabled(false);
        b.setEnabled(true);
        return b;
    }
    
    /**
     * Adds method breakpoint on the method with given methodName
     * that belongs to the class with given className.
     *
     * @param className name of the class the created breakpoint belongs to.
     * @param methodName name of the method the new breakpoint is created on.
     * @return newly created Breakpoint or null
     * if the creation was not successful.
     */
    public static Breakpoint addMethodBreakpoint(String className, String methodName) {
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        MethodElement me = Common.getMethodElement(className, methodName);
        if (me == null) {
            Common.error+="Cannot obtain method element for "+className+"."+methodName+".";
            return null;
        }
        Debugger d = getDebugger();
        if (d == null) return null;
        Breakpoint b = d.createBreakpoint(me);
        if (b == null) {
            Common.error="Can not create breakpoint on MethodElement.";
            return null;
        }
        //PENDING
        b.setEnabled(false);
        b.setEnabled(true);
        return b;
    }
    
    /**
     * Looks for method breakpoint on the method with given methodName
     * that belongs to the class with given className.
     *
     * @param className name of the class the desired breakpoint belongs to.
     * @param methodName name of the method the desired breakpoint is set on.
     * @return Breakpoint that match the given arguments or
     * null if such breakpoint doesn't exist.
     */
    public static Breakpoint findMethodBreakpoint(String className, String methodName) {
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        try {
            MethodElement me = Common.getMethodElement(className, methodName);
            if (me == null) {
                Common.error+="Cannot obtain method element for "+className+"."+methodName+".";
                return null;
            }
            Debugger d = getDebugger();
            if (d == null) return null;
            return d.findBreakpoint(me);
        } catch (Exception e) {
            Common.error="Exception thrown while looking for method breakpoint. "+Common.getString(e)+".";
            return null;
        }
    }
    
    /**
     * Looks for the method breakpoint set on the class with given
     *  className.
     *
     * @param className name of the class the desired breakpoint belongs to.
     * @return Breakpoint set on the constructor of the class
     * with given className or null if such breakpoint
     * doesn't exist.
     */
    public static Breakpoint findConstructorBreakpoint(String className) {
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        try {
            ClassElement ce = ClassElement.forName(className);
            if (ce == null) {
                Common.error+="Cannot find class element for class "+className+".";
                return null;
            }
            ConstructorElement cos[]=ce.getConstructors();
            if ((cos==null)||(cos.length==0)) {
                Common.error="Cannot find constructor in class "+className+".";
                return null;
            }
            Debugger d = getDebugger();
            if (d == null) return null;
            return d.findBreakpoint(cos[0]);
        } catch (Exception e) {
            Common.error="Exception thrown while looking for method breakpoint on constructor. "+Common.getString(e)+".";            
            return null;
        }
    }
    
    /**
     * Prints the line the debugger is stopped on.
     *
     * @return the line the debugger is stopped on.
     */
    public static Line getCurrentLine() {
        final Object o=new Object();
        Debugger d = getDebugger();
        if (d == null) return null;
        Line l;
        synchronized (o) {
            l=d.getCurrentLine();
            if (l==null) {
                PropertyChangeListener pcl;
                d.addPropertyChangeListener(pcl=new PropertyChangeListener() {
                    public void propertyChange(PropertyChangeEvent e) {
                        String s = e.getPropertyName();
                        if ((s == null)||!s.equals(org.openide.debugger.Debugger.PROP_CURRENT_LINE)) return;
                        synchronized (o) {
                            o.notify();
                        }
                    }
                });
                l=d.getCurrentLine();
                if (l==null) {
                    try {
                        o.wait(30000);
                    } catch (InterruptedException e) {
                    }
                }
                l=d.getCurrentLine();
                d.removePropertyChangeListener(pcl);
            }
        }        
        return l;
    }
        
    private static final boolean noGoToAtFinish = System.getProperty("os.name").toLowerCase().indexOf("windows") != (-1);
    
    /**
     * Continues debugging and expecting the debugger to finish.
     * If the debugger stop on some breakpoint then its finished.
     * The editor with the source code of the class specified by
     * its className is closed.
     *
     * @param className name of the class to finish. Editor with this class
     * will be closed.
     * @return true if the debugger finished. Returns
     * false otherwise.
     */
    public static boolean goToFinish(String className) {
        if (noGoToAtFinish) {
            boolean result = finish();
            
            Common.closeEditor(className);
            return result;
        }
        
        //PENDING
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
        }
        //PENDING Debugger finished is not fired correctly for the delegating
        // debugger, by now. So, it's necessary to obtain current debugger.
        org.netbeans.modules.debugger.delegator.DelegatingDebugger dd=
        (org.netbeans.modules.debugger.delegator.DelegatingDebugger)getDebugger();        
        Debugger d=dd.getCurrentDebugger();        
        DebuggerStateListener pcl=new DebuggerStateListener();
        d.addPropertyChangeListener(pcl);
        synchronized (pcl) {
            try {
                dd.go();
            } catch (DebuggerException e) {
                Common.error="Problems with go to finish. "+Common.getString(e)+".";
                return false;
            }
            try {
                pcl.wait(30000);
            } catch (InterruptedException e) {
            }
        }
        d.removePropertyChangeListener(pcl);
        boolean result;
        if (d.getState()==Debugger.DEBUGGER_STOPPED) {            
            finish();
            Common.error="Debugger stopped instead of finished. "+getCurrentLine()+".";
            result=false;
        } else {
            result=true;
        }
        Common.closeEditor(className);
        return result;
    }
    
    /**
     * Returns value of the given watch.
     *
     * @param w watch whose value we want to obtain.
     * @return value of the given watch.
     */
    public static String getWatchValue(final Watch w) {
        String s;
        synchronized (w) {
            s=w.getAsText();
            if ((s==null)||("null".equals(s))) {
                PropertyChangeListener pcl;
                w.addPropertyChangeListener(pcl=new PropertyChangeListener() {
                    public void propertyChange(PropertyChangeEvent e) {
                        String ss = e.getPropertyName();
                        if (ss==null) {
                            if ((w.getAsText()==null)||("null".equals(w.getAsText()))) return;
                        } else {
                            if (!ss.equals(org.openide.debugger.Watch.PROP_AS_TEXT)) return;
                        }
                        synchronized (w) {
                            w.notify();
                        }
                    }
                });
                s=w.getAsText();
                if ((s==null)||("null".equals(s))) {
                    try {
                        w.wait(10000);
                    } catch (InterruptedException e) {
                    }
                }
                s=w.getAsText();
                w.removePropertyChangeListener(pcl);
            }
        }
        return s;
    }    
        
}

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.