1 33 34 package edu.rice.cs.drjava.model; 35 36 37 import java.awt.EventQueue ; 38 39 import java.io.File ; 40 import java.io.FileFilter ; 41 import java.io.IOException ; 42 import java.io.OutputStream ; 43 44 import java.net.MalformedURLException ; 45 import java.net.URL ; 46 47 import java.rmi.RemoteException ; 48 49 import java.util.ArrayList ; 50 import java.util.LinkedList ; 51 import java.util.List ; 52 import java.util.Vector ; 53 import java.util.StringTokenizer ; 54 55 import javax.swing.text.BadLocationException ; 56 import javax.swing.SwingUtilities ; 57 58 import edu.rice.cs.util.ClassPathVector; 59 import edu.rice.cs.util.FileOpenSelector; 60 import edu.rice.cs.drjava.model.FileSaveSelector; 61 import edu.rice.cs.util.FileOps; 62 import edu.rice.cs.util.OperationCanceledException; 63 import edu.rice.cs.util.UnexpectedException; 64 import edu.rice.cs.util.newjvm.AbstractMasterJVM; 65 import edu.rice.cs.util.text.EditDocumentException; 66 import edu.rice.cs.util.swing.Utilities; 67 68 import edu.rice.cs.drjava.DrJava; 69 import edu.rice.cs.drjava.config.OptionConstants; 70 import edu.rice.cs.drjava.config.OptionEvent; 71 import edu.rice.cs.drjava.config.OptionListener; 72 73 import edu.rice.cs.drjava.model.definitions.ClassNameNotFoundException; 74 import edu.rice.cs.drjava.model.definitions.DefinitionsDocument; 75 import edu.rice.cs.drjava.model.definitions.InvalidPackageException; 76 import edu.rice.cs.drjava.model.debug.Breakpoint; 77 import edu.rice.cs.drjava.model.debug.Debugger; 78 import edu.rice.cs.drjava.model.debug.DebugException; 79 import edu.rice.cs.drjava.model.debug.JPDADebugger; 80 import edu.rice.cs.drjava.model.debug.NoDebuggerAvailable; 81 import edu.rice.cs.drjava.model.debug.DebugListener; 82 import edu.rice.cs.drjava.model.debug.DebugWatchData; 83 import edu.rice.cs.drjava.model.debug.DebugThreadData; 84 import edu.rice.cs.drjava.model.repl.DefaultInteractionsModel; 85 import edu.rice.cs.drjava.model.repl.DummyInteractionsListener; 86 import edu.rice.cs.drjava.model.repl.InteractionsDocument; 87 import edu.rice.cs.drjava.model.repl.InteractionsDJDocument; 88 import edu.rice.cs.drjava.model.repl.InteractionsListener; 89 import edu.rice.cs.drjava.model.repl.InteractionsScriptModel; 90 import edu.rice.cs.drjava.model.repl.newjvm.MainJVM; 91 import edu.rice.cs.drjava.model.compiler.CompilerListener; 92 import edu.rice.cs.drjava.model.compiler.CompilerModel; 93 import edu.rice.cs.drjava.model.compiler.DefaultCompilerModel; 94 import edu.rice.cs.drjava.model.junit.DefaultJUnitModel; 95 import edu.rice.cs.drjava.model.junit.JUnitModel; 96 import edu.rice.cs.drjava.ui.MainFrame; 97 98 import java.io.*; 99 100 106 public class DefaultGlobalModel extends AbstractGlobalModel { 107 108 109 110 111 112 113 114 115 protected final InteractionsDJDocument _interactionsDocument; 116 117 118 final MainJVM _jvm; 119 120 121 protected final DefaultInteractionsModel _interactionsModel; 122 123 124 protected InteractionsListener _interactionsListener = new InteractionsListener() { 125 public void interactionStarted() { } 126 127 public void interactionEnded() { } 128 129 public void interactionErrorOccurred(int offset, int length) { } 130 131 public void interpreterResetting() { } 132 133 public void interpreterReady(File wd) { 134 File buildDir = _state.getBuildDirectory(); 135 if (buildDir != null) { 136 try { 138 _jvm.addBuildDirectoryClassPath(FileOps.toURL(new File (buildDir.getAbsolutePath()))); 139 } catch(MalformedURLException murle) { 140 throw new RuntimeException (murle); 142 } 143 } 144 } 145 146 public void interpreterResetFailed(Throwable t) { } 147 148 public void interpreterExited(int status) { } 149 150 public void interpreterChanged(boolean inProgress) { } 151 152 public void interactionIncomplete() { } 153 154 public void slaveJVMUsed() { } 155 }; 156 157 private CompilerListener _clearInteractionsListener = 158 new CompilerListener() { 159 public void compileStarted() { } 160 161 public void compileEnded(File workDir, List <? extends File > excludedFiles) { 162 if ( ((_compilerModel.getNumErrors() == 0) || (_compilerModel.getCompilerErrorModel().hasOnlyWarnings())) 164 && ! _junitModel.isTestInProgress() && _resetAfterCompile) { 165 resetInteractions(workDir); } 167 } 168 public void saveBeforeCompile() { } 169 public void saveUntitled() { } 170 }; 171 172 174 175 private final CompilerModel _compilerModel; 176 177 178 private volatile boolean _resetAfterCompile = true; 179 180 181 private volatile int _numCompErrors = 0; 182 183 184 185 186 private final DefaultJUnitModel _junitModel; 187 188 189 190 191 protected final JavadocModel _javadocModel; 192 193 194 195 196 private volatile Debugger _debugger = NoDebuggerAvailable.ONLY; 197 198 199 200 201 public DefaultGlobalModel() { 202 File workDir = Utilities.TEST_MODE ? new File (System.getProperty("user.home")) : getWorkingDirectory(); 204 _jvm = new MainJVM(workDir); 205 _compilerModel = new DefaultCompilerModel(this); 207 _junitModel = new DefaultJUnitModel(_jvm, _compilerModel, this); 208 _javadocModel = new DefaultJavadocModel(this); 209 _interactionsDocument = new InteractionsDJDocument(); 210 211 _interactionsModel = new DefaultInteractionsModel(this, _jvm, _interactionsDocument, workDir); 212 _interactionsModel.addListener(_interactionsListener); 213 _jvm.setInteractionsModel(_interactionsModel); 214 _jvm.setJUnitModel(_junitModel); 215 216 _jvm.setOptionArgs(DrJava.getConfig().getSetting(SLAVE_JVM_ARGS)); 217 218 DrJava.getConfig().addOptionListener(SLAVE_JVM_ARGS, new OptionListener<String >() { 219 public void optionChanged(OptionEvent<String > oe) { _jvm.setOptionArgs(oe.value); } 220 }); 221 222 _createDebugger(); 223 224 _interactionsModel.addListener(_notifier); 226 _compilerModel.addListener(_notifier); 227 _junitModel.addListener(_notifier); 228 _javadocModel.addListener(_notifier); 229 230 _compilerModel.addListener(_clearInteractionsListener); 234 235 _jvm.startInterpreterJVM(); 238 239 } 242 243 244 250 251 253 254 public void setBuildDirectory(File f) { 255 _state.setBuildDirectory(f); 256 if (f != null) { 257 try { 259 _jvm.addBuildDirectoryClassPath(FileOps.toURL(new File (f.getAbsolutePath()))); 260 } 261 catch(MalformedURLException murle) { 262 throw new RuntimeException (murle); 265 } 266 } 267 268 _notifier.projectBuildDirChanged(); 269 setProjectChanged(true); 270 setClassPathChanged(true); 271 } 272 273 275 276 public DefaultInteractionsModel getInteractionsModel() { return _interactionsModel; } 277 278 279 public InteractionsDJDocument getSwingInteractionsDocument() { return _interactionsDocument; } 280 281 public InteractionsDocument getInteractionsDocument() { return _interactionsModel.getDocument(); } 282 283 284 public CompilerModel getCompilerModel() { return _compilerModel; } 285 286 287 public JUnitModel getJUnitModel() { return _junitModel; } 288 289 290 public JavadocModel getJavadocModel() { return _javadocModel; } 291 292 public int getNumCompErrors() { return _numCompErrors; } 293 public void setNumCompErrors(int num) { _numCompErrors = num; } 294 295 296 public void dispose() { 297 _jvm.killInterpreter(null); 299 _notifier.removeAllListeners(); } 304 305 306 public void disposeExternalResources() { 307 _jvm.killInterpreter(null); 309 } 310 311 public void resetInteractions(File wd) { resetInteractions(wd, false); } 312 313 318 public void resetInteractions(File wd, boolean forceReset) { 319 File workDir = _interactionsModel.getWorkingDirectory(); 321 if (wd == null) { wd = workDir; } 322 324 if (! forceReset && ! _jvm.slaveJVMUsed() && ! isClassPathChanged() && wd.equals(workDir)) { 325 _interactionsModel._notifyInterpreterReady(wd); 328 return; 329 } 330 if (DrJava.getConfig().getSetting(STICKY_INTERACTIONS_DIRECTORY)) { 332 DrJava.getConfig().setSetting(LAST_INTERACTIONS_DIRECTORY, wd); 334 } 335 _interactionsModel.resetInterpreter(wd); 336 } 337 338 339 public void interpretCurrentInteraction() { _interactionsModel.interpretCurrentInteraction(); } 340 341 344 public void loadHistory(FileOpenSelector selector) throws IOException { _interactionsModel.loadHistory(selector); } 345 346 347 public InteractionsScriptModel loadHistoryAsScript(FileOpenSelector selector) 348 throws IOException , OperationCanceledException { 349 return _interactionsModel.loadHistoryAsScript(selector); 350 } 351 352 353 public void clearHistory() { _interactionsModel.getDocument().clearHistory(); } 354 355 358 public void saveHistory(FileSaveSelector selector) throws IOException { 359 _interactionsModel.getDocument().saveHistory(selector); 360 } 361 362 367 public void saveHistory(FileSaveSelector selector, String editedVersion) throws IOException { 368 _interactionsModel.getDocument().saveHistory(selector, editedVersion); 369 } 370 371 372 public String getHistoryAsStringWithSemicolons() { 373 return _interactionsModel.getDocument().getHistoryAsStringWithSemicolons(); 374 } 375 376 377 public String getHistoryAsString() { 378 return _interactionsModel.getDocument().getHistoryAsString(); 379 } 380 381 382 public void printDebugMessage(String s) { 383 _interactionsModel.getDocument(). 384 insertBeforeLastPrompt(s + "\n", InteractionsDocument.DEBUGGER_STYLE); 385 } 386 387 388 public void waitForInterpreter() { _jvm.ensureInterpreterConnected(); } 389 390 391 392 public ClassPathVector getInteractionsClassPath() { return _jvm.getClassPath(); } 393 394 398 void setResetAfterCompile(boolean shouldReset) { _resetAfterCompile = shouldReset; } 399 400 401 public Debugger getDebugger() { return _debugger; } 402 403 406 public int getDebugPort() throws IOException { return _interactionsModel.getDebugPort(); } 407 408 410 414 class ConcreteOpenDefDoc extends AbstractGlobalModel.ConcreteOpenDefDoc { 415 418 ConcreteOpenDefDoc(File f) { super(f); } 419 420 421 ConcreteOpenDefDoc() { super(); } 422 423 424 public void startCompile() throws IOException { _compilerModel.compile(ConcreteOpenDefDoc.this); } 425 426 private volatile InteractionsListener _runMain; 427 428 436 public void runMain() throws ClassNameNotFoundException, IOException { 437 assert EventQueue.isDispatchThread(); 438 439 final String className = getDocument().getQualifiedClassName(); 441 final InteractionsDocument iDoc = _interactionsModel.getDocument(); 442 if (! checkIfClassFileInSync()) { 443 iDoc.insertBeforeLastPrompt(DOCUMENT_OUT_OF_SYNC_MSG, InteractionsDocument.ERROR_STYLE); 444 return; 445 } 446 447 final boolean wasDebuggerEnabled = getDebugger().isReady(); 448 449 _runMain = new DummyInteractionsListener() { 450 public void interpreterReady(File wd) { 451 if (wasDebuggerEnabled && (! getDebugger().isReady())) { 453 try { getDebugger().startUp(); } catch(DebugException de) { } 454 } 455 456 iDoc.clearCurrentInput(); 458 iDoc.append("java " + className, null); 459 460 _interactionsModel.interpretCurrentInteraction(); 462 _notifier.runStarted(ConcreteOpenDefDoc.this); 463 SwingUtilities.invokeLater(new Runnable () { 464 public void run() { 465 467 _interactionsModel.removeListener(_runMain); 468 } 469 }); 470 471 } 472 }; 473 474 _interactionsModel.addListener(_runMain); 475 476 File workDir; 477 if (isProjectActive()) workDir = getWorkingDirectory(); else { 479 try { workDir = getSourceRoot(); } 481 catch (InvalidPackageException e) { workDir = null; } 482 } 483 resetInteractions(workDir); 485 } 486 487 488 public void startJUnit() throws ClassNotFoundException , IOException { _junitModel.junit(this); } 489 490 494 public void generateJavadoc(FileSaveSelector saver) throws IOException { 495 _javadocModel.javadocDocument(this, saver, getClassPath().toString()); 497 } 498 499 500 public void removeFromDebugger() { 501 while (getBreakpointManager().getRegions().size() > 0) { 502 Breakpoint bp = getBreakpointManager().getRegions().get(0); 503 getBreakpointManager().removeRegion(bp); 504 } 505 } 506 } 507 508 511 protected ConcreteOpenDefDoc _createOpenDefinitionsDocument() { return new ConcreteOpenDefDoc(); } 512 513 516 protected ConcreteOpenDefDoc _createOpenDefinitionsDocument(File f) throws IOException { 517 if (! f.exists()) throw new FileNotFoundException("file " + f + " cannot be found"); 518 return new ConcreteOpenDefDoc(f); 519 } 520 521 524 protected void addDocToClassPath(OpenDefinitionsDocument doc) { 525 try { 526 File classPath = doc.getSourceRoot(); 527 try { 528 URL pathURL = FileOps.toURL(classPath); 529 if (doc.isAuxiliaryFile()) 530 _interactionsModel.addProjectFilesClassPath(pathURL); 531 else _interactionsModel.addExternalFilesClassPath(pathURL); 532 setClassPathChanged(true); 533 } 534 catch(MalformedURLException murle) { } 535 } 536 catch (InvalidPackageException e) { 537 } 539 } 540 541 544 private void _createDebugger() { 545 try { 546 _debugger = new JPDADebugger(this); 547 _jvm.setDebugModel((JPDADebugger) _debugger); 548 549 getBreakpointManager().addListener(new RegionManagerListener<Breakpoint>() { 551 public void regionAdded(final Breakpoint bp, int index) { setProjectChanged(true); } 552 public void regionChanged(final Breakpoint bp, int index) { setProjectChanged(true); } 553 public void regionRemoved(final Breakpoint bp) { 554 try { 555 getDebugger().removeBreakpoint(bp); 556 } catch(DebugException de) { } 557 setProjectChanged(true); 558 } 559 }); 560 getBookmarkManager().addListener(new RegionManagerListener<DocumentRegion>() { 561 public void regionAdded(DocumentRegion r, int index) { setProjectChanged(true); } 562 public void regionChanged(DocumentRegion r, int index) { setProjectChanged(true); } 563 public void regionRemoved(DocumentRegion r) { setProjectChanged(true); } 564 }); 565 566 _debugger.addListener(new DebugListener() { 567 public void watchSet(final DebugWatchData w) { setProjectChanged(true); } 568 public void watchRemoved(final DebugWatchData w) { setProjectChanged(true); } 569 570 public void regionAdded(final Breakpoint bp, int index) { } 571 public void regionChanged(final Breakpoint bp, int index) { } 572 public void regionRemoved(final Breakpoint bp) { } 573 public void debuggerStarted() { } 574 public void debuggerShutdown() { } 575 public void threadLocationUpdated(OpenDefinitionsDocument doc, int lineNumber, boolean shouldHighlight) { } 576 public void breakpointReached(final Breakpoint bp) { } 577 public void stepRequested() { } 578 public void currThreadSuspended() { } 579 public void currThreadResumed() { } 580 public void threadStarted() { } 581 public void currThreadDied() { } 582 public void nonCurrThreadDied() { } 583 public void currThreadSet(DebugThreadData thread) { } 584 }); 585 } 586 catch( NoClassDefFoundError ncdfe ) { 587 _debugger = NoDebuggerAvailable.ONLY; 589 } 590 catch( UnsupportedClassVersionError ucve ) { 591 _debugger = NoDebuggerAvailable.ONLY; 593 } 594 catch( Throwable t ) { 595 _debugger = NoDebuggerAvailable.ONLY; 597 } 598 } 599 600 603 public ClassPathVector getClassPath() { 604 ClassPathVector result = new ClassPathVector(); 605 606 if (isProjectActive()) { 607 File buildDir = getBuildDirectory(); 608 if (buildDir != null) { _addFileToClassPath(buildDir, result); } 609 610 617 File projRoot = getProjectRoot(); 618 if (projRoot != null) { _addFileToClassPath(projRoot, result); } 619 620 ClassPathVector projectExtras = getExtraClassPath(); 621 if (projectExtras != null) { result.addAll(projectExtras); } 622 } 623 else { 624 for (File f : getSourceRootSet()) { _addFileToClassPath(f, result); } 625 } 626 627 Vector <File > globalExtras = DrJava.getConfig().getSetting(EXTRA_CLASSPATH); 628 if (globalExtras != null) { 629 for (File f : globalExtras) { _addFileToClassPath(f, result); } 630 } 631 632 637 String currentClassPath = System.getProperty("java.class.path"); 638 if (currentClassPath != null) { 639 StringTokenizer tokens = new StringTokenizer (currentClassPath, File.pathSeparator); 641 while (tokens.hasMoreTokens()) { 642 _addFileToClassPath(new File (tokens.nextToken()), result); 643 } 644 } 645 646 return result; 647 } 648 649 650 private void _addFileToClassPath(File f, ClassPathVector cp) { 651 653 try { cp.add(FileOps.toURL(f)); } 654 catch (MalformedURLException e) { } 655 } 656 657 661 public void resetInteractionsClassPath() { 662 ClassPathVector projectExtras = getExtraClassPath(); 663 if (projectExtras != null) for (URL cpE : projectExtras) { _interactionsModel.addProjectClassPath(cpE); } 665 666 Vector <File > cp = DrJava.getConfig().getSetting(EXTRA_CLASSPATH); 667 if (cp != null) { 668 for (File f : cp) { 669 try { _interactionsModel.addExtraClassPath(FileOps.toURL(f)); } 670 catch(MalformedURLException murle) { 671 System.out.println("File " + f + " in your extra classpath could not be parsed to a URL; " + 672 "it may contain un-URL-encodable characters."); 673 } 674 } 675 } 676 677 for (OpenDefinitionsDocument odd: getAuxiliaryDocuments()) { 678 try { _interactionsModel.addProjectFilesClassPath(FileOps.toURL(odd.getSourceRoot())); } 680 catch(MalformedURLException murle) { } 681 catch(InvalidPackageException e) { } 682 } 683 684 for (OpenDefinitionsDocument odd: getNonProjectDocuments()) { 685 try { 687 File sourceRoot = odd.getSourceRoot(); 688 if (sourceRoot != null) _interactionsModel.addExternalFilesClassPath(FileOps.toURL(sourceRoot)); 689 } 690 catch(MalformedURLException murle) { } 691 catch(InvalidPackageException e) { } 692 } 693 694 696 try { _interactionsModel.addProjectFilesClassPath(FileOps.toURL(getProjectRoot())); } 697 catch(MalformedURLException murle) { } 698 setClassPathChanged(false); } 700 701 716 } 717 | Popular Tags |