1 11 12 package org.eclipse.debug.internal.ui.views.console; 13 14 15 import java.io.IOException ; 16 import java.util.ArrayList ; 17 import java.util.Collections ; 18 import java.util.Comparator ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Vector ; 22 23 import org.eclipse.debug.core.DebugEvent; 24 import org.eclipse.debug.core.DebugPlugin; 25 import org.eclipse.debug.core.IDebugEventSetListener; 26 import org.eclipse.debug.core.IStreamListener; 27 import org.eclipse.debug.core.model.IFlushableStreamMonitor; 28 import org.eclipse.debug.core.model.IProcess; 29 import org.eclipse.debug.core.model.IStreamMonitor; 30 import org.eclipse.debug.core.model.IStreamsProxy; 31 import org.eclipse.debug.internal.ui.DebugUIPlugin; 32 import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; 33 import org.eclipse.debug.ui.DebugUITools; 34 import org.eclipse.debug.ui.IDebugUIConstants; 35 import org.eclipse.debug.ui.console.IConsole; 36 import org.eclipse.debug.ui.console.IConsoleColorProvider; 37 import org.eclipse.debug.ui.console.IConsoleHyperlink; 38 import org.eclipse.jface.preference.IPreferenceStore; 39 import org.eclipse.jface.text.BadLocationException; 40 import org.eclipse.jface.text.BadPositionCategoryException; 41 import org.eclipse.jface.text.DocumentEvent; 42 import org.eclipse.jface.text.IDocument; 43 import org.eclipse.jface.text.IDocumentPartitioner; 44 import org.eclipse.jface.text.IDocumentPartitionerExtension; 45 import org.eclipse.jface.text.IRegion; 46 import org.eclipse.jface.text.ITypedRegion; 47 import org.eclipse.jface.text.Position; 48 import org.eclipse.jface.text.Region; 49 import org.eclipse.jface.util.IPropertyChangeListener; 50 import org.eclipse.jface.util.PropertyChangeEvent; 51 import org.eclipse.swt.widgets.Display; 52 import org.eclipse.ui.console.ConsolePlugin; 53 54 58 public class ConsoleDocumentPartitioner implements IDocumentPartitioner, IDocumentPartitionerExtension, IPropertyChangeListener, IConsole, IDebugEventSetListener { 59 60 protected IProcess fProcess; 61 protected IConsoleColorProvider fColorProvider; 62 private IStreamsProxy fProxy; 63 protected List fStreamListeners = new ArrayList (2); 64 65 private String [] fSortedLineDelimiters; 66 67 private boolean fUpdatingBuffer = false; 69 private int fLowWaterMark; 70 private int fHighWaterMark; 71 72 private int fMaxAppendSize; 74 75 class StreamEntry { 76 79 private String fStreamIdentifier; 80 83 private String fText = null; 84 85 StreamEntry(String text, String streamIdentifier) { 86 fText = text; 87 fStreamIdentifier = streamIdentifier; 88 } 89 90 93 public String getStreamIdentifier() { 94 return fStreamIdentifier; 95 } 96 97 100 public String getText() { 101 return fText; 102 } 103 104 public boolean isClosedEntry() { 105 return false; 106 } 107 } 108 109 112 class StreamsClosedEntry extends StreamEntry { 113 StreamsClosedEntry() { 114 super("", ""); } 116 117 public boolean isClosedEntry() { 118 return true; 119 } 120 } 121 122 class StreamListener implements IStreamListener { 123 124 private String fStreamIdentifier; 125 private IStreamMonitor fStreamMonitor; 126 private boolean fIsSystemOut = false; 127 private boolean fIsSystemErr = false; 128 129 public StreamListener(String streamIdentifier, IStreamMonitor streamMonitor) { 130 fStreamIdentifier = streamIdentifier; 131 fStreamMonitor = streamMonitor; 132 fIsSystemOut = IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM.equals(streamIdentifier); 133 fIsSystemErr = IDebugUIConstants.ID_STANDARD_ERROR_STREAM.equals(streamIdentifier); 134 } 135 136 public void streamAppended(String newText, IStreamMonitor monitor) { 137 if (fIsSystemOut) { 138 DebugUIPlugin.getDefault().getConsoleDocumentManager().aboutToWriteSystemOut(getProcess()); 139 } else if (fIsSystemErr) { 140 DebugUIPlugin.getDefault().getConsoleDocumentManager().aboutToWriteSystemErr(getProcess()); 141 } 142 ConsoleDocumentPartitioner.this.streamAppended(newText, fStreamIdentifier); 143 } 144 145 public void streamClosed(IStreamMonitor monitor) { 146 } 148 149 public void connect() { 150 fStreamMonitor.addListener(this); 151 String contents= fStreamMonitor.getContents(); 152 if (fStreamMonitor instanceof IFlushableStreamMonitor) { 153 IFlushableStreamMonitor flushableStreamMonitor = (IFlushableStreamMonitor)fStreamMonitor; 155 flushableStreamMonitor.flushContents(); 156 flushableStreamMonitor.setBuffered(false); 157 } 158 if (contents.length() > 0) { 159 streamAppended(contents, fStreamMonitor); 160 } 161 } 162 163 public void disconnect() { 164 fStreamMonitor.removeListener(this); 165 } 166 } 167 168 169 175 private Vector fQueue = new Vector (10); 176 177 180 private Thread fPollingThread = null; 181 182 185 private boolean fAppending = false; 186 187 190 private boolean fKilled = false; 191 192 195 private boolean fPoll = false; 196 197 200 private boolean fClosed= false; 201 202 205 private IDocument fDocument = null; 206 207 210 private int fLineLength = 0; 211 212 215 private int fMaxLineLength = 80; 216 217 220 private boolean fWrap = false; 221 222 225 private List fPartitions = new ArrayList (5); 226 227 231 private static final long BASE_DELAY= 100L; 232 233 236 private String fLastStreamIdentifier= null; 237 238 241 private StringBuffer fInputBuffer = new StringBuffer (); 242 243 246 private Vector fPendingLinks = new Vector (); 247 248 251 private ConsoleLineNotifier fLineNotifier = null; 252 253 256 public void connect(IDocument document) { 257 fDocument = document; 258 fDocument.addPositionCategory(HyperlinkPosition.HYPER_LINK_CATEGORY); 259 document.setDocumentPartitioner(this); 260 IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore(); 261 fWrap = store.getBoolean(IDebugPreferenceConstants.CONSOLE_WRAP); 262 fMaxLineLength = store.getInt(IDebugPreferenceConstants.CONSOLE_WIDTH); 263 store.addPropertyChangeListener(this); 264 fColorProvider.connect(fProcess, this); 265 DebugPlugin.getDefault().addDebugEventListener(this); 266 if (fProcess.isTerminated()) { 267 streamsClosed(); 271 } 272 } 273 274 277 public void disconnect() { 278 kill(); 279 if (fLineNotifier != null) { 280 fLineNotifier.disconnect(); 281 } 282 fColorProvider.disconnect(); 283 fDocument.setDocumentPartitioner(null); 284 DebugPlugin.getDefault().removeDebugEventListener(this); 285 } 286 287 290 public void documentAboutToBeChanged(DocumentEvent event) { 291 } 292 293 296 public boolean documentChanged(DocumentEvent event) { 297 return documentChanged2(event) != null; 298 } 299 300 303 public String [] getLegalContentTypes() { 304 return new String [] {InputPartition.INPUT_PARTITION_TYPE, OutputPartition.OUTPUT_PARTITION_TYPE, BreakPartition.BREAK_PARTITION_TYPE}; 305 } 306 307 310 public String getContentType(int offset) { 311 ITypedRegion partition = getPartition(offset); 312 if (partition != null) { 313 return partition.getType(); 314 } 315 return null; 316 } 317 318 321 public ITypedRegion[] computePartitioning(int offset, int length) { 322 if (offset == 0 && length == fDocument.getLength()) { 323 return (ITypedRegion[])fPartitions.toArray(new ITypedRegion[fPartitions.size()]); 324 } else { 325 int end = offset + length; 326 List list = new ArrayList (); 327 for (int i = 0; i < fPartitions.size(); i++) { 328 ITypedRegion partition = (ITypedRegion)fPartitions.get(i); 329 int partitionStart = partition.getOffset(); 330 int partitionEnd = partitionStart + partition.getLength(); 331 if ((offset >= partitionStart && offset <= partitionEnd) || 332 (offset < partitionStart && end >= partitionStart)) { 333 list.add(partition); 334 } 335 } 336 return (ITypedRegion[])list.toArray(new ITypedRegion[list.size()]); 337 } 338 } 339 340 343 public ITypedRegion getPartition(int offset) { 344 for (int i = 0; i < fPartitions.size(); i++) { 345 ITypedRegion partition = (ITypedRegion)fPartitions.get(i); 346 int start = partition.getOffset(); 347 int end = start + partition.getLength(); 348 if (offset >= start && offset < end) { 349 return partition; 350 } 351 } 352 return null; 353 } 354 355 358 public IRegion documentChanged2(DocumentEvent event) { 359 if (fUpdatingBuffer) { 360 return new Region(0, fDocument.getLength()); 361 } 362 addPendingLinks(); 363 String text = event.getText(); 364 if (isAppendInProgress()) { 365 addPartition(new OutputPartition(fLastStreamIdentifier, event.getOffset(), text.length())); 367 if (fLineNotifier != null) { 368 fLineNotifier.consoleChanged(event); 369 } 370 } else { 371 int amountDeleted = event.getLength() - text.length(); 373 int docLength = fDocument.getLength(); 374 int bufferStartOffset = docLength + amountDeleted - fInputBuffer.length(); 375 int bufferModifyOffset = event.getOffset() - bufferStartOffset; 376 int bufferModifyOffsetEnd = bufferModifyOffset + event.getLength(); 377 378 if (docLength == 0) { 379 fQueue.clear(); 381 fInputBuffer.setLength(0); 382 fPartitions.clear(); 383 if (fLineNotifier != null) { 385 fLineNotifier.setLinesProcessed(0); 386 } 387 try { 389 Position[] positions = fDocument.getPositions(HyperlinkPosition.HYPER_LINK_CATEGORY); 390 for (int i = 0; i < positions.length; i++) { 391 Position position = positions[i]; 392 fDocument.removePosition(HyperlinkPosition.HYPER_LINK_CATEGORY, position); 393 } 394 } catch (BadPositionCategoryException e) { 395 } 396 return new Region(0,0); 397 } 398 399 if (amountDeleted > 0) { 400 fInputBuffer.replace(bufferModifyOffset, bufferModifyOffsetEnd, text); 402 InputPartition partition = new InputPartition(IDebugUIConstants.ID_STANDARD_INPUT_STREAM, bufferStartOffset, fInputBuffer.length()); 404 fPartitions.set(fPartitions.size() - 1, partition); 405 } else { 406 409 String [] lineDelimiters= getLegalLineDelimiters(); 411 StringBuffer temp =new StringBuffer (fInputBuffer.toString()); 412 temp.replace(bufferModifyOffset, bufferModifyOffsetEnd, text); 413 String remaining = temp.toString(); 414 int partitionOffset = bufferStartOffset; 415 fInputBuffer.setLength(0); 416 boolean includesLF = false; 417 for (int i= lineDelimiters.length - 1; i >= 0; i--) { 419 int lf = remaining.indexOf(lineDelimiters[i]); 420 while (lf >= 0) { 421 includesLF = true; 422 int split = lf + lineDelimiters[i].length(); 423 fInputBuffer.append(remaining.substring(0, split)); 424 remaining = remaining.substring(split); 425 String buffer = fInputBuffer.toString(); 426 fInputBuffer.setLength(0); 427 InputPartition written = (InputPartition)addPartition(new InputPartition(IDebugUIConstants.ID_STANDARD_INPUT_STREAM, partitionOffset, split)); 428 written.setReadOnly(true); 429 partitionOffset += split; 430 addPartition(new InputPartition(IDebugUIConstants.ID_STANDARD_INPUT_STREAM, partitionOffset, 0)); 431 if (fProxy != null) { 432 try { 433 fProxy.write(buffer); 434 } catch (IOException ioe) { 435 DebugUIPlugin.log(ioe); 436 } 437 } 438 lf = remaining.indexOf(lineDelimiters[i]); 439 } 440 if (includesLF) { 441 break; 442 } 443 } 444 if (remaining.length() > 0) { 445 fInputBuffer.append(remaining); 446 addPartition(new InputPartition(IDebugUIConstants.ID_STANDARD_INPUT_STREAM, partitionOffset, remaining.length())); 447 } 448 } 449 } 450 ITypedRegion[] affectedRegions = computePartitioning(event.getOffset(), text.length()); 451 if (affectedRegions.length == 0) { 452 return null; 453 } 454 if (affectedRegions.length == 1) { 455 return affectedRegions[0]; 456 } 457 int affectedLength = affectedRegions[0].getLength(); 458 for (int i = 1; i < affectedRegions.length; i++) { 459 ITypedRegion region = affectedRegions[i]; 460 affectedLength += region.getLength(); 461 } 462 return new Region(affectedRegions[0].getOffset(), affectedLength); 463 } 464 465 469 protected StreamPartition addPartition(StreamPartition partition) { 470 if (fPartitions.isEmpty()) { 471 fPartitions.add(partition); 472 } else { 473 int index = fPartitions.size() - 1; 474 StreamPartition last = (StreamPartition)fPartitions.get(index); 475 if (last.canBeCombinedWith(partition)) { 476 partition = last.combineWith(partition); 478 fPartitions.set(index, partition); 479 } else { 480 fPartitions.add(partition); 482 } 483 } 484 return partition; 485 } 486 487 491 protected void addPendingLinks() { 492 synchronized (fPendingLinks) { 493 if (fPendingLinks.isEmpty()) { 494 return; 495 } 496 Iterator links = fPendingLinks.iterator(); 497 while (links.hasNext()) { 498 HyperlinkPosition link = (HyperlinkPosition)links.next(); 499 if ((link.getOffset() + link.getLength()) <= fDocument.getLength()) { 500 links.remove(); 501 addLink(link.getHyperLink(), link.getOffset(), link.getLength()); 502 } 503 } 504 } 505 } 506 507 public ConsoleDocumentPartitioner(IProcess process, IConsoleColorProvider colorProvider) { 508 fProcess= process; 509 fColorProvider = colorProvider; 510 IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore(); 511 boolean limit = store.getBoolean(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT); 512 if (limit) { 513 fLowWaterMark = store.getInt(IDebugPreferenceConstants.CONSOLE_LOW_WATER_MARK); 514 fHighWaterMark = store.getInt(IDebugPreferenceConstants.CONSOLE_HIGH_WATER_MARK); 515 fMaxAppendSize = fLowWaterMark; 516 } else { 517 fLowWaterMark = -1; 518 fHighWaterMark = -1; 519 fMaxAppendSize = 80000; 520 } 521 } 522 523 526 public synchronized void kill() { 527 if (!fKilled) { 528 fKilled = true; 529 if (fPollingThread != null && fPollingThread.isAlive()) { 530 fPollingThread.interrupt(); 531 } 532 fPoll = false; 533 Iterator iter = fStreamListeners.iterator(); 534 while (iter.hasNext()) { 535 StreamListener listener = (StreamListener)iter.next(); 536 listener.disconnect(); 537 } 538 DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); 539 } 540 } 541 542 public synchronized void startReading() { 543 if (fPollingThread != null) { 544 return; 546 } 547 Runnable r = new Runnable () { 548 public void run() { 549 pollAndSleep(); 550 } 551 }; 552 fPoll = true; 553 fPollingThread = new Thread (r, "Console Polling Thread"); fPollingThread.start(); 555 } 556 557 561 protected void pollAndSleep() { 562 while (!fKilled && fPoll && (!isClosed() || !fQueue.isEmpty())) { 563 poll(); 564 try { 565 Thread.sleep(BASE_DELAY); 566 } catch (InterruptedException e) { 567 } 568 } 569 } 570 571 574 protected void poll() { 575 if (isAppendInProgress()) { 576 return; 577 } 578 synchronized(fQueue) { 579 StringBuffer buffer = null; 580 StreamEntry prev = null; 581 int processed = 0; 582 int amount = 0; 583 String [] lds = fDocument.getLegalLineDelimiters(); 584 boolean closed= false; 585 while (!fKilled && !closed && processed < fQueue.size() && amount < fMaxAppendSize) { 586 StreamEntry entry = (StreamEntry)fQueue.get(processed); 587 if (entry.isClosedEntry()) { 588 closed = true; 589 processed++; 590 } else if (prev == null || prev.getStreamIdentifier().equals(entry.getStreamIdentifier())) { 591 String text = entry.getText(); 592 if (buffer == null) { 593 buffer = new StringBuffer (text.length()); 594 } 595 if (isWrap()) { 596 for (int i = 0; i < text.length(); i++) { 597 if (fLineLength >= fMaxLineLength) { 598 String d = getLineDelimiter(text, i, lds); 599 if (d == null) { 600 buffer.append(lds[0]); 601 } else { 602 buffer.append(d); 603 i = i + d.length(); 604 } 605 fLineLength = 0; 606 } 607 if (i < text.length()) { 608 String lineDelimiter = getLineDelimiter(text, i, lds); 609 if (lineDelimiter == null) { 610 buffer.append(text.charAt(i)); 611 fLineLength++; 612 } else { 613 buffer.append(lineDelimiter); 614 fLineLength = 0; 615 i = i + lineDelimiter.length() - 1; 616 } 617 } 618 } 619 } else { 620 buffer.append(text); 621 } 622 prev = entry; 623 processed++; 624 amount+= entry.getText().length(); 625 } else { 626 if (buffer != null) { 629 appendToDocument(buffer.toString(), prev.getStreamIdentifier()); 630 buffer.setLength(0); 631 prev = null; 632 } 633 } 634 } 635 if (buffer != null) { 636 appendToDocument(buffer.toString(), prev.getStreamIdentifier()); 637 } 638 if (closed) { 639 Display display= DebugUIPlugin.getStandardDisplay(); 640 if (display != null) { 641 display.asyncExec(new Runnable () { 642 public void run() { 643 if (fLineNotifier != null) { 644 fLineNotifier.streamsClosed(); 645 } 646 } 647 }); 648 } 649 } 650 for (int i = 0; i < processed; i++) { 651 fQueue.remove(0); 652 } 653 } 654 } 655 656 664 protected String getLineDelimiter(String text, int pos, String [] lineDelimiters) { 665 String ld = null; 666 for (int i = 0; i < lineDelimiters.length; i++) { 667 if (text.regionMatches(pos, lineDelimiters[i], 0, lineDelimiters[i].length())) { 668 if (ld == null) { 669 ld = lineDelimiters[i]; 670 } else { 671 if (ld.length() < lineDelimiters[i].length()) { 672 ld = lineDelimiters[i]; 673 } 674 } 675 } 676 } 677 return ld; 678 } 679 680 683 protected boolean isWrap() { 684 return fWrap; 685 } 686 687 693 protected void appendToDocument(final String text, final String streamIdentifier) { 694 Runnable r = new Runnable () { 695 public void run() { 696 setAppendInProgress(true); 697 fLastStreamIdentifier = streamIdentifier; 698 try { 699 fDocument.replace(fDocument.getLength(), 0, text); 700 warnOfContentChange(); 701 } catch (BadLocationException e) { 702 } 703 setAppendInProgress(false); 704 checkOverflow(); 705 } 706 }; 707 Display display = DebugUIPlugin.getStandardDisplay(); 708 if (display != null) { 709 display.asyncExec(r); 710 } 711 } 712 713 717 protected void checkOverflow() { 718 if (fHighWaterMark >= 0) { 719 if (fDocument.getLength() > fHighWaterMark) { 720 int lineDifference = 0; 721 if (fLineNotifier != null) { 722 int processed = fLineNotifier.getLinesProcessed(); 723 int numLines = fDocument.getNumberOfLines(); 724 lineDifference = numLines - processed; 725 } 726 int overflow = fDocument.getLength() - fLowWaterMark; 727 fUpdatingBuffer = true; 728 try { 729 List newParitions = new ArrayList (fPartitions.size()); 731 Iterator partitions = fPartitions.iterator(); 732 while (partitions.hasNext()) { 733 ITypedRegion region = (ITypedRegion)partitions.next(); 734 if (region instanceof StreamPartition) { 735 StreamPartition streamPartition = (StreamPartition)region; 736 ITypedRegion newPartition = null; 737 int offset = region.getOffset(); 738 if (offset < overflow) { 739 int endOffset = offset + region.getLength(); 740 if (endOffset < overflow) { 741 } else { 743 int length = endOffset - overflow; 745 newPartition = streamPartition.createNewPartition(streamPartition.getStreamIdentifier(), 0, length); 746 } 747 } else { 748 newPartition = streamPartition.createNewPartition(streamPartition.getStreamIdentifier(), streamPartition.getOffset() - overflow, streamPartition.getLength()); 750 } 751 if (newPartition != null) { 752 newParitions.add(newPartition); 753 } 754 } 755 } 756 fPartitions = newParitions; 757 try { 759 Position[] hyperlinks = fDocument.getPositions(HyperlinkPosition.HYPER_LINK_CATEGORY); 760 for (int i = 0; i < hyperlinks.length; i++) { 761 HyperlinkPosition position = (HyperlinkPosition)hyperlinks[i]; 762 fDocument.removePosition(HyperlinkPosition.HYPER_LINK_CATEGORY, position); 764 if (position.getOffset() >= overflow) { 765 try { 767 fDocument.addPosition(HyperlinkPosition.HYPER_LINK_CATEGORY, new HyperlinkPosition(position.getHyperLink(), position.getOffset() - overflow, position.getLength())); 768 } catch (BadLocationException e) { 769 } 770 } 771 } 772 } catch (BadPositionCategoryException e) { 773 } 774 synchronized (fPendingLinks) { 775 Vector newPendingLinks = new Vector (fPendingLinks.size()); 777 Iterator pendingLinks = fPendingLinks.iterator(); 778 while (pendingLinks.hasNext()) { 779 HyperlinkPosition position = (HyperlinkPosition)pendingLinks.next(); 780 if (position.getOffset() >= overflow) { 781 newPendingLinks.add(new HyperlinkPosition(position.getHyperLink(), position.getOffset() - overflow, position.getLength())); 782 } 783 } 784 fPendingLinks = newPendingLinks; 785 } 786 787 try { 789 fDocument.replace(0, overflow, ""); } catch (BadLocationException e) { 791 DebugUIPlugin.log(e); 792 } 793 } finally { 794 if (fLineNotifier != null) { 796 fLineNotifier.setLinesProcessed(fDocument.getNumberOfLines() - lineDifference); 797 } 798 fUpdatingBuffer = false; 799 } 800 } 801 } 802 } 803 804 808 protected void streamAppended(String text, String streamIdentifier) { 809 synchronized (fQueue) { 810 if (fClosed) { 811 DebugUIPlugin.logErrorMessage("An attempt was made to append text to the console, after it was closed."); } else { 814 fQueue.add(new StreamEntry(text, streamIdentifier)); 815 } 816 } 817 } 818 819 823 protected void streamsClosed() { 824 synchronized (fQueue) { 825 if (!fClosed) { 826 fQueue.add(new StreamsClosedEntry()); 827 fClosed = true; 828 } 829 } 830 } 831 832 836 protected void setAppendInProgress(boolean appending) { 837 fAppending = appending; 838 } 839 840 844 protected boolean isAppendInProgress() { 845 return fAppending; 846 } 847 848 851 public void propertyChange(PropertyChangeEvent event) { 852 if (event.getProperty().equals(IDebugPreferenceConstants.CONSOLE_WRAP)) { 853 fWrap = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.CONSOLE_WRAP); 854 } else if (event.getProperty().equals(IDebugPreferenceConstants.CONSOLE_WIDTH)) { 855 fMaxLineLength = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.CONSOLE_WIDTH); 856 } 857 } 858 859 863 protected String [] getLegalLineDelimiters() { 864 if (fSortedLineDelimiters == null) { 865 String [] lineDelimiters = fDocument.getLegalLineDelimiters(); 866 List list = new ArrayList (lineDelimiters.length); 867 for (int i = 0; i < lineDelimiters.length; i++) { 868 list.add(lineDelimiters[i]); 869 } 870 Comparator comparator = new Comparator () { 871 874 public int compare(Object a, Object b) { 875 String s1 = (String )a; 876 String s2 = (String )b; 877 return s2.length() - s1.length(); 878 } 879 880 }; 881 Collections.sort(list, comparator); 882 fSortedLineDelimiters = (String [])list.toArray(new String [lineDelimiters.length]); 883 } 884 return fSortedLineDelimiters; 885 } 886 887 890 public void connect(IStreamMonitor streamMonitor, String streamIdentifer) { 891 if (streamMonitor != null) { 892 StreamListener listener = new StreamListener(streamIdentifer, streamMonitor); 893 fStreamListeners.add(listener); 894 listener.connect(); 895 startReading(); 897 } 898 } 899 900 903 public void connect(IStreamsProxy streamsProxy) { 904 fProxy = streamsProxy; 905 connect(streamsProxy.getOutputStreamMonitor(), IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM); 906 connect(streamsProxy.getErrorStreamMonitor(), IDebugUIConstants.ID_STANDARD_ERROR_STREAM); 907 } 908 909 913 protected boolean isClosed() { 914 return fClosed; 915 } 916 917 protected IConsoleColorProvider getColorProvider() { 918 return fColorProvider; 919 } 920 921 924 public void addLink(IConsoleHyperlink link, int offset, int length) { 925 HyperlinkPosition hyperlinkPosition = new HyperlinkPosition(link, offset, length); 926 try { 927 fDocument.addPosition(HyperlinkPosition.HYPER_LINK_CATEGORY, hyperlinkPosition); 928 } catch (BadPositionCategoryException e) { 929 DebugUIPlugin.log(e); 931 } catch (BadLocationException e) { 932 fPendingLinks.add(hyperlinkPosition); 934 } 935 } 936 937 940 public IDocument getDocument() { 941 return fDocument; 942 } 943 944 947 public IProcess getProcess() { 948 return fProcess; 949 } 950 951 956 public void connectLineNotifier(ConsoleLineNotifier lineNotifier) { 957 fLineNotifier = lineNotifier; 958 lineNotifier.connect(this); 959 } 960 961 964 public IRegion getRegion(IConsoleHyperlink link) { 965 try { 966 Position[] positions = getDocument().getPositions(HyperlinkPosition.HYPER_LINK_CATEGORY); 967 for (int i = 0; i < positions.length; i++) { 968 HyperlinkPosition position = (HyperlinkPosition)positions[i]; 969 if (position.getHyperLink().equals(link)) { 970 return new Region(position.getOffset(), position.getLength()); 971 } 972 } 973 } catch (BadPositionCategoryException e) { 974 } 975 return null; 976 } 977 980 public void handleDebugEvents(DebugEvent[] events) { 981 for (int i = 0; i < events.length; i++) { 982 DebugEvent event = events[i]; 983 if (event.getKind() == DebugEvent.TERMINATE && event.getSource().equals(getProcess())) { 984 DebugPlugin.getDefault().removeDebugEventListener(this); 985 streamsClosed(); 986 } 987 } 988 989 } 990 991 private void warnOfContentChange() { 992 ConsolePlugin.getDefault().getConsoleManager().warnOfContentChange(DebugUITools.getConsole(fProcess)); 993 } 994 995 } 996 | Popular Tags |