Clover coverage report - DrJava Test Coverage (drjava-20120304-r5456)
Coverage timestamp: Sun Mar 4 2012 03:13:23 CST
file stats: LOC: 634   Methods: 61
NCLOC: 347   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
GlobalEventNotifier.java 50% 62.3% 63.9% 62.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.model;
 38   
 39    import java.io.File;
 40    import java.util.List;
 41   
 42    import edu.rice.cs.drjava.model.compiler.CompilerListener;
 43    import edu.rice.cs.util.FileOpenSelector;
 44    import edu.rice.cs.util.classloader.ClassFileError;
 45    import edu.rice.cs.util.swing.AsyncTask;
 46   
 47    /** Keeps track of all listeners to the model, and has the ability to notify them of some event.
 48    * <p>
 49    * This class has a specific role of managing GlobalModelListeners. Other classes with similar names use similar
 50    * code to perform the same function for other interfaces, e.g. InteractionsEventNotifier and JavadocEventNotifier.
 51    * These classes implement the appropriate interface definition so that they can be used transparently as composite
 52    * packaging for a particular listener interface.
 53    * <p>
 54    * Components which might otherwise manage their own list of listeners use EventNotifiers instead to simplify their
 55    * internal implementation. Notifiers should therefore be considered a private implementation detail of the
 56    * components, and should not be used directly outside of the "host" component.
 57    * <p>
 58    * TODO: remove direct references to GlobalEventNotifier outside of DefaultGlobalModel
 59    * TODO: remove public modifier from this class when above has happened
 60    *
 61    * All methods in this class must use the synchronization methods provided by ReaderWriterLock. This ensures that
 62    * multiple notifications (reads) can occur simultaneously, but only one thread can be adding or removing listeners
 63    * (writing) at a time, and no reads can occur during a write.
 64    * <p>
 65    * <i>No</i> methods on this class should be synchronized using traditional Java synchronization!
 66    * <p>
 67    * @version $Id: GlobalEventNotifier.java 5236 2010-04-27 01:43:36Z mgricken $
 68    */
 69    // QUESTION: why are we still using _lock operations? All notifiers should run in the event thread.
 70   
 71    public class GlobalEventNotifier extends EventNotifier<GlobalModelListener>
 72    implements GlobalModelListener /*, Serializable */ {
 73   
 74  0 public <P,R> void executeAsyncTask(AsyncTask<P,R> task, P param, boolean showProgress, boolean lockUI) {
 75  0 _lock.startRead();
 76  0 try { for (GlobalModelListener l : _listeners) { l.executeAsyncTask(task, param, showProgress, lockUI); } }
 77  0 finally { _lock.endRead(); }
 78    }
 79   
 80  1 public void filesNotFound(File... f) {
 81  1 _lock.startRead();
 82  1 try { for (GlobalModelListener l : _listeners) { l.filesNotFound(f); } }
 83  1 finally { _lock.endRead(); }
 84    }
 85   
 86    /** @return the intersection of all the return values from the listeners. */
 87  0 public File[] filesReadOnly(File... f) {
 88  0 _lock.startRead();
 89  0 java.util.LinkedList<File> files = new java.util.LinkedList<File>();
 90  0 for(File fi: f) { files.add(fi); }
 91  0 try {
 92  0 for (GlobalModelListener l : _listeners) {
 93  0 java.util.List<File> retry = java.util.Arrays.asList(l.filesReadOnly(f));
 94  0 files.retainAll(retry);
 95    }
 96    }
 97  0 finally { _lock.endRead(); }
 98  0 return files.toArray(new File[files.size()]);
 99    }
 100   
 101    /** Performs any UI related steps to handle the case in which a file is being opened that
 102    * is already open and modified. The two choices are to revert to the copy on disk, or to
 103    * keep the current changes.
 104    * @param doc {@code true} if the user wishes to revert the document, {@code false} to ignore
 105    */
 106  0 public void handleAlreadyOpenDocument(OpenDefinitionsDocument doc) {
 107  0 _lock.startRead();
 108  0 try { for(GlobalModelListener l : _listeners) { l.handleAlreadyOpenDocument(doc); } }
 109  0 finally { _lock.endRead(); }
 110    }
 111   
 112    /* -------------- project state ------------------*/
 113  3 public void openProject(File pfile, FileOpenSelector files) {
 114  3 _lock.startRead();
 115  3 try { for (GlobalModelListener l : _listeners) { l.openProject(pfile, files); } }
 116  3 finally { _lock.endRead(); }
 117    }
 118   
 119  2 public void projectClosed() {
 120  2 _lock.startRead();
 121  2 try { for (GlobalModelListener l : _listeners) { l.projectClosed();} }
 122  2 finally { _lock.endRead(); }
 123    }
 124   
 125  36 public void allFilesClosed() {
 126  36 _lock.startRead();
 127  8 try { for (GlobalModelListener l : _listeners) { l.allFilesClosed();} }
 128  36 finally { _lock.endRead(); }
 129    }
 130   
 131  0 public void projectModified() {
 132  0 _lock.startRead();
 133  0 try { for (GlobalModelListener l : _listeners) { l.projectModified(); } }
 134  0 finally { _lock.endRead(); }
 135    }
 136   
 137  167 public void projectBuildDirChanged() {
 138  167 _lock.startRead();
 139  8 try { for (GlobalModelListener l : _listeners) { l.projectBuildDirChanged(); } }
 140  167 finally { _lock.endRead(); }
 141    }
 142   
 143  165 public void projectWorkDirChanged() {
 144  165 _lock.startRead();
 145  6 try { for (GlobalModelListener l : _listeners) { l.projectWorkDirChanged(); } }
 146  165 finally { _lock.endRead(); }
 147    }
 148   
 149  324 public void projectRunnableChanged() {
 150  324 _lock.startRead();
 151  6 try { for (GlobalModelListener l : _listeners) { l.projectRunnableChanged(); } }
 152  324 finally { _lock.endRead(); }
 153    }
 154   
 155   
 156    /* ---------- Deprecated Methods ---------- */
 157   
 158    /** Lets the listeners know some event has taken place.
 159    * @param n tells the listener what happened.
 160    */
 161  0 public void notifyListeners(Notifier n) {
 162  0 _lock.startRead();
 163  0 try { for (GlobalModelListener l : _listeners) { n.notifyListener(l); } }
 164  0 finally { _lock.endRead(); }
 165    }
 166   
 167    /** Allows the GlobalModel to ask its listeners a yes/no question and receive a response.
 168    * @param p the question being asked of the listeners
 169    * @return the listeners' responses ANDed together, true if they all
 170    * agree, false if some disagree
 171    * @deprecated Use listener methods directly instead.
 172    */
 173  0 @Deprecated
 174    public boolean pollListeners(Poller p) {
 175  0 _lock.startRead();
 176  0 try {
 177  0 for (GlobalModelListener l: _listeners) { if (! p.poll(l)) return false; }
 178  0 return true;
 179    }
 180  0 finally { _lock.endRead(); }
 181    }
 182   
 183    /** Class model for notifying listeners of an event.
 184    * @deprecated Use listener methods directly instead.
 185    */
 186    @Deprecated
 187    public abstract static class Notifier {
 188    public abstract void notifyListener(GlobalModelListener l);
 189    }
 190   
 191    /** Class model for asking listeners a yes/no question.
 192    * @deprecated Use listener methods directly instead.
 193    */
 194    @Deprecated
 195    public abstract static class Poller {
 196    public abstract boolean poll(GlobalModelListener l);
 197    }
 198   
 199    // ---------- End of Deprecated Methods ----------
 200   
 201   
 202   
 203    //------------------------------ GlobalModel -------------------------------//
 204   
 205    /** Called when a file's main method is about to be run. */
 206  2 public void prepareForRun(OpenDefinitionsDocument doc) {
 207  2 _lock.startRead();
 208  0 try { for (GlobalModelListener l : _listeners) { l.prepareForRun(doc); } }
 209  2 finally { _lock.endRead(); }
 210    }
 211   
 212    /** Called after a new document is created. */
 213  423 public void newFileCreated(OpenDefinitionsDocument doc) {
 214  423 _lock.startRead();
 215  139 try { for (GlobalModelListener l : _listeners) { l.newFileCreated(doc); } }
 216  423 finally { _lock.endRead(); }
 217    }
 218   
 219    /** Called when the console window is reset. */
 220  5 public void consoleReset() {
 221  5 _lock.startRead();
 222  8 try { for (GlobalModelListener l : _listeners) { l.consoleReset(); } }
 223  5 finally { _lock.endRead(); }
 224    }
 225   
 226    /** Called after the current document is saved. */
 227  86 public void fileSaved(OpenDefinitionsDocument doc) {
 228    // ScrollableDialog sd = new ScrollableDialog(null, "fileSaved(" + doc + ") called in GlobalEventNotifier.java", "", "");
 229    // sd.show();
 230  86 _lock.startRead();
 231  10 try { for (GlobalModelListener l : _listeners) { l.fileSaved(doc); } }
 232  86 finally { _lock.endRead(); }
 233    }
 234   
 235    /** Called after a file is opened and read into the current document. */
 236  75 public void fileOpened(OpenDefinitionsDocument doc) {
 237  75 _lock.startRead();
 238  43 try { for (GlobalModelListener l : _listeners) { l.fileOpened(doc); } }
 239  75 finally { _lock.endRead(); }
 240    }
 241   
 242    /** Called after a document is closed. */
 243  185 public void fileClosed(OpenDefinitionsDocument doc) {
 244  185 _lock.startRead();
 245  64 try { for (GlobalModelListener l : _listeners) { l.fileClosed(doc); } }
 246  185 finally { _lock.endRead(); }
 247    }
 248   
 249    /** Called after a document is reverted. */
 250  1 public void fileReverted(OpenDefinitionsDocument doc) {
 251  1 _lock.startRead();
 252  1 try { for (GlobalModelListener l : _listeners) { l.fileReverted(doc); } }
 253  1 finally { _lock.endRead(); }
 254    }
 255   
 256    /** Called when an undoable edit occurs. */
 257  28 public void undoableEditHappened() {
 258  28 _lock.startRead();
 259  27 try { for (GlobalModelListener l : _listeners) { l.undoableEditHappened(); } }
 260  28 finally { _lock.endRead(); }
 261    }
 262   
 263    /** Called to ask the listeners if it is OK to abandon the current document. */
 264  43 public boolean canAbandonFile(OpenDefinitionsDocument doc) {
 265  43 _lock.startRead();
 266  43 try {
 267  2 for (GlobalModelListener l: _listeners) { if (! l.canAbandonFile(doc)) return false; }
 268  41 return true;
 269    }
 270  43 finally { _lock.endRead(); }
 271    }
 272   
 273    /** Called to ask the listeners save the file before quitting at the user's option.
 274    * @return true if quitting should continue, false if the user cancelled */
 275  0 public boolean quitFile(OpenDefinitionsDocument doc) {
 276  0 _lock.startRead();
 277  0 try {
 278    // if one of the listeners returns false (=user cancelled), abort
 279  0 for (GlobalModelListener l: _listeners) { if (!l.quitFile(doc)) return false; }
 280    }
 281  0 finally { _lock.endRead(); }
 282  0 return true;
 283    }
 284   
 285    /** Called to ask the listeners if it is OK to revert the current document to the version saved on disk. */
 286  2 public boolean shouldRevertFile(OpenDefinitionsDocument doc) {
 287  2 _lock.startRead();
 288  2 try {
 289  1 for (GlobalModelListener l: _listeners) { if (! l.shouldRevertFile(doc)) return false; }
 290  1 return true;
 291    }
 292  2 finally { _lock.endRead(); }
 293    }
 294   
 295    /** Called when the selection in the navigator changes the current directory without changing the active document. */
 296  189 public void currentDirectoryChanged(File dir) {
 297  189 _lock.startRead();
 298  26 try { for (GlobalModelListener l : _listeners) { l.currentDirectoryChanged(dir); } }
 299  189 finally { _lock.endRead(); }
 300    }
 301   
 302    /** Called when the selection in the navigator changes the active document. */
 303  395 public void activeDocumentChanged(OpenDefinitionsDocument active) {
 304  395 _lock.startRead();
 305  195 try { for (GlobalModelListener l : _listeners) { l.activeDocumentChanged(active); } }
 306  395 finally { _lock.endRead(); }
 307    }
 308   
 309    /** Called when the active document is refreshed. */
 310  10 public void activeDocumentRefreshed(OpenDefinitionsDocument active) {
 311  10 _lock.startRead();
 312  12 try { for (GlobalModelListener l : _listeners) { l.activeDocumentRefreshed(active); } }
 313  10 finally { _lock.endRead(); }
 314    }
 315   
 316    /** Called to shift the focus to the Definitions Pane. */
 317  0 public void focusOnDefinitionsPane() {
 318  0 _lock.startRead();
 319  0 try { for (GlobalModelListener l : _listeners) { l.focusOnDefinitionsPane(); } }
 320  0 finally { _lock.endRead(); }
 321    }
 322   
 323    /** Called to shift the focus to the last focus owner among the main frame panes. */
 324  0 public void focusOnLastFocusOwner() {
 325  0 _lock.startRead();
 326  0 try { for (GlobalModelListener l : _listeners) { l.focusOnLastFocusOwner(); } }
 327  0 finally { _lock.endRead(); }
 328    }
 329    // /** Called to demand that all files be saved before running the main method of a document. It is up to the caller
 330    // * of this method to check if the documents have been saved, using IGetDocuments.hasModifiedDocuments(). This is
 331    // * nor used currently, but it is commented out in case it is needed later.
 332    // */
 333    // public void saveBeforeRun() {
 334    // _lock.startRead();
 335    // try { for (GlobalModelListener l : _listeners) { l.saveBeforeRun(); } }
 336    // finally { _lock.endRead(); }
 337    // }
 338   
 339    //------------------------------ Interactions ------------------------------//
 340   
 341    /** Called after an interaction is started by the GlobalModel. */
 342  35 public void interactionStarted() {
 343  35 _lock.startRead();
 344  34 try { for (GlobalModelListener l : _listeners) { l.interactionStarted(); } }
 345  35 finally { _lock.endRead(); }
 346    }
 347   
 348    /** Called when an interaction has finished running. */
 349  33 public void interactionEnded() {
 350  33 _lock.startRead();
 351  33 try { for (GlobalModelListener l : _listeners) { l.interactionEnded(); } }
 352  33 finally { _lock.endRead(); }
 353    }
 354   
 355    /** Called when the interactions window generates a syntax error.
 356    * @param offset the error's offset into the InteractionsDocument.
 357    * @param length the length of the error.
 358    */
 359  0 public void interactionErrorOccurred(int offset, int length) {
 360  0 _lock.startRead();
 361  0 try { for (GlobalModelListener l : _listeners) { l.interactionErrorOccurred(offset, length); } }
 362  0 finally { _lock.endRead(); }
 363    }
 364   
 365    /** Called when the interactionsJVM has begun resetting. */
 366  21 public void interpreterResetting() {
 367  21 _lock.startRead();
 368  20 try { for (GlobalModelListener l : _listeners) { l.interpreterResetting(); } }
 369  21 finally { _lock.endRead(); }
 370    }
 371   
 372    /** Called when the interactions window is reset. */
 373  25 public void interpreterReady(File wd) {
 374  25 _lock.startRead();
 375  27 try { for (GlobalModelListener l : _listeners) { l.interpreterReady(wd); } }
 376  25 finally { _lock.endRead(); }
 377    }
 378   
 379    /** Called if the interpreter reset failed.
 380    * @param t Throwable explaining why the reset failed.
 381    * (Subclasses must maintain listeners.)
 382    */
 383  0 public void interpreterResetFailed(final Throwable t) {
 384  0 _lock.startRead();
 385  0 try { for (GlobalModelListener l : _listeners) { l.interpreterResetFailed(t); } }
 386  0 finally { _lock.endRead(); }
 387    }
 388   
 389    /** Called when the interactions JVM was closed by System.exit or by being aborted. Immediately after this the
 390    * interactions will be reset.
 391    * @param status the exit code
 392    */
 393  2 public void interpreterExited(int status) {
 394  2 _lock.startRead();
 395  2 try { for (GlobalModelListener l : _listeners) { l.interpreterExited(status); } }
 396  2 finally { _lock.endRead(); }
 397    }
 398   
 399    /** Called when the active interpreter is changed.
 400    * @param inProgress Whether the new interpreter is processing an interaction (i.e,. whether an interactionEnded
 401    * event will be fired)
 402    */
 403  1 public void interpreterChanged(boolean inProgress) {
 404  1 _lock.startRead();
 405  1 try { for (GlobalModelListener l : _listeners) { l.interpreterChanged(inProgress); } }
 406  1 finally { _lock.endRead(); }
 407    }
 408   
 409    //-------------------------------- Compiler --------------------------------//
 410   
 411    /** Called after a compile is started by the GlobalModel. */
 412  56 public void compileStarted() {
 413  56 _lock.startRead();
 414  56 try { for (GlobalModelListener l : _listeners) { l.compileStarted(); }
 415    }
 416  56 finally { _lock.endRead(); }
 417    }
 418   
 419    /** Called when a compile has finished running. */
 420  56 public void compileEnded(File workDir, List<? extends File> excludedFiles) {
 421  56 _lock.startRead();
 422  56 try { for (GlobalModelListener l : _listeners) { l.compileEnded(workDir, excludedFiles); } }
 423  56 finally { _lock.endRead(); }
 424    }
 425   
 426    /** Called if a compile is aborted. */
 427  2 public void compileAborted(Exception e) {
 428  2 _lock.startRead();
 429  2 try { for (GlobalModelListener l : _listeners) { l.compileAborted(e); } }
 430  2 finally { _lock.endRead(); }
 431    }
 432    /** Called to demand that all files be saved before compiling. It is up to the caller of this method to check
 433    * if the documents have been saved, using IGetDocuments.hasModifiedDocuments().
 434    */
 435  6 public void saveBeforeCompile() {
 436  6 _lock.startRead();
 437  6 try { for (GlobalModelListener l : _listeners) { l.saveBeforeCompile(); } }
 438  6 finally { _lock.endRead(); }
 439    }
 440   
 441    /** Called to demand that the active document, which is untitled, is saved before compiling. */
 442  0 public void saveUntitled() {
 443  0 _lock.startRead();
 444  0 try { for (GlobalModelListener l : _listeners) { l.saveUntitled(); } }
 445  0 finally { _lock.endRead(); }
 446    }
 447   
 448    /** Called after the active compiler has been changed. */
 449  0 public void activeCompilerChanged() {
 450  0 _lock.startRead();
 451  0 try { for (GlobalModelListener l : _listeners) { l.activeCompilerChanged(); } }
 452  0 finally { _lock.endRead(); }
 453    }
 454   
 455    //---------------------------------- JUnit ---------------------------------//
 456   
 457    /** Called when trying to test a non-TestCase class.
 458    * @param isTestAll whether or not it was a use of the test all button
 459    * @param didCompileFail whether or not a compile before this JUnit attempt failed
 460    */
 461  3 public void nonTestCase(boolean isTestAll, boolean didCompileFail) {
 462  3 _lock.startRead();
 463  3 try { for (GlobalModelListener l : _listeners) { l.nonTestCase(isTestAll, didCompileFail); } }
 464  3 finally { _lock.endRead(); }
 465    }
 466   
 467    /** Called when trying to test an illegal class file.
 468    * @param e the ClassFileError thrown when DrJava attempted to load the offending file
 469    */
 470  0 public void classFileError(ClassFileError e) {
 471  0 _lock.startRead();
 472  0 try { for (GlobalModelListener l : _listeners) { l.classFileError(e); } }
 473  0 finally { _lock.endRead(); }
 474    }
 475   
 476    /** Called before attempting unit testing if tested class files are out of sync, to give the user a chance to save. Do
 477    * not continue with JUnit if the user doesn't recompile!
 478    */
 479  3 public void compileBeforeJUnit(final CompilerListener cl, List<OpenDefinitionsDocument> outOfSync) {
 480    // Utilities.show("compileBeforeJUnit invoked with argument " + cl + " in GlobalEventNotifier " + this);
 481  3 _lock.startRead();
 482  3 try { for (GlobalModelListener l : _listeners) { l.compileBeforeJUnit(cl, outOfSync); } }
 483  3 finally { _lock.endRead(); }
 484    }
 485   
 486    /** Called after JUnit is started by the GlobalModel. */
 487  16 public void junitStarted() {
 488  16 _lock.startRead();
 489  16 try { for (GlobalModelListener l : _listeners) { l.junitStarted(); } }
 490  16 finally { _lock.endRead(); }
 491    }
 492   
 493    /** Called when testing specific list of classes. */
 494  0 public void junitClassesStarted() {
 495  0 _lock.startRead();
 496  0 try { for (GlobalModelListener l : _listeners) { l.junitClassesStarted(); } }
 497  0 finally { _lock.endRead(); }
 498    }
 499   
 500    /** Called to indicate that a suite of tests has started running.
 501    * @param numTests The number of tests in the suite to be run.
 502    */
 503  17 public void junitSuiteStarted(int numTests) {
 504  17 _lock.startRead();
 505  18 try { for (GlobalModelListener l : _listeners) { l.junitSuiteStarted(numTests); } }
 506  17 finally { _lock.endRead(); }
 507    }
 508   
 509    /** Called when a particular test is started.
 510    * @param name The name of the test being started.
 511    */
 512  25 public void junitTestStarted(String name) {
 513  25 _lock.startRead();
 514  25 try { for (GlobalModelListener l : _listeners) { l.junitTestStarted(name); } }
 515  25 finally { _lock.endRead(); }
 516    }
 517   
 518    /** Called when a particular test has ended.
 519    * @param name the name of the test that has ended
 520    * @param wasSuccessful whether the test passed or not
 521    * @param causedError if not successful, whether the test caused an error or simply failed
 522    */
 523  24 public void junitTestEnded(String name, boolean wasSuccessful, boolean causedError) {
 524  24 _lock.startRead();
 525  24 try {
 526  24 for (GlobalModelListener l : _listeners) { l.junitTestEnded(name, wasSuccessful, causedError); }
 527    }
 528  24 finally { _lock.endRead(); }
 529    }
 530   
 531    /** Called after JUnit is finished running tests. */
 532  16 public void junitEnded() {
 533  16 _lock.startRead();
 534  16 try { for (GlobalModelListener l : _listeners) { l.junitEnded(); } }
 535  16 finally { _lock.endRead(); }
 536    }
 537   
 538    // /** Called to demand that all files be saved before running JUnit tests. It is up to the caller of this
 539    // * method to check if the documents have been saved, using IGetDocuments.hasModifiedDocuments(). This is
 540    // * never called currently, but it is commented out in case it is needed later. */
 541    // public void saveBeforeJUnit() {
 542    // _lock.startRead();
 543    // try {
 544    // for (GlobalModelListener l : _listeners) {
 545    // l.saveBeforeJUnit();
 546    // }
 547    // }
 548    // finally {
 549    // _lock.endRead();
 550    // }
 551    // }
 552   
 553    //--------------------------------- Javadoc --------------------------------//
 554   
 555    /** Called after Javadoc is started by the GlobalModel. */
 556  0 public void javadocStarted() {
 557  0 _lock.startRead();
 558  0 try { for (GlobalModelListener l : _listeners) { l.javadocStarted(); } }
 559  0 finally { _lock.endRead(); }
 560    }
 561   
 562    /** Called after Javadoc is finished.
 563    * @param success whether the Javadoc operation generated proper output
 564    * @param destDir if (success) the location where the output was generated, otherwise undefined (possibly null)
 565    * @param allDocs Whether Javadoc was run for all open documents
 566    */
 567  0 public void javadocEnded(boolean success, File destDir, boolean allDocs) {
 568  0 _lock.startRead();
 569  0 try { for (GlobalModelListener l : _listeners) { l.javadocEnded(success, destDir, allDocs); } }
 570  0 finally { _lock.endRead(); }
 571    }
 572   
 573   
 574    /** Called before attempting Javadoc, to give the user a chance to save. Do not continue with Javadoc if the user
 575    * doesn't save!
 576    */
 577  0 public void saveBeforeJavadoc() {
 578  0 _lock.startRead();
 579  0 try { for (GlobalModelListener l : _listeners) { l.saveBeforeJavadoc(); } }
 580  0 finally { _lock.endRead(); }
 581    }
 582   
 583    /** Called before attempting Javadoc, to give the user a chance to compile. Do not continue with Javadoc if the
 584    * user doesn't comoile!
 585    */
 586  0 public void compileBeforeJavadoc(final CompilerListener afterCompile) {
 587  0 _lock.startRead();
 588  0 try { for (GlobalModelListener l : _listeners) { l.compileBeforeJavadoc(afterCompile); } }
 589  0 finally { _lock.endRead(); }
 590    }
 591   
 592    // /** Called to demand that all files be saved before starting the debugger. It is up to the caller of this method
 593    // * to check if the documents have been saved, using IGetDocuments.hasModifiedDocuments(). This is not used
 594    // * currently, but it is commented out in case it is needed later. */
 595    // public void saveBeforeDebug() {
 596    // _lock.startRead();
 597    // try { for (GlobalModelListener l : _listeners) { l.saveBeforeDebug(); } }
 598    // finally { _lock.endRead(); }
 599    // }
 600   
 601    /** Notifies the view that the current interaction is incomplete. */
 602  0 public void interactionIncomplete() {
 603  0 _lock.startRead();
 604  0 try { for (GlobalModelListener l : _listeners) { l.interactionIncomplete(); } }
 605  0 finally { _lock.endRead(); }
 606    }
 607   
 608    /** Notifies the view that the current file path contains a #. */
 609  0 public void filePathContainsPound() {
 610  0 _lock.startRead();
 611  0 try { for (GlobalModelListener l : _listeners) { l.filePathContainsPound(); } }
 612  0 finally { _lock.endRead(); }
 613    }
 614   
 615    // ----- Cache -----
 616  0 public void documentNotFound(OpenDefinitionsDocument d, File f) {
 617  0 _lock.startRead();
 618  0 try { for (GlobalModelListener l : _listeners) { l.documentNotFound(d,f); } }
 619  0 finally { _lock.endRead(); }
 620    }
 621   
 622    // ----- BrowserHistory -----
 623  27 public void browserChanged() {
 624  27 _lock.startRead();
 625  25 try { for (GlobalModelListener l : _listeners) { l.browserChanged(); } }
 626  27 finally { _lock.endRead(); }
 627    }
 628   
 629  27 public void updateCurrentLocationInDoc() {
 630  27 _lock.startRead();
 631  25 try { for (GlobalModelListener l : _listeners) { l.updateCurrentLocationInDoc(); } }
 632  27 finally { _lock.endRead(); }
 633    }
 634    }