Clover coverage report - DrJava Test Coverage (drjava-20120422-r5456)
Coverage timestamp: Sun Apr 22 2012 03:13:25 CDT
file stats: LOC: 329   Methods: 32
NCLOC: 178   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
InteractionsDJDocument.java 11.8% 33% 50% 31.9%
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.model.repl;
 38   
 39    import edu.rice.cs.drjava.model.AbstractDJDocument;
 40    import edu.rice.cs.drjava.model.definitions.indent.Indenter;
 41    import edu.rice.cs.drjava.model.definitions.CompoundUndoManager;
 42    import edu.rice.cs.drjava.model.GlobalEventNotifier;
 43   
 44    import edu.rice.cs.plt.tuple.Pair;
 45    import edu.rice.cs.util.UnexpectedException;
 46    import edu.rice.cs.util.text.EditDocumentException;
 47    import edu.rice.cs.util.text.ConsoleDocumentInterface;
 48    import edu.rice.cs.util.text.ConsoleDocument;
 49    import edu.rice.cs.util.swing.Utilities;
 50   
 51    import java.awt.*;
 52    import java.util.List;
 53    import java.util.LinkedList;
 54    import javax.swing.text.AbstractDocument;
 55    import javax.swing.undo.*;
 56   
 57    import static edu.rice.cs.drjava.model.definitions.ColoringView.*;
 58   
 59    /** Represents a Swing-based InteractionsDocument. Extends AbstractDJDocument which contains code shared by
 60    * the Swing interactions and definitions documents.
 61    */
 62    public class InteractionsDJDocument extends AbstractDJDocument implements ConsoleDocumentInterface {
 63   
 64    /** Whether the document currently has a prompt and is ready to accept input. */
 65    private volatile boolean _hasPrompt;
 66   
 67    /** A flag indicating that the interpreter was recently reset, and to reset the styles list
 68    * the next time a style is added. Cannot reset immediately because then the styles would be lost while
 69    * the interactions pane is resetting.
 70    */
 71    private volatile boolean _toClear = false;
 72   
 73    // fields for use by undo/redo functionality
 74    private static final int UNDO_LIMIT = 100;
 75    private volatile CompoundUndoManager _undoManager;
 76    private volatile boolean _isModifiedSinceSave = false;
 77    private volatile GlobalEventNotifier _notifier;
 78   
 79    /** Standard constructor. */
 80  443 public InteractionsDJDocument() {
 81  443 super();
 82  443 _hasPrompt = false;
 83  443 _notifier = new GlobalEventNotifier(); // so this isn't null
 84    }
 85   
 86   
 87  316 public InteractionsDJDocument(GlobalEventNotifier notifier){
 88  316 super();
 89  316 _hasPrompt = false;
 90  316 _notifier=notifier;
 91  316 resetUndoManager();
 92    }
 93   
 94  116 public boolean hasPrompt() { return _hasPrompt; }
 95   
 96    /** Sets the _hasPrompt property.
 97    * @param val new boolean value for _hasPrompt.
 98    */
 99  1051 public void setHasPrompt(boolean val) {
 100  1051 _hasPrompt = val;
 101    }
 102   
 103  749 protected void _styleChanged() { /* Do nothing */ }
 104   
 105    //-------------Undo/Redo Functionality---------------------//
 106    /** Appending any information for the reduced model from each undo command */
 107    private static class CommandUndoableEdit extends AbstractUndoableEdit {
 108    private final Runnable _undoCommand;
 109    private final Runnable _redoCommand;
 110   
 111  743 public CommandUndoableEdit(final Runnable undoCommand, final Runnable redoCommand) {
 112  743 _undoCommand = undoCommand;
 113  743 _redoCommand = redoCommand;
 114    }
 115   
 116  5 public void undo() throws CannotUndoException {
 117  5 super.undo();
 118  5 _undoCommand.run();
 119    }
 120   
 121  1 public void redo() throws CannotRedoException {
 122  1 super.redo();
 123  1 _redoCommand.run();
 124    }
 125   
 126  0 public boolean isSignificant() { return false; }
 127    }
 128   
 129    /** Getter method for CompoundUndoManager
 130    * @return _undoManager
 131    */
 132  362 public CompoundUndoManager getUndoManager() { return _undoManager; }
 133   
 134    /** Resets the undo manager. */
 135  519 public void resetUndoManager() {
 136  519 _undoManager = new CompoundUndoManager(_notifier);
 137  519 _undoManager.setLimit(UNDO_LIMIT);
 138    }
 139   
 140    /** Public accessor for the next undo action. */
 141  0 public UndoableEdit getNextUndo() { return _undoManager.getNextUndo(); }
 142   
 143    /** Public accessor for the next undo action. */
 144  0 public UndoableEdit getNextRedo() { return _undoManager.getNextRedo(); }
 145   
 146    /** Informs this document's undo manager that the document has been saved. */
 147  0 public void documentSaved() { _undoManager.documentSaved(); }
 148   
 149  0 protected int startCompoundEdit() { return _undoManager.startCompoundEdit(); }
 150   
 151  0 protected void endCompoundEdit(int key) { _undoManager.endCompoundEdit(key); }
 152   
 153    //This method added for FrenchKeyBoardFix
 154  0 protected void endLastCompoundEdit() { _undoManager.endLastCompoundEdit(); }
 155   
 156  743 protected void addUndoRedo(AbstractDocument.DefaultDocumentEvent chng, Runnable undoCommand, Runnable doCommand) {
 157  743 chng.addEdit(new CommandUndoableEdit(undoCommand, doCommand));
 158    }
 159   
 160  250 public boolean undoManagerCanUndo() { return _undoManager.canUndo(); }
 161   
 162  250 public boolean undoManagerCanRedo() { return _undoManager.canRedo(); }
 163   
 164  0 public void updateModifiedSinceSave() {
 165  0 _isModifiedSinceSave = _undoManager.isModified();
 166    // if (_odd != null) _odd.documentReset();
 167    }
 168   
 169    /** Sets the modification state of this document to true and updates the state of the associated _odd.
 170    * Assumes that write lock is already held.
 171    */
 172  0 private void _setModifiedSinceSave() {
 173  0 /* */ assert Utilities.TEST_MODE || EventQueue.isDispatchThread();
 174  0 if (! _isModifiedSinceSave) {
 175  0 _isModifiedSinceSave = true;
 176    //if (_odd != null) _odd.documentModified(); // null test required for some unit tests
 177    }
 178    }
 179   
 180    /** Resets the modification state of this document. Used after a document has been saved or reverted. */
 181  0 public void resetModification() {
 182  0 _isModifiedSinceSave = false;
 183  0 _undoManager.documentSaved();
 184    // if (_odd != null) _odd.documentReset(); // null test required for some unit tests
 185    }
 186   
 187    /** Determines if the document has been modified since the last save.
 188    * @return true if the document has been modified
 189    */
 190  0 public boolean isModifiedSinceSave() { return _isModifiedSinceSave; }
 191   
 192    //-------------end Undo/Redo Functionality---------------------//
 193   
 194   
 195    /** Returns a new indenter. Eventually to be used to return an interactions indenter */
 196  0 protected Indenter makeNewIndenter(int indentLevel) { return new Indenter(indentLevel); }
 197   
 198    /** A list of styles and their locations augmenting this document. This augmentation is NOT part of the reduced
 199    * model; it a separate extension that uses itself as a mutual exclusion lock. This list holds pairs of location
 200    * intervals and strings (identifying styles). In essence it maps regions to colors (??).
 201    * in the document and styles, which is basically a map of regions where the coloring view that is now attached to
 202    * the Interactions Pane. It is not allowed to use the reduced model to determine the color settings when
 203    * rendering text. (Why not? -- Corky) We keep a list of all places where styles not considered by the reduced
 204    * are being used, such as System.out, System.err, and the various return styles for Strings and other Objects.
 205    * Since the LinkedList class is not thread safe, we have to synchronized all methods that access pointers in
 206    * _stylesList and the associated boolean _toClear.
 207    */
 208    private List<Pair<Pair<Integer,Integer>,String>> _stylesList = new LinkedList<Pair<Pair<Integer,Integer>,String>>();
 209   
 210    /** Adds the given coloring style to the styles list. Only runs in event thread. */
 211  703 public void addColoring(int start, int end, String style) {
 212    // synchronized(_stylesList) {
 213  703 if (_toClear) {
 214  20 _stylesList.clear();
 215  20 _toClear = false;
 216    }
 217  703 if (style != null)
 218  689 _stylesList.add(0, new Pair<Pair<Integer,Integer>,String>
 219    (new Pair<Integer,Integer>(Integer.valueOf(start),Integer.valueOf(end)), style));
 220    // }
 221    }
 222   
 223    /** Accessor method used to copy contents of _stylesList to an array. Used in test cases. */
 224  13 public Pair<Pair<Integer, Integer>, String>[] getStyles() {
 225  13 synchronized(_stylesList) {
 226    // TODO: file javac bug report concerning placement of @SuppressWarnings. Fails if rhs of result binding is used as body of return statement.
 227  13 @SuppressWarnings({"unchecked", "rawtypes"})
 228    Pair<Pair<Integer, Integer>, String>[] result = _stylesList.toArray(new Pair[0]);
 229  13 return result;
 230    }
 231    }
 232   
 233    /** Attempts to set the coloring on the graphics based upon the content of the styles list
 234    * returns false if the point is not in the list. Only runs in event thread.
 235    */
 236  0 public boolean setColoring(int point, Graphics g) {
 237  0 synchronized(_stylesList) {
 238  0 for(Pair<Pair<Integer,Integer>,String> p : _stylesList) {
 239  0 Pair<Integer,Integer> loc = p.first();
 240  0 if (loc.first() <= point && loc.second() >= point) {
 241  0 if (p.second().equals(InteractionsDocument.ERROR_STYLE)) {
 242    //DrJava.consoleErr().println("Error Style");
 243  0 g.setColor(ERROR_COLOR);
 244  0 g.setFont(g.getFont().deriveFont(Font.BOLD));
 245    }
 246  0 else if (p.second().equals(InteractionsDocument.DEBUGGER_STYLE)) {
 247    //DrJava.consoleErr().println("Debugger Style");
 248  0 g.setColor(DEBUGGER_COLOR);
 249  0 g.setFont(g.getFont().deriveFont(Font.BOLD));
 250    }
 251  0 else if (p.second().equals(ConsoleDocument.SYSTEM_OUT_STYLE)) {
 252    //DrJava.consoleErr().println("System.out Style");
 253  0 g.setColor(INTERACTIONS_SYSTEM_OUT_COLOR);
 254  0 g.setFont(MAIN_FONT);
 255    }
 256  0 else if (p.second().equals(ConsoleDocument.SYSTEM_IN_STYLE)) {
 257    //DrJava.consoleErr().println("System.in Style");
 258  0 g.setColor(INTERACTIONS_SYSTEM_IN_COLOR);
 259  0 g.setFont(MAIN_FONT);
 260    }
 261  0 else if (p.second().equals(ConsoleDocument.SYSTEM_ERR_STYLE)) {
 262    //DrJava.consoleErr().println("System.err Style");
 263  0 g.setColor(INTERACTIONS_SYSTEM_ERR_COLOR);
 264  0 g.setFont(MAIN_FONT);
 265    }
 266  0 else if (p.second().equals(InteractionsDocument.OBJECT_RETURN_STYLE)) {
 267  0 g.setColor(NORMAL_COLOR);
 268  0 g.setFont(MAIN_FONT);
 269    }
 270  0 else if (p.second().equals(InteractionsDocument.STRING_RETURN_STYLE)) {
 271  0 g.setColor(DOUBLE_QUOTED_COLOR);
 272  0 g.setFont(MAIN_FONT);
 273    }
 274  0 else if (p.second().equals(InteractionsDocument.NUMBER_RETURN_STYLE)) {
 275  0 g.setColor(NUMBER_COLOR);
 276  0 g.setFont(MAIN_FONT);
 277    }
 278  0 else if (p.second().equals(InteractionsDocument.CHARACTER_RETURN_STYLE)) {
 279  0 g.setColor(SINGLE_QUOTED_COLOR);
 280  0 g.setFont(MAIN_FONT);
 281    }
 282  0 else return false; /* Normal text color */
 283   
 284  0 return true;
 285    }
 286    }
 287  0 return false;
 288    }
 289    }
 290   
 291    /** Attempts to set the font on the graphics context based upon the styles held in the styles list. Only runs in
 292    * event thread.
 293    */
 294  0 public void setBoldFonts(int point, Graphics g) {
 295  0 synchronized(_stylesList) {
 296  0 for(Pair<Pair<Integer,Integer>,String> p : _stylesList) {
 297  0 Pair<Integer,Integer> loc = p.first();
 298  0 if (loc.first() <= point && loc.second() >= point) {
 299  0 if (p.second().equals(InteractionsDocument.ERROR_STYLE))
 300  0 g.setFont(g.getFont().deriveFont(Font.BOLD));
 301  0 else if (p.second().equals(InteractionsDocument.DEBUGGER_STYLE))
 302  0 g.setFont(g.getFont().deriveFont(Font.BOLD));
 303  0 else g.setFont(MAIN_FONT);
 304  0 return;
 305    }
 306    }
 307    }
 308    }
 309   
 310    /** Called when the Interactions pane is reset. Only runs in event thread. */
 311  21 public void clearColoring() { synchronized(_stylesList) { _toClear = true; } }
 312   
 313    /** @return true iff the end of the current interaction is an open comment block
 314    */
 315  0 public boolean _inBlockComment() {
 316  0 boolean toReturn = _inBlockComment(getLength());
 317  0 return toReturn;
 318    }
 319   
 320    /** Inserts the given exception data into the document with the given style.
 321    * @param message Message contained in the exception
 322    * @param styleName name of the style for formatting the exception
 323    */
 324  0 public void appendExceptionResult(String message, String styleName) {
 325    // Note that there is similar code in InteractionsDocument. Something should be refactored.
 326  0 try { insertText(getLength(), message + "\n", styleName); }
 327  0 catch (EditDocumentException ble) { throw new UnexpectedException(ble); }
 328    }
 329    }