diff options
Diffstat (limited to 'org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java')
-rw-r--r-- | org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java | 497 |
1 files changed, 0 insertions, 497 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java deleted file mode 100644 index 283c0ed3a19..00000000000 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java +++ /dev/null @@ -1,497 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 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.jface.text.reconciler; - - -import org.eclipse.core.runtime.IProgressMonitor; - -import org.eclipse.jface.text.Assert; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IDocumentListener; -import org.eclipse.jface.text.ITextInputListener; -import org.eclipse.jface.text.ITextViewer; - - - - -/** - * Abstract implementation of <code>IReconciler</code>. The reconciler - * listens to input document changes as well as changes of - * the input document of the text viewer it is installed on. Depending on - * its configuration it manages the received change notifications in a - * queue folding neighboring or overlapping changes together. The reconciler - * processes the dirty regions as a background activity after having waited for further - * changes for the configured duration of time. A reconciler is started using its - * <code>install</code> method. As a first step <code>initialProcess</code> is - * executed in the background. Then, the reconciling thread waits for changes that - * need to be reconciled. A reconciler can be resumed by calling <code>forceReconciling</code> - * independent from the existence of actual changes. This mechanism is for subclasses only. - * It is the clients responsibility to stop a reconciler using its <code>uninstall</code> - * method. Unstopped reconcilers do not free their resources.<p> - * It is subclass responsibility to specify how dirty regions are processed. - * - * @see IReconciler - * @see IDocumentListener - * @see ITextInputListener - * @see DirtyRegion - * @since 2.0 - */ -abstract public class AbstractReconciler implements IReconciler { - - - /** - * Background thread for the reconciling activity. - */ - class BackgroundThread extends Thread { - - /** Has the reconciler been canceled */ - private boolean fCanceled= false; - /** Has the reconciler been reset */ - private boolean fReset= false; - /** Has a change been applied */ - private boolean fIsDirty= false; - /** Is a reconciling strategy active */ - private boolean fIsActive= false; - - /** - * Creates a new background thread. The thread - * runs with minimal priority. - * - * @param name the thread's name - */ - public BackgroundThread(String name) { - super(name); - setPriority(Thread.MIN_PRIORITY); - setDaemon(true); - } - - /** - * Returns whether a reconciling strategy is active right now. - * - * @return <code>true</code> if a activity is active - */ - public boolean isActive() { - return fIsActive; - } - - /** - * Cancels the background thread. - */ - public void cancel() { - fCanceled= true; - synchronized (fDirtyRegionQueue) { - fDirtyRegionQueue.notifyAll(); - } - } - - /** - * Suspends the caller of this method until this background thread has - * emptied the dirty region queue. - */ - public void suspendCallerWhileDirty() { - while (fIsDirty) { - synchronized (fDirtyRegionQueue) { - if (fIsDirty) { - try { - fDirtyRegionQueue.wait(); - } catch (InterruptedException x) { - } - } - } - } - } - - /** - * Reset the background thread as the text viewer has been changed, - */ - public void reset() { - - if (fDelay > 0) { - - synchronized (this) { - fIsDirty= true; - fReset= true; - } - - } else { - - synchronized (this) { - fIsDirty= true; - } - - synchronized (fDirtyRegionQueue) { - fDirtyRegionQueue.notifyAll(); - } - } - - reconcilerReset(); - } - - /** - * The background activity. Waits until there is something in the - * queue managing the changes that have been applied to the text viewer. - * Removes the first change from the queue and process it.<p> - * Calls <code>initialProcess</code> on entrance. - */ - public void run() { - - synchronized (fDirtyRegionQueue) { - try { - fDirtyRegionQueue.wait(fDelay); - } catch (InterruptedException x) { - } - } - - initialProcess(); - - while (!fCanceled) { - - synchronized (fDirtyRegionQueue) { - try { - fDirtyRegionQueue.wait(fDelay); - } catch (InterruptedException x) { - } - } - - if (fCanceled) - break; - - if (!fIsDirty) - continue; - - if (fReset) { - synchronized (this) { - fReset= false; - } - continue; - } - - DirtyRegion r= null; - synchronized (fDirtyRegionQueue) { - r= fDirtyRegionQueue.removeNextDirtyRegion(); - } - - fIsActive= true; - - if (fProgressMonitor != null) - fProgressMonitor.setCanceled(false); - - process(r); - - synchronized (fDirtyRegionQueue) { - if (0 == fDirtyRegionQueue.getSize()) { - synchronized (this) { - fIsDirty= fProgressMonitor != null ? fProgressMonitor.isCanceled() : false; - } - fDirtyRegionQueue.notifyAll(); - } - } - - fIsActive= false; - } - } - } - - /** - * Internal document listener and text input listener. - */ - class Listener implements IDocumentListener, ITextInputListener { - - /* - * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) - */ - public void documentAboutToBeChanged(DocumentEvent e) { - } - - /* - * @see IDocumentListener#documentChanged(DocumentEvent) - */ - public void documentChanged(DocumentEvent e) { - - if (fProgressMonitor != null && fThread.isActive()) - fProgressMonitor.setCanceled(true); - - if (fIsIncrementalReconciler) - createDirtyRegion(e); - - fThread.reset(); - } - - /* - * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument) - */ - public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { - - if (oldInput == fDocument) { - - if (fDocument != null) - fDocument.removeDocumentListener(this); - - if (fIsIncrementalReconciler) { - fDirtyRegionQueue.purgeQueue(); - if (fDocument != null && fDocument.getLength() > 0) { - DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), null); - createDirtyRegion(e); - fThread.suspendCallerWhileDirty(); - } - } - - fDocument= null; - } - } - - /* - * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument) - */ - public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { - - fDocument= newInput; - if (fDocument == null) - return; - - - reconcilerDocumentChanged(fDocument); - - fDocument.addDocumentListener(this); - - if (fIsIncrementalReconciler) { - DocumentEvent e= new DocumentEvent(fDocument, 0, 0, fDocument.get()); - createDirtyRegion(e); - } - - startReconciling(); - } - } - - /** Queue to manage the changes applied to the text viewer */ - private DirtyRegionQueue fDirtyRegionQueue; - /** The background thread */ - private BackgroundThread fThread; - /** Internal document and text input listener */ - private Listener fListener; - /** The background thread delay */ - private int fDelay= 500; - /** Are there incremental reconciling strategies? */ - private boolean fIsIncrementalReconciler= true; - /** The progress monitor used by this reconciler */ - private IProgressMonitor fProgressMonitor; - - /** The text viewer's document */ - private IDocument fDocument; - /** The text viewer */ - private ITextViewer fViewer; - - - /** - * Processes a dirty region. If the dirty region is <code>null</code> the whole - * document is consider being dirty. The dirty region is partitioned by the - * document and each partition is handed over to a reconciling strategy registered - * for the partition's content type. - * - * @param dirtyRegion the dirty region to be processed - */ - abstract protected void process(DirtyRegion dirtyRegion); - - /** - * Hook called when the document whose contents should be reconciled - * has been changed, i.e., the input document of the text viewer this - * reconciler is installed on. Usually, subclasses use this hook to - * inform all their reconciling strategies about the change. - * - * @param newDocument the new reconciler document - */ - abstract protected void reconcilerDocumentChanged(IDocument newDocument); - - - /** - * Creates a new reconciler without configuring it. - */ - protected AbstractReconciler() { - super(); - } - - /** - * Tells the reconciler how long it should wait for further text changes before - * activating the appropriate reconciling strategies. - * - * @param delay the duration in milli seconds of a change collection period. - */ - public void setDelay(int delay) { - fDelay= delay; - } - - /** - * Tells the reconciler whether any of the available reconciling strategies - * is interested in getting detailed dirty region information or just in the - * fact the the document has been changed. In the second case, the reconciling - * can not incrementally be pursued. - * - * @param isIncremental indicates whether this reconciler will be configured with - * incremental reconciling strategies - * - * @see DirtyRegion - * @see IReconcilingStrategy - */ - public void setIsIncrementalReconciler(boolean isIncremental) { - fIsIncrementalReconciler= isIncremental; - } - - /** - * Sets the progress monitor of this reconciler. - * - * @param monitor the monitor to be used - */ - public void setProgressMonitor(IProgressMonitor monitor) { - fProgressMonitor= monitor; - } - - /** - * Returns whether any of the reconciling strategies is interested in - * detailed dirty region information. - * - * @return whether this reconciler is incremental - * - * @see IReconcilingStrategy - */ - protected boolean isIncrementalReconciler() { - return fIsIncrementalReconciler; - } - - /** - * Returns the input document of the text viewer this reconciler is installed on. - * - * @return the reconciler document - */ - protected IDocument getDocument() { - return fDocument; - } - - /** - * Returns the text viewer this reconciler is installed on. - * - * @return the text viewer this reconciler is installed on - */ - protected ITextViewer getTextViewer() { - return fViewer; - } - - /** - * Returns the progress monitor of this reconciler. - * - * @return the progress monitor of this reconciler - */ - protected IProgressMonitor getProgressMonitor() { - return fProgressMonitor; - } - - /* - * @see IReconciler#install(ITextViewer) - */ - public void install(ITextViewer textViewer) { - - Assert.isNotNull(textViewer); - - fViewer= textViewer; - - fListener= new Listener(); - fViewer.addTextInputListener(fListener); - - fDirtyRegionQueue= new DirtyRegionQueue(); - fThread= new BackgroundThread(getClass().getName()); - } - - /* - * @see IReconciler#uninstall() - */ - public void uninstall() { - if (fListener != null) { - - fViewer.removeTextInputListener(fListener); - if (fDocument != null) fDocument.removeDocumentListener(fListener); - fListener= null; - - synchronized (this) { - // http://dev.eclipse.org/bugs/show_bug.cgi?id=19135 - BackgroundThread bt= fThread; - fThread= null; - bt.cancel(); - } - } - } - - /** - * Creates a dirty region for a document event and adds it to the queue. - * - * @param e the document event for which to create a dirty region - */ - private void createDirtyRegion(DocumentEvent e) { - - if (e.getLength() == 0 && e.getText() != null) { - // Insert - fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText())); - - } else if (e.getText() == null || e.getText().length() == 0) { - // Remove - fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null)); - - } else { - // Replace (Remove + Insert) - fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null)); - fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText())); - } - } - - /** - * This method is called on startup of the background activity. It is called only - * once during the life time of the reconciler. Clients may reimplement this method. - */ - protected void initialProcess() { - } - - /** - * Forces the reconciler to reconcile the structure of the whole document. - * Clients may extend this method. - */ - protected void forceReconciling() { - - if (fDocument != null) { - - if (fIsIncrementalReconciler) { - DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), fDocument.get()); - createDirtyRegion(e); - } - - startReconciling(); - } - } - - /** - * Starts the reconciler to reconcile the queued dirty-regions. - * Clients may extend this method. - */ - protected synchronized void startReconciling() { - if (fThread == null) - return; - - if (!fThread.isAlive()) - fThread.start(); - - fThread.reset(); - } - - /** - * Hook that is called after the reconciler thread has been reset. - */ - protected void reconcilerReset() { - } -} |