1 33 34 package edu.rice.cs.drjava.model; 35 36 import java.awt.Color ; 37 import java.awt.Container ; 38 import java.awt.EventQueue ; 39 import java.awt.Font ; 40 import java.awt.event.FocusEvent ; 41 import java.awt.event.FocusListener ; 42 import java.awt.print.PageFormat ; 43 import java.awt.print.Pageable ; 44 import java.awt.print.PrinterException ; 45 import java.awt.print.PrinterJob ; 46 import java.io.ByteArrayInputStream ; 47 import java.io.File ; 48 import java.io.FileFilter ; 49 import java.io.FileNotFoundException ; 50 import java.io.FileReader ; 51 import java.io.FilenameFilter ; 52 import java.io.InputStreamReader ; 53 import java.io.IOException ; 54 import java.io.OutputStream ; 55 import java.io.StringReader ; 56 57 import java.util.AbstractMap ; 58 import java.util.ArrayList ; 59 import java.util.Collections ; 60 import java.util.Comparator ; 61 import java.util.HashSet ; 62 import java.util.Hashtable ; 63 import java.util.LinkedHashMap ; 64 import java.util.LinkedList ; 65 import java.util.List ; 66 import java.util.ListIterator ; 67 import java.util.Vector ; 68 import java.util.WeakHashMap ; 69 70 import javax.swing.SwingUtilities ; 71 import javax.swing.event.DocumentListener ; 72 import javax.swing.event.UndoableEditListener ; 73 import javax.swing.text.AttributeSet ; 74 import javax.swing.text.BadLocationException ; 75 import javax.swing.text.Element ; 76 import javax.swing.text.Position ; 77 import javax.swing.text.Segment ; 78 import javax.swing.text.Style ; 79 import javax.swing.ProgressMonitor ; 80 81 import edu.rice.cs.drjava.DrJava; 82 import edu.rice.cs.drjava.DrJavaRoot; 83 import edu.rice.cs.drjava.config.FileOption; 84 import edu.rice.cs.drjava.config.OptionConstants; 85 import edu.rice.cs.drjava.config.OptionEvent ; 86 import edu.rice.cs.drjava.config.OptionListener; 87 import edu.rice.cs.drjava.model.cache.DCacheAdapter; 88 import edu.rice.cs.drjava.model.cache.DDReconstructor; 89 import edu.rice.cs.drjava.model.cache.DocumentCache ; 90 import edu.rice.cs.drjava.model.compiler.CompilerModel; 91 import edu.rice.cs.drjava.model.debug.Breakpoint; 92 import edu.rice.cs.drjava.model.debug.DebugBreakpointData; 93 import edu.rice.cs.drjava.model.debug.DebugException ; 94 import edu.rice.cs.drjava.model.debug.DebugWatchData; 95 import edu.rice.cs.drjava.model.debug.Debugger; 96 import edu.rice.cs.drjava.model.debug.NoDebuggerAvailable; 97 import edu.rice.cs.drjava.model.definitions.ClassNameNotFoundException ; 98 import edu.rice.cs.drjava.model.definitions.CompoundUndoManager; 99 import edu.rice.cs.drjava.model.definitions.DefinitionsDocument; 100 import edu.rice.cs.drjava.model.definitions.DefinitionsEditorKit; 102 import edu.rice.cs.drjava.model.definitions.DocumentUIListener ; 103 import edu.rice.cs.drjava.model.definitions.InvalidPackageException; 104 import edu.rice.cs.drjava.model.definitions.reducedmodel.HighlightStatus; 105 import edu.rice.cs.drjava.model.definitions.reducedmodel.IndentInfo ; 106 import edu.rice.cs.drjava.model.definitions.reducedmodel.ReducedModelState; 107 import edu.rice.cs.drjava.model.junit.JUnitModel; 108 import edu.rice.cs.drjava.model.print.DrJavaBook; 109 import edu.rice.cs.drjava.model.repl.DefaultInteractionsModel ; 110 import edu.rice.cs.drjava.model.repl.InteractionsDJDocument; 111 import edu.rice.cs.drjava.model.repl.InteractionsDocument; 112 import edu.rice.cs.drjava.model.repl.InteractionsScriptModel; 113 import edu.rice.cs.drjava.project.DocFile ; 114 import edu.rice.cs.drjava.project.DocumentInfoGetter; 115 import edu.rice.cs.drjava.project.MalformedProjectFileException; 116 import edu.rice.cs.drjava.project.ProjectFileIR; 117 import edu.rice.cs.drjava.project.ProjectFileParser ; 118 import edu.rice.cs.drjava.project.ProjectProfile; 119 import edu.rice.cs.drjava.ui.MainFrame; 120 import edu.rice.cs.drjava.ui.SplashScreen; 121 122 import edu.rice.cs.plt.tuple.Pair; 123 import edu.rice.cs.plt.io.IOUtil; 124 import edu.rice.cs.plt.iter.IterUtil; 125 import edu.rice.cs.plt.lambda.LambdaUtil; 126 127 import edu.rice.cs.util.ClassPathVector; 128 import edu.rice.cs.util.FileOpenSelector; 129 import edu.rice.cs.util.FileOps; 130 import edu.rice.cs.util.Lambda; 131 import edu.rice.cs.util.Log; 132 import edu.rice.cs.util.NullFile; 133 import edu.rice.cs.util.OperationCanceledException ; 134 import edu.rice.cs.util.OrderedHashSet; 135 import edu.rice.cs.util.SRunnable; 136 import edu.rice.cs.util.StringOps; 137 import edu.rice.cs.util.UnexpectedException; 138 import edu.rice.cs.util.docnavigation.AWTContainerNavigatorFactory ; 139 import edu.rice.cs.util.docnavigation.IDocumentNavigator; 140 import edu.rice.cs.util.docnavigation.INavigationListener; 141 import edu.rice.cs.util.docnavigation.INavigatorItem; 142 import edu.rice.cs.util.docnavigation.INavigatorItemFilter ; 143 import edu.rice.cs.util.docnavigation.JTreeSortNavigator; 144 import edu.rice.cs.util.docnavigation.NodeData; 145 import edu.rice.cs.util.docnavigation.NodeDataVisitor; 146 import edu.rice.cs.util.swing.AsyncCompletionArgs ; 147 import edu.rice.cs.util.swing.AsyncTask; 148 import edu.rice.cs.util.swing.IAsyncProgress; 149 import edu.rice.cs.util.swing.DocumentIterator; 150 import edu.rice.cs.util.swing.Utilities; 151 import edu.rice.cs.util.text.AbstractDocumentInterface ; 152 import edu.rice.cs.util.text.ConsoleDocument; 153 import edu.rice.cs.util.ReaderWriterLock; 154 155 import static java.lang.Math .*; 156 157 161 public class AbstractGlobalModel implements SingleDisplayModel, OptionConstants, DocumentIterator { 162 163 public static Log _log = new Log("GlobalModel.txt", false); 164 165 166 protected DocumentCache _cache; 167 168 static final String DOCUMENT_OUT_OF_SYNC_MSG = 169 "Current document is out of sync with the Interactions Pane and should be recompiled!\n"; 170 171 static final String CLASSPATH_OUT_OF_SYNC_MSG = 172 "Interactions Pane is out of sync with the current classpath and should be reset!\n"; 173 174 176 180 183 public void addAuxiliaryFile(OpenDefinitionsDocument doc) { _state.addAuxFile(doc.getRawFile()); } 184 195 198 public void removeAuxiliaryFile(OpenDefinitionsDocument doc) { _state.remAuxFile(doc.getRawFile()); } 199 215 220 public final GlobalEventNotifier _notifier = new GlobalEventNotifier(); 221 222 224 225 protected final DefinitionsEditorKit _editorKit = new DefinitionsEditorKit(_notifier); 226 227 228 private final AbstractMap <File , OpenDefinitionsDocument> _documentsRepos = 230 new LinkedHashMap <File , OpenDefinitionsDocument>(); 231 232 234 235 protected final ConsoleDocument _consoleDoc; 236 237 238 protected final InteractionsDJDocument _consoleDocAdapter; 239 240 243 private final Object _systemWriterLock = new Object (); 244 245 248 public static final int WRITE_DELAY = 5; 249 250 251 protected volatile PageFormat _pageFormat = new PageFormat (); 252 253 256 private volatile OpenDefinitionsDocument _activeDocument; 257 258 262 private volatile File _activeDirectory; 263 264 265 private volatile boolean classPathChanged = false; 266 267 270 protected volatile IDocumentNavigator<OpenDefinitionsDocument> _documentNavigator = 271 new AWTContainerNavigatorFactory<OpenDefinitionsDocument>().makeListNavigator(); 272 273 274 protected final ConcreteRegionManager<Breakpoint> _breakpointManager; 275 276 277 public RegionManager<Breakpoint> getBreakpointManager() { return _breakpointManager; } 278 279 280 protected final ConcreteRegionManager<DocumentRegion> _bookmarkManager; 281 282 283 public RegionManager<DocumentRegion> getBookmarkManager() { return _bookmarkManager; } 284 285 286 protected final LinkedList <RegionManager<MovingDocumentRegion>> _findResultsManagers; 287 288 289 public List <RegionManager<MovingDocumentRegion>> getFindResultsManagers() { 290 return new LinkedList <RegionManager<MovingDocumentRegion>>(_findResultsManagers); 291 } 292 293 294 public RegionManager<MovingDocumentRegion> createFindResultsManager() { 295 ConcreteRegionManager<MovingDocumentRegion> rm = new ConcreteRegionManager<MovingDocumentRegion>(); 296 _findResultsManagers.add(rm); 297 298 for (final OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 300 doc.addFindResultsManager(rm); 301 } 302 return rm; 303 } 304 305 306 public void disposeFindResultsManager(RegionManager<MovingDocumentRegion> rm) { 307 for (final OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 309 doc.removeFindResultsManager(rm); 310 } 311 _findResultsManagers.remove(rm); 312 } 313 314 315 protected final ConcreteRegionManager<DocumentRegion> _browserHistoryManager; 316 317 318 public RegionManager<DocumentRegion> getBrowserHistoryManager() { return _browserHistoryManager; } 319 320 327 329 330 public AbstractGlobalModel() { 331 _cache = new DocumentCache(); 332 333 _consoleDocAdapter = new InteractionsDJDocument(); 334 _consoleDoc = new ConsoleDocument(_consoleDocAdapter); 335 336 _bookmarkManager = new ConcreteRegionManager<DocumentRegion>(); 337 _findResultsManagers = new LinkedList <RegionManager<MovingDocumentRegion>>(); 338 _browserHistoryManager = new ConcreteRegionManager<DocumentRegion>(); 339 340 _breakpointManager = new ConcreteRegionManager<Breakpoint>() { 341 public boolean changeRegionHelper(final Breakpoint oldBP, final Breakpoint newBP) { 342 if (oldBP.isEnabled() != newBP.isEnabled()) { 344 oldBP.setEnabled(newBP.isEnabled()); 345 return true; 346 } 347 return false; 348 } 349 }; 350 351 _registerOptionListeners(); 352 353 setFileGroupingState(makeFlatFileGroupingState()); 354 _notifier.projectRunnableChanged(); 355 _init(); 356 } 357 358 private void _init() { 359 360 361 final NodeDataVisitor<OpenDefinitionsDocument, Boolean > _gainVisitor = new NodeDataVisitor<OpenDefinitionsDocument, Boolean >() { 362 public Boolean itemCase(OpenDefinitionsDocument doc, Object ... p) { 363 Boolean modelInitiated = (Boolean )p[0]; 364 OpenDefinitionsDocument oldDoc = AbstractGlobalModel.this.getActiveDocument(); 368 _setActiveDoc(doc); 372 final File oldDir = _activeDirectory; final File dir = doc.getParentDirectory(); if (dir != null && ! dir.equals(oldDir)) { 376 378 _activeDirectory = dir; 379 _notifier.currentDirectoryChanged(_activeDirectory); 380 } 381 return Boolean.valueOf(true); 382 } 383 public Boolean fileCase(File f, Object ... p) { 384 if (! f.isAbsolute()) { File root = _state.getProjectFile().getParentFile().getAbsoluteFile(); 386 f = new File (root, f.getPath()); 387 } 388 _activeDirectory = f; _notifier.currentDirectoryChanged(f); 390 return Boolean.valueOf(true); 391 } 392 public Boolean stringCase(String s, Object ... p) { return Boolean.valueOf(false); } 393 }; 394 395 _documentNavigator.addNavigationListener(new INavigationListener<OpenDefinitionsDocument>() { 396 public void gainedSelection(NodeData<? extends OpenDefinitionsDocument> dat, boolean modelInitiated) { 397 dat.execute(_gainVisitor, modelInitiated); } 398 public void lostSelection(NodeData<? extends OpenDefinitionsDocument> dat, boolean modelInitiated) { 399 } 400 }); 401 402 _documentNavigator.addFocusListener(new FocusListener () { 403 public void focusGained(FocusEvent e) { 404 if (_documentNavigator.getCurrent() != null) _notifier.focusOnDefinitionsPane(); 407 } 408 public void focusLost(FocusEvent e) { } 409 }); 410 411 _ensureNotEmpty(); 412 setActiveFirstDocument(); 413 414 OptionListener<Integer > clipboardHistorySizeListener = new OptionListener<Integer >() { 416 public void optionChanged(OptionEvent<Integer > oce) { 417 ClipboardHistoryModel.singleton().resize(oce.value); 418 } 419 }; 420 DrJava.getConfig().addOptionListener(CLIPBOARD_HISTORY_SIZE, clipboardHistorySizeListener); 421 ClipboardHistoryModel.singleton().resize(DrJava.getConfig().getSetting(CLIPBOARD_HISTORY_SIZE).intValue()); 422 423 OptionListener<Integer > browserHistoryMaxSizeListener = new OptionListener<Integer >() { 425 public void optionChanged(OptionEvent<Integer > oce) { 426 AbstractGlobalModel.this.getBrowserHistoryManager().setMaximumSize(oce.value); 427 } 428 }; 429 DrJava.getConfig().addOptionListener(BROWSER_HISTORY_MAX_SIZE, browserHistoryMaxSizeListener); 430 getBrowserHistoryManager().setMaximumSize(DrJava.getConfig().getSetting(BROWSER_HISTORY_MAX_SIZE).intValue()); 431 } 432 433 434 protected File getSourceRoot(String packageName, File sourceFile) throws InvalidPackageException { 435 if (packageName.equals("")) { 437 return sourceFile.getParentFile(); 439 } 440 441 ArrayList <String > packageStack = new ArrayList <String >(); 442 int dotIndex = packageName.indexOf('.'); 443 int curPartBegins = 0; 444 445 while (dotIndex != -1) { 446 packageStack.add (packageName.substring(curPartBegins, dotIndex)); 447 curPartBegins = dotIndex + 1; 448 dotIndex = packageName.indexOf('.', dotIndex + 1); 449 } 450 451 packageStack.add (packageName.substring(curPartBegins)); 453 454 try { 457 File parentDir = sourceFile.getCanonicalFile (); 458 while (! packageStack.isEmpty()) { 459 String part = pop(packageStack); 460 parentDir = parentDir.getParentFile(); 461 if (parentDir == null) throw new UnexpectedException("parent dir is null!"); 462 463 if (! part.equals(parentDir.getName())) { 465 String msg = "The source file " + sourceFile.getAbsolutePath() + 466 " is in the wrong directory or in the wrong package. " + 467 "The directory name " + parentDir.getName() + 468 " does not match the package component " + part + "."; 469 470 throw new InvalidPackageException(-1, msg); 471 } 472 } 473 474 parentDir = parentDir.getParentFile(); 477 if (parentDir == null) { 478 throw new RuntimeException ("parent dir of first component of package name is null!"); 479 } 480 return parentDir; 481 } 482 catch (IOException ioe) { 483 String msg = "Could not locate directory of the source file: " + ioe; 484 throw new InvalidPackageException(-1, msg); 485 } 486 } 487 488 490 493 protected volatile FileGroupingState _state; 494 495 496 public void setFileGroupingState(FileGroupingState state) { 497 _state = state; 498 _notifier.projectRunnableChanged(); 499 _notifier.projectBuildDirChanged(); 500 _notifier.projectWorkDirChanged(); 501 } 503 504 protected FileGroupingState 505 makeProjectFileGroupingState(File pr, File main, File bd, File wd, File project, File [] srcFiles, File [] auxFiles, 506 ClassPathVector cp, File cjf, int cjflags) { 507 return new ProjectFileGroupingState(pr, main, bd, wd, project, srcFiles, auxFiles, cp, cjf, cjflags); 508 } 509 510 511 public boolean isClassPathChanged() { return classPathChanged; } 512 513 514 public void setClassPathChanged(boolean changed) { 515 classPathChanged = changed; 516 } 517 518 519 public void setProjectChanged(boolean changed) { 520 _state.setProjectChanged(changed); 521 } 523 524 525 public boolean isProjectChanged() { return _state.isProjectChanged(); } 526 527 528 public boolean isProjectActive() { return _state.isProjectActive(); } 529 530 532 public File getProjectFile() { return _state.getProjectFile(); } 533 534 537 public File [] getProjectFiles() { return _state.getProjectFiles(); } 538 539 540 public boolean inProject(File f) { return _state.inProject(f); } 541 542 546 public boolean inProjectPath(OpenDefinitionsDocument doc) { return _state.inProjectPath(doc); } 547 548 549 public void setMainClass(File f) { 550 _state.setMainClass(f); 551 _notifier.projectRunnableChanged(); 552 setProjectChanged(true); 553 } 554 555 556 public File getMainClass() { return _state.getMainClass(); } 557 558 559 public void setCreateJarFile(File f) { 560 _state.setCreateJarFile(f); 561 setProjectChanged(true); 562 } 563 564 565 public File getCreateJarFile() { return _state.getCreateJarFile(); } 566 567 568 public void setCreateJarFlags(int f) { 569 _state.setCreateJarFlags(f); 570 setProjectChanged(true); 571 } 572 573 574 public int getCreateJarFlags() { return _state.getCreateJarFlags(); } 575 576 577 public File getProjectRoot() { return _state.getProjectRoot(); } 578 579 580 public void setProjectRoot(File f) { 581 _state.setProjectRoot(f); 582 setProjectChanged(true); 584 } 585 586 587 public void setProjectFile(File f) { _state.setProjectFile(f); } 588 589 590 public File getBuildDirectory() { return _state.getBuildDirectory(); } 591 592 593 public void setBuildDirectory(File f) { 594 _state.setBuildDirectory(f); 595 _notifier.projectBuildDirChanged(); 596 setProjectChanged(true); 597 } 598 599 600 public File getMasterWorkingDirectory() { 601 File file; 602 try { 603 file = FileOps.getValidDirectory(DrJava.getConfig().getSetting(LAST_DIRECTORY)); 605 } 606 catch (RuntimeException e) { 607 DrJava.getConfig().setSetting(LAST_DIRECTORY, FileOption.NULL_FILE); 609 file = FileOps.getValidDirectory(DrJava.getConfig().getSetting(LAST_DIRECTORY)); 610 } 611 DrJava.getConfig().setSetting(LAST_DIRECTORY, file); 613 return file; 614 } 615 616 617 public File getWorkingDirectory() { return _state.getWorkingDirectory(); } 618 619 620 public void setWorkingDirectory(File f) { 621 _state.setWorkingDirectory(f); 622 _notifier.projectWorkDirChanged(); 623 setProjectChanged(true); 624 if (DrJava.getConfig().getSetting(STICKY_INTERACTIONS_DIRECTORY)) { 625 DrJava.getConfig().setSetting(LAST_INTERACTIONS_DIRECTORY, _state.getWorkingDirectory()); 627 } 628 } 629 630 public void cleanBuildDirectory() { _state.cleanBuildDirectory(); } 631 632 public List <File > getClassFiles() { return _state.getClassFiles(); } 633 634 635 protected static String getPackageName(String classname) { 636 int index = classname.lastIndexOf("."); 637 if (index != -1) return classname.substring(0, index); 638 else return ""; 639 } 640 641 642 class ProjectFileGroupingState implements FileGroupingState { 643 644 volatile File _projRoot; 645 volatile File _mainFile; 646 volatile File _buildDir; 647 volatile File _workDir; 648 volatile File _projectFile; 649 final File [] _projectFiles; 650 volatile File [] _auxFiles; 651 volatile ClassPathVector _projExtraClassPath; 652 private boolean _isProjectChanged = false; 653 volatile File _createJarFile; 654 volatile int _createJarFlags; 655 656 HashSet <String > _projFilePaths = new HashSet <String >(); 657 658 659 ProjectFileGroupingState(File project) { 660 this(project.getParentFile(), null, null, null, project, new File [0], new File [0], new ClassPathVector(), null, 0); 661 } 662 663 ProjectFileGroupingState(File pr, File main, File bd, File wd, File project, File [] srcFiles, File [] auxFiles, ClassPathVector cp, File cjf, int cjflags) { 664 _projRoot = pr; 665 _mainFile = main; 667 _buildDir = bd; 668 _workDir = wd; 669 _projectFile = project; 670 _projectFiles = srcFiles; 671 _auxFiles = auxFiles; 672 _projExtraClassPath = cp; 673 674 if (_projectFiles != null) try { for (File file : _projectFiles) { _projFilePaths.add( file.getCanonicalPath()); } } 675 catch(IOException e) { } 676 677 _createJarFile = cjf; 678 _createJarFlags = cjflags; 679 } 680 681 public boolean isProjectActive() { return true; } 682 683 686 public boolean inProjectPath(OpenDefinitionsDocument doc) { 687 if (doc.isUntitled()) return false; 688 689 File f; 693 try { f = doc.getFile(); } 694 catch(FileMovedException fme) { f = fme.getFile(); } 695 return inProjectPath(f); 696 } 697 698 701 public boolean inProjectPath(File f) { return IOUtil.isMember(f, getProjectRoot()); } 702 703 706 public File getProjectFile() { return _projectFile; } 707 708 public boolean inProject(File f) { 709 String path; 710 711 if (isUntitled(f) || ! inProjectPath(f)) return false; 712 try { 713 path = f.getCanonicalPath(); 714 return _projFilePaths.contains(path); 715 } 716 catch(IOException ioe) { return false; } 717 } 718 719 public File [] getProjectFiles() { return _projectFiles; } 720 721 public File getProjectRoot() { 722 if (_projRoot == null || _projRoot.equals( FileOption.NULL_FILE)) return _projectFile.getParentFile(); 723 return _projRoot; 725 } 726 727 public File getBuildDirectory() { return _buildDir; } 728 729 public File getWorkingDirectory() { 730 try { 731 if (_workDir == null || _workDir == FileOption.NULL_FILE) 732 return _projectFile.getParentFile().getCanonicalFile(); return _workDir.getCanonicalFile(); 734 } 735 catch(IOException e) { } 736 return _workDir.getAbsoluteFile(); 737 } 738 739 740 public void setProjectFile(File f) { _projectFile = f; } 741 742 public void setProjectRoot(File f) { 743 _projRoot = f; 744 } 746 747 748 public void addAuxFile(File f) { 749 synchronized(_auxFiles) { 750 int n = _auxFiles.length; 751 File [] newAuxFiles = new File [n + 1]; 752 System.arraycopy(_auxFiles, 0, newAuxFiles, 0, n); newAuxFiles[n] = f; 754 _auxFiles = newAuxFiles; 755 } 756 } 757 758 760 public void remAuxFile(File file) { 761 synchronized(_auxFiles) { 762 int newLen = _auxFiles.length - 1; 763 File [] newAuxFiles = new File [newLen]; 764 try { 765 int j = 0; 766 for (File f: _auxFiles) { 767 if (! f.equals(file)) { 768 newAuxFiles[j] = file; 769 j++; 770 } 771 } 772 if (j < newLen) throw new IllegalStateException ("auxFiles list contain two copies of " + file); 773 _auxFiles = newAuxFiles; 774 } 775 catch(Exception e) { throw new UnexpectedException(e); 777 } 778 } 779 } 780 781 public void setBuildDirectory(File f) { _buildDir = f; } 782 783 public void setWorkingDirectory(File f) { _workDir = f; } 784 785 public File getMainClass() { return _mainFile; } 786 787 public void setMainClass(File f) { _mainFile = f; } 788 789 public void setCreateJarFile(File f) { _createJarFile = f; } 790 791 public File getCreateJarFile() { return _createJarFile; } 792 793 public void setCreateJarFlags(int f) { _createJarFlags = f; } 794 795 public int getCreateJarFlags() { return _createJarFlags; } 796 797 public boolean isProjectChanged() { return _isProjectChanged; } 798 799 public void setProjectChanged(boolean changed) { _isProjectChanged = changed; } 800 801 public boolean isAuxiliaryFile(File f) { 802 String path; 803 804 if (isUntitled(f)) return false; 805 806 try { path = f.getCanonicalPath();} 807 catch(IOException ioe) { return false; } 808 809 synchronized(_auxFiles) { 810 for (File file : _auxFiles) { 811 try { if (file.getCanonicalPath().equals(path)) return true; } 812 catch(IOException ioe) { } 813 } 814 return false; 815 } 816 } 817 818 public void cleanBuildDirectory() { 820 File dir = this.getBuildDirectory (); 821 _notifier.executeAsyncTask(_findFilesToCleanTask, dir, false, true); 822 } 823 824 private AsyncTask<File ,List <File >> _findFilesToCleanTask = new AsyncTask<File ,List <File >>("Find Files to Clean") { 825 private FilenameFilter _filter = new FilenameFilter () { 826 public boolean accept(File parent, String name) { 827 return new File (parent, name).isDirectory() || name.endsWith(".class"); 828 } 829 }; 830 831 public List <File > runAsync(File buildDir, IAsyncProgress monitor) throws Exception { 832 List <File > accumulator = new LinkedList <File >(); 833 helper(buildDir, accumulator); return accumulator; 835 } 836 public void complete(AsyncCompletionArgs<List <File >> args) { 837 _notifier.executeAsyncTask(_deleteFilesTask, args.getResult(), true, true); 838 } 839 public String getDiscriptionMessage() { 840 return "Finding files to delete..."; 841 } 842 private void helper(File file, List <File > accumulator) { 843 if (file.isDirectory ()) { 844 File [] children = file.listFiles(_filter); 845 for (File child : children) { 846 helper(child, accumulator); 847 accumulator.add(file); 848 } 849 } 850 else if ( file.getName().endsWith(".class")){ 851 accumulator.add(file); 852 } 853 } 854 }; 855 856 private AsyncTask<List <File >,List <File >> _deleteFilesTask = new AsyncTask<List <File >,List <File >>("Delete Files") { 857 public List <File > runAsync(List <File > filesToDelete, IAsyncProgress monitor) throws Exception { 858 List <File > undeletableFiles = new ArrayList <File >(); 859 860 monitor.setMinimum (0); 861 monitor.setMaximum(filesToDelete.size()); 862 int progress = 1; 863 for(File file : filesToDelete) { 864 if (monitor.isCanceled()) { 865 break; 866 } 867 monitor.setNote(file.getName()); 868 boolean could = file.delete(); 869 if (!could) undeletableFiles.add(file); 870 monitor.setProgress(progress++); 871 } 872 return undeletableFiles; 874 } 875 public void complete(AsyncCompletionArgs<List <File >> args) { 876 } 878 public String getDiscriptionMessage() { 879 return "Deleting files..."; 880 } 881 }; 882 883 public List <File > getClassFiles() { 884 File dir = this.getBuildDirectory (); 885 LinkedList <File > acc = new LinkedList <File >(); 886 getClassFilesHelper(dir, acc); 887 if (! dir.exists()) dir.mkdirs(); 888 return acc; 889 } 890 891 private void getClassFilesHelper(File f, LinkedList <File > acc) { 892 if (f.isDirectory()) { 893 894 File fs[] = f.listFiles(new FilenameFilter () { 895 public boolean accept(File parent, String name) { 896 return new File (parent, name).isDirectory() || name.endsWith(".class"); 897 } 898 }); 899 900 if (fs!=null) { for (File kid: fs) { getClassFilesHelper(kid, acc); } 902 } 903 904 } else if (f.getName().endsWith(".class")) acc.add(f); 905 } 906 907 909 public ClassPathVector getExtraClassPath() { return _projExtraClassPath; } 910 public void setExtraClassPath(ClassPathVector cp) { 911 _projExtraClassPath = cp; 912 setClassPathChanged(true); 913 } 914 } 915 916 protected FileGroupingState makeFlatFileGroupingState() { return new FlatFileGroupingState(); } 917 918 class FlatFileGroupingState implements FileGroupingState { 919 public File getBuildDirectory() { return null; } 920 public File getProjectRoot() { return getWorkingDirectory(); } 921 public File getWorkingDirectory() { 922 try { 924 File [] roots = getSourceRootSet(); 925 if (roots.length == 0) { 926 File file = null; 929 if (DrJava.getConfig().getSetting(STICKY_INTERACTIONS_DIRECTORY)) { 931 try { 932 file = FileOps.getValidDirectory(DrJava.getConfig().getSetting(LAST_INTERACTIONS_DIRECTORY)); 934 } 936 catch (RuntimeException e) { file = null; } 937 } 938 if (file == null) { 939 DrJava.getConfig().setSetting(LAST_INTERACTIONS_DIRECTORY, FileOption.NULL_FILE); 941 file = FileOps.getValidDirectory(DrJava.getConfig().getSetting(LAST_INTERACTIONS_DIRECTORY)); 942 } 943 DrJava.getConfig().setSetting(LAST_INTERACTIONS_DIRECTORY, file); 945 return file; 947 } 948 return roots[0].getCanonicalFile(); 950 } 951 catch(IOException e) { } 952 return new File (System.getProperty("user.home")); } 955 public boolean isProjectActive() { return false; } 956 public boolean inProjectPath(OpenDefinitionsDocument doc) { return false; } 957 public boolean inProjectPath(File f) { return false; } 958 public File getProjectFile() { return null; } 959 public void setBuildDirectory(File f) { } 960 public void setProjectFile(File f) { } 961 public void setProjectRoot(File f) { } 962 public void addAuxFile(File f) { } 963 public void remAuxFile(File f) { } 964 public void setWorkingDirectory(File f) { } 965 public File [] getProjectFiles() { return null; } 966 public boolean inProject(File f) { return false; } 967 public File getMainClass() { return null; } 968 public void setMainClass(File f) { } 969 public void setCreateJarFile(File f) { } 970 public File getCreateJarFile() { return null; } 971 public void setCreateJarFlags(int f) { } 972 public int getCreateJarFlags() { return 0; } 973 public ClassPathVector getExtraClassPath() { return new ClassPathVector(); } 974 public void setExtraClassPath(ClassPathVector cp) { } 975 public boolean isProjectChanged() { return false; } 976 public void setProjectChanged(boolean changed) { } 977 public boolean isAuxiliaryFile(File f) { return false; } 978 979 public void cleanBuildDirectory() { } 980 981 public List <File > getClassFiles() { return new LinkedList <File >(); } 982 } 983 984 987 public String getSourceBinTitle() { return "[ Source Files ]"; } 988 989 992 public String getExternalBinTitle() { return "[ External Files ]"; } 993 994 997 public String getAuxiliaryBinTitle() { return "[ Included External Files ]"; } 998 999 1001 1004 public void addListener(GlobalModelListener listener) { _notifier.addListener(listener); } 1005 1006 1010 public void removeListener(GlobalModelListener listener) { _notifier.removeListener(listener); } 1011 1012 1014 public DefinitionsEditorKit getEditorKit() { return _editorKit; } 1015 1016 1017 public DefaultInteractionsModel getInteractionsModel() { 1018 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interaction"); 1019 } 1020 1021 1022 public InteractionsDJDocument getSwingInteractionsDocument() { 1023 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interaction"); 1024 } 1025 1026 1027 public InteractionsDocument getInteractionsDocument() { 1028 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interaction"); 1029 } 1030 1031 public ConsoleDocument getConsoleDocument() { return _consoleDoc; } 1032 1033 public InteractionsDJDocument getSwingConsoleDocument() { return _consoleDocAdapter; } 1034 1035 public PageFormat getPageFormat() { return _pageFormat; } 1036 1037 public void setPageFormat(PageFormat format) { _pageFormat = format; } 1038 1039 public CompilerModel getCompilerModel() { 1040 throw new UnsupportedOperationException ("AbstractGlobalModel does not support compilation"); 1041 } 1042 1043 1044 public int getNumCompErrors() { 1045 throw new UnsupportedOperationException ("AbstractGlobalModel does not support compilation"); 1046 } 1047 1048 1049 public void setNumCompErrors(int num) { 1050 throw new UnsupportedOperationException ("AbstractGlobalModel does not support compilation"); 1051 }; 1052 1053 1054 public JUnitModel getJUnitModel() { 1055 throw new UnsupportedOperationException ("AbstractGlobalModel does not support unit testing"); 1056 } 1057 1058 1059 public JavadocModel getJavadocModel() { 1060 throw new UnsupportedOperationException ("AbstractGlobalModel does not support javadoc"); 1061 } 1062 1063 public IDocumentNavigator<OpenDefinitionsDocument> getDocumentNavigator() { return _documentNavigator; } 1064 1065 public void setDocumentNavigator(IDocumentNavigator<OpenDefinitionsDocument> newnav) { _documentNavigator = newnav; } 1066 1067 1070 public OpenDefinitionsDocument newFile(File parentDir) { 1071 final ConcreteOpenDefDoc doc = _createOpenDefinitionsDocument(); 1072 doc.setParentDirectory(parentDir); 1073 doc.setFile(new NullFile()); 1074 addDocToNavigator(doc); 1075 _notifier.newFileCreated(doc); 1076 return doc; 1077 } 1078 1079 1082 public OpenDefinitionsDocument newFile() { 1083 File dir = _activeDirectory; 1084 if (dir == null) dir = getMasterWorkingDirectory(); 1085 OpenDefinitionsDocument doc = newFile(dir); 1087 setActiveDocument(doc); 1088 return doc; 1089 } 1090 1091 1097 public OpenDefinitionsDocument newTestCase(String name, boolean makeSetUp, boolean makeTearDown) { 1098 boolean elementary = (DrJava.getConfig().getSetting(LANGUAGE_LEVEL) == 1); 1099 1100 final StringBuilder buf = new StringBuilder (); 1101 if (! elementary) buf.append("import junit.framework.TestCase;\n\n"); 1102 buf.append("/**\n"); 1103 buf.append("* A JUnit test case class.\n"); 1104 buf.append("* Every method starting with the word \"test\" will be called when running\n"); 1105 buf.append("* the test with JUnit.\n"); 1106 buf.append("*/\n"); 1107 if (! elementary) buf.append("public "); 1108 buf.append("class "); 1109 buf.append(name); 1110 buf.append(" extends TestCase {\n\n"); 1111 if (makeSetUp) { 1112 buf.append("/**\n"); 1113 buf.append("* This method is called before each test method, to perform any common\n"); 1114 buf.append("* setup if necessary.\n"); 1115 buf.append("*/\n"); 1116 if (! elementary) buf.append("public "); 1117 buf.append("void setUp() throws Exception {\n}\n\n"); 1118 } 1119 if (makeTearDown) { 1120 buf.append("/**\n"); 1121 buf.append("* This method is called after each test method, to perform any common\n"); 1122 buf.append("* clean-up if necessary.\n"); 1123 buf.append("*/\n"); 1124 if (! elementary) buf.append("public "); 1125 buf.append("void tearDown() throws Exception {\n}\n\n"); 1126 } 1127 buf.append("/**\n"); 1128 buf.append("* A test method.\n"); 1129 buf.append("* (Replace \"X\" with a name describing the test. You may write as\n"); 1130 buf.append ("* many \"testSomething\" methods in this class as you wish, and each\n"); 1131 buf.append("* one will be called when running JUnit over this class.)\n"); 1132 buf.append("*/\n"); 1133 if (! elementary) buf.append("public "); 1134 buf.append("void testX() {\n}\n\n"); 1135 buf.append("}\n"); 1136 String test = buf.toString(); 1137 1138 OpenDefinitionsDocument openDoc = newFile(); 1139 try { 1140 openDoc.insertString(0, test, null); 1141 openDoc.indentLines(0, test.length()); 1142 } 1143 catch (BadLocationException ble) { 1144 throw new UnexpectedException(ble); 1145 } 1146 return openDoc; 1147 } 1148 1149 1150 public DocumentCache getDocumentCache() { return _cache; } 1151 1152 1154 1163 public OpenDefinitionsDocument openFile(FileOpenSelector com) throws 1164 IOException , OperationCanceledException, AlreadyOpenException { 1165 boolean closeUntitled = _hasOneEmptyDocument(); 1167 OpenDefinitionsDocument oldDoc = _activeDocument; 1168 OpenDefinitionsDocument openedDoc = openFileHelper(com); 1169 if (closeUntitled) closeFileHelper(oldDoc); 1170 setActiveDocument(openedDoc); 1173 setProjectChanged(true); 1174 return openedDoc; 1176 } 1177 1178 protected OpenDefinitionsDocument openFileHelper(FileOpenSelector com) throws IOException , 1179 OperationCanceledException, AlreadyOpenException { 1180 1181 final File file = (com.getFiles())[0].getCanonicalFile(); OpenDefinitionsDocument odd = _openFile(file); 1184 try { 1187 File classPath = odd.getSourceRoot (); 1188 addDocToClassPath(odd); 1189 setClassPathChanged(true); 1190 } 1191 catch (InvalidPackageException e) { 1192 } 1194 1195 return odd; 1196 } 1197 1198 1208 public OpenDefinitionsDocument[] openFiles(FileOpenSelector com) 1209 throws IOException , OperationCanceledException, AlreadyOpenException { 1210 1211 boolean closeUntitled = _hasOneEmptyDocument(); 1213 OpenDefinitionsDocument oldDoc = _activeDocument; 1214 1215 OpenDefinitionsDocument[] openedDocs = openFilesHelper(com); 1216 if (openedDocs.length > 0) { 1217 if (closeUntitled) closeFileHelper(oldDoc); 1218 setActiveDocument(openedDocs[0]); 1220 } 1221 return openedDocs; 1222 } 1223 1224 protected OpenDefinitionsDocument[] openFilesHelper(FileOpenSelector com) 1225 throws IOException , OperationCanceledException, AlreadyOpenException { 1226 1227 final File [] files = com.getFiles(); 1228 if (files == null) { throw new IOException ("No Files returned from FileSelector"); } 1229 OpenDefinitionsDocument[] docs = _openFiles(files); 1230 return docs; 1231 } 1232 1233 1236 1238 1239 private OpenDefinitionsDocument[] _openFiles(File [] files) 1240 throws IOException , OperationCanceledException, AlreadyOpenException { 1241 1242 ArrayList <OpenDefinitionsDocument> alreadyOpenDocuments = new ArrayList <OpenDefinitionsDocument>(); 1243 ArrayList <OpenDefinitionsDocument> retDocs = new ArrayList <OpenDefinitionsDocument>(); 1244 1245 1247 LinkedList <File > filesNotFound = new LinkedList <File >(); 1248 LinkedList <OpenDefinitionsDocument> filesOpened = new LinkedList <OpenDefinitionsDocument>(); 1249 for (final File f: files) { 1250 if (f == null) throw new IOException ("File name returned from FileSelector is null"); 1251 try { 1252 OpenDefinitionsDocument d = _rawOpenFile(IOUtil.attemptCanonicalFile(f)); 1253 retDocs.add(d); 1255 filesOpened.add(d); 1256 } 1257 catch (AlreadyOpenException aoe) { 1258 OpenDefinitionsDocument d = aoe.getOpenDocument(); 1259 retDocs.add(d); 1260 alreadyOpenDocuments.add(d); 1261 } 1262 catch(FileNotFoundException e) { filesNotFound.add(f); } 1263 } 1264 1265 for (final OpenDefinitionsDocument d: filesOpened) { 1266 _completeOpenFile(d); } 1268 for (File f: filesNotFound) { _notifier.fileNotFound(f); } 1270 1271 if (! alreadyOpenDocuments.isEmpty()) { 1272 for(OpenDefinitionsDocument d : alreadyOpenDocuments) { 1273 _notifier.handleAlreadyOpenDocument(d); 1274 _notifier.fileOpened(d); 1275 } 1276 } 1277 1278 if (retDocs != null) { 1279 return retDocs.toArray(new OpenDefinitionsDocument[0]); 1280 } 1281 else { 1282 throw new OperationCanceledException(); 1284 } 1285 } 1286 1287 1288 1290 1293 public void openFolder(File dir, boolean rec) throws IOException , OperationCanceledException, AlreadyOpenException { 1294 if (dir == null) return; 1296 if (dir.isDirectory()) { 1297 Iterable <File > filesIterable; 1298 1299 String extension = DrJavaRoot.LANGUAGE_LEVEL_EXTENSIONS[DrJava.getConfig().getSetting(LANGUAGE_LEVEL)]; 1300 1301 FileFilter match = IOUtil.predicateFileFilter(LambdaUtil.and(IOUtil.IS_FILE, 1302 IOUtil.extensionFilePredicate(extension))); 1303 if (rec) { filesIterable = IOUtil.listFilesRecursively(dir, match); } 1304 else { filesIterable = IOUtil.attemptListFilesAsIterable(dir, match); } 1305 List <File > files = IterUtil.asList(filesIterable); 1306 1307 if (isProjectActive()) { 1308 Collections.sort(files, new Comparator <File >() { 1309 public int compare(File o1,File o2) { 1310 return - o1.getAbsolutePath().compareTo(o2.getAbsolutePath()); 1311 } 1312 }); 1313 } 1314 else { 1315 Collections.sort(files, new Comparator <File >() { 1316 public int compare(File o1,File o2) { 1317 return - o1.getName().compareTo(o2.getName()); 1318 } 1319 }); 1320 } 1321 1322 int ct = files.size(); 1323 1324 final File [] sfiles = files.toArray(new File [ct]); 1325 1326 openFiles(new FileOpenSelector() { public File [] getFiles() { return sfiles; } }); 1327 1328 if (ct > 0 && _state.inProjectPath(dir)) setProjectChanged(true); 1329 } 1330 } 1331 1332 1333 1338 public void saveAllFiles(FileSaveSelector com) throws IOException { 1339 OpenDefinitionsDocument curdoc = getActiveDocument(); 1340 saveAllFilesHelper(com); 1341 setActiveDocument(curdoc); } 1343 1344 1345 protected void saveAllFilesHelper(FileSaveSelector com) throws IOException { 1346 1347 boolean isProjActive = isProjectActive(); 1348 1349 for (final OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { if (doc.isUntitled() && (isProjActive || ! doc.isModifiedSinceSave())) continue; 1352 aboutToSaveFromSaveAll(doc); 1353 doc.saveFile(com); 1354 } 1355 } 1356 1357 1360 public void createNewProject(File projFile) { setFileGroupingState(new ProjectFileGroupingState(projFile)); } 1361 1362 1363 public void configNewProject() throws IOException { 1364 1365 assert EventQueue.isDispatchThread(); 1366 1367 File projFile = getProjectFile(); 1369 1370 ProjectProfile builder = new ProjectProfile(projFile); 1371 1372 ArrayList <DocFile> srcFileList = new ArrayList <DocFile>(); 1374 LinkedList <DocFile> auxFileList = new LinkedList <DocFile>(); 1375 ArrayList <File > extFileList = new ArrayList <File >(); 1376 1377 File projectRoot = builder.getProjectRoot(); 1378 1379 1381 ClassPathVector exCp = new ClassPathVector(); 1382 1383 for (OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 1384 1385 File f = doc.getFile(); 1386 1387 if (doc.isUntitled()) extFileList.add(f); 1388 else if (IOUtil.isMember(f, projectRoot)) { 1389 DocFile file = new DocFile(f); 1390 file.setPackage(doc.getPackageName()); builder.addSourceFile(file); 1392 srcFileList.add(file); 1393 } 1394 else if ( doc.isAuxiliaryFile()) { 1395 DocFile file = new DocFile(f); 1396 file.setPackage(doc.getPackageName()); builder.addAuxiliaryFile(new DocFile(f)); 1398 auxFileList.add(file); 1399 } 1400 else extFileList.add(f); 1401 } 1402 1403 1406 builder.write(); 1408 1409 _loadProject(builder); 1410 } 1411 1415 public ProjectProfile _makeProjectProfile(File file, Hashtable <OpenDefinitionsDocument, DocumentInfoGetter> info) throws IOException { 1416 ProjectProfile builder = new ProjectProfile(file); 1417 1418 File pr = getProjectRoot(); 1420 if (pr != null) builder.setProjectRoot(pr); 1421 1422 ArrayList <File > srcFileList = new ArrayList <File >(); 1424 LinkedList <File > auxFileList = new LinkedList <File >(); 1425 1426 for (OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 1427 if (doc.inProjectPath()) { 1428 DocumentInfoGetter g = info.get(doc); 1429 builder.addSourceFile(g); 1430 srcFileList.add(g.getFile()); 1431 } 1432 else if (doc.isAuxiliaryFile()) { 1433 DocumentInfoGetter g = info.get(doc); 1434 builder.addAuxiliaryFile(g); 1435 auxFileList.add(g.getFile()); 1436 } 1437 } 1438 1439 if (_documentNavigator instanceof JTreeSortNavigator) { 1441 String [] paths = ((JTreeSortNavigator<?>)_documentNavigator).getCollapsedPaths(); 1442 for (String s : paths) { builder.addCollapsedPath(s); } 1443 } 1444 1445 ClassPathVector exCp = getExtraClassPath(); 1446 if (exCp != null) { 1447 ArrayList <File > exCpF = exCp.asFileVector(); 1448 for (File f : exCpF) { 1449 builder.addClassPathFile(f); 1450 } 1452 } 1453 1455 File bd = getBuildDirectory(); 1457 if (bd != null) builder.setBuildDirectory(bd); 1458 1459 File wd = getWorkingDirectory(); if (wd != null) builder.setWorkingDirectory(wd); 1462 1463 File mainClass = getMainClass(); 1465 if (mainClass != null) builder.setMainClass(mainClass); 1466 1467 File createJarFile = getCreateJarFile(); 1469 if (createJarFile != null) builder.setCreateJarFile(createJarFile); 1470 1471 int createJarFlags = getCreateJarFlags(); 1472 if (createJarFlags != 0) builder.setCreateJarFlags (createJarFlags); 1473 1474 ArrayList <DebugBreakpointData> l = new ArrayList <DebugBreakpointData>(); 1476 for(Breakpoint bp: getBreakpointManager().getRegions()) { l.add(bp); } 1477 builder.setBreakpoints(l); 1478 try { 1479 builder.setWatches(getDebugger().getWatches()); 1480 } 1481 catch(DebugException de) { } 1482 1483 builder.setBookmarks(getBookmarkManager().getRegions()); 1485 1486 return builder; 1487 } 1488 1489 1492 public void saveProject(File file, Hashtable <OpenDefinitionsDocument, DocumentInfoGetter> info) throws IOException { 1493 ProjectProfile builder = _makeProjectProfile(file, info); 1494 1495 builder.write(); 1497 1498 1503 ClassPathVector exCp = new ClassPathVector(); 1504 for (File f : builder.getClassPaths()) { exCp.add(f); } 1505 setFileGroupingState(makeProjectFileGroupingState(builder.getProjectRoot(), builder.getMainClass (), 1506 builder.getBuildDirectory(), builder.getWorkingDirectory(), file, 1507 builder.getSourceFiles(), builder.getAuxiliaryFiles(), exCp, 1508 builder.getCreateJarFile(), builder.getCreateJarFlags())); 1509 } 1510 1511 public void reloadProject(File file, Hashtable <OpenDefinitionsDocument, DocumentInfoGetter> info) throws IOException { 1512 boolean projChanged = isProjectChanged(); 1513 ProjectProfile builder = _makeProjectProfile(file, info); 1514 _loadProject(builder); 1515 setProjectChanged(projChanged); 1516 } 1517 1518 1523 public void openProject(File projectFile) throws IOException , MalformedProjectFileException { 1524 _loadProject(ProjectFileParser.ONLY.parse(projectFile)); 1525 } 1526 1527 1531 private void _loadProject(final ProjectFileIR ir) throws IOException { 1532 1533 assert EventQueue.isDispatchThread(); 1534 1535 final DocFile[] srcFiles = ir.getSourceFiles(); 1536 final DocFile[] auxFiles = ir.getAuxiliaryFiles(); 1537 final File projectFile = ir.getProjectFile(); 1538 final File projectRoot = ir.getProjectRoot(); 1539 final File buildDir = ir.getBuildDirectory (); 1540 final File workDir = ir.getWorkingDirectory(); 1541 final File mainClass = ir.getMainClass(); 1542 final File [] projectClassPaths = ir.getClassPaths(); 1543 final File createJarFile = ir.getCreateJarFile (); 1544 int createJarFlags = ir.getCreateJarFlags(); 1545 1546 getBrowserHistoryManager().clearRegions(); 1548 1549 getBreakpointManager().clearRegions(); 1551 for (DebugBreakpointData dbd: ir.getBreakpoints()) { 1552 try { 1553 getDebugger().toggleBreakpoint(getDocumentForFile( dbd.getFile()), dbd.getOffset(), dbd.getLineNumber(), 1554 dbd.isEnabled()); 1555 } 1556 catch(DebugException de) { } 1557 } 1558 1559 try { getDebugger().removeAllWatches(); } 1561 catch(DebugException de) { } 1562 for (DebugWatchData dwd: ir.getWatches()) { 1563 try { getDebugger().addWatch( dwd.getName()); } 1564 catch(DebugException de) { } 1565 } 1566 1567 getBookmarkManager().clearRegions(); 1569 for (final DocumentRegion bm: ir.getBookmarks ()) { 1570 final OpenDefinitionsDocument odd = getDocumentForFile(bm.getFile()); 1571 getBookmarkManager().addRegion(new SimpleDocumentRegion(odd, odd.getFile(), bm.getStartOffset(), bm.getEndOffset())); 1572 } 1573 1574 final String projfilepath = projectRoot.getCanonicalPath(); 1575 1576 1580 1582 1586 List <Pair<String , INavigatorItemFilter<OpenDefinitionsDocument>>> l = 1587 new LinkedList <Pair<String , INavigatorItemFilter<OpenDefinitionsDocument>>>(); 1588 1589 l.add(new Pair<String , INavigatorItemFilter<OpenDefinitionsDocument>>(getSourceBinTitle(), 1590 new INavigatorItemFilter<OpenDefinitionsDocument>() { 1591 public boolean accept(OpenDefinitionsDocument d) { return d.inProjectPath(); } 1592 })); 1593 1594 l.add(new Pair<String , INavigatorItemFilter<OpenDefinitionsDocument>>(getAuxiliaryBinTitle(), 1595 new INavigatorItemFilter<OpenDefinitionsDocument>() { 1596 public boolean accept(OpenDefinitionsDocument d) { return d.isAuxiliaryFile(); } 1597 })); 1598 1599 l.add(new Pair<String , INavigatorItemFilter<OpenDefinitionsDocument>>(getExternalBinTitle(), 1600 new INavigatorItemFilter<OpenDefinitionsDocument>() { 1601 public boolean accept(OpenDefinitionsDocument d) { 1602 return !(d.inProject() || d.isAuxiliaryFile()) || d.isUntitled(); 1603 } 1604 })); 1605 1606 IDocumentNavigator<OpenDefinitionsDocument> newNav = 1607 new AWTContainerNavigatorFactory<OpenDefinitionsDocument>().makeTreeNavigator(projfilepath, getDocumentNavigator(), l); 1608 1609 setDocumentNavigator(newNav); 1610 1611 1616 ClassPathVector extraClassPaths = new ClassPathVector(); 1617 for (File f : projectClassPaths) { extraClassPaths.add(f); } 1618 1619 1621 setFileGroupingState(makeProjectFileGroupingState(projectRoot, mainClass, buildDir, workDir, projectFile, srcFiles, 1622 auxFiles, extraClassPaths, createJarFile, createJarFlags)); 1623 1624 resetInteractions(getWorkingDirectory()); 1626 ArrayList <DocFile> projFiles = new ArrayList <DocFile>(); 1627 DocFile active = null; 1628 for (DocFile f: srcFiles) { 1629 if (f.lastModified() > f.getSavedModDate()) f.setSavedModDate (f.lastModified()); 1630 projFiles.add(f); 1631 } 1632 for (DocFile f: auxFiles) { 1633 if (f.lastModified() > f.getSavedModDate()) f.setSavedModDate (f.lastModified()); 1634 projFiles.add(f); 1635 } 1636 if (active != null) projFiles.add(active); 1638 1639 1641 final List <OpenDefinitionsDocument> projDocs = getProjectDocuments(); 1643 1646 if (! projDocs.isEmpty()) 1647 for (OpenDefinitionsDocument d: projDocs) { 1650 try { 1651 final String path = fixPathForNavigator(d.getFile().getCanonicalPath()); 1652 _documentNavigator.refreshDocument(d, path); } 1654 catch(IOException e) { } 1655 } 1656 1659 final DocFile[] filesToOpen = projFiles.toArray(new DocFile[projFiles.size()]); 1662 _notifier.projectOpened(projectFile, new FileOpenSelector() { 1663 public File [] getFiles() { return filesToOpen; } 1664 }); 1665 1666 1686 if (_documentNavigator instanceof JTreeSortNavigator) 1687 ((JTreeSortNavigator<?>)_documentNavigator).collapsePaths(ir.getCollapsedPaths()); 1688 } 1689 1690 1694 public void closeProject(boolean suppressReset) { 1695 setDocumentNavigator(new AWTContainerNavigatorFactory<OpenDefinitionsDocument>(). 1696 makeListNavigator(getDocumentNavigator())); 1697 setFileGroupingState(makeFlatFileGroupingState()); 1698 1699 if (! suppressReset) resetInteractions(getWorkingDirectory()); 1700 _notifier.projectClosed(); 1701 } 1702 1703 1706 public void aboutToSaveFromSaveAll(OpenDefinitionsDocument doc) { 1707 if ( doc.isUntitled()) setActiveDocument(doc); 1708 } 1709 1710 1715 public boolean closeFile(OpenDefinitionsDocument doc) { 1716 List <OpenDefinitionsDocument> list = new LinkedList <OpenDefinitionsDocument>(); 1717 list.add(doc); 1718 return closeFiles(list); 1719 } 1720 1721 1725 public boolean closeAllFiles() { 1726 List <OpenDefinitionsDocument> docs = getOpenDefinitionsDocuments(); 1727 boolean res = closeFiles(docs); 1728 if (res) { 1729 resetInteractions(getWorkingDirectory()); 1731 } 1732 return res; 1733 } 1734 1735 1749 public boolean closeFiles(List <OpenDefinitionsDocument> docs) { 1750 if (docs.size() == 0) return true; 1751 1752 _log.log("closeFiles(" + docs + ") called"); 1753 1754 for (OpenDefinitionsDocument doc : docs) { 1755 if (! doc.canAbandonFile()) return false; } 1756 1757 1759 if (docs.size() == getOpenDefinitionsDocumentsSize()) newFile(); 1760 1761 1763 _ensureNotActive(docs); 1764 1765 for (OpenDefinitionsDocument doc : docs) { closeFileWithoutPrompt(doc); } 1767 return true; 1768 } 1769 1770 1771 protected boolean closeFileHelper(OpenDefinitionsDocument doc) { 1772 boolean canClose = doc.canAbandonFile(); 1774 if (canClose) return closeFileWithoutPrompt(doc); 1775 return false; 1776 } 1777 1778 1784 public boolean closeFileWithoutPrompt(final OpenDefinitionsDocument doc) { 1785 1787 _log.log("closeFileWithoutPrompt(" + doc + ") called; getRawFile() = " + doc.getRawFile()); 1788 _log.log("_documentsRepos = " + _documentsRepos); 1789 boolean found; 1790 synchronized(_documentsRepos) { found = (_documentsRepos.remove(doc.getRawFile()) != null); } 1791 1792 if (! found) { 1793 _log.log("Cannot close " + doc + "; not found!"); 1794 return false; 1795 } 1796 1797 doc.getBreakpointManager().clearRegions(); 1799 doc.getBookmarkManager().clearRegions(); 1800 for (RegionManager<MovingDocumentRegion> rm: doc.getFindResultsManagers()) rm.clearRegions(); 1801 doc.getBrowserHistoryManager().clearRegions(); 1802 1803 Utilities.invokeLater (new SRunnable() { 1804 public void run() { _documentNavigator.removeDocument(doc); } }); 1806 _notifier.fileClosed(doc); 1807 doc.close(); 1808 return true; 1809 } 1810 1811 1815 public boolean closeAllFilesOnQuit() { 1816 1817 List <OpenDefinitionsDocument> docs = getOpenDefinitionsDocuments(); 1818 1819 OpenDefinitionsDocument retainedDoc = null; 1821 1822 for (OpenDefinitionsDocument doc : docs) { 1823 if (! doc.canAbandonFile()) { retainedDoc = doc; break; } 1824 } 1825 1826 if (retainedDoc != null) { return false; 1829 } 1830 1831 newFile(); 1835 1836 _ensureNotActive(docs); 1839 1840 for (OpenDefinitionsDocument doc : docs) { closeFileWithoutPrompt(doc); } 1842 1843 return true; 1844 } 1845 1846 1847 public void quit() { quit(false); } 1848 1849 1850 public void forceQuit() { quit(true); } 1851 1852 1853 private void quit(boolean force) { 1854 try { 1856 if (! force && ! closeAllFilesOnQuit()) return; 1857 1858 1866 1867 shutdown(force); 1868 } 1869 catch(Throwable t) { shutdown(true); } 1870 } 1871 1872 1873 private void shutdown(boolean force) { 1874 if (force) Runtime.getRuntime().halt(0); 1875 1876 dispose(); 1878 if (DrJava.getConfig().getSetting(OptionConstants.DRJAVA_USE_FORCE_QUIT)) { 1879 Runtime.getRuntime().halt(0); } 1881 1882 Thread monitor = new Thread (new Runnable () { 1883 public void run() { 1884 try { Thread.sleep(2000); } 1885 catch(InterruptedException e) { } 1886 Runtime.getRuntime().halt(0); } 1888 }); 1889 monitor.setDaemon(true); 1890 monitor.start(); 1891 System.exit(0); 1892 } 1893 1894 1895 public void dispose() { 1896 synchronized(_documentsRepos) { _documentsRepos.clear(); } 1897 Utilities.invokeLater(new SRunnable() { 1898 public void run() { _documentNavigator.clear(); } }); 1900 SwingUtilities.invokeLater(new Runnable () { public void run() { _notifier.removeAllListeners(); } }); 1902 } 1903 1904 1905 public void disposeExternalResources() { } 1906 1907 1908 public OpenDefinitionsDocument getDocumentForFile(File file) throws IOException { 1909 OpenDefinitionsDocument doc = _getOpenDocument(file); 1911 if (doc == null) { 1912 final File f = file; 1914 FileOpenSelector selector = 1915 new FileOpenSelector() { public File [] getFiles() { return new File [] {f}; } }; 1916 try { doc = openFile(selector);} 1917 catch (AlreadyOpenException e) { doc = e.getOpenDocument(); } 1918 catch (OperationCanceledException e) { throw new UnexpectedException(e); } 1919 } 1920 return doc; 1921 } 1922 1923 1926 public boolean isAlreadyOpen(File file) { return (_getOpenDocument(file) != null); } 1927 1928 1932 public OpenDefinitionsDocument getODDForDocument(AbstractDocumentInterface doc) { 1933 1936 if (doc instanceof OpenDefinitionsDocument) return (OpenDefinitionsDocument) doc; 1937 if (doc instanceof DefinitionsDocument) return ((DefinitionsDocument) doc).getOpenDefDoc(); 1938 throw new IllegalStateException ("Could not get the OpenDefinitionsDocument for Document: " + doc); 1939 } 1940 1941 1942 public DocumentIterator getDocumentIterator() { return this; } 1943 1944 1948 public OpenDefinitionsDocument getNextDocument(OpenDefinitionsDocument d) { 1949 OpenDefinitionsDocument nextdoc = null; OpenDefinitionsDocument doc = getODDForDocument(d); 1952 nextdoc = _documentNavigator.getNext(doc); 1953 if (nextdoc == doc) nextdoc = _documentNavigator.getFirst(); OpenDefinitionsDocument res = getNextDocHelper(nextdoc); 1955 return res; 1957 } 1960 1961 private OpenDefinitionsDocument getNextDocHelper(OpenDefinitionsDocument nextdoc) { 1962 if ( nextdoc.isUntitled() || nextdoc.verifyExists()) return nextdoc; 1963 1965 return getNextDocument(nextdoc); 1967 } 1968 1969 1973 public OpenDefinitionsDocument getPrevDocument(OpenDefinitionsDocument d) { 1974 OpenDefinitionsDocument prevdoc = null; OpenDefinitionsDocument doc = getODDForDocument(d); 1977 prevdoc = _documentNavigator.getPrevious(doc); 1978 if (prevdoc == doc) prevdoc = _documentNavigator.getLast(); return getPrevDocHelper(prevdoc); 1980 } 1983 1984 private OpenDefinitionsDocument getPrevDocHelper(OpenDefinitionsDocument prevdoc) { 1985 if (prevdoc.isUntitled() || prevdoc.verifyExists()) return prevdoc; 1986 1988 return getPrevDocument(prevdoc); 1990 } 1991 1992 public int getDocumentCount() { return _documentsRepos.size(); } 1993 1994 1998 public List <OpenDefinitionsDocument> getOpenDefinitionsDocuments() { 1999 synchronized(_documentsRepos) { 2000 ArrayList <OpenDefinitionsDocument> docs = new ArrayList <OpenDefinitionsDocument>(_documentsRepos.size()); 2001 for (OpenDefinitionsDocument doc: _documentsRepos.values()) { docs.add(doc); } 2002 return docs; 2003 } 2004 } 2005 2006 public List <OpenDefinitionsDocument> getSortedOpenDefinitionsDocuments() { return getOpenDefinitionsDocuments(); } 2007 2008 2009 public int getOpenDefinitionsDocumentsSize() { synchronized(_documentsRepos) { return _documentsRepos.size(); } } 2010 2011 2012 public boolean hasOutOfSyncDocuments() { 2013 for (OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 2014 if (doc.isSourceFile() && ! doc.checkIfClassFileInSync()) { 2015 return true; 2017 } 2018 } 2019 return false; 2020 } 2021 2022 2026 void setDefinitionsIndent(int indent) { 2027 for (OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { doc.setIndent(indent); } 2028 } 2029 2030 2031 public void resetInteractions(File wd) { } 2032 2033 2034 public void resetInteractions(File wd, boolean forceReset) { } 2035 2036 2037 public void resetConsole() { 2038 _consoleDoc.reset(""); 2039 _notifier.consoleReset(); 2040 } 2041 2042 2043 public void interpretCurrentInteraction() { 2044 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2045 } 2046 2047 2048 public void loadHistory(FileOpenSelector selector) throws IOException { 2049 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2050 } 2051 2052 2053 public InteractionsScriptModel loadHistoryAsScript(FileOpenSelector selector) throws 2054 IOException , OperationCanceledException { 2055 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2056 } 2057 2058 2059 public void clearHistory() { 2060 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2061 } 2062 2063 2064 public void saveHistory(FileSaveSelector selector) throws IOException { 2065 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2066 } 2067 2068 2069 public void saveHistory(FileSaveSelector selector, String editedVersion) throws IOException { 2070 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2071 } 2072 2073 2074 public String getHistoryAsStringWithSemicolons() { 2075 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2076 } 2077 2078 2079 public String getHistoryAsString() { 2080 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2081 } 2082 2083 2084 private void _registerOptionListeners() { 2085 2088 DrJava.getConfig().addOptionListener(BACKUP_FILES, new BackUpFileOptionListener()); 2089 Boolean makeBackups = DrJava.getConfig().getSetting(BACKUP_FILES); 2090 FileOps.DefaultFileSaver.setBackupsEnabled(makeBackups.booleanValue ()); 2091 2092 } 2098 2099 2107 protected void _docAppend(ConsoleDocument doc, String s, String style) { 2108 synchronized(_systemWriterLock) { 2109 try { 2110 doc.insertBeforeLastPrompt (s, style); 2111 2112 _systemWriterLock.wait(WRITE_DELAY); 2114 } 2115 catch (InterruptedException e) { 2116 } 2118 } 2119 } 2120 2121 2122 2123 public void systemOutPrint(String s) {_docAppend(_consoleDoc, s, ConsoleDocument.SYSTEM_OUT_STYLE); } 2124 2125 2126 public void systemErrPrint(String s) { _docAppend(_consoleDoc, s, ConsoleDocument.SYSTEM_ERR_STYLE); } 2127 2128 2129 public void systemInEcho(String s) { _docAppend(_consoleDoc, s, ConsoleDocument.SYSTEM_IN_STYLE); } 2130 2131 2132 public void printDebugMessage(String s) { 2133 throw new UnsupportedOperationException ("AbstractGlobalModel does not support debugging"); 2134 } 2135 2136 2137 2138 public void waitForInterpreter() { 2139 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2140 } 2141 2142 2143 2144 public ClassPathVector getInteractionsClassPath() { 2145 throw new UnsupportedOperationException ("AbstractGlobalModel does not support interactions"); 2146 } 2147 2148 2151 public ClassPathVector getExtraClassPath() { return _state.getExtraClassPath(); } 2152 2153 2156 public void setExtraClassPath(ClassPathVector cp) { 2157 _state.setExtraClassPath(cp); 2158 setClassPathChanged(true); 2159 } 2161 2162 2169 public File [] getSourceRootSet() { 2170 HashSet <File > roots = new HashSet <File >(); 2171 2172 for (OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 2173 try { 2174 if (! doc.isUntitled()) { 2175 File root = doc.getSourceRoot (); 2176 if (root != null) roots.add(root); } 2178 } 2179 catch (InvalidPackageException e) { 2180 2182 } 2183 } 2184 return roots.toArray(new File [roots.size()]); 2185 } 2186 2187 2194 2195 public Debugger getDebugger() { 2196 return NoDebuggerAvailable.ONLY; 2198 } 2199 2200 2201 public int getDebugPort() throws IOException { 2202 throw new UnsupportedOperationException ("AbstractGlobalModel does not support debugging"); 2203 } 2204 2205 2208 public boolean hasModifiedDocuments() { 2209 for (OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 2210 if (doc.isModifiedSinceSave()) return true; 2211 } 2212 return false; 2213 } 2214 2215 2218 public boolean hasUntitledDocuments() { 2219 for (OpenDefinitionsDocument doc: getOpenDefinitionsDocuments()) { 2220 if (doc.isUntitled()) return true; 2221 } 2222 return false; 2223 } 2224 2225 2229 public File getSourceFile(String fileName) { 2230 File [] sourceRoots = getSourceRootSet(); 2231 for (File s: sourceRoots) { 2232 File f = _getSourceFileFromPath(fileName, s); 2233 if (f != null) return f; 2234 } 2235 Vector <File > sourcepath = DrJava.getConfig().getSetting(OptionConstants.DEBUG_SOURCEPATH); 2236 return findFileInPaths(fileName, sourcepath); 2237 } 2238 2239 2244 public File findFileInPaths(String fileName, List <File > paths) { 2245 for (File p: paths) { 2246 File f = _getSourceFileFromPath(fileName, p); 2247 if (f != null) return f; 2248 } 2249 return null; 2250 } 2251 2252 2257 private File _getSourceFileFromPath(String fileName, File path) { 2258 String root = path.getAbsolutePath(); 2259 File f = new File (root + System.getProperty("file.separator") + fileName); 2260 return f.exists() ? f : null; 2261 } 2262 2263 private static volatile int ID_COUNTER = 0; 2264 2265 2267 static class ConcreteRegionManager<R extends DocumentRegion> extends EventNotifier<RegionManagerListener<R>> 2268 implements RegionManager<R> { 2269 2270 protected volatile Vector <R> _regions = new Vector <R>(); 2271 protected volatile R _current = null; 2272 protected volatile int _maxSize; 2273 2274 2277 public ConcreteRegionManager(int size) { _maxSize = size; } 2278 2279 2280 public ConcreteRegionManager() { this(0); } 2281 2282 2287 public R getRegionAt(OpenDefinitionsDocument odd, int offset) { 2288 for (R r: _regions) { 2289 if (r.getDocument().equals(odd) && offset >= r.getStartOffset() && offset <= r.getEndOffset()) return r; 2290 } 2291 return null; 2292 } 2293 2294 2301 public R getRegionOverlapping(OpenDefinitionsDocument odd, int startOffset, int endOffset) { 2302 for (R r: _regions) { 2303 if (! (r.getDocument().equals(odd))) { continue; } 2304 2305 if ((r.getStartOffset() >= startOffset && r.getEndOffset() <= endOffset) || (r.getStartOffset() <= startOffset && r.getEndOffset() >= endOffset) || (r.getStartOffset() >= startOffset && r.getStartOffset() <= endOffset) || (r.getEndOffset() >= startOffset && r.getEndOffset() <= endOffset)) { return r; 2311 } 2312 } 2313 return null; 2315 } 2316 2317 2318 protected int getIndexOf(R region) { 2319 int index = 0; 2320 for (R r: _regions) { 2321 if (region == r) return index; 2322 else ++index; 2323 } 2324 return -1; 2325 } 2326 2327 2331 public void addRegion(final R region) { 2332 int index = getIndexOf(_current); 2333 if (! region.equals(_current) && 2335 (index == _regions.size() - 1 || ! region.equals(_regions.get(index + 1))) && 2336 (index <= 0 || ! region.equals(_regions.get(index - 1)))) { 2337 if ((_current != null) && (index >= 0)) _regions.add(index + 1, region); 2338 else _regions.add(region); 2339 2340 _current = region; 2341 final int regionIndex = getIndexOf(region); 2342 final String stackTrace = StringOps.getStackTrace(); 2343 2344 Utilities.invokeLater(new Runnable () { public void run() { 2346 _lock.startRead(); 2347 try { 2348 for (RegionManagerListener<R> l: _listeners) { l.regionAdded(region, regionIndex); } 2349 } finally { _lock.endRead(); } 2350 } }); 2351 2352 shrinkManager(); 2354 } 2355 else { 2356 if ((index < _regions.size()-1) && (region.equals(_regions.get(index+1)))) nextCurrentRegion(); 2358 else if ((index > 0) && (region.equals(_regions.get(index-1)))) prevCurrentRegion(); 2360 } 2361 } 2362 2363 2364 protected void removeMoreRecentThanCurrent() { 2365 if (_current != null) { 2366 int index = getIndexOf(_current); 2367 if (index < 0) return; 2368 while (index < _regions.size() - 1) { removeRegion(_regions.lastElement()); } } 2370 } 2371 2372 2373 protected void shrinkManager() { 2374 if (_maxSize > 0) { 2375 int size; 2376 while ((size = _regions.size()) > _maxSize) { 2377 int index = getIndexOf(_current); 2378 if (index <= (size - 1)/2) { 2379 _regions.remove(size - 1); 2381 } 2382 else { 2383 _regions.remove(0); 2385 } 2386 } 2387 } 2388 } 2389 2390 2393 public void removeRegion(final R region) { 2394 final R cur = _current; if (region == cur) { 2399 if (nextCurrentRegion().equals(cur)) { 2400 if (prevCurrentRegion().equals(cur)) { 2401 _current = null; 2402 } 2403 } 2404 } 2405 for(int i = 0; i < _regions.size(); ++i) { 2406 if (region == _regions.get(i)) { 2407 _regions.remove(i); 2408 break; 2409 } 2410 } 2411 2412 Utilities.invokeLater(new Runnable () { public void run() { 2414 _lock.startRead(); 2415 try { 2416 for (RegionManagerListener<R> l: _listeners) { l.regionRemoved (region); } 2417 } finally { _lock.endRead(); } 2418 } }); 2419 } 2420 2421 2422 public Vector <R> getRegions() { return _regions; } 2423 2424 2425 public void clearRegions() { 2426 _current = null; 2427 while (_regions.size() > 0) { removeRegion(_regions.get(0)); } 2428 } 2429 2430 2431 public R getCurrentRegion() { 2432 if (! _regions.contains(_current)) _current = null; 2433 return _current; 2434 } 2435 2436 2437 public int getCurrentRegionIndex() { 2438 if (_current != null) return getIndexOf(_current); 2439 return -1; 2440 } 2441 2442 2443 public boolean isCurrentRegionFirst() { 2444 return getIndexOf(_current) == 0; 2445 } 2446 2447 2448 public boolean isCurrentRegionLast() { return (getIndexOf(_current) == _regions.size() - 1); } 2449 2450 2452 public void setCurrentRegion(R region) { 2453 _current = region; 2455 } 2456 2457 2459 public R nextCurrentRegion() { 2460 if (_current != null) { 2461 int index = getIndexOf(_current); 2462 if (index + 1 < _regions.size()) _current = _regions.get(index+1); 2463 } 2464 else _current = _regions.lastElement(); 2465 return _current; 2466 } 2467 2468 2470 public R prevCurrentRegion() { 2471 if (_current!=null) { 2472 int index = getIndexOf(_current); 2473 if (index-1 >= 0) { 2474 _current = _regions.get(index-1); 2475 } 2476 } 2477 else { 2478 _current = _regions.lastElement(); 2479 } 2480 return _current; 2481 } 2482 2483 2487 public void setMaximumSize(int size) { 2488 _maxSize = size; 2489 2490 shrinkManager(); 2492 } 2493 2494 2495 public int getMaximumSize() { 2496 return _maxSize; 2497 } 2498 2499 2502 public void changeRegion(R region, Lambda<Object ,R> cmd) { 2503 final int index = getIndexOf(region); 2504 if (index<0) { return; } 2505 final R r = _regions.get(index); 2506 cmd.apply(r); 2507 Utilities.invokeLater(new Runnable () { public void run() { 2508 _lock.startRead(); 2510 try { 2511 for (RegionManagerListener<R> l: _listeners) { l.regionChanged(r, index); } 2512 } finally { _lock.endRead(); } 2513 } }); 2514 } 2515 2516 2517 public void removeAllListeners() { 2518 throw new UnsupportedOperationException ("ConcreteRegionManager does not support removing all listeners"); 2519 } 2522 } 2523 2524 2525 public void addToBrowserHistory() { 2526 if (! EventQueue.isDispatchThread()) return; 2527 final OpenDefinitionsDocument doc = getActiveDocument(); 2528 2529 int startPos = 0; int endPos = 0; File file = null; 2533 if (doc != null) { 2534 try { 2535 startPos = doc.createPosition(doc.getCaretPosition()).getOffset(); 2536 endPos = doc.createPosition(doc.getLineEndPos(doc.getCaretPosition())).getOffset(); 2537 file = doc.getFile(); 2538 } 2539 catch (FileMovedException fme) { } 2540 catch (BadLocationException ble) { throw new UnexpectedException(ble); } 2541 2542 getBrowserHistoryManager().addRegion(new SimpleDocumentRegion(doc, file, startPos, endPos)); 2543 } 2544 } 2545 2546 2547 public ClassPathVector getClassPath() { 2548 throw new UnsupportedOperationException ("AbstractGlobalModel does not support class paths"); 2549 } 2550 2551 public static boolean isUntitled(final File f) { return f == null || (f instanceof NullFile); } 2552 2553 2555 2560 class ConcreteOpenDefDoc implements OpenDefinitionsDocument { 2561 protected class SubsetRegionManager<R extends DocumentRegion> extends EventNotifier<RegionManagerListener<R>> 2562 implements RegionManager<R> { 2563 2564 2565 private volatile RegionManager<R> _superSetManager; 2566 2567 2568 public SubsetRegionManager(RegionManager<R> ssm) { _superSetManager = ssm; } 2569 2570 2571 public RegionManager<R> getSuperSetManager() { return _superSetManager; } 2572 2573 2578 public R getRegionAt(OpenDefinitionsDocument odd, int offset) { 2579 return _superSetManager.getRegionAt(odd, offset); 2580 } 2581 2582 2589 public R getRegionOverlapping(OpenDefinitionsDocument odd, int startOffset, int endOffset) { 2590 return _superSetManager.getRegionOverlapping(odd, startOffset, endOffset); 2591 } 2592 2593 2596 public void addRegion(R region) { _superSetManager.addRegion(region); } 2597 2598 2601 public void removeRegion(R region) { _superSetManager.removeRegion(region); } 2602 2603 2604 public Vector <R> getRegions() { 2605 Vector <R> accum = new Vector <R>(); 2606 Vector <R> regions = _superSetManager.getRegions(); 2607 for (R r: regions) { 2608 if (r.getDocument().equals(ConcreteOpenDefDoc.this)) { accum.add(r); } 2609 } 2610 return accum; 2611 } 2612 2613 2614 public void clearRegions() { 2615 Vector <R> regions = getRegions(); 2616 for (R r: regions) { 2617 _superSetManager.removeRegion(r); 2618 } 2619 } 2620 2621 2624 public void changeRegion(R region, Lambda<Object ,R> cmd) { 2625 _superSetManager.changeRegion(region, cmd); 2626 } 2627 2628 2629 private class FilteredRegionManagerListener<R extends DocumentRegion> implements RegionManagerListener<R> { 2630 private RegionManagerListener<R> _decoree; 2631 public FilteredRegionManagerListener(RegionManagerListener<R> d) { _decoree = d; } 2632 public RegionManagerListener<R> getDecoree() { return _decoree; } 2633 public void regionAdded(R r, int index) { if (r.getDocument().equals(ConcreteOpenDefDoc.this)) { _decoree.regionAdded(r, index); } } 2634 public void regionChanged(R r, int index) { if (r.getDocument().equals(ConcreteOpenDefDoc.this)) { _decoree.regionChanged(r, index); } } 2635 public void regionRemoved(R r) { if (r.getDocument().equals(ConcreteOpenDefDoc.this)) { _decoree.regionRemoved(r); } } 2636 } 2637 2638 2641 protected final LinkedList <FilteredRegionManagerListener<R>> _filters = new LinkedList <FilteredRegionManagerListener<R>>(); 2642 2643 2647 protected final ReaderWriterLock _lock = new ReaderWriterLock(); 2648 2649 2652 public void addListener(RegionManagerListener<R> listener) { 2653 FilteredRegionManagerListener<R> filter = new FilteredRegionManagerListener<R>(listener); 2654 _lock.startWrite(); 2655 try { _filters.add(filter); } 2656 finally { 2657 _lock.endWrite(); 2658 _superSetManager.addListener(filter); 2659 } 2660 } 2661 2662 2665 public void removeListener(RegionManagerListener<R> listener) { 2666 _lock.startWrite(); 2667 try { 2668 for (FilteredRegionManagerListener<R> filter: _filters) { 2669 if (filter.getDecoree().equals(listener)) { 2670 _listeners.remove(filter); 2671 _superSetManager.removeListener(filter); 2672 } 2673 } 2674 } 2675 finally { _lock.endWrite(); } 2676 } 2677 2678 2679 public void removeAllListeners() { 2680 _lock.startWrite(); 2681 try { 2682 for (FilteredRegionManagerListener<R> filter: _filters) { 2683 _listeners.remove(filter); 2684 _superSetManager.removeListener(filter); 2685 } 2686 } 2687 finally { _lock.endWrite(); } 2688 } 2689 2690 2691 public R getCurrentRegion() { 2692 throw new UnsupportedOperationException ("SubsetRegionManager.getCurrentRegion not supported"); 2694 } 2695 2696 2697 public int getCurrentRegionIndex() { 2698 throw new UnsupportedOperationException ("SubsetRegionManager.getCurrentRegionIndex not supported"); 2700 } 2701 2702 2704 public void setCurrentRegion(R region) { 2705 throw new UnsupportedOperationException ("SubsetRegionManager.setCurrentRegion not supported"); 2707 } 2708 2709 2711 public R nextCurrentRegion() { 2712 throw new UnsupportedOperationException ("SubsetRegionManager.nextCurrentRegion not supported"); 2714 } 2715 2716 2718 public R prevCurrentRegion() { 2719 throw new UnsupportedOperationException ("SubsetRegionManager.prevCurrentRegion not supported"); 2721 } 2722 2723 2724 public boolean isCurrentRegionFirst() { 2725 throw new UnsupportedOperationException ("SubsetRegionManager.isCurrentRegionFirst not supported"); 2727 } 2728 2729 2730 public boolean isCurrentRegionLast() { 2731 throw new UnsupportedOperationException ("SubsetRegionManager.isCurrentRegionLast not supported"); 2733 } 2734 2735 2741 public void setMaximumSize(int size) { 2742 throw new UnsupportedOperationException ("SubsetRegionManager.setMaximumSize not supported"); 2743 } 2744 2745 2746 public int getMaximumSize() { 2747 throw new UnsupportedOperationException ("SubsetRegionManager.getMaximumSize not supported"); 2748 } 2749 } 2750 2751 2753 2754 private byte[] _image; 2755 private volatile File _file; 2756 private volatile long _timestamp; 2757 2758 2759 private volatile int _caretPosition; 2760 2761 2762 private volatile File _parentDir; 2763 2764 2768 protected volatile String _packageName = ""; 2769 2770 private volatile DCacheAdapter _cacheAdapter; 2771 2772 2773 protected final SubsetRegionManager<Breakpoint> _breakpointManager; 2774 2775 2776 protected final SubsetRegionManager<DocumentRegion> _bookmarkManager; 2777 2778 2779 protected final LinkedList <SubsetRegionManager<MovingDocumentRegion>> _findResultsManagers; 2780 2781 2782 protected final SubsetRegionManager<DocumentRegion> _browserHistoryManager; 2783 2784 private volatile int _initVScroll; 2785 private volatile int _initHScroll; 2786 private volatile int _initSelStart; 2787 private volatile int _initSelEnd; 2788 2789 private volatile int _id; 2790 private volatile DrJavaBook _book; 2791 2792 2795 ConcreteOpenDefDoc(File f) { this(f, f.getParentFile(), f.lastModified()); } 2796 2797 2798 ConcreteOpenDefDoc() { this(null, null, 0L); } 2799 2800 2801 private ConcreteOpenDefDoc(File f, File dir, long stamp) { 2802 2803 _file = f; 2804 _parentDir = dir; 2805 _timestamp = stamp; 2806 _image = null; 2807 _id = ID_COUNTER++; 2808 2809 try { 2810 DDReconstructor ddr = makeReconstructor(); 2812 _cacheAdapter = _cache.register(this, ddr); 2814 } catch(IllegalStateException e) { throw new UnexpectedException(e); } 2815 2816 _breakpointManager = new SubsetRegionManager<Breakpoint>(AbstractGlobalModel.this.getBreakpointManager()); 2817 _bookmarkManager = new SubsetRegionManager<DocumentRegion>(AbstractGlobalModel.this.getBookmarkManager()); 2818 _findResultsManagers = new LinkedList <SubsetRegionManager<MovingDocumentRegion>>(); 2819 for (RegionManager<MovingDocumentRegion> rm: AbstractGlobalModel.this.getFindResultsManagers ()) { 2820 addFindResultsManager(rm); 2821 } 2822 _browserHistoryManager = new SubsetRegionManager<DocumentRegion>(AbstractGlobalModel.this.getBrowserHistoryManager()); 2823 } 2824 2825 2827 2828 public File getRawFile() { return _file; } 2829 2830 2835 public File getFile() throws FileMovedException { 2836 File f = _file; if (AbstractGlobalModel.isUntitled(f)) return null; if (f.exists()) return f; 2839 else throw new FileMovedException(f, "This document's file has been moved or deleted."); 2840 } 2841 2842 public void setFile(final File file) { 2843 synchronized(this) { _file = file; 2845 if (! AbstractGlobalModel.isUntitled(file)) _timestamp = file.lastModified(); 2846 else _timestamp = 0L; 2847 } 2848 } 2849 2850 2851 public long getTimestamp() { return _timestamp; } 2852 2853 2854 public void resetModification() { 2855 synchronized(this) { 2856 getDocument().resetModification(); 2857 File f = _file; 2858 if (! AbstractGlobalModel.isUntitled(f)) _timestamp = f.lastModified(); 2859 } 2860 } 2861 2862 2863 public File getParentDirectory() { return _parentDir; } 2864 2865 2868 public void setParentDirectory(File pd) { 2869 synchronized(this) { 2870 if (! AbstractGlobalModel.isUntitled(_file)) 2871 throw new IllegalArgumentException ("The parent directory can only be set for untitled documents"); 2872 _parentDir = pd; 2873 } 2874 } 2875 2876 public int getInitialVerticalScroll() { return _initVScroll; } 2877 public int getInitialHorizontalScroll() { return _initHScroll; } 2878 public int getInitialSelectionStart() { return _initSelStart; } 2879 public int getInitialSelectionEnd() { return _initSelEnd; } 2880 2881 void setInitialVScroll(int i) { _initVScroll = i; } 2882 void setInitialHScroll(int i) { _initHScroll = i; } 2883 void setInitialSelStart(int i) { _initSelStart = i; } 2884 void setInitialSelEnd(int i) { _initSelEnd = i; } 2885 2886 2889 protected DefinitionsDocument getDocument() { 2890 2891 try { return _cacheAdapter.getDocument(); } 2893 catch(IOException ioe) { try { 2896 _notifier.documentNotFound(this, _file); 2897 final String path = fixPathForNavigator(getFile().getCanonicalFile().getCanonicalPath()); 2898 Utilities.invokeLater(new SRunnable() { public void run() { _documentNavigator.refreshDocument(ConcreteOpenDefDoc.this, path); } 2900 }); 2901 return _cacheAdapter.getDocument(); 2902 } 2903 catch(Throwable t) { throw new UnexpectedException(t); } 2904 } 2905 } 2906 2907 2910 2913 public String getFirstTopLevelClassName() throws ClassNameNotFoundException { 2914 return getDocument().getFirstTopLevelClassName(); 2915 } 2916 2917 2920 public String getMainClassName() throws ClassNameNotFoundException { 2921 return getDocument().getMainClassName(); 2922 } 2923 2924 2925 public String getFileName() { 2926 if (isUntitled()) return "(Untitled)"; 2927 return _file.getName(); 2928 } 2929 2930 2931 public String getName() { 2932 String fileName = getFileName(); 2933 if (isModifiedSinceSave()) fileName = fileName + "*"; 2934 else fileName = fileName + " "; return fileName; 2936 } 2937 2938 2939 public String getCanonicalPath() { 2940 if (isUntitled()) { return "(Untitled)"; } 2941 else { return IOUtil.attemptCanonicalFile(getRawFile()).getPath(); } 2942 } 2943 2944 2945 public String getCompletePath() { 2946 String path = getCanonicalPath(); 2947 if (isModifiedSinceSave()) path = path + " *"; 2949 return path; 2950 } 2951 2952 2957 public File getSourceRoot() throws InvalidPackageException { return _getSourceRoot(_packageName); } 2958 2959 2960 public String getPackageName() { return _packageName; } 2961 2962 2963 public void setPackage(String name) { _packageName = name; } 2964 2965 2966 public String getPackageNameFromDocument() { return getDocument().getPackageName(); } 2967 2968 2969 2972 public void updateModifiedSinceSave() { getDocument().updateModifiedSinceSave(); } 2973 2974 2975 public int id() { return _id; } 2976 2977 2980 public Pageable getPageable() throws IllegalStateException { return _book; } 2981 2982 2983 public void cleanUpPrintJob() { _book = null; } 2984 2985 2987 2991 public boolean inProjectPath() { return _state.inProjectPath(this); } 2992 2993 2994 public boolean inNewProjectPath(File projRoot) { 2995 try { return ! isUntitled() && IOUtil.isMember(getFile(), projRoot); } 2996 catch(FileMovedException e) { return false; } 2997 } 2998 2999 3000 public boolean inProject() { return ! isUntitled() && _state.inProject(_file); } 3001 3002 3003 public boolean isAuxiliaryFile() { return ! isUntitled() && _state.isAuxiliaryFile(_file); } 3004 3005 3006 public boolean isSourceFile() { 3007 if (isUntitled()) return false; String name = _file.getName(); 3009 for (String ext: CompilerModel.EXTENSIONS) { if (name.endsWith(ext)) return true; } 3010 return false; 3011 } 3012 3013 3016 public boolean isUntitled() { return AbstractGlobalModel.isUntitled(_file); } 3017 3018 public boolean isUntitledAndEmpty() { return isUntitled() && getLength() == 0; } 3020 3021 public boolean fileExists() { 3022 File f = _file; return ! AbstractGlobalModel.isUntitled(f) && f.exists(); 3024 } 3025 3026 3028 3029 public boolean verifyExists() { 3030 if (fileExists()) return true; 3032 try { 3034 _notifier.documentNotFound(this, _file); 3035 File f = getFile(); 3036 if (isUntitled()) return false; 3037 String path = fixPathForNavigator(getFile().getCanonicalPath()); 3038 _documentNavigator.refreshDocument(this, path); 3039 return true; 3040 } 3041 catch(Throwable t) { return false; } 3042 } 3044 3045 3046 protected DDReconstructor makeReconstructor() { 3047 return new DDReconstructor() { 3048 3049 private volatile int _loc = 0; 3051 3052 private volatile DocumentListener [] _list = { }; 3054 private volatile List <FinalizationListener<DefinitionsDocument>> _finalListeners = 3055 new LinkedList <FinalizationListener<DefinitionsDocument>>(); 3056 3057 private volatile WeakHashMap < DefinitionsDocument.WrappedPosition, Integer > _positions = 3059 new WeakHashMap <DefinitionsDocument.WrappedPosition, Integer >(); 3060 3061 public DefinitionsDocument make() throws IOException , BadLocationException , FileMovedException { 3062 3063 DefinitionsDocument newDefDoc = new DefinitionsDocument(_notifier); 3065 newDefDoc.setOpenDefDoc(ConcreteOpenDefDoc.this); 3066 3067 if (_image != null) { 3068 _editorKit.read(new InputStreamReader (new ByteArrayInputStream (_image)), newDefDoc, 0); 3069 _log.log("Reading from image for " + _file + " containing " + _image.length + " chars"); 3070 } 3071 else if (! isUntitled()) { 3072 final InputStreamReader reader = new FileReader (_file); 3073 _editorKit.read(reader, newDefDoc, 0); 3074 reader.close(); } 3076 _loc = Math.min(_loc, newDefDoc.getLength()); _loc = Math.max(_loc, 0); newDefDoc.setCurrentLocation(_loc); 3079 for (DocumentListener d : _list) { 3080 if (d instanceof DocumentUIListener) newDefDoc.addDocumentListener(d); 3081 } 3082 for (FinalizationListener<DefinitionsDocument> l: _finalListeners) { 3083 newDefDoc.addFinalizationListener(l); 3084 } 3085 3086 newDefDoc.setWrappedPositionOffsets(_positions); 3088 3089 newDefDoc.resetModification(); 3091 assert ! newDefDoc.isModifiedSinceSave(); 3093 _packageName = newDefDoc.getPackageName(); 3096 return newDefDoc; 3098 } 3099 3100 3101 3145 3156 3159 public void saveDocInfo(DefinitionsDocument doc) { 3160 String text = doc.getText(); 3165 if (text.length() > 0) { 3166 _image = text.getBytes(); 3167 _log.log("Saving image containing " + _image.length + " chars for " + _file); 3168 } 3169 _loc = doc.getCurrentLocation(); 3170 _list = doc.getDocumentListeners(); 3171 _finalListeners = doc.getFinalizationListeners (); 3172 3173 _positions.clear(); 3175 _positions = doc.getWrappedPositionOffsets(); 3176 } 3177 3178 public void addDocumentListener(DocumentListener dl) { 3179 ArrayList <DocumentListener > tmp = new ArrayList <DocumentListener >(); 3180 for (DocumentListener l: _list) { if (dl != l) tmp.add(l); } 3181 tmp.add(dl); 3182 _list = tmp.toArray (new DocumentListener [tmp.size()]); 3183 } 3184 public String toString() { return ConcreteOpenDefDoc.this.toString(); } 3185 }; 3186 } 3187 3188 3194 public boolean saveFile(FileSaveSelector com) throws IOException { 3195 if (! isModifiedSinceSave()) return true; 3198 if (isUntitled()) return saveFileAs(com); 3199 3200 3202 3204 _packageName = getDocument().getPackageName(); 3206 FileSaveSelector realCommand = com; 3207 try { 3208 final File file = getFile(); 3209 if (! isUntitled()) { 3211 realCommand = new TrivialFSS(file); 3212 } 3214 } 3215 catch (FileMovedException fme) { 3216 if ( com.shouldSaveAfterFileMoved(this, fme.getFile())) realCommand = com; 3218 else return false; 3219 } 3221 return saveFileAs(realCommand); 3223 } 3224 3225 3234 public boolean saveFileAs(FileSaveSelector com) throws IOException { 3235 _packageName = getDocument().getPackageName(); 3237 try { 3238 final OpenDefinitionsDocument openDoc = this; 3239 final File file = com.getFile().getCanonicalFile(); 3240 _log.log("saveFileAs called on " + file); 3241 OpenDefinitionsDocument otherDoc = _getOpenDocument(file); 3242 3243 boolean openInOtherDoc = ((otherDoc != null) && (openDoc != otherDoc)); 3245 3246 if (openInOtherDoc) { 3248 boolean shouldOverwrite = com.warnFileOpen(file); 3249 if (! shouldOverwrite) return true; } 3251 3252 if (! file.exists() || com.verifyOverwrite()) { 3254 3256 if (! file.getCanonicalFile().getName().equals(file.getName())) file.renameTo(file); 3258 3259 if (file.getAbsolutePath().indexOf("#") != -1) _notifier.filePathContainsPound(); 3262 3263 FileOps.saveFile(new FileOps.DefaultFileSaver(file) { 3266 3267 public void saveTo(OutputStream os) throws IOException { 3268 DefinitionsDocument dd = getDocument(); 3269 try { 3270 _editorKit.write(os, dd, 0, dd.getLength()); 3271 } 3273 catch (BadLocationException docFailed) { throw new UnexpectedException(docFailed); } 3274 } 3275 }); 3276 resetModification(); 3277 synchronized(_documentsRepos) { 3278 File f = getRawFile(); 3279 _documentsRepos.remove(f); 3283 _documentsRepos.put(file, this); 3284 } 3285 setFile(file); 3286 3287 3288 getDocument().setCachedClassFile(null); 3296 checkIfClassFileInSync(); 3297 3298 _notifier.fileSaved(openDoc); 3300 3301 addDocToClassPath(this); 3303 3304 3305 _documentNavigator.refreshDocument(this, fixPathForNavigator(file.getCanonicalPath())); 3306 3307 3308 setProjectChanged(true); 3309 } 3310 return true; 3311 } 3312 catch (OperationCanceledException oce) { 3313 return false; 3316 } 3317 } 3318 3319 3320 3321 public void preparePrintJob() throws BadLocationException , FileMovedException { 3322 String fileName = "(Untitled)"; 3323 File sourceFile = getFile(); if (! AbstractGlobalModel.isUntitled(sourceFile)) fileName = sourceFile.getAbsolutePath(); 3325 3326 _book = new DrJavaBook(getDocument().getText(), fileName, _pageFormat); 3327 } 3328 3329 3330 public void print() throws PrinterException , BadLocationException , FileMovedException { 3331 preparePrintJob(); 3332 PrinterJob printJob = PrinterJob.getPrinterJob(); 3333 printJob.setPageable(_book); 3334 if (printJob.printDialog()) printJob.print(); 3335 cleanUpPrintJob(); 3336 } 3337 3338 3339 3340 public void startCompile() throws IOException { 3341 throw new UnsupportedOperationException ("AbstractGlobalModel does not support compilation"); 3342 } 3343 3344 3345 public void runMain() throws IOException , ClassNameNotFoundException { 3346 throw new UnsupportedOperationException ("AbstractGlobalModel does not support running"); 3347 } 3348 3349 3350 public void startJUnit() throws IOException , ClassNotFoundException { 3351 throw new UnsupportedOperationException ("AbstractGlobalModel does not support unit testing"); 3352 } 3353 3354 3355 public void generateJavadoc(FileSaveSelector saver) throws IOException { 3356 throw new UnsupportedOperationException ("AbstractGlobalModel does not support javadoc"); 3357 } 3358 3359 3362 public boolean isModifiedSinceSave() { 3363 3366 if (_cacheAdapter != null && _cacheAdapter.isReady()) return getDocument().isModifiedSinceSave(); 3367 else return false; 3368 } 3369 3370 public void documentSaved() { _cacheAdapter.documentSaved(getFileName()); } 3371 3372 public void documentModified() { _cacheAdapter.documentModified(); } 3373 3374 public void documentReset() { _cacheAdapter.documentReset(); } 3375 3376 3379 public boolean modifiedOnDisk() { 3380 boolean ret = false; 3381 final File f = _file; if (! AbstractGlobalModel.isUntitled(f)) ret = (f.lastModified() > _timestamp); 3383 return ret; 3384 } 3385 3386 3390 public boolean checkIfClassFileInSync() { 3391 _log.log("checkIfClassFileInSync() called for " + this); 3392 if (isUntitled()) return true; 3394 DefinitionsDocument dd = getDocument(); 3396 if (isModifiedSinceSave()) { 3397 dd.setClassFileInSync(false); 3398 return false; 3400 } 3401 3402 File classFile = dd.getCachedClassFile(); 3404 if (classFile == null) { 3406 classFile = _locateClassFile(); 3408 dd.setCachedClassFile(classFile); 3410 if ((classFile == null) || (! classFile.exists())) { 3411 dd.setClassFileInSync(false); 3414 return false; 3415 } 3416 } 3417 3418 3420 File sourceFile; 3421 try { sourceFile = getFile(); } 3422 catch (FileMovedException fme) { 3423 dd.setClassFileInSync(false); 3424 return false; 3426 } 3427 if (sourceFile != null) { 3428 _log.log(sourceFile + " has timestamp " + sourceFile.lastModified()); 3429 _log.log(classFile + " has timestamp " + classFile.lastModified()); 3430 } 3431 if (sourceFile == null || sourceFile.lastModified() > classFile.lastModified()) { dd.setClassFileInSync(false); 3433 return false; 3435 } 3436 else { 3437 dd.setClassFileInSync (true); 3438 return true; 3439 } 3440 } 3441 3442 3445 private File _locateClassFile() { 3446 if (isUntitled()) return null; 3447 3448 String className; 3449 try { className = getDocument().getQualifiedClassName(); } 3450 catch (ClassNameNotFoundException cnnfe) { 3451 _log.log("_locateClassFile() failed for " + this + " because getQualifedClassName returned ClassNotFound"); 3452 return null; 3453 } 3454 _log.log("In _locateClassFile, className = " + className); 3455 String ps = System.getProperty("file.separator"); 3456 className = StringOps.replace(className, ".", ps); 3458 String fileName = className + ".class"; 3459 3460 _log.log("In _locateClassFile, classfileName = " + fileName); 3461 3462 ArrayList <File > roots = new ArrayList <File >(); 3464 3465 if (getBuildDirectory() != null) roots.add(getBuildDirectory()); 3466 3467 try { 3469 File root = getSourceRoot(); 3470 _log.log("Directory " + root + " added to list of source roots"); 3471 roots.add(root); 3472 } 3473 catch (InvalidPackageException ipe) { 3474 try { 3475 _log.log(this + " has no source root, using parent directory instead"); 3476 File root = getFile().getParentFile(); 3477 if (root != null) { 3478 roots.add(root); 3479 _log.log("Added parent directory " + root + " to list of source roots"); 3480 } 3481 } 3482 catch(NullPointerException e) { throw new UnexpectedException(e); } 3483 catch(FileMovedException fme) { 3484 _log.log("File for " + this + "has moved; adding parent directory to list of roots"); 3486 File root = fme.getFile().getParentFile(); 3487 if (root != null) roots.add(root); 3488 } 3489 } 3490 3491 File classFile = findFileInPaths(fileName, roots); 3492 if (classFile != null) { 3493 _log.log("Found source file " + classFile + " for " + this); 3494 return classFile; 3495 } 3496 3497 _log.log(this + " not found on path of source roots"); 3498 String cp = System.getProperty("java.class.path"); 3500 String pathSeparator = System.getProperty("path.separator"); 3501 Vector <File > cpVector = new Vector <File >(); 3502 int i = 0; 3503 while (i < cp.length()) { 3504 int nextSeparator = cp.indexOf(pathSeparator, i); 3505 if (nextSeparator == -1) { 3506 cpVector.add(new File (cp.substring(i, cp.length()))); 3507 break; 3508 } 3509 cpVector.add(new File (cp.substring(i, nextSeparator))); 3510 i = nextSeparator + 1; 3511 } 3512 classFile = findFileInPaths(fileName, cpVector); 3513 3514 if (classFile != null) return classFile; 3515 3516 return findFileInPaths(fileName, DrJava.getConfig().getSetting(EXTRA_CLASSPATH)); 3518 } 3519 3520 3524 public boolean revertIfModifiedOnDisk() throws IOException { 3525 final OpenDefinitionsDocument doc = this; 3526 if (modifiedOnDisk()) { 3527 boolean shouldRevert = _notifier.shouldRevertFile(doc); 3528 if (shouldRevert) doc.revertFile(); 3529 return shouldRevert; 3530 } 3531 return false; 3532 } 3533 3534 3535 public void close() { 3536 removeFromDebugger(); 3537 _cacheAdapter.close(); 3538 } 3539 3540 3541 public void revertFile() throws IOException { 3542 3543 final OpenDefinitionsDocument doc = this; 3544 3545 removeFromDebugger(); 3547 doc.getBreakpointManager().clearRegions(); 3548 doc.getBookmarkManager().clearRegions(); 3549 for (RegionManager<MovingDocumentRegion> rm: doc.getFindResultsManagers()) rm.clearRegions(); 3550 doc.getBrowserHistoryManager().clearRegions(); 3551 3552 if (doc.isUntitled()) throw new UnexpectedException("Cannot revert an Untitled file!"); 3553 3554 try { 3555 File file = doc.getFile(); 3557 FileReader reader = new FileReader (file); 3558 doc.clear(); 3559 3560 _editorKit.read(reader, doc, 0); 3561 reader.close(); 3563 resetModification(); 3564 doc.checkIfClassFileInSync(); 3565 setCurrentLocation(0); 3566 _notifier.fileReverted(doc); 3567 } 3568 catch (BadLocationException e) { throw new UnexpectedException(e); } 3569 } 3570 3571 3576 public boolean canAbandonFile() { 3577 if (isUntitledAndEmpty()) return true; 3579 File f = _file; 3580 if (isModifiedSinceSave() || (! AbstractGlobalModel.isUntitled(f) && ! f.exists() && _cacheAdapter.isReady())) 3581 return _notifier.canAbandonFile(this); 3582 else return true; 3583 } 3584 3585 3589 public boolean quitFile() { 3590 assert EventQueue.isDispatchThread(); 3591 File f = _file; 3592 if (isModifiedSinceSave() || (f != null && ! f.exists() && _cacheAdapter.isReady())) return _notifier.quitFile(this); 3593 return true; 3594 } 3595 3596 3601 public int gotoLine(int line) { 3602 DefinitionsDocument dd = getDocument(); 3603 dd.gotoLine(line); 3604 return dd.getCurrentLocation(); 3605 } 3606 3607 3608 public void setCurrentLocation(int location) { _caretPosition = location; getDocument().setCurrentLocation(location); } 3609 3610 3611 public int getCurrentLocation() { return getDocument().getCurrentLocation(); } 3612 3613 3614 public int getCaretPosition() { return _caretPosition; } 3615 3616 3619 public int balanceBackward() { return getDocument().balanceBackward(); } 3620 3621 3624 public int balanceForward() { return getDocument().balanceForward(); } 3625 3626 3627 public RegionManager<Breakpoint> getBreakpointManager() { return _breakpointManager; } 3628 3629 3630 public RegionManager<DocumentRegion> getBookmarkManager() { return _bookmarkManager; } 3631 3632 3633 public List <RegionManager<MovingDocumentRegion>> getFindResultsManagers() { 3634 LinkedList <RegionManager<MovingDocumentRegion>> newList = new LinkedList <RegionManager<MovingDocumentRegion>>(); 3635 for (SubsetRegionManager<MovingDocumentRegion> rm: _findResultsManagers) { newList.add (rm); } 3636 return newList; 3637 } 3638 3639 3641 public void addFindResultsManager(RegionManager<MovingDocumentRegion> rm) { 3642 _findResultsManagers.add(new SubsetRegionManager<MovingDocumentRegion>(rm)); 3643 } 3644 3645 3647 public void removeFindResultsManager(RegionManager<MovingDocumentRegion> rm) { 3648 for (SubsetRegionManager<MovingDocumentRegion> ssrm: _findResultsManagers) { 3649 if (ssrm.getSuperSetManager().equals(rm)) { 3650 _findResultsManagers.remove(ssrm); 3651 break; 3652 } 3653 } 3654 } 3655 3656 3657 public RegionManager<DocumentRegion> getBrowserHistoryManager() { return _browserHistoryManager; } 3658 3659 3660 public void removeFromDebugger() { } 3661 3662 3668 File _getSourceRoot(String packageName) throws InvalidPackageException { 3669 3670 if (isUntitled()) 3671 throw new InvalidPackageException(-1, "Can not get source root for unsaved file. Please save."); 3672 3673 File sourceFile; 3674 try { sourceFile = getFile(); } 3675 catch (FileMovedException fme) { 3676 throw new 3677 InvalidPackageException(-1, "File has been moved or deleted from its previous location. Please save."); 3678 } 3679 3680 if (packageName.equals("")) { return sourceFile.getParentFile(); } 3681 3682 ArrayList <String > packageStack = new ArrayList <String >(); 3683 int dotIndex = packageName.indexOf('.'); 3684 int curPartBegins = 0; 3685 3686 while (dotIndex != -1) { 3687 packageStack.add(packageName.substring(curPartBegins, dotIndex)); 3688 curPartBegins = dotIndex + 1; 3689 dotIndex = packageName.indexOf ('.', dotIndex + 1); 3690 } 3691 3692 packageStack.add(packageName.substring(curPartBegins)); 3694 3695 try { 3697 File parentDir = sourceFile.getCanonicalFile(); 3698 File grandParentDir; 3699 while (! packageStack.isEmpty()) { 3700 String part = pop(packageStack); 3701 parentDir = parentDir.getParentFile(); 3702 grandParentDir = parentDir.getParentFile(); 3703 3704 if (parentDir == null) throw new RuntimeException ("parent dir is null!"); 3705 3706 boolean equal; 3708 if (grandParentDir!=null) { 3709 File packageDir = new File (grandParentDir,part); 3712 equal = packageDir.equals(parentDir); 3713 } 3714 else { 3715 equal = part.equals(parentDir.getName()); 3719 } 3720 if (!equal) { 3721 String msg = "The source file " + sourceFile.getAbsolutePath() + 3722 " is in the wrong directory or in the wrong package. " + 3723 "The directory name " + parentDir.getName() + 3724 " does not match the package component " + part + "."; 3725 3726 throw new InvalidPackageException(-1, msg); 3727 } 3728 } 3729 3730 parentDir = parentDir.getParentFile(); 3733 if (parentDir == null) { 3734 throw new RuntimeException ("parent dir of first component is null?!"); 3735 } 3736 3737 return parentDir; 3738 } 3739 catch (IOException ioe) { 3740 String msg = "Could not locate directory of the source file: " + ioe; 3741 throw new InvalidPackageException(-1, msg); 3742 } 3743 } 3744 3745 public String toString() { return getFileName(); } 3746 3747 3748 public int compareTo(OpenDefinitionsDocument o) { return _id - o.id(); } 3749 3750 3751 public void addDocumentListener(DocumentListener listener) { 3752 if (_cacheAdapter.isReady()) getDocument().addDocumentListener(listener); 3753 else _cacheAdapter.getReconstructor().addDocumentListener(listener); 3754 } 3755 3756 List <UndoableEditListener > _undoableEditListeners = new LinkedList <UndoableEditListener >(); 3757 3758 public void addUndoableEditListener(UndoableEditListener listener) { 3759 _undoableEditListeners.add(listener); 3760 getDocument().addUndoableEditListener(listener); 3761 } 3762 3763 public void removeUndoableEditListener(UndoableEditListener listener) { 3764 _undoableEditListeners.remove(listener); 3765 getDocument().removeUndoableEditListener(listener); 3766 } 3767 3768 public UndoableEditListener [] getUndoableEditListeners() { 3769 return getDocument().getUndoableEditListeners(); 3770 } 3771 3772 public Position createUnwrappedPosition(int offs) throws BadLocationException { 3773 return getDocument().createUnwrappedPosition(offs); 3774 } 3775 3776 public Position createPosition(int offs) throws BadLocationException { 3777 return getDocument().createPosition(offs); 3778 } 3779 3780 public Element getDefaultRootElement() { return getDocument().getDefaultRootElement(); } 3781 3782 public Position getEndPosition() { return getDocument().getEndPosition(); } 3783 3784 public int getLength() { 3785 return getDocument().getLength(); 3788 } 3791 3792 public Object getProperty(Object key) { return getDocument().getProperty(key); } 3793 3794 public Element [] getRootElements() { return getDocument().getRootElements(); } 3795 3796 public Position getStartPosition() { return getDocument().getStartPosition(); } 3797 3798 3805 3807 3808 public String getText() { return getDocument().getText(); } 3809 3810 public String getText(int offset, int length) throws BadLocationException { 3811 return getDocument().getText(offset, length); 3812 } 3813 3814 public void getText(int offset, int length, Segment txt) throws BadLocationException { 3815 getDocument().getText(offset, length, txt); 3816 } 3817 3818 public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { 3819 getDocument().insertString(offset, str, a); 3820 } 3821 3822 public void append(String str, AttributeSet set) { getDocument().append(str, set); } 3823 3824 public void append(String str, Style style) { getDocument().append(str, style); } 3825 3826 public void putProperty(Object key, Object value) { getDocument().putProperty(key, value); } 3827 3828 public void remove(int offs, int len) throws BadLocationException { getDocument().remove(offs, len); } 3829 3830 public void removeDocumentListener(DocumentListener listener) { 3831 getDocument().removeDocumentListener(listener); 3832 } 3833 3834 public void render(Runnable r) { getDocument().render(r); } 3835 3836 3837 3838 3841 public boolean undoManagerCanUndo() { return _cacheAdapter.isReady() && getUndoManager().canUndo(); } 3842 3846 public boolean undoManagerCanRedo() { return _cacheAdapter.isReady() && getUndoManager().canRedo(); } 3847 3848 3849 public CompoundUndoManager getUndoManager() { return getDocument().getUndoManager(); } 3850 3851 public int getLineStartPos(int pos) { return getDocument().getLineStartPos(pos); } 3852 3853 public int getLineEndPos(int pos) { return getDocument().getLineEndPos(pos); } 3854 3855 public int commentLines(int selStart, int selEnd) { return getDocument().commentLines(selStart, selEnd); } 3856 3857 public int uncommentLines(int selStart, int selEnd) { 3858 return getDocument().uncommentLines(selStart, selEnd); 3859 } 3860 3861 public void indentLines(int selStart, int selEnd) { getDocument().indentLines(selStart, selEnd); } 3862 3863 public int getCurrentLine() { return getDocument().getCurrentLine(); } 3864 3865 public int getCurrentCol() { return getDocument().getCurrentCol(); } 3866 3867 public boolean getClassFileInSync() { return getDocument().getClassFileInSync(); } 3868 3869 public int getIntelligentBeginLinePos(int currPos) throws BadLocationException { 3870 return getDocument().getIntelligentBeginLinePos(currPos); 3871 } 3872 3873 public int getOffset(int lineNum) { return getDocument().getOffset(lineNum); } 3874 3875 public String getQualifiedClassName() throws ClassNameNotFoundException { 3876 return getDocument().getQualifiedClassName(); 3877 } 3878 3879 public String getQualifiedClassName(int pos) throws ClassNameNotFoundException { 3880 return getDocument().getQualifiedClassName(pos); 3881 } 3882 3883 public ReducedModelState getStateAtCurrent() { return getDocument().getStateAtCurrent(); } 3884 3885 public void resetUndoManager() { 3886 if (_cacheAdapter.isReady()) getDocument().resetUndoManager(); 3888 } 3889 3890 public File getCachedClassFile() { return getDocument().getCachedClassFile(); } 3891 3892 public void setCachedClassFile(File f) { getDocument().setCachedClassFile(f); } 3893 3894 public DocumentListener [] getDocumentListeners() { return getDocument().getDocumentListeners(); } 3895 3896 3898 public void setTab(String tab, int pos) { getDocument().setTab(tab,pos); } 3899 3900 public int getWhiteSpace() { return getDocument().getWhiteSpace(); } 3901 3902 public boolean posInParenPhrase(int pos) { return getDocument().posInParenPhrase(pos); } 3903 3904 public boolean posInParenPhrase() { return getDocument().posInParenPhrase(); } 3905 3906 public String getEnclosingClassName(int pos, boolean fullyQualified) throws BadLocationException , ClassNameNotFoundException { 3907 return getDocument().getEnclosingClassName(pos, fullyQualified); 3908 } 3909 3910 public int findPrevEnclosingBrace(int pos, char opening, char closing) throws BadLocationException { 3911 return getDocument().findPrevEnclosingBrace(pos, opening, closing); 3912 } 3913 3914 public int findNextEnclosingBrace(int pos, char opening, char closing) throws BadLocationException { 3915 return getDocument().findNextEnclosingBrace(pos, opening, closing); 3916 } 3917 3918 public int findPrevNonWSCharPos(int pos) throws BadLocationException { 3919 return getDocument().findPrevNonWSCharPos(pos); 3920 } 3921 3922 public int getFirstNonWSCharPos(int pos) throws BadLocationException { 3923 return getDocument().getFirstNonWSCharPos(pos); 3924 } 3925 3926 public int getFirstNonWSCharPos(int pos, boolean acceptComments) throws BadLocationException { 3927 return getDocument().getFirstNonWSCharPos(pos, acceptComments); 3928 } 3929 3930 public int getFirstNonWSCharPos (int pos, char[] whitespace, boolean acceptComments) 3931 throws BadLocationException { 3932 return getDocument().getFirstNonWSCharPos(pos, whitespace, acceptComments); 3933 } 3934 3935 public int getLineFirstCharPos(int pos) throws BadLocationException { 3936 return getDocument().getLineFirstCharPos(pos); 3937 } 3938 3939 public int findCharOnLine(int pos, char findChar) { 3940 return getDocument().findCharOnLine(pos, findChar); 3941 } 3942 3943 public String getIndentOfCurrStmt(int pos) throws BadLocationException { 3944 return getDocument().getIndentOfCurrStmt(pos); 3945 } 3946 3947 public String getIndentOfCurrStmt(int pos, char[] delims) throws BadLocationException { 3948 return getDocument().getIndentOfCurrStmt(pos, delims); 3949 } 3950 3951 public String getIndentOfCurrStmt(int pos, char[] delims, char[] whitespace) throws BadLocationException { 3952 return getDocument().getIndentOfCurrStmt(pos, delims, whitespace); 3953 } 3954 3955 public void indentLines(int selStart, int selEnd, int reason, ProgressMonitor pm) 3956 throws OperationCanceledException { 3957 getDocument().indentLines(selStart, selEnd, reason, pm); 3958 } 3959 3960 public int findPrevCharPos(int pos, char[] whitespace) throws BadLocationException { 3961 return getDocument().findPrevCharPos(pos, whitespace); 3962 } 3963 3964 public boolean findCharInStmtBeforePos(char findChar, int position) { 3965 return getDocument().findCharInStmtBeforePos(findChar, position); 3966 } 3967 3968 public int findPrevDelimiter(int pos, char[] delims) throws BadLocationException { 3969 return getDocument().findPrevDelimiter(pos, delims); 3970 } 3971 3972 public int findPrevDelimiter(int pos, char[] delims, boolean skipParenPhrases) throws BadLocationException { 3973 return getDocument().findPrevDelimiter(pos, delims, skipParenPhrases); 3974 } 3975 3976 public void resetReducedModelLocation() { getDocument().resetReducedModelLocation(); } 3977 3978 public ReducedModelState stateAtRelLocation(int dist) { return getDocument().stateAtRelLocation(dist); } 3979 3980 public IndentInfo getIndentInformation() { return getDocument().getIndentInformation(); } 3981 3982 public void move(int dist) { getDocument().move(dist); } 3983 3984 public Vector <HighlightStatus> getHighlightStatus(int start, int end) { 3985 return getDocument().getHighlightStatus(start, end); 3986 } 3987 3988 public void setIndent(int indent) { getDocument().setIndent(indent); } 3989 3990 public int getIndent() { return getDocument().getIndent(); } 3991 3992 3994 3995 public void addFinalizationListener(FinalizationListener<DefinitionsDocument> fl) { 3996 getDocument().addFinalizationListener(fl); 3997 } 3998 3999 public List <FinalizationListener<DefinitionsDocument>> getFinalizationListeners() { 4000 return getDocument().getFinalizationListeners(); 4001 } 4002 4003 public Font getFont(AttributeSet attr) { return getDocument().getFont(attr); } 4005 4006 public Color getBackground(AttributeSet attr) { return getDocument().getBackground(attr); } 4007 4008 public Color getForeground(AttributeSet attr) { return getDocument().getForeground(attr); } 4009 4010 public Element getCharacterElement(int pos) { return getDocument().getCharacterElement(pos); } 4011 4012 public Element getParagraphElement(int pos) { return getDocument().getParagraphElement(pos); } 4013 4014 public Style getLogicalStyle(int p) { return getDocument().getLogicalStyle(p); } 4015 4016 public void setLogicalStyle(int pos, Style s) { getDocument().setLogicalStyle(pos, s); } 4017 4018 public void setCharacterAttributes(int offset, int length, AttributeSet s, boolean replace) { 4019 getDocument().setCharacterAttributes(offset, length, s, replace); 4020 } 4021 4022 public void setParagraphAttributes(int offset, int length, AttributeSet s, boolean replace) { 4023 getDocument().setParagraphAttributes(offset, length, s, replace); 4024 } 4025 4026 public Style getStyle(String nm) { return getDocument().getStyle(nm); } 4027 4028 public void removeStyle(String nm) { getDocument().removeStyle(nm); } 4029 4030 public Style addStyle(String nm, Style parent) { return getDocument().addStyle(nm, parent); } 4031 4032 public void clear() { getDocument().clear(); } 4033 4034 4035 4036 4037 public void acquireReadLock() { getDocument().acquireReadLock(); } 4038 4039 4040 public void releaseReadLock() { getDocument().releaseReadLock(); } 4041 4042 4043 public void acquireWriteLock() { getDocument().acquireWriteLock(); } 4044 4045 4046 public void releaseWriteLock() { getDocument().releaseWriteLock(); } 4047 4048 4050 4051 public int getNumberOfLines() { return getLineOfOffset(getEndPosition().getOffset()-1); } 4052 4053 4056 public int getLineOfOffset(int offset) { 4057 return getDefaultRootElement().getElementIndex(offset); 4058 } 4059 } 4060 4061 private static class TrivialFSS implements FileSaveSelector { 4062 private File _file; 4063 private TrivialFSS(File file) { _file = file; } 4064 public File getFile() throws OperationCanceledException { return _file; } 4065 public boolean warnFileOpen(File f) { return true; } 4066 public boolean verifyOverwrite() { return true; } 4067 public boolean shouldSaveAfterFileMoved(OpenDefinitionsDocument doc, File oldFile) { return true; } 4068 } 4069 4070 4073 protected ConcreteOpenDefDoc _createOpenDefinitionsDocument() { return new ConcreteOpenDefDoc(); } 4074 4075 4078 protected ConcreteOpenDefDoc _createOpenDefinitionsDocument(File f) throws IOException { 4079 if (! f.exists()) throw new FileNotFoundException ("file " + f + " cannot be found"); 4080 return new ConcreteOpenDefDoc(f); 4081 } 4082 4083 4087 protected OpenDefinitionsDocument _getOpenDocument(File file) { 4088 synchronized(_documentsRepos) { return _documentsRepos.get(file); } 4089 } 4090 4091 4092 public List <OpenDefinitionsDocument> getNonProjectDocuments() { 4093 List <OpenDefinitionsDocument> allDocs = getOpenDefinitionsDocuments(); 4094 List <OpenDefinitionsDocument> selectedDocs = new LinkedList <OpenDefinitionsDocument>(); 4095 for (OpenDefinitionsDocument d : allDocs) { 4096 if (! d.inProjectPath() && ! d.isAuxiliaryFile ()) selectedDocs.add(d); 4097 } 4098 return selectedDocs; 4099 } 4100 4101 4102 public List <OpenDefinitionsDocument> getAuxiliaryDocuments() { 4103 List <OpenDefinitionsDocument> allDocs = getOpenDefinitionsDocuments(); 4104 List <OpenDefinitionsDocument> selectedDocs = new LinkedList <OpenDefinitionsDocument>(); 4105 for (OpenDefinitionsDocument d : allDocs) 4106 if (d.isAuxiliaryFile()) selectedDocs.add(d); 4107 return selectedDocs; 4108 } 4109 4110 4111 public List <OpenDefinitionsDocument> getProjectDocuments() { 4112 List <OpenDefinitionsDocument> allDocs = getOpenDefinitionsDocuments(); 4113 List <OpenDefinitionsDocument> projectDocs = new LinkedList <OpenDefinitionsDocument>(); 4114 for (OpenDefinitionsDocument d: allDocs) 4115 if (d.inProjectPath() || d.isAuxiliaryFile()) projectDocs.add(d); 4116 return projectDocs; 4117 } 4118 4120 public String fixPathForNavigator(String path) throws IOException { 4121 String parent = path.substring(0, path.lastIndexOf(File.separator )); 4122 String topLevelPath; 4123 String rootPath = getProjectRoot().getCanonicalPath(); 4124 4125 if (! parent.equals(rootPath) && ! parent.startsWith(rootPath + File.separator)) 4126 4127 return ""; 4128 else 4129 return parent.substring(rootPath.length()); 4130 } 4131 4132 4136 private OpenDefinitionsDocument _rawOpenFile(File file) throws IOException , AlreadyOpenException{ 4137 OpenDefinitionsDocument openDoc = _getOpenDocument(file); 4138 if (openDoc != null) throw new AlreadyOpenException(openDoc); final ConcreteOpenDefDoc doc = _createOpenDefinitionsDocument(file); 4140 if (file instanceof DocFile) { 4141 DocFile df = (DocFile)file; 4142 Pair<Integer ,Integer > scroll = df.getScroll(); 4143 Pair<Integer ,Integer > sel = df.getSelection(); 4144 String pkg = df.getPackage(); 4145 doc.setPackage(pkg); doc.setInitialVScroll(scroll.first()); 4147 doc.setInitialHScroll( scroll.second()); 4148 doc.setInitialSelStart(sel.first()); 4149 doc.setInitialSelEnd(sel.second()); 4150 } 4151 else { 4152 doc.setPackage(doc.getPackageNameFromDocument()); } 4155 return doc; 4156 } 4157 4158 4159 protected static <T> T pop(ArrayList <T> stack) { return stack.remove(stack.size() - 1); } 4160 4161 4165 protected void addDocToNavigator(final OpenDefinitionsDocument doc) { 4166 Utilities.invokeLater(new SRunnable() { 4167 public void run() { 4168 try { 4169 if (doc.isUntitled()) _documentNavigator.addDocument(doc); 4170 else { 4171 String path = doc.getFile().getCanonicalPath(); 4172 _documentNavigator.addDocument(doc, fixPathForNavigator(path)); 4173 } 4174 } 4175 catch(IOException e) { _documentNavigator.addDocument(doc); } 4176 }}); 4177 synchronized(_documentsRepos) { _documentsRepos.put(doc.getRawFile(), doc); } 4178 } 4179 4180 4182 protected void addDocToClassPath(OpenDefinitionsDocument doc) { } 4183 4184 4188 public OpenDefinitionsDocument _openFile(File file) throws IOException , AlreadyOpenException { 4189 4190 OpenDefinitionsDocument doc = _rawOpenFile(file); 4191 _completeOpenFile(doc); 4192 return doc; 4193 } 4194 4195 private void _completeOpenFile(OpenDefinitionsDocument d) { 4196 addDocToNavigator(d); 4197 addDocToClassPath(d); 4198 4199 try { 4200 File f = d.getFile(); 4201 if (!inProject(f) && inProjectPath(d)) { 4202 setProjectChanged(true); 4203 } 4204 } catch(FileMovedException fme) { 4205 4206 } 4207 4208 _notifier.fileOpened(d); 4209 } 4210 4211 private static class BackUpFileOptionListener implements OptionListener<Boolean > { 4212 public void optionChanged (OptionEvent<Boolean > oe) { 4213 Boolean value = oe.value; 4214 FileOps.DefaultFileSaver.setBackupsEnabled (value.booleanValue()); 4215 } 4216 } 4217 4218 4220 4221 public OpenDefinitionsDocument getActiveDocument() { return _activeDocument; } 4222 4223 4226 public void setActiveDocument(final OpenDefinitionsDocument doc) { 4227 4233 4234 4237 try { 4238 Utilities.invokeAndWait(new SRunnable() { 4239 public void run() { 4240 _documentNavigator.setNextChangeModelInitiated(true); 4242 addToBrowserHistory(); 4243 _documentNavigator.setActiveDoc(doc); 4244 } 4245 }); 4246 } 4247 catch(Exception e) { throw new UnexpectedException(e); } 4248 } 4249 4250 public Container getDocCollectionWidget() { return _documentNavigator.asContainer(); } 4251 4252 4253 public void setActiveNextDocument() { 4254 OpenDefinitionsDocument key = _activeDocument; 4255 OpenDefinitionsDocument nextKey = _documentNavigator.getNext(key); 4256 if (key != nextKey) setActiveDocument(nextKey); 4257 else setActiveDocument(_documentNavigator.getFirst()); 4258 4259 } 4260 4261 4262 public void setActivePreviousDocument() { 4263 OpenDefinitionsDocument key = _activeDocument; 4264 OpenDefinitionsDocument prevKey = _documentNavigator.getPrevious(key); 4265 if (key != prevKey) setActiveDocument(prevKey); 4266 else setActiveDocument(_documentNavigator.getLast()); 4267 4268 } 4269 4270 4272 4273 private boolean _hasOneEmptyDocument() { 4274 return getOpenDefinitionsDocumentsSize() == 1 && _activeDocument.isUntitled() && 4275 ! _activeDocument.isModifiedSinceSave(); 4276 } 4277 4278 4279 private void _ensureNotEmpty() { 4280 if (getOpenDefinitionsDocumentsSize() == 0) newFile(getMasterWorkingDirectory()); 4281 } 4282 4283 4286 private void _ensureNotActive(List <OpenDefinitionsDocument> docs) { 4287 if (docs.contains(getActiveDocument())) { 4288 IDocumentNavigator<OpenDefinitionsDocument> nav = getDocumentNavigator(); 4290 4291 OpenDefinitionsDocument item = docs.get(docs.size()-1); 4292 OpenDefinitionsDocument nextActive = nav.getNext(item); 4293 if (!nextActive.equals(item)) { 4294 setActiveDocument(nextActive); 4295 return; 4296 } 4297 4298 item = docs.get(0); 4299 nextActive = nav.getPrevious(item); 4300 if (!nextActive.equals(item)) { 4301 setActiveDocument(nextActive); 4302 return; 4303 } 4304 4305 throw new RuntimeException ("No document to set active before closing"); 4306 } 4307 } 4308 4309 4310 public void setActiveFirstDocument() { 4311 4312 4313 setActiveDocument(getOpenDefinitionsDocuments().get(0)); 4314 } 4315 4316 private void _setActiveDoc(INavigatorItem idoc) { 4317 _activeDocument = (OpenDefinitionsDocument) idoc; 4319 refreshActiveDocument(); 4321 } 4322 4323 4326 public void refreshActiveDocument() { 4327 try { 4328 _activeDocument.checkIfClassFileInSync(); 4329 _notifier.activeDocumentChanged(_activeDocument); 4331 } catch(DocumentClosedException dce) { } 4332 } 4333} 4334 4335 | Popular Tags |