diff options
Diffstat (limited to 'org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java')
-rw-r--r-- | org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java | 669 |
1 files changed, 0 insertions, 669 deletions
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java deleted file mode 100644 index 412fe0d0b..000000000 --- a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java +++ /dev/null @@ -1,669 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.ui.internal.console; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IDocumentPartitionerExtension; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITypedRegion; -import org.eclipse.jface.text.Region; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.console.ConsolePlugin; -import org.eclipse.ui.console.IConsoleDocumentPartitioner; -import org.eclipse.ui.console.IOConsole; -import org.eclipse.ui.console.IOConsoleInputStream; -import org.eclipse.ui.console.IOConsoleOutputStream; -import org.eclipse.ui.progress.UIJob; - -/** - * Partitions an IOConsole's document - * @since 3.1 - * - */ -public class IOConsolePartitioner implements IConsoleDocumentPartitioner, IDocumentPartitionerExtension { - private PendingPartition consoleClosedPartition; - private IDocument document; - private ArrayList partitions; - /** - * Blocks of data that have not yet been appended to the document. - */ - private ArrayList pendingPartitions; - /** - * A list of PendingPartitions to be appended by the updateJob - */ - private ArrayList updatePartitions; - /** - * The last partition appended to the document - */ - private IOConsolePartition lastPartition; - /** - * Job that appends pending partitions to the document. - */ - private QueueProcessingJob queueJob; - /** - * The input stream attached to this document. - */ - private IOConsoleInputStream inputStream; - /** - * Flag to indicate that the updateJob is updating the document. - */ - private boolean updateInProgress; - /** - * A list of partitions containing input from the console, that have - * not been appended to the input stream yet. - */ - private ArrayList inputPartitions; - /** - * offset used by updateJob - */ - private int firstOffset; - /** - * An array of legal line delimiters - */ - private String[] lld; - private int highWaterMark = -1; - private int lowWaterMark = -1; - private boolean connected = false; - - private IOConsole console; - - private TrimJob trimJob = new TrimJob(); - /** - * Lock for appending to and removing from the document - used - * to synchronize addition of new text/partitions in the update - * job and handling buffer overflow/clearing of the console. - */ - private Object overflowLock = new Object(); - - public IOConsolePartitioner(IOConsoleInputStream inputStream, IOConsole console) { - this.inputStream = inputStream; - this.console = console; - trimJob.setRule(console.getSchedulingRule()); - } - - public IDocument getDocument() { - return document; - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#connect(org.eclipse.jface.text.IDocument) - */ - public void connect(IDocument doc) { - document = doc; - document.setDocumentPartitioner(this); - lld = document.getLegalLineDelimiters(); - partitions = new ArrayList(); - pendingPartitions = new ArrayList(); - inputPartitions = new ArrayList(); - queueJob = new QueueProcessingJob(); - queueJob.setSystem(true); - queueJob.setRule(console.getSchedulingRule()); - connected = true; - } - - public int getHighWaterMark() { - return highWaterMark; - } - - public int getLowWaterMark() { - return lowWaterMark; - } - - public void setWaterMarks(int low, int high) { - lowWaterMark = low; - highWaterMark = high; - ConsolePlugin.getStandardDisplay().asyncExec(new Runnable() { - public void run() { - checkBufferSize(); - } - }); - } - - /** - * Notification from the console that all of its streams have been closed. - */ - public void streamsClosed() { - consoleClosedPartition = new PendingPartition(null, null); - synchronized (pendingPartitions) { - pendingPartitions.add(consoleClosedPartition); - } - queueJob.schedule(); //ensure that all pending partitions are processed. - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#disconnect() - */ - public void disconnect() { - synchronized (overflowLock) { - document = null; - partitions.clear(); - connected = false; - try { - inputStream.close(); - } catch (IOException e) { - } - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) - */ - public void documentAboutToBeChanged(DocumentEvent event) { - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#documentChanged(org.eclipse.jface.text.DocumentEvent) - */ - public boolean documentChanged(DocumentEvent event) { - return documentChanged2(event) != null; - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#getLegalContentTypes() - */ - public String[] getLegalContentTypes() { - return new String[] { IOConsolePartition.OUTPUT_PARTITION_TYPE, IOConsolePartition.INPUT_PARTITION_TYPE }; - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#getContentType(int) - */ - public String getContentType(int offset) { - return getPartition(offset).getType(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#computePartitioning(int, int) - */ - public ITypedRegion[] computePartitioning(int offset, int length) { - int rangeEnd = offset + length; - int left= 0; - int right= partitions.size() - 1; - int mid= 0; - IOConsolePartition position= null; - - if (left == right) { - return new IOConsolePartition[]{(IOConsolePartition) partitions.get(0)}; - } - while (left < right) { - - mid= (left + right) / 2; - - position= (IOConsolePartition) partitions.get(mid); - if (rangeEnd < position.getOffset()) { - if (left == mid) - right= left; - else - right= mid -1; - } else if (offset > (position.getOffset() + position.getLength() - 1)) { - if (right == mid) - left= right; - else - left= mid +1; - } else { - left= right= mid; - } - } - - - List list = new ArrayList(); - int index = left - 1; - if (index >= 0) { - position= (IOConsolePartition) partitions.get(index); - while (index >= 0 && (position.getOffset() + position.getLength()) > offset) { - index--; - if (index >= 0) { - position= (IOConsolePartition) partitions.get(index); - } - } - } - index++; - position= (IOConsolePartition) partitions.get(index); - while (index < partitions.size() && (position.getOffset() < rangeEnd)) { - list.add(position); - index++; - if (index < partitions.size()) { - position= (IOConsolePartition) partitions.get(index); - } - } - - return (ITypedRegion[]) list.toArray(new IOConsolePartition[list.size()]); - } - - - /* - * (non-Javadoc) - * @see org.eclipse.jface.text.IDocumentPartitioner#getPartition(int) - */ - public ITypedRegion getPartition(int offset) { - for (int i = 0; i < partitions.size(); i++) { - ITypedRegion partition = (ITypedRegion) partitions.get(i); - int start = partition.getOffset(); - int end = start + partition.getLength(); - if (offset >= start && offset < end) { - return partition; - } - } - - if (lastPartition == null) { - synchronized(partitions) { - lastPartition = new IOConsolePartition(inputStream, ""); //$NON-NLS-1$ - lastPartition.setOffset(offset); - partitions.add(lastPartition); - inputPartitions.add(lastPartition); - } - } - return lastPartition; - } - - /** - * Enforces the buffer size. - * When the number of lines in the document exceeds the high water mark, the - * beginning of the document is trimmed until the number of lines equals the - * low water mark. - */ - private void checkBufferSize() { - if (document != null && highWaterMark > 0) { - int length = document.getLength(); - if (length > highWaterMark) { - if (trimJob.getState() == Job.NONE) { //if the job isn't already running - trimJob.setOffset(length - lowWaterMark); - trimJob.schedule(); - } - } - } - } - - /** - * Clears the console - */ - public void clearBuffer() { - synchronized (overflowLock) { - trimJob.setOffset(-1); - trimJob.setRule(console.getSchedulingRule()); - trimJob.schedule(); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.text.IDocumentPartitionerExtension#documentChanged2(org.eclipse.jface.text.DocumentEvent) - */ - public IRegion documentChanged2(DocumentEvent event) { - if (document == null) { - return null; //another thread disconnected the partitioner - } - if (document.getLength() == 0) { //document cleared - partitions.clear(); - inputPartitions.clear(); - pendingPartitions.clear(); - lastPartition = null; - return new Region(0, 0); - } - - - if (updateInProgress) { - synchronized(partitions) { - if (updatePartitions != null) { - for (Iterator i = updatePartitions.iterator(); i.hasNext(); ) { - PendingPartition pp = (PendingPartition) i.next(); - if (pp == consoleClosedPartition) { - continue; - } - - int ppLen = pp.text.length(); - if (lastPartition != null && lastPartition.getStream() == pp.stream) { - int len = lastPartition.getLength(); - lastPartition.setLength(len + ppLen); - } else { - IOConsolePartition partition = new IOConsolePartition(pp.stream, ppLen); - partition.setOffset(firstOffset); - lastPartition = partition; - partitions.add(partition); - } - firstOffset += ppLen; - } - } - } - } else {// user input. - int amountDeleted = event.getLength() ; - - if (amountDeleted > 0) { - int offset = event.fOffset; - IOConsolePartition partition = (IOConsolePartition) getPartition(offset); - if(partition == lastPartition) { - partition.delete(event.fOffset-partition.getOffset(), amountDeleted); - } - } - - synchronized(partitions) { - if (lastPartition == null || lastPartition.isReadOnly()) { - lastPartition = new IOConsolePartition(inputStream, event.fText); //$NON-NLS-1$ - lastPartition.setOffset(event.fOffset); - partitions.add(lastPartition); - inputPartitions.add(lastPartition); - } else { - lastPartition.insert(event.fText, (event.fOffset-lastPartition.getOffset())); - } - - int lastLineDelimiter = -1; - String partitionText = lastPartition.getString(); - for (int i = 0; i < lld.length; i++) { - String ld = lld[i]; - int index = partitionText.lastIndexOf(ld); - if (index != -1) { - index += ld.length(); - } - if (index > lastLineDelimiter) { - lastLineDelimiter = index; - } - } - if (lastLineDelimiter != -1) { - StringBuffer input = new StringBuffer(); - Iterator it = inputPartitions.iterator(); - while (it.hasNext()) { - IOConsolePartition partition = (IOConsolePartition) it.next(); - if (partition.getOffset() + partition.getLength() <= event.fOffset + lastLineDelimiter) { - if (partition == lastPartition) { - lastPartition = null; - } - input.append(partition.getString()); - partition.clearBuffer(); - partition.setReadOnly(); - it.remove(); - } else { - //create a new partition containing everything up to the line delimiter - //and append that to the string buffer. - String contentBefore = partitionText.substring(0, lastLineDelimiter); - IOConsolePartition newPartition = new IOConsolePartition(inputStream, contentBefore); - newPartition.setOffset(partition.getOffset()); - newPartition.setReadOnly(); - newPartition.clearBuffer(); - int index = partitions.indexOf(partition); - partitions.add(index, newPartition); - input.append(contentBefore); - //delete everything that has been appended to the buffer. - partition.delete(0, lastLineDelimiter); - partition.setOffset(lastLineDelimiter + partition.getOffset()); - lastLineDelimiter = 0; - } - } - if (input.length() > 0) { - inputStream.appendData(input.toString()); - } - - } - } - } - - return new Region(event.fOffset, event.fText.length()); - } - - private void setUpdateInProgress(boolean b) { - updateInProgress = b; - } - - /** - * A stream has been appended, add to pendingPartions list and schedule updateJob. - * updateJob is scheduled with a slight delay, this allows the console to run the job - * less frequently and update the document with a greater amount of data each time - * the job is run - * @param stream The stream that was written to. - * @param s The string that should be appended to the document. - */ - public void streamAppended(IOConsoleOutputStream stream, String s) { - synchronized(pendingPartitions) { - PendingPartition last = (PendingPartition) (pendingPartitions.size() > 0 ? pendingPartitions.get(pendingPartitions.size()-1) : null); - if (last != null && last.stream == stream) { - last.append(s); - } else { - pendingPartitions.add(new PendingPartition(stream, s)); - queueJob.schedule(100); - } - } - } - - /** - * Holds data until updateJob can be run and the document can be updated. - */ - private class PendingPartition { - String text; - IOConsoleOutputStream stream; - - PendingPartition(IOConsoleOutputStream stream, String text) { - this.stream = stream; - this.text=text; - } - - void append(String moreText) { - text += moreText; - } - } - - /** - * Updates the document. Will append everything that is available before - * finishing. - */ - private class QueueProcessingJob extends Job { - - QueueProcessingJob() { - super("IOConsole Updater"); //$NON-NLS-1$ - } - - /* - * (non-Javadoc) - * @see org.eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor) - */ - protected IStatus run(IProgressMonitor monitor) { - synchronized (overflowLock) { - - Display display = ConsolePlugin.getStandardDisplay(); - - ArrayList pendingCopy = new ArrayList(); - StringBuffer buffer = null; - boolean consoleClosed = false; - while (display != null && pendingPartitions.size() > 0) { - synchronized(pendingPartitions) { - pendingCopy.addAll(pendingPartitions); - pendingPartitions.clear(); - } - - buffer = new StringBuffer(); - for (Iterator i = pendingCopy.iterator(); i.hasNext(); ) { - PendingPartition pp = (PendingPartition) i.next(); - if (pp != consoleClosedPartition) { - buffer.append(pp.text); - } else { - consoleClosed = true; - } - } - } - - final ArrayList finalCopy = pendingCopy; - final String toAppend = buffer.toString(); - final boolean notifyClosed = consoleClosed; - - display.asyncExec(new Runnable() { - public void run() { - if (connected) { - setUpdateInProgress(true); - updatePartitions = finalCopy; - firstOffset = document.getLength(); - try { - document.replace(firstOffset, 0, toAppend.toString()); - } catch (BadLocationException e) { - } - updatePartitions = null; - setUpdateInProgress(false); - } - if (notifyClosed) { - console.partitionerFinished(); - } - checkBufferSize(); - } - }); - } - - return Status.OK_STATUS; - } - - /* - * Job will process as much as it can each time it's run, but it gets - * scheduled everytime a PendingPartition is added to the list, meaning - * that this job could get scheduled unnecessarily in cases of heavy output. - * Note however, that schedule() will only reschedule a running/scheduled Job - * once even if it's called many times. - */ - public boolean shouldRun() { - boolean shouldRun = connected && pendingPartitions != null && pendingPartitions.size() > 0; - return shouldRun; - } - } - - - - - - - - /** - * Job to trim the console document, runs in the UI thread. - */ - private class TrimJob extends UIJob { - - /** - * trims output up to the line containing the given offset, - * or all output if -1. - */ - private int truncateOffset; - - /** - * Creates a new job to trim the buffer. - */ - TrimJob() { - super("Trim Job"); //$NON-NLS-1$ - setSystem(true); - } - - /** - * Sets the trim offset. - * - * @param offset trims output up to the line containing the given offset - */ - public void setOffset(int offset) { - truncateOffset = offset; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) - */ - public IStatus runInUIThread(IProgressMonitor monitor) { - if (document == null) { - return Status.OK_STATUS; - } - - int length = document.getLength(); - if (truncateOffset < length) { - synchronized (overflowLock) { - try { - if (truncateOffset < 0) { - // clear - setUpdateInProgress(true); - document.set(""); //$NON-NLS-1$ - setUpdateInProgress(false); - partitions.clear(); - } else { - // overflow - int cutoffLine = document.getLineOfOffset(truncateOffset); - int cutOffset = document.getLineOffset(cutoffLine); - - - // set the new length of the first partition - IOConsolePartition partition = (IOConsolePartition) getPartition(cutOffset); - partition.setLength(partition.getOffset() + partition.getLength() - cutOffset); - - setUpdateInProgress(true); - document.replace(0, cutOffset, ""); //$NON-NLS-1$ - setUpdateInProgress(false); - - //remove partitions and reset Partition offsets - int index = partitions.indexOf(partition); - for (int i = 0; i < index; i++) { - partitions.remove(0); - } - - int offset = 0; - for (Iterator i = partitions.iterator(); i.hasNext(); ) { - IOConsolePartition p = (IOConsolePartition) i.next(); - p.setOffset(offset); - offset += p.getLength(); - } - } - } catch (BadLocationException e) { - } - } - } - return Status.OK_STATUS; - } - } - - - - - - - - /* (non-Javadoc) - * @see org.eclipse.ui.console.IConsoleDocumentPartitioner#isReadOnly(int) - */ - public boolean isReadOnly(int offset) { - return ((IOConsolePartition)getPartition(offset)).isReadOnly(); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.console.IConsoleDocumentPartitioner#computeStyleRange(int, int) - */ - public StyleRange[] getStyleRanges(int offset, int length) { - if (!connected) { - return new StyleRange[0]; - } - IOConsolePartition[] computedPartitions = (IOConsolePartition[])computePartitioning(offset, length); - StyleRange[] styles = new StyleRange[computedPartitions.length]; - for (int i = 0; i < computedPartitions.length; i++) { - int rangeStart = Math.max(computedPartitions[i].getOffset(), offset); - int rangeLength = computedPartitions[i].getLength(); - styles[i] = computedPartitions[i].getStyleRange(rangeStart, rangeLength); - } - return styles; - } - - -}
\ No newline at end of file |