Clover coverage report - DrJava Test Coverage (drjava-20120304-r5456)
Coverage timestamp: Sun Mar 4 2012 03:13:23 CST
file stats: LOC: 219   Methods: 13
NCLOC: 125   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
DrJavaErrorHandler.java 0% 1.8% 15.4% 3%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.drjava.ui;
 38   
 39    import javax.swing.JButton;
 40    import java.util.ArrayList;
 41    import javax.swing.JFrame;
 42   
 43    import edu.rice.cs.drjava.DrJava;
 44    import edu.rice.cs.util.UnexpectedException;
 45    import edu.rice.cs.util.swing.Utilities;
 46    import edu.rice.cs.drjava.config.OptionConstants;
 47    //import edu.rice.cs.plt.swing.SwingUtil;
 48    import edu.rice.cs.util.Log;
 49   
 50    /** The handle() method in this class is called every time an uncaught exception propagates to an AWT action.
 51    * The static log() method can be used to put log entries into the error log but continue execution.
 52    * This does not automatically update the "DrJava Errors" window when new errors occur. In the case of errors,
 53    * we want to minimize the effects on the GUI. If we want to see an updated dialog, we can click on the
 54    * "DrJava Errors" button again.
 55    * @version $Id: DrJavaErrorHandler.java 5439 2011-08-11 17:13:04Z rcartwright $
 56    */
 57    public class DrJavaErrorHandler implements Thread.UncaughtExceptionHandler {
 58   
 59    public static final DrJavaErrorHandler INSTANCE = new DrJavaErrorHandler();
 60   
 61  6 private DrJavaErrorHandler() { }
 62   
 63    /** Handles an uncaught exception. This gets called automatically by AWT. */
 64  0 public void uncaughtException(Thread t, Throwable thrown) {
 65  0 record(thrown);
 66    }
 67   
 68    /** the list of errors */
 69    private static volatile ArrayList<Throwable> _errors = new ArrayList<Throwable>();
 70   
 71    /** the button to show */
 72    private static volatile JButton _errorsButton;
 73   
 74    /** Sets the button to show. */
 75  38 public static void setButton(JButton b) { _errorsButton = b; }
 76   
 77    /** Gets the button to show. */
 78  0 public static JButton getButton() { return _errorsButton; }
 79   
 80    /** Returns the size of the error list. */
 81  0 public static int getErrorCount() { return _errors.size(); }
 82   
 83    /** Returns the error with the given index. */
 84  0 public static Throwable getError(int index) {
 85   
 86  0 if (index >= 0 && index < _errors.size()) return _errors.get(index);
 87  0 else return new UnexpectedException("Error in DrJavaErrorHandler");
 88    }
 89   
 90    /** Clears the list of errors. */
 91  0 public static void clearErrors() { _errors.clear(); }
 92   
 93    /** Record the throwable in the errors list. */
 94  0 public static void record(final Throwable thrown) {
 95  0 Utilities.invokeLater(new Runnable() {
 96  0 public void run() {
 97  0 try { // put the entire handler in a try-block so we don't have an exception in here call the exception handler again (infinite loop)
 98  0 if (thrown instanceof OutOfMemoryError) {
 99    // if this is an OutOfMemoryError inside DrJava, try to suggest to increase Main JVM's max heap
 100  0 Runtime.getRuntime().gc();
 101  0 JFrame f = DrJavaErrorWindow.getFrame();
 102  0 if (f instanceof MainFrame) {
 103  0 MainFrame mf = (MainFrame)f;
 104  0 mf.askToIncreaseMasterMaxHeap();
 105    }
 106    }
 107  0 else if (thrown.toString().startsWith("com.sun.jdi.VMOutOfMemoryException")) {
 108    // if this is an VMOutOfMemoryException, suggest to increase Interaction JVM's max heap
 109  0 JFrame f = DrJavaErrorWindow.getFrame();
 110  0 if (f instanceof MainFrame) {
 111  0 MainFrame mf = (MainFrame)f;
 112  0 mf.askToIncreaseSlaveMaxHeap();
 113    }
 114    }
 115  0 else if (isSwingBugArrayIndexOufOfBoundsExceptionInCharWidth(thrown)) {
 116    // we just ignore this exception
 117  0 return;
 118    }
 119  0 _errors.add(thrown);
 120  0 if (_errorsButton != null) {
 121  0 _errorsButton.setVisible(true);
 122    }
 123  0 if (_errors.size() == 1 && ! Utilities.TEST_MODE &&
 124    DrJava.getConfig().getSetting(OptionConstants.DIALOG_DRJAVA_ERROR_POPUP_ENABLED).booleanValue()) {
 125  0 DrJavaErrorPopup popup = new DrJavaErrorPopup(DrJavaErrorWindow.getFrame(), thrown);
 126  0 Utilities.setPopupLoc(popup, popup.getOwner());
 127  0 popup.setVisible(true);
 128    }
 129    }
 130    catch(Throwable t) { /* we're in a bad situation here; an exception in the exception handler cannot be dealt with, so ignore it */ }
 131    }
 132    });
 133    }
 134   
 135    /** Return true if this is an exception thrown because of the Swing bug:
 136    * https://sourceforge.net/tracker/?func=detail&atid=438935&aid=2831821&group_id=44253
 137    * @return true if this is the Swing bug */
 138  0 public static boolean isSwingBugArrayIndexOufOfBoundsExceptionInCharWidth(Throwable thrown) {
 139    // only ignore on Sun/Oracle JVMs
 140  0 if (!edu.rice.cs.plt.reflect.JavaVersion.CURRENT_FULL.vendor().
 141  0 equals(edu.rice.cs.plt.reflect.JavaVersion.VendorType.ORACLE)) return false;
 142   
 143    // only ignore if current version is older than 6.0_18 (6.0_18 > JavaVersion.CURRENT_FULL)
 144  0 if (edu.rice.cs.plt.reflect.JavaVersion.parseFullVersion("6.0_18","Sun","Sun").
 145  0 compareTo(edu.rice.cs.plt.reflect.JavaVersion.CURRENT_FULL)<=0) return false;
 146   
 147  0 if (!(thrown instanceof ArrayIndexOutOfBoundsException)) return false;
 148   
 149  0 StackTraceElement[] stes = new StackTraceElement[] {
 150    new StackTraceElement("sun.font.FontDesignMetrics","charsWidth",null,-1),
 151    new StackTraceElement("javax.swing.text.Utilities","getTabbedTextOffset",null,-1),
 152    new StackTraceElement("javax.swing.text.Utilities","getTabbedTextOffset",null,-1),
 153    new StackTraceElement("javax.swing.text.Utilities","getTabbedTextOffset",null,-1),
 154    new StackTraceElement("javax.swing.text.PlainView","viewToModel",null,-1),
 155    new StackTraceElement("javax.swing.plaf.basic.BasicTextUI$RootView","viewToModel",null,-1),
 156    new StackTraceElement("javax.swing.plaf.basic.BasicTextUI","viewToModel",null,-1)
 157    };
 158   
 159  0 StackTraceElement[] stesBottom = new StackTraceElement[] {
 160    new StackTraceElement("java.awt.EventQueue","dispatchEvent",null,-1),
 161    new StackTraceElement("java.awt.EventDispatchThread","pumpOneEventForFilters",null,-1),
 162    new StackTraceElement("java.awt.EventDispatchThread","pumpEventsForFilter",null,-1),
 163    new StackTraceElement("java.awt.EventDispatchThread","pumpEventsForHierarchy",null,-1),
 164    new StackTraceElement("java.awt.EventDispatchThread","pumpEvents",null,-1),
 165    new StackTraceElement("java.awt.EventDispatchThread","pumpEvents",null,-1),
 166    new StackTraceElement("java.awt.EventDispatchThread","run",null,-1)
 167    };
 168   
 169  0 StackTraceElement[] tst = thrown.getStackTrace();
 170   
 171  0 if (tst.length<stes.length+stesBottom.length) return false;
 172   
 173  0 for(int i=0; i<stes.length; ++i) {
 174  0 if (!stes[i].equals(tst[i])) return false;
 175    }
 176   
 177  0 for(int i=0; i<stesBottom.length; ++i) {
 178  0 if (!stesBottom[stesBottom.length-i-1].equals(tst[tst.length-i-1])) return false;
 179    }
 180   
 181  0 return true;
 182    }
 183   
 184    /** Simulate the Swing bug's exception stack trace. */
 185  0 public static void simulateSwingBugArrayIndexOufOfBoundsExceptionInCharWidth() {
 186  0 StackTraceElement[] stes = new StackTraceElement[] {
 187    new StackTraceElement("sun.font.FontDesignMetrics","charsWidth",null,-1),
 188    new StackTraceElement("javax.swing.text.Utilities","getTabbedTextOffset",null,-1),
 189    new StackTraceElement("javax.swing.text.Utilities","getTabbedTextOffset",null,-1),
 190    new StackTraceElement("javax.swing.text.Utilities","getTabbedTextOffset",null,-1),
 191    new StackTraceElement("javax.swing.text.PlainView","viewToModel",null,-1),
 192    new StackTraceElement("javax.swing.plaf.basic.BasicTextUI$RootView","viewToModel",null,-1),
 193    new StackTraceElement("javax.swing.plaf.basic.BasicTextUI","viewToModel",null,-1),
 194   
 195    new StackTraceElement("foo","bar",null,-1),
 196    new StackTraceElement("foo","bar",null,-1),
 197   
 198    new StackTraceElement("java.awt.EventQueue","dispatchEvent",null,-1),
 199    new StackTraceElement("java.awt.EventDispatchThread","pumpOneEventForFilters",null,-1),
 200    new StackTraceElement("java.awt.EventDispatchThread","pumpEventsForFilter",null,-1),
 201    new StackTraceElement("java.awt.EventDispatchThread","pumpEventsForHierarchy",null,-1),
 202    new StackTraceElement("java.awt.EventDispatchThread","pumpEvents",null,-1),
 203    new StackTraceElement("java.awt.EventDispatchThread","pumpEvents",null,-1),
 204    new StackTraceElement("java.awt.EventDispatchThread","run",null,-1)
 205    };
 206  0 ArrayIndexOutOfBoundsException t = new ArrayIndexOutOfBoundsException(63);
 207  0 t.setStackTrace(stes);
 208  0 t.printStackTrace(System.out);
 209  0 throw t;
 210    }
 211   
 212    /** Log an unexpected situation. */
 213  0 public static void log(String message) { record(new LoggedCondition(message)); }
 214   
 215    /** The throwable used for logging unexpected situations. */
 216    public static class LoggedCondition extends Throwable {
 217  0 public LoggedCondition(String s) { super(s); }
 218    }
 219    }