Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/text/BasicStructuredDocument.java')
-rw-r--r--bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/text/BasicStructuredDocument.java2685
1 files changed, 0 insertions, 2685 deletions
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/text/BasicStructuredDocument.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/text/BasicStructuredDocument.java
deleted file mode 100644
index 8b687bb2ad..0000000000
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/text/BasicStructuredDocument.java
+++ /dev/null
@@ -1,2685 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2001, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * Jens Lukowski/Innoopract - initial renaming/restructuring
- *
- *******************************************************************************/
-package org.eclipse.wst.sse.core.internal.text;
-
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.BadPartitioningException;
-import org.eclipse.jface.text.BadPositionCategoryException;
-import org.eclipse.jface.text.DefaultLineTracker;
-import org.eclipse.jface.text.DocumentEvent;
-import org.eclipse.jface.text.DocumentPartitioningChangedEvent;
-import org.eclipse.jface.text.FindReplaceDocumentAdapter;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IDocumentExtension;
-import org.eclipse.jface.text.IDocumentExtension3;
-import org.eclipse.jface.text.IDocumentListener;
-import org.eclipse.jface.text.IDocumentPartitioner;
-import org.eclipse.jface.text.IDocumentPartitionerExtension;
-import org.eclipse.jface.text.IDocumentPartitionerExtension2;
-import org.eclipse.jface.text.IDocumentPartitioningListener;
-import org.eclipse.jface.text.IDocumentPartitioningListenerExtension;
-import org.eclipse.jface.text.IDocumentPartitioningListenerExtension2;
-import org.eclipse.jface.text.ILineTracker;
-import org.eclipse.jface.text.IPositionUpdater;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextStore;
-import org.eclipse.jface.text.ITypedRegion;
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.text.SequentialRewriteTextStore;
-import org.eclipse.jface.text.TypedRegion;
-import org.eclipse.wst.sse.core.internal.Logger;
-import org.eclipse.wst.sse.core.internal.document.StructuredDocumentFactory;
-import org.eclipse.wst.sse.core.internal.encoding.EncodingMemento;
-import org.eclipse.wst.sse.core.internal.ltk.parser.RegionParser;
-import org.eclipse.wst.sse.core.internal.provisional.events.AboutToBeChangedEvent;
-import org.eclipse.wst.sse.core.internal.provisional.events.IModelAboutToBeChangedListener;
-import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
-import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
-import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
-import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
-import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentEvent;
-import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredTextReParser;
-import org.eclipse.wst.sse.core.internal.text.rules.StructuredTextPartitioner;
-import org.eclipse.wst.sse.core.internal.undo.IStructuredTextUndoManager;
-import org.eclipse.wst.sse.core.internal.undo.StructuredTextUndoManager;
-import org.eclipse.wst.sse.core.internal.util.Assert;
-import org.eclipse.wst.sse.core.internal.util.Debug;
-import org.eclipse.wst.sse.core.internal.util.Utilities;
-
-
-/**
- * The standard implementation of structured document.
- */
-public class BasicStructuredDocument implements IStructuredDocument, IDocumentExtension, IDocumentExtension3, CharSequence, IRegionComparible {
-
- /**
- * This ThreadLocal construct is used so each thread can maintain its only
- * pointer to the double linked list that manages the documents regions.
- * The only thing we "gaurd" for is that a previously cached region has
- * been deleted.
- *
- * The object that is kept in the thread local's map, is just a pointer to
- * an array position. That's because the object there needs to be "free"
- * from references to other objects, or it will not be garbage collected.
- */
- private class CurrentDocumentRegionCache {
- // I'm assuming for now there would never be so many threads that
- // this arrayList needs to be bounded, or 'cleaned up'.
- // this assumption should be tested in practice and long running
- // jobs -- found not to be a good assumption. See below.
- private List cachedRegionPositionArray = Collections.synchronizedList(new ArrayList());
- private final boolean DEBUG = false;
- private final int MAX_SIZE = 50;
-
-
- private ThreadLocal threadLocalCachePosition = new ThreadLocal();
-
- IStructuredDocumentRegion get() {
- IStructuredDocumentRegion region = null;
- int pos = getThreadLocalPosition();
- try {
- region = (IStructuredDocumentRegion) cachedRegionPositionArray.get(pos);
- }
- catch (IndexOutOfBoundsException e) {
- // even though the cachedRegionPosition is synchronized,
- // that just means each access is syncronized, its
- // still possible for another thread to cause it to
- // be cleared, after this thread gets it position.
- // So, if that happens, all we can do is reset to beginning.
- // This should be extremely rare (in other words, probably
- // not worth using synchronized blocks
- // to access cachedRegionPositionArray.
- reinitThreadLocalPosition();
- resetToInitialState();
- }
- if (region == null) {
- region = resetToInitialState();
- }
- else
- // region not null
- if (region.isDeleted()) {
- region = resetToInitialState();
- }
- return region;
- }
-
- private int getThreadLocalPosition() {
- Object threadLocalObject = threadLocalCachePosition.get();
- int pos = -1;
- if (threadLocalObject == null) {
-
- pos = reinitThreadLocalPosition();
- }
- else {
- pos = ((Integer) threadLocalObject).intValue();
- }
- return pos;
- }
-
- /**
- * @return
- */
- private int reinitThreadLocalPosition() {
- Integer position;
- int pos;
- // TODO_future: think of a better solution that doesn't
- // require this kludge. This is especially required because
- // some infrasture, such as reconciler, actually null out
- // their thread object and recreate it, 500 msecs later
- // (approximately).
- // Note: the likely solution in future is to clear after every
- // heavy use of getCachedRegion, such as in creating node
- // lists, or reparsing or partioning.
- if (cachedRegionPositionArray.size() > MAX_SIZE) {
- cachedRegionPositionArray.clear();
- if (DEBUG) {
- System.out.println("cachedRegionPositionArray cleared at size " + MAX_SIZE); //$NON-NLS-1$
- }
- }
- position = new Integer(cachedRegionPositionArray.size());
- threadLocalCachePosition.set(position);
- cachedRegionPositionArray.add(position.intValue(), null);
- pos = position.intValue();
- return pos;
- }
-
- private IStructuredDocumentRegion resetToInitialState() {
- IStructuredDocumentRegion region;
- region = getFirstStructuredDocumentRegion();
- set(region);
- return region;
- }
-
- // TODO: make privite if used, else delete
- void set(int pos, IStructuredDocumentRegion region) {
- cachedRegionPositionArray.set(pos, region);
- }
-
- void set(IStructuredDocumentRegion region) {
- try {
- int pos = getThreadLocalPosition();
- cachedRegionPositionArray.set(pos, region);
- }
- catch (IndexOutOfBoundsException e) {
- // even though the cachedRegionPosition is synchronized,
- // that just means each access is syncronized, its
- // still possible for another thread to cause it to
- // be cleared, after this thread gets it position.
- // So, if that happens, all we can do is reset to beginning.
- // This should be extremely rare (in other words, probably
- // not worth using synchronized blocks
- // to access cachedRegionPositionArray.
- reinitThreadLocalPosition();
- resetToInitialState();
- }
- }
- }
-
- /**
- * This NullDocumentEvent is used to complete the "aboutToChange" and
- * "changed" cycle, when in fact the original change is no longer valid.
- * The only known (valid) case of this is when a model re-initialize takes
- * place, which causes setText to be called in the middle of some previous
- * change. [This architecture will be improved in future].
- */
- public class NullDocumentEvent extends DocumentEvent {
- public NullDocumentEvent() {
- this(BasicStructuredDocument.this, 0, 0, ""); //$NON-NLS-1$
- }
-
- private NullDocumentEvent(IDocument doc, int offset, int length, String text) {
- super(doc, offset, length, text);
- }
- }
-
- class RegisteredReplace {
- /** The owner of this replace operation. */
- IDocumentListener fOwner;
- /** The replace operation */
- IDocumentExtension.IReplace fReplace;
-
- /**
- * Creates a new bundle object.
- *
- * @param owner
- * the document listener owning the replace operation
- * @param replace
- * the replace operation
- */
- RegisteredReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) {
- fOwner = owner;
- fReplace = replace;
- }
- }
-
- /**
- * these control variable isn't mark as 'final' since there's some unit
- * tests that manipulate it. For final product, it should be.
- */
-
- private static boolean USE_LOCAL_THREAD = true;
-
- /**
- * purely for debugging/performance measurements In practice, would always
- * be 'true'. (and should never be called by called by clients). Its not
- * 'final' or private just so it can be varied during
- * debugging/performance measurement runs.
- *
- * @param use_local_thread
- */
- public static void setUSE_LOCAL_THREAD(final boolean use_local_thread) {
- USE_LOCAL_THREAD = use_local_thread;
- }
-
- private IStructuredDocumentRegion cachedDocumentRegion;
- private EncodingMemento encodingMemento;
- private boolean fAcceptPostNotificationReplaces = true;
- private CurrentDocumentRegionCache fCurrentDocumnetRegionCache;
- private DocumentEvent fDocumentEvent;
- private IDocumentListener[] fDocumentListeners;
-
- /**
- * The registered document partitioners.
- */
- private Map fDocumentPartitioners;
- /** The registered document partitioning listeners */
- private List fDocumentPartitioningListeners;
- private IStructuredDocumentRegion firstDocumentRegion;
- private RegionParser fParser;
- private GenericPositionManager fPositionManager;
- private List fPostNotificationChanges;
- private IDocumentListener[] fPrenotifiedDocumentListeners;
- private int fReentranceCount = 0;
- private IStructuredTextReParser fReParser;
- private int fStoppedCount = 0;
-
- private ITextStore fStore;
- private Object[] fStructuredDocumentAboutToChangeListeners;
- private Object[] fStructuredDocumentChangedListeners;
- private Object[] fStructuredDocumentChangingListeners;
-
- private ILineTracker fTracker;
- private IStructuredTextUndoManager fUndoManager;
- private IStructuredDocumentRegion lastDocumentRegion;
-
- private byte[] listenerLock = new byte[0];
- private NullDocumentEvent NULL_DOCUMENT_EVENT;
-
- //
- /**
- * in case preferred delimiter is not set, we'll assume the platform
- * default Note: it is not final static to make sure it won't be inlined
- * by compiler.
- */
- private final String PlatformLineDelimiter = System.getProperty("line.separator"); //$NON-NLS-1$
- /**
- * theoretically, a document can contain mixed line delimiters
- */
- private String preferedDelimiter;
- private final String READ_ONLY_REGIONS_CATEGORY = "_READ_ONLY_REGIONS_CATEGORY_"; //$NON-NLS-1$
- /**
- * debug variable only
- *
- * @param parser
- */
- private long startStreamTime;
- /**
- * debug variable only
- *
- * @param parser
- */
- private long startTime;
-
- public BasicStructuredDocument() {
- super();
- fCurrentDocumnetRegionCache = new CurrentDocumentRegionCache();
- fStore = new StructuredDocumentTextStore(50, 300);
- setLineTracker(new DefaultLineTracker());
- NULL_DOCUMENT_EVENT = new NullDocumentEvent();
-
- internal_addPositionCategory(READ_ONLY_REGIONS_CATEGORY);
- internal_addPositionUpdater(new DeleteEqualPositionUpdater(READ_ONLY_REGIONS_CATEGORY));
-
- }
-
- /**
- * This is the primary way to get a new structuredDocument. Its best to
- * use the factory methods in ModelManger to create a new
- * IStructuredDocument, since it will get and initialize the parser
- * according to the desired content type.
- */
- public BasicStructuredDocument(RegionParser parser) {
- this();
- Assert.isNotNull(parser, "Program Error: IStructuredDocument can not be created with null parser"); //$NON-NLS-1$
- // go through setter in case there is side effects
- internal_setParser(parser);
- }
-
- private void _clearDocumentEvent() {
- // no hard and fast requirement to null out ... just seems like
- // a good idea, since we are done with it.
- fDocumentEvent = null;
- }
-
- private void _fireDocumentAboutToChange(Object[] listeners) {
- // most DocumentAboutToBeChanged listeners do not anticipate
- // DocumentEvent == null. So make sure documentEvent is not
- // null. (this should never happen, yet it does sometimes)
- if (fDocumentEvent == null) {
- fDocumentEvent = new NullDocumentEvent();
- }
- // we must assign listeners to local variable, since the add and
- // remove
- // listner
- // methods can change the actual instance of the listener array from
- // another thread
- if (listeners != null) {
- Object[] holdListeners = listeners;
- // Note: the docEvent is created in replaceText API
- // fire
- for (int i = 0; i < holdListeners.length; i++) {
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- startTime = System.currentTimeMillis();
- }
- // safeguard from listeners that throw exceptions
- try {
- // this is a safe cast, since addListners requires a
- // IStructuredDocumentListener
- ((IDocumentListener) holdListeners[i]).documentAboutToBeChanged(fDocumentEvent);
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- long stopTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t IStructuredDocument::fireStructuredDocumentEvent. Time was " + (stopTime - startTime) + " msecs to fire NewModelEvent to instance of " + holdListeners[i].getClass()); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- }
- }
-
- private void notifyDocumentPartitionersAboutToChange(DocumentEvent documentEvent) {
- if (fDocumentPartitioners != null) {
- Iterator e = fDocumentPartitioners.values().iterator();
- while (e.hasNext()) {
- IDocumentPartitioner p = (IDocumentPartitioner) e.next();
- // safeguard from listeners that throw exceptions
- try {
- p.documentAboutToBeChanged(documentEvent);
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- }
- }
- }
-
- private void _fireDocumentChanged(Object[] listeners, StructuredDocumentEvent event) {
-
- // we must assign listeners to local variable, since the add and
- // remove
- // listner
- // methods can change the actual instance of the listener array from
- // another thread
- if (listeners != null) {
- Object[] holdListeners = listeners;
- // NOTE: document event is created in replace Text API and setText
- // API
- // now fire
- for (int i = 0; i < holdListeners.length; i++) {
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- startTime = System.currentTimeMillis();
- }
-
- // safeguard from listeners that throw exceptions
- try {
- // this is a safe cast, since addListners requires a
- // IStructuredDocumentListener
- // Notes: fDocumentEvent can be "suddenly" null, if one of
- // the
- // previous changes
- // caused a "setText" to be called. The only known case of
- // this
- // is a model reset
- // due to page directive changing. Eventually we should
- // change
- // archetecture to have
- // event que and be able to "cancel" pending events, but
- // for
- // now, we'll just pass a
- // NullDocumentEvent. By the way, it is important to send
- // something, since clients might
- // have indeterminant state due to "aboutToChange" being
- // sent
- // earlier.
- if (fDocumentEvent == null) {
- ((IDocumentListener) holdListeners[i]).documentChanged(NULL_DOCUMENT_EVENT);
- }
- else {
- ((IDocumentListener) holdListeners[i]).documentChanged(fDocumentEvent);
- }
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- long stopTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t IStructuredDocument::fireStructuredDocumentEvent. Time was " + (stopTime - startTime) + " msecs to fire NewModelEvent to instance of " + holdListeners[i].getClass()); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- }
- }
-
- private void notifyDocumentPartitionersDocumentChanged(DocumentEvent documentEvent) {
- if (fDocumentPartitioners != null) {
- Iterator e = fDocumentPartitioners.values().iterator();
- while (e.hasNext()) {
- IDocumentPartitioner p = (IDocumentPartitioner) e.next();
- // safeguard from listeners that throw exceptions
- try {
- if (p instanceof IDocumentPartitionerExtension) {
- // IRegion changedPartion =
- ((IDocumentPartitionerExtension) p).documentChanged2(documentEvent);
- }
- else {
- p.documentChanged(documentEvent);
- }
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- }
- }
- }
-
-
- private void _fireEvent(Object[] listeners, NoChangeEvent event) {
- // we must assign listeners to local variable, since the add and
- // remove
- // listner
- // methods can change the actual instance of the listener array from
- // another thread
- if (listeners != null) {
- Object[] holdListeners = listeners;
- for (int i = 0; i < holdListeners.length; i++) {
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- startTime = System.currentTimeMillis();
- }
- // safeguard from listeners that throw exceptions
- try {
- // this is a safe cast, since addListners requires a
- // IStructuredDocumentListener
- ((IStructuredDocumentListener) holdListeners[i]).noChange(event);
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- long stopTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t IStructuredDocument::fireStructuredDocumentEvent. Time was " + (stopTime - startTime) + " msecs to fire NewModelEvent to instance of " + holdListeners[i].getClass()); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- }
- }
-
- private void _fireEvent(Object[] listeners, RegionChangedEvent event) {
- // we must assign listeners to local variable, since the add and
- // remove
- // listner
- // methods can change the actual instance of the listener array from
- // another thread
- if (listeners != null) {
- Object[] holdListeners = listeners;
- for (int i = 0; i < holdListeners.length; i++) {
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- startTime = System.currentTimeMillis();
- }
- // safeguard from listeners that throw exceptions
- try {
- // this is a safe cast, since addListners requires a
- // IStructuredDocumentListener
- ((IStructuredDocumentListener) holdListeners[i]).regionChanged(event);
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- long stopTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t IStructuredDocument::fireStructuredDocumentEvent. Time was " + (stopTime - startTime) + " msecs to fire NewModelEvent to instance of " + holdListeners[i].getClass()); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- }
- }
-
- private void _fireEvent(Object[] listeners, RegionsReplacedEvent event) {
- // we must assign listeners to local variable, since the add and
- // remove
- // listner
- // methods can change the actual instance of the listener array from
- // another thread
- if (listeners != null) {
- Object[] holdListeners = listeners;
- for (int i = 0; i < holdListeners.length; i++) {
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- startTime = System.currentTimeMillis();
- }
- // safeguard from listeners that throw exceptions
- try {
- // this is a safe cast, since addListners requires a
- // IStructuredDocumentListener
- ((IStructuredDocumentListener) holdListeners[i]).regionsReplaced(event);
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- long stopTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t IStructuredDocument::fireStructuredDocumentEvent. Time was " + (stopTime - startTime) + " msecs to fire NewModelEvent to instance of " + holdListeners[i].getClass()); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- }
- }
-
- private void _fireEvent(Object[] listeners, StructuredDocumentRegionsReplacedEvent event) {
- // we must assign listeners to local variable, since the add and
- // remove
- // listner
- // methods can change the actual instance of the listener array from
- // another thread
- if (listeners != null) {
- Object[] holdListeners = listeners;
- for (int i = 0; i < holdListeners.length; i++) {
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- startTime = System.currentTimeMillis();
- }
- // safeguard from listeners that throw exceptions
- try {
- // this is a safe cast, since addListners requires a
- // IStructuredDocumentListener
- ((IStructuredDocumentListener) holdListeners[i]).nodesReplaced(event);
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- long stopTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t IStructuredDocument::fireStructuredDocumentEvent. Time was " + (stopTime - startTime) + " msecs to fire NewModelEvent to instance of " + holdListeners[i].getClass()); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- }
- }
-
- private void _fireStructuredDocumentAboutToChange(Object[] listeners) {
- // we must assign listeners to local variable, since the add and
- // remove
- // listner
- // methods can change the actual instance of the listener array from
- // another thread
- if (listeners != null) {
- Object[] holdListeners = listeners;
- // Note: the docEvent is created in replaceText API
- // fire
- for (int i = 0; i < holdListeners.length; i++) {
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- startTime = System.currentTimeMillis();
- }
- // safeguard from listeners that throw exceptions
- try {
- // notice the AboutToBeChangedEvent is created from the
- // DocumentEvent, since it is (nearly)
- // the same information. ?What to do about
- // originalRequester?
- if (fDocumentEvent == null) {
- fDocumentEvent = new NullDocumentEvent();
- }
- AboutToBeChangedEvent aboutToBeChangedEvent = new AboutToBeChangedEvent(this, null, fDocumentEvent.getText(), fDocumentEvent.getOffset(), fDocumentEvent.getLength());
- // this is a safe cast, since addListners requires a
- // IStructuredDocumentListener
- ((IModelAboutToBeChangedListener) holdListeners[i]).modelAboutToBeChanged(aboutToBeChangedEvent);
- }
- catch (Exception exception) {
- Logger.logException(exception);
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentEventOnly) {
- long stopTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t IStructuredDocument::fireStructuredDocumentEvent. Time was " + (stopTime - startTime) + " msecs to fire NewModelEvent to instance of " + holdListeners[i].getClass()); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- }
- }
-
- protected void acquireLock() {
- // do nothing here in super class
- }
-
- /**
- * addModelAboutToBeChangedListener method comment.
- */
- public void addDocumentAboutToChangeListener(IModelAboutToBeChangedListener listener) {
- synchronized (listenerLock) {
-
- // make sure listener is not already in listening
- // (and if it is, print a warning to aid debugging, if needed)
- if (!Utilities.contains(fStructuredDocumentAboutToChangeListeners, listener)) {
- int oldSize = 0;
- if (fStructuredDocumentAboutToChangeListeners != null) {
- // normally won't be null, but we need to be sure, for
- // first
- // time through
- oldSize = fStructuredDocumentAboutToChangeListeners.length;
- }
- int newSize = oldSize + 1;
- Object[] newListeners = new Object[newSize];
- if (fStructuredDocumentAboutToChangeListeners != null) {
- System.arraycopy(fStructuredDocumentAboutToChangeListeners, 0, newListeners, 0, oldSize);
- }
- // add listener to last position
- newListeners[newSize - 1] = listener;
- //
- // now switch new for old
- fStructuredDocumentAboutToChangeListeners = newListeners;
- //
- }
- }
- }
-
- /**
- * The StructuredDocumentListners and ModelChagnedListeners are very
- * similar. They both receive identical events. The difference is the
- * timing. The "pure" StructuredDocumentListners are notified after the
- * structuredDocument has been changed, but before other, related models
- * may have been changed such as the Structural Model. The Structural
- * model is in fact itself a "pure" StructuredDocumentListner. The
- * ModelChangedListeners can rest assured that all models and data have
- * been updated from the change by the tiem they are notified. This is
- * especially important for the text widget, for example, which may rely
- * on both structuredDocument and structural model information.
- */
- public void addDocumentChangedListener(IStructuredDocumentListener listener) {
- synchronized (listenerLock) {
-
- if (Debug.debugStructuredDocument) {
- System.out.println("IStructuredDocument::addModelChangedListener. Request to add an instance of " + listener.getClass() + " as a listener on structuredDocument."); //$NON-NLS-2$//$NON-NLS-1$
- }
- // make sure listener is not already in listening
- // (and if it is, print a warning to aid debugging, if needed)
- if (Utilities.contains(fStructuredDocumentChangedListeners, listener)) {
- if (Debug.displayWarnings) {
- System.out.println("IStructuredDocument::addModelChangedListener. listener " + listener + " was addeded more than once. "); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- else {
- if (Debug.debugStructuredDocument) {
- System.out.println("IStructuredDocument::addModelChangedListener. Adding an instance of " + listener.getClass() + " as a listener on structuredDocument."); //$NON-NLS-2$//$NON-NLS-1$
- }
- int oldSize = 0;
- if (fStructuredDocumentChangedListeners != null) {
- // normally won't be null, but we need to be sure, for
- // first
- // time through
- oldSize = fStructuredDocumentChangedListeners.length;
- }
- int newSize = oldSize + 1;
- Object[] newListeners = new Object[newSize];
- if (fStructuredDocumentChangedListeners != null) {
- System.arraycopy(fStructuredDocumentChangedListeners, 0, newListeners, 0, oldSize);
- }
- // add listener to last position
- newListeners[newSize - 1] = listener;
- //
- // now switch new for old
- fStructuredDocumentChangedListeners = newListeners;
- //
- // when a listener is added,
- // send the new model event to that one particular listener,
- // so it
- // can initialize itself with the current state of the model
- // listener.newModel(new NewModelEvent(this, listener));
- }
- }
- }
-
- public void addDocumentChangingListener(IStructuredDocumentListener listener) {
- synchronized (listenerLock) {
-
- if (Debug.debugStructuredDocument) {
- System.out.println("IStructuredDocument::addStructuredDocumentListener. Request to add an instance of " + listener.getClass() + " as a listener on structuredDocument."); //$NON-NLS-2$//$NON-NLS-1$
- }
- // make sure listener is not already in listening
- // (and if it is, print a warning to aid debugging, if needed)
- if (Utilities.contains(fStructuredDocumentChangingListeners, listener)) {
- if (Debug.displayWarnings) {
- System.out.println("IStructuredDocument::addStructuredDocumentListener. listener " + listener + " was addeded more than once. "); //$NON-NLS-2$//$NON-NLS-1$
- }
- }
- else {
- if (Debug.debugStructuredDocument) {
- System.out.println("IStructuredDocument::addStructuredDocumentListener. Adding an instance of " + listener.getClass() + " as a listener on structuredDocument."); //$NON-NLS-2$//$NON-NLS-1$
- }
- int oldSize = 0;
- if (fStructuredDocumentChangingListeners != null) {
- // normally won't be null, but we need to be sure, for
- // first
- // time through
- oldSize = fStructuredDocumentChangingListeners.length;
- }
- int newSize = oldSize + 1;
- Object[] newListeners = new Object[newSize];
- if (fStructuredDocumentChangingListeners != null) {
- System.arraycopy(fStructuredDocumentChangingListeners, 0, newListeners, 0, oldSize);
- }
- // add listener to last position
- newListeners[newSize - 1] = listener;
- //
- // now switch new for old
- fStructuredDocumentChangingListeners = newListeners;
- //
- // when a listener is added,
- // send the new model event to that one particular listener,
- // so it
- // can initialize itself with the current state of the model
- // listener.newModel(new NewModelEvent(this, listener));
- }
- }
- }
-
- /**
- * We manage our own document listners, instead of delegating to our
- * parentDocument, so we can fire at very end (and not when the
- * parentDocument changes).
- *
- */
- public void addDocumentListener(IDocumentListener listener) {
- synchronized (listenerLock) {
-
- // make sure listener is not already in listening
- // (and if it is, print a warning to aid debugging, if needed)
- if (!Utilities.contains(fDocumentListeners, listener)) {
- int oldSize = 0;
- if (fDocumentListeners != null) {
- // normally won't be null, but we need to be sure, for
- // first
- // time through
- oldSize = fDocumentListeners.length;
- }
- int newSize = oldSize + 1;
- IDocumentListener[] newListeners = null;
- newListeners = new IDocumentListener[newSize];
- if (fDocumentListeners != null) {
- System.arraycopy(fDocumentListeners, 0, newListeners, 0, oldSize);
- }
- // add listener to last position
- newListeners[newSize - 1] = listener;
- // now switch new for old
- fDocumentListeners = newListeners;
- }
- }
- }
-
- /*
- * @see org.eclipse.jface.text.IDocument#addDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
- *
- * Registers the document partitioning listener with the document. After
- * registration the IDocumentPartitioningListener is informed about each
- * partition change cause by a document manipulation. If a document
- * partitioning listener is also a document listener, the following
- * notification sequence is guaranteed if a document manipulation changes
- * the document partitioning: 1)
- * listener.documentAboutToBeChanged(DocumentEvent); 2)
- * listener.documentPartitioningChanged(); 3)
- * listener.documentChanged(DocumentEvent); If the listener is already
- * registered nothing happens.
- *
- * @see IDocumentPartitioningListener
- */
-
- public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) {
- synchronized (listenerLock) {
-
- Assert.isNotNull(listener);
- if (fDocumentPartitioningListeners == null) {
- fDocumentPartitioningListeners = new ArrayList(1);
- }
- if (!fDocumentPartitioningListeners.contains(listener))
- fDocumentPartitioningListeners.add(listener);
- }
- }
-
- /**
- * Adds the position to the document's default position category. The
- * default category must be specified by the implementer. A position that
- * has been added to a position category is updated at each change applied
- * to the document.
- *
- * @exception BadLocationException
- * If position is not a valid range in the document
- */
- public void addPosition(Position position) throws BadLocationException {
- getPositionManager().addPosition(position);
- }
-
- /**
- * @see IDocument#addPosition
- * @exception BadLocationException
- * If position is not a valid range in the document
- * @exception BadPositionCategoryException
- * If the category is not defined for the document
- */
- public void addPosition(String category, Position position) throws BadLocationException, BadPositionCategoryException {
- getPositionManager().addPosition(category, position);
- }
-
- /**
- * @see IDocument#addPositionCategory
- */
- public void addPositionCategory(String category) {
- internal_addPositionCategory(category);
- }
-
- /**
- * @see IDocument#addPositionUpdater
- */
- public void addPositionUpdater(IPositionUpdater updater) {
- internal_addPositionUpdater(updater);
- }
-
- /**
- * Adds the given document listener as one which is notified before those
- * document listeners added with <code>addDocumentListener</code> are
- * notified. If the given listener is also registered using
- * <code>addDocumentListener</code> it will be notified twice. If the
- * listener is already registered nothing happens.
- * <p>
- *
- * This method is not for public use, it may only be called by
- * implementers of <code>IDocumentAdapter</code> and only if those
- * implementers need to implement <code>IDocumentListener</code>.
- *
- * @param documentAdapter
- * the listener to be added as prenotified document listener
- */
- public void addPrenotifiedDocumentListener(IDocumentListener documentAdapter) {
- synchronized (listenerLock) {
-
- if (fPrenotifiedDocumentListeners != null) {
- int previousSize = fPrenotifiedDocumentListeners.length;
- IDocumentListener[] listeners = new IDocumentListener[previousSize + 1];
- System.arraycopy(fPrenotifiedDocumentListeners, 0, listeners, 0, previousSize);
- listeners[previousSize] = documentAdapter;
- fPrenotifiedDocumentListeners = listeners;
- }
- else {
- fPrenotifiedDocumentListeners = new IDocumentListener[1];
- fPrenotifiedDocumentListeners[0] = documentAdapter;
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.CharSequence#charAt(int)
- */
- public char charAt(int arg0) {
- try {
- return getChar(0);
- }
- catch (BadLocationException e) {
- throw new IndexOutOfBoundsException();
- }
- }
-
- /**
- * This form of the API removes all read only positions, as should be done
- * we 'setText' is called. Note: an alternative algorithm may simply
- * remove the category (and it would get added back in later, if/when
- * readonly regions added.
- */
- private void clearReadOnly() {
- Position[] positions = null;
- try {
- positions = getPositions(READ_ONLY_REGIONS_CATEGORY);
- }
- catch (BadPositionCategoryException e) {
- Logger.logException("program error: should never occur", e); //$NON-NLS-1$
- }
- for (int i = 0; i < positions.length; i++) {
- Position position = positions[i];
- // note we don't fire the "about to change" or "changed" events,
- // since presumably, text is all going away and being replaced
- // anyway.
- position.delete();
- }
- }
-
-
- public void clearReadOnly(int startOffset, int length) {
- // TODO DW I still need to implement smarter algorithm that
- // adust existing RO regions, if needed. For now, I'll just
- // remove any that overlap.
- try {
- Position[] positions = getPositions(READ_ONLY_REGIONS_CATEGORY);
- for (int i = 0; i < positions.length; i++) {
- Position position = positions[i];
- if (position.overlapsWith(startOffset, length)) {
- String effectedText = this.get(startOffset, length);
- // fDocumentEvent = new DocumentEvent(this, startOffset,
- // length, effectedText);
- fireReadOnlyAboutToBeChanged();
- position.delete();
- NoChangeEvent noChangeEvent = new NoChangeEvent(this, null, effectedText, startOffset, length);
- noChangeEvent.reason = NoChangeEvent.READ_ONLY_STATE_CHANGE;
- fireReadOnlyStructuredDocumentEvent(noChangeEvent);
- }
- }
- }
- catch (BadPositionCategoryException e) {
- // just means no readonly regions been defined yet
- // so nothing to do.
- }
- }
-
- /**
- * Computes the index at which a <code>Position</code> with the
- * specified offset would be inserted into the given category. As the
- * ordering inside a category only depends on the offset, the index must
- * be choosen to be the first of all positions with the same offset.
- *
- * @param category
- * the category in which would be added
- * @param offset
- * the position offset to be considered
- * @return the index into the category
- * @exception BadLocationException
- * if offset is invalid in this document
- * @exception BadPositionCategoryException
- * if category is undefined in this document
- */
- public int computeIndexInCategory(String category, int offset) throws org.eclipse.jface.text.BadPositionCategoryException, org.eclipse.jface.text.BadLocationException {
- return getPositionManager().computeIndexInCategory(category, offset);
- }
-
- /**
- * Computes the number of lines in the given text. For a given implementer
- * of this interface this method returns the same result as
- * <code>set(text); getNumberOfLines()</code>.
- *
- * @param text
- * the text whose number of lines should be computed
- * @return the number of lines in the given text
- */
- public int computeNumberOfLines(String text) {
- return getTracker().computeNumberOfLines(text);
- }
-
- /**
- * Computes the partitioning of the given document range using the
- * document's partitioner.
- *
- * @param offset
- * the document offset at which the range starts
- * @param length
- * the length of the document range
- * @return a specification of the range's partitioning
- * @throws BadLocationException
- * @throws BadPartitioningException
- */
- public ITypedRegion[] computePartitioning(int offset, int length) throws BadLocationException {
- ITypedRegion[] typedRegions = null;
- try {
- typedRegions = computePartitioning(IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING, offset, length, false);
- }
- catch (BadPartitioningException e) {
- // impossible in this context
- throw new Error(e);
- }
- if (typedRegions == null) {
- typedRegions = new ITypedRegion[0];
- }
- return typedRegions;
- }
-
-
- public ITypedRegion[] computePartitioning(String partitioning, int offset, int length, boolean includeZeroLengthPartitions) throws BadLocationException, BadPartitioningException {
- if ((0 > offset) || (0 > length) || (offset + length > getLength()))
- throw new BadLocationException();
-
- IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
-
- if (partitioner instanceof IDocumentPartitionerExtension2)
- return ((IDocumentPartitionerExtension2) partitioner).computePartitioning(offset, length, includeZeroLengthPartitions);
- else if (partitioner != null)
- return partitioner.computePartitioning(offset, length);
- else if (IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING.equals(partitioning))
- return new TypedRegion[]{new TypedRegion(offset, length, DEFAULT_CONTENT_TYPE)};
- else
- throw new BadPartitioningException();
- }
-
- /**
- * @see IDocument#containsPosition
- */
- public boolean containsPosition(String category, int offset, int length) {
- return getPositionManager().containsPosition(category, offset, length);
- }
-
- /**
- * @see IDocument#containsPositionCategory
- */
- public boolean containsPositionCategory(String category) {
- return getPositionManager().containsPositionCategory(category);
- }
-
- public boolean containsReadOnly(int startOffset, int length) {
- boolean result = false;
- try {
- Position[] positions = getPositions(READ_ONLY_REGIONS_CATEGORY);
- for (int i = 0; i < positions.length; i++) {
- Position position = positions[i];
- if (position.overlapsWith(startOffset, length)) {
- result = true;
- break;
- }
- }
- }
- catch (BadPositionCategoryException e) {
- // just means no readonly regions been defined yet
- // so obviously false
- result = false;
- }
- return result;
- }
-
- private void executePostNotificationChanges() {
- if (fStoppedCount > 0)
- return;
- while (fPostNotificationChanges != null) {
- List changes = fPostNotificationChanges;
- fPostNotificationChanges = null;
- Iterator e = changes.iterator();
- while (e.hasNext()) {
- RegisteredReplace replace = (RegisteredReplace) e.next();
- replace.fReplace.perform(this, replace.fOwner);
- }
- }
- }
-
- private void fireDocumentAboutToChanged() {
- // most DocumentAboutToBeChanged listeners do not anticipate
- // DocumentEvent == null. So make sure documentEvent is not
- // null. (this should never happen, yet it does sometimes)
- if (fDocumentEvent == null) {
- fDocumentEvent = new NullDocumentEvent();
- }
-
- _fireStructuredDocumentAboutToChange(fStructuredDocumentAboutToChangeListeners);
- // Note: the docEvent is created in replaceText API! (or set Text)
- _fireDocumentAboutToChange(fPrenotifiedDocumentListeners);
- notifyDocumentPartitionersAboutToChange(fDocumentEvent);
- _fireDocumentAboutToChange(fDocumentListeners);
- }
-
- /**
- * Fires the document partitioning changed notification to all registered
- * document partitioning listeners. Uses a robust iterator.
- *
- * @param event
- * the document partitioning changed event
- *
- * @see IDocumentPartitioningListenerExtension2
- */
- protected void fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent event) {
- if (fDocumentPartitioningListeners == null || fDocumentPartitioningListeners.size() == 0)
- return;
-
- List list = new ArrayList(fDocumentPartitioningListeners);
- Iterator e = list.iterator();
- while (e.hasNext()) {
- IDocumentPartitioningListener l = (IDocumentPartitioningListener) e.next();
- if (l instanceof IDocumentPartitioningListenerExtension2) {
- IDocumentPartitioningListenerExtension2 extension2 = (IDocumentPartitioningListenerExtension2) l;
- extension2.documentPartitioningChanged(event);
- }
- else if (l instanceof IDocumentPartitioningListenerExtension) {
- IDocumentPartitioningListenerExtension extension = (IDocumentPartitioningListenerExtension) l;
- extension.documentPartitioningChanged(this, event.getCoverage());
- }
- else {
- l.documentPartitioningChanged(this);
- }
- }
-
- }
-
- private void fireReadOnlyAboutToBeChanged() {
- _fireStructuredDocumentAboutToChange(fStructuredDocumentAboutToChangeListeners);
- // Note: the docEvent is created in replaceText API! (or set Text)
- // _fireDocumentAboutToChange(fPrenotifiedDocumentListeners);
- // _fireDocumentAboutToChange(fDocumentListeners);
- }
-
- private void fireReadOnlyStructuredDocumentEvent(NoChangeEvent event) {
- _fireEvent(fStructuredDocumentChangingListeners, event);
- _fireEvent(fStructuredDocumentChangedListeners, event);
- // _fireDocumentChanged(fPrenotifiedDocumentListeners, event);
- // _fireDocumentChanged(fDocumentListeners, event);
- // _clearDocumentEvent();
- }
-
- private void fireStructuredDocumentEvent(NoChangeEvent event) {
- _fireEvent(fStructuredDocumentChangingListeners, event);
- _fireEvent(fStructuredDocumentChangedListeners, event);
- _fireDocumentChanged(fPrenotifiedDocumentListeners, event);
- notifyDocumentPartitionersDocumentChanged(event);
- _fireDocumentChanged(fDocumentListeners, event);
- _clearDocumentEvent();
- }
-
- private void fireStructuredDocumentEvent(RegionChangedEvent event) {
- _fireEvent(fStructuredDocumentChangingListeners, event);
- _fireEvent(fStructuredDocumentChangedListeners, event);
- _fireDocumentChanged(fPrenotifiedDocumentListeners, event);
- notifyDocumentPartitionersDocumentChanged(event);
- _fireDocumentChanged(fDocumentListeners, event);
- _clearDocumentEvent();
- }
-
- private void fireStructuredDocumentEvent(RegionsReplacedEvent event) {
- _fireEvent(fStructuredDocumentChangingListeners, event);
- _fireEvent(fStructuredDocumentChangedListeners, event);
- _fireDocumentChanged(fPrenotifiedDocumentListeners, event);
- notifyDocumentPartitionersDocumentChanged(event);
- _fireDocumentChanged(fDocumentListeners, event);
- _clearDocumentEvent();
- }
-
- private void fireStructuredDocumentEvent(StructuredDocumentRegionsReplacedEvent event) {
- _fireEvent(fStructuredDocumentChangingListeners, event);
- _fireEvent(fStructuredDocumentChangedListeners, event);
- _fireDocumentChanged(fPrenotifiedDocumentListeners, event);
- notifyDocumentPartitionersDocumentChanged(event);
- _fireDocumentChanged(fDocumentListeners, event);
- _clearDocumentEvent();
- }
-
- /**
- * Returns the document's complete text.
- */
- public String get() {
- return getStore().get(0, getLength());
- }
-
- /**
- * Returns length characters from the document's text starting from the
- * specified position.
- *
- * @throws BadLocationException
- *
- * @exception BadLocationException
- * If the range is not valid in the document
- */
- public String get(int offset, int length) {
- String result = null;
- int myLength = getLength();
- if (0 > offset)
- offset = 0;
- if (0 > length)
- length = 0;
- if (offset + length > myLength) {
- // first try adjusting length to fit
- int lessLength = myLength - offset;
- if ((lessLength >= 0) && (offset + lessLength == myLength)) {
- length = lessLength;
- }
- else {
- // second, try offset
- int moreOffset = myLength - length;
- if ((moreOffset >= 0) && (moreOffset + length == myLength)) {
- offset = moreOffset;
- }
- else {
- // can happen if myLength is 0.
- // no adjustment possible.
- result = new String();
- }
- }
-
- }
- if (result == null) {
- result = getStore().get(offset, length);
- }
- return result;
- }
-
- public Object getAdapter(Class adapter) {
- return Platform.getAdapterManager().getAdapter(this, adapter);
- }
-
- IStructuredDocumentRegion getCachedDocumentRegion() {
- IStructuredDocumentRegion result = null;
- if (USE_LOCAL_THREAD) {
- result = fCurrentDocumnetRegionCache.get();
- }
- else {
- result = cachedDocumentRegion;
- }
- return result;
- }
-
- /**
- * @see IDocument#getChar
- * @exception BadLocationException
- * If position is not a valid range in the document
- */
- public char getChar(int pos) throws BadLocationException {
- char result = 0x00;
- try {
- result = getStore().get(pos);
- }
- catch (IndexOutOfBoundsException e) {
- throw new BadLocationException(e.getLocalizedMessage());
- }
- return result;
- }
-
- /**
- * Returns the type of the document partition containing the given
- * character position.
- */
- public String getContentType(int offset) throws BadLocationException {
- return getDocumentPartitioner().getContentType(offset);
- }
-
-
- public String getContentType(String partitioning, int offset, boolean preferOpenPartitions) throws BadLocationException, BadPartitioningException {
- if ((0 > offset) || (offset > getLength()))
- throw new BadLocationException();
-
- IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
-
- if (partitioner instanceof IDocumentPartitionerExtension2)
- return ((IDocumentPartitionerExtension2) partitioner).getContentType(offset, preferOpenPartitions);
- else if (partitioner != null)
- return partitioner.getContentType(offset);
- else if (IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING.equals(partitioning))
- return DEFAULT_CONTENT_TYPE;
- else
- throw new BadPartitioningException();
- }
-
- /*
- * This method can be used when this class implements IDocumentExtension4.
- *
- * @see org.eclipse.jface.text.IDocumentExtension4#getDefaultLineDelimiter()
- */
- private String getDefaultLineDelimiter() {
- // specific preferred line delimiter
- if (preferedDelimiter != null)
- return preferedDelimiter;
-
-
- // no line delimiter has been used so just use platform's default
- String lineDelimiter = null;
- String sysLineDelimiter = PlatformLineDelimiter;
- String[] delimiters = getLegalLineDelimiters();
- Assert.isTrue(delimiters.length > 0);
- for (int i = 0; i < delimiters.length; i++) {
- if (delimiters[i].equals(sysLineDelimiter)) {
- lineDelimiter = sysLineDelimiter;
- break;
- }
- }
-
- // no platform default so just use first legal delimiter
- if (lineDelimiter == null)
- lineDelimiter = delimiters[0];
-
- return lineDelimiter;
- }
-
- /**
- * Returns the document's partitioner.
- *
- * @see IDocumentPartitioner
- */
- public IDocumentPartitioner getDocumentPartitioner() {
- return getDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING);
- }
-
-
- public IDocumentPartitioner getDocumentPartitioner(String partitioning) {
-
- IDocumentPartitioner documentPartitioner = null;
- if (fDocumentPartitioners != null) {
- documentPartitioner = (IDocumentPartitioner) fDocumentPartitioners.get(partitioning);
- }
- return documentPartitioner;
- }
-
- public EncodingMemento getEncodingMemento() {
- return encodingMemento;
- }
-
- public IStructuredDocumentRegion getFirstStructuredDocumentRegion() {
- // should we update cachedNode?
- // We should to keep consistent philosophy of remembering last
- // requested position,
- // for efficiency.
- setCachedDocumentRegion(firstDocumentRegion);
- return firstDocumentRegion;
- }
-
- public IStructuredDocumentRegion getLastStructuredDocumentRegion() {
- // should we update cachedNode?
- // We should to keep consistent philosophy of remembering last
- // requested position,
- // for efficiency.
- setCachedDocumentRegion(lastDocumentRegion);
- return lastDocumentRegion;
- }
-
- /*
- * -------------------------- partitions
- * ----------------------------------
- */
- public String[] getLegalContentTypes() {
- String[] result = null;
- try {
- result = getLegalContentTypes(IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING);
- }
- catch (BadPartitioningException e) {
- // impossible in this context
- throw new Error(e);
- }
- return result;
- }
-
- public String[] getLegalContentTypes(String partitioning) throws BadPartitioningException {
- IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
- if (partitioner != null)
- return partitioner.getLegalContentTypes();
- if (IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING.equals(partitioning))
- return new String[]{DEFAULT_CONTENT_TYPE};
- throw new BadPartitioningException();
- }
-
- /*
- * ------------------ line delimiter conversion
- * ---------------------------
- */
- public String[] getLegalLineDelimiters() {
- return getTracker().getLegalLineDelimiters();
- }
-
- /**
- * @see IDocument#getLength
- */
- public int getLength() {
- return getStore().getLength();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument#getLineDelimiter()
- */
- public String getLineDelimiter() {
- return getDefaultLineDelimiter();
- }
-
- /**
- * Returns the line delimiter of that line
- *
- * @exception BadLocationException
- * If the line number is invalid in the document
- */
- public String getLineDelimiter(int line) throws org.eclipse.jface.text.BadLocationException {
- return getTracker().getLineDelimiter(line);
- }
-
- /**
- * Returns a description of the specified line. The line is described by
- * its offset and its length excluding the line's delimiter.
- *
- * @param line
- * the line of interest
- * @return a line description
- * @exception BadLocationException
- * if the line number is invalid in this document
- */
- public org.eclipse.jface.text.IRegion getLineInformation(int line) throws org.eclipse.jface.text.BadLocationException {
- return getTracker().getLineInformation(line);
- }
-
- /**
- * Returns a description of the line at the given offset. The description
- * contains the offset and the length of the line excluding the line's
- * delimiter.
- *
- * @param offset
- * the offset whose line should be described
- * @return a region describing the line
- * @exception BadLocationException
- * if offset is invalid in this document
- */
- public org.eclipse.jface.text.IRegion getLineInformationOfOffset(int offset) throws org.eclipse.jface.text.BadLocationException {
- return getTracker().getLineInformationOfOffset(offset);
- }
-
- /*
- * ---------------------- line information
- * --------------------------------
- */
- public int getLineLength(int line) throws org.eclipse.jface.text.BadLocationException {
- return getTracker().getLineLength(line);
- }
-
- /**
- * Determines the offset of the first character of the given line.
- *
- * @param line
- * the line of interest
- * @return the document offset
- * @exception BadLocationException
- * if the line number is invalid in this document
- */
- public int getLineOffset(int line) throws org.eclipse.jface.text.BadLocationException {
- return getTracker().getLineOffset(line);
- }
-
- public int getLineOfOffset(int offset) {
- int result = -1;
- try {
- result = getTracker().getLineNumberOfOffset(offset);
- }
- catch (BadLocationException e) {
- if (Logger.DEBUG_DOCUMENT)
- Logger.log(Logger.INFO, "Dev. Program Info Only: IStructuredDocument::getLineOfOffset: offset out of range, zero assumed. offset = " + offset, e); //$NON-NLS-1$ //$NON-NLS-2$
- result = 0;
- }
- return result;
- }
-
- /**
- * Returns the number of lines in this document
- *
- * @return the number of lines in this document
- */
- public int getNumberOfLines() {
- return getTracker().getNumberOfLines();
- }
-
- /**
- * Returns the number of lines which are occupied by a given text range.
- *
- * @param offset
- * the offset of the specified text range
- * @param length
- * the length of the specified text range
- * @return the number of lines occupied by the specified range
- * @exception BadLocationException
- * if specified range is invalid in this tracker
- */
- public int getNumberOfLines(int offset, int length) throws org.eclipse.jface.text.BadLocationException {
- return getTracker().getNumberOfLines(offset, length);
- }
-
- /**
- * This is public, temporarily, for use by tag lib classes.
- */
- public RegionParser getParser() {
- if (fParser == null) {
- throw new IllegalStateException("IStructuredDocument::getParser. Parser needs to be set before use"); //$NON-NLS-1$
- }
- return fParser;
- }
-
- /**
- * Returns the document partition in which the position is located. The
- * partition is specified as typed region.
- */
- public ITypedRegion getPartition(int offset) throws BadLocationException {
- ITypedRegion partition = null;
- try {
- partition = getPartition(IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING, offset, false);
- }
- catch (BadPartitioningException e) {
- throw new Error(e);
- }
- if (partition == null) {
- throw new Error();
- }
- return partition;
- }
-
-
- public ITypedRegion getPartition(String partitioning, int offset, boolean preferOpenPartitions) throws BadLocationException, BadPartitioningException {
- if ((0 > offset) || (offset > getLength()))
- throw new BadLocationException();
- ITypedRegion result = null;
-
- IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
-
- if (partitioner instanceof IDocumentPartitionerExtension2) {
- result = ((IDocumentPartitionerExtension2) partitioner).getPartition(offset, preferOpenPartitions);
- }
- else if (partitioner != null) {
- result = partitioner.getPartition(offset);
- }
- else if (IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING.equals(partitioning)) {
- result = new TypedRegion(0, getLength(), DEFAULT_CONTENT_TYPE);
- }
- else
- throw new BadPartitioningException();
- return result;
- }
-
-
- public String[] getPartitionings() {
- if (fDocumentPartitioners == null)
- return new String[0];
- String[] partitionings = new String[fDocumentPartitioners.size()];
- fDocumentPartitioners.keySet().toArray(partitionings);
- return partitionings;
- }
-
- /**
- * Returns all position categories added to this document.
- */
- public String[] getPositionCategories() {
- return getPositionManager().getPositionCategories();
- }
-
- /**
- * @return Returns the positionManager.
- */
- private GenericPositionManager getPositionManager() {
- if (fPositionManager == null) {
- fPositionManager = new GenericPositionManager(this);
- }
- return fPositionManager;
- }
-
- /**
- * Returns all Positions of the given position category.
- *
- * @exception BadPositionCategoryException
- * If category is not defined for the document
- */
- public Position[] getPositions(String category) throws org.eclipse.jface.text.BadPositionCategoryException {
- return getPositionManager().getPositions(category);
- }
-
- /**
- * @see IDocument#getPositionUpdaters
- */
- public IPositionUpdater[] getPositionUpdaters() {
- return getPositionManager().getPositionUpdaters();
- }
-
- /**
- * This method can return null, which is the case if the offset is just
- * before or just after the existing text. Compare with
- * getNodeAtCharacterOffset.
- */
- public IStructuredDocumentRegion getRegionAtCharacterOffset(int offset) {
- IStructuredDocumentRegion result = null;
-
- // FIXME: need to synch on 'cachedRegion' (but since that's a
- // constantly changing object, we
- // can't, so need to add a "region_lock" object, and use it here, and
- // in re-parser.
- // Oh, and need to make sure, after synch, that the region is not
- // deleted, and if so, I guess go back
- // to the beginning!
-
- // cached node can be null when document is empty
- IStructuredDocumentRegion potentialCachedRegion = getCachedDocumentRegion();
- if (potentialCachedRegion != null) {
-
- //
-
- // if we already have the right node, return that.
- if (potentialCachedRegion.containsOffset(offset)) {
- result = potentialCachedRegion;
- }
- else {
- // first, find out what direction to go, relative to
- // cachedNode.
- // negative means "towards the front" of the file,
- // postitive
- // means
- // towards the end.
- int direction = offset - potentialCachedRegion.getStart();
- if (direction < 0) {
- // search towards beginning
- while (!potentialCachedRegion.containsOffset(offset)) {
- IStructuredDocumentRegion tempNode = potentialCachedRegion.getPrevious();
- if (tempNode == null) {
- break;
- }
- else {
- potentialCachedRegion = tempNode;
- }
- }
- }
- else {
- // search towards end
- // There is a legitamat condition where the
- // offset will not be contained in any node,
- // which is if the offset is just past the last
- // character of text.
- // And, we must gaurd against setting cachedNode to
- // null!
- while (!potentialCachedRegion.containsOffset(offset)) {
- IStructuredDocumentRegion tempNode = potentialCachedRegion.getNext();
- if (tempNode == null)
- break;
- else
- potentialCachedRegion = tempNode;
- }
- }
- }
- result = potentialCachedRegion;
- }
- // just to be doubly sure we never assign null to an already valid
- // cachedRegion.
- // I believe any time 'result' is null at this point, that just means
- // we have an
- // empty document, and the cachedRegion is already null, but we check
- // and print
- // warning, just so during development we be sure we never accidently
- // break this assumption.
- if (result != null)
- setCachedDocumentRegion(result);
- else if (getCachedDocumentRegion() != null) {
- throw new IllegalStateException("Program Error: no region could be found to cache, but cache was non null. Indicates corrupted model or region list"); //$NON-NLS-1$
- }
-
- return result;
- }
-
- public IStructuredDocumentRegionList getRegionList() {
- CoreNodeList result = null;
- if (getCachedDocumentRegion() == null)
- result = new CoreNodeList(null);
- else
- result = new CoreNodeList(getFirstStructuredDocumentRegion());
-
- return result;
- }
-
-
- public IStructuredDocumentRegion[] getStructuredDocumentRegions() {
- return getStructuredDocumentRegions(0, getLength());
- }
-
- /**
- * <p>
- * In the case of 0 length, the <code>IStructuredDocumentRegion</code>
- * at the character offset is returened. In other words, the region to the
- * right of the caret is returned. except for at the end of the document,
- * then the last region is returned.
- * </p>
- * <p>
- * Otherwise all the regions "inbetween" the indicated range are returned,
- * including the regions which overlap the region.
- * </p>
- *
- * <br>
- * eg.
- * <p>
- * <br>
- * eg.
- *
- * <pre>
- * &lt;html&gt;[&lt;head&gt;&lt;/head&gt;]&lt;/html&gt; returns &lt;head&gt;,&lt;/head&gt;
- * </pre>
- * <pre>
- * &lt;ht[ml&gt;&lt;head&gt;&lt;/he]ad&gt;&lt;/html&gt; returns &lt;html&gt;,&lt;head&gt;,&lt;/head&gt;
- * </pre>
- *
- * <pre>
- * &lt;html&gt;[&lt;head&gt;&lt;/head&gt;]&lt;/html&gt; returns &lt;head&gt;,&lt;/head&gt;
- * </pre>
- * <pre>
- * &lt;ht[ml&gt;&lt;head&gt;&lt;/he]ad&gt;&lt;/html&gt; returns &lt;html&gt;,&lt;head&gt;,&lt;/head&gt;
- * </pre>
- *
- * </p>
- */
- public IStructuredDocumentRegion[] getStructuredDocumentRegions(int start, int length) {
-
- if (length < 0)
- throw new IllegalArgumentException("can't have negative length"); //$NON-NLS-1$
-
- // this will make the right edge of the range point into the selection
- // eg. <html>[<head></head>]</html>
- // will return <head>,</head> instead of <head>,</head>,</html>
- if (length > 0)
- length--;
-
- List results = new ArrayList();
-
- // start thread safe block
- try {
- acquireLock();
-
- IStructuredDocumentRegion currentRegion = getRegionAtCharacterOffset(start);
- IStructuredDocumentRegion endRegion = getRegionAtCharacterOffset(start + length);
- while (currentRegion != endRegion && currentRegion != null) {
- results.add(currentRegion);
- currentRegion = currentRegion.getNext();
- }
- // need to add that last end region
- // can be null in the case of an empty document
- if (endRegion != null)
- results.add(endRegion);
- }
- finally {
- releaseLock();
- }
- // end thread safe block
-
- return (IStructuredDocumentRegion[]) results.toArray(new IStructuredDocumentRegion[results.size()]);
- }
-
- /**
- * was made public for easier testing. Normally should never be used by
- * client codes.
- */
- public IStructuredTextReParser getReParser() {
- if (fReParser == null) {
- fReParser = new StructuredDocumentReParser();
- fReParser.setStructuredDocument(this);
- }
- return fReParser;
- }
-
- private ITextStore getStore() {
- Assert.isNotNull(fStore);
- return fStore;
- }
-
- public String getText() {
- String result = get();
- return result;
- }
-
- /**
- * Returns the document's line tracker. Assumes that the document has been
- * initialized with a line tracker.
- *
- * @return the document's line tracker
- */
- private ILineTracker getTracker() {
- Assert.isNotNull(fTracker);
- return fTracker;
- }
-
- public IStructuredTextUndoManager getUndoManager() {
- if (fUndoManager == null) {
- fUndoManager = new StructuredTextUndoManager();
- }
- return fUndoManager;
- }
-
- void initializeFirstAndLastDocumentRegion() {
- // cached Node must also be first, at the initial point. Only
- // valid
- // to call this method right after the first parse.
- //
- // when starting afresh, our cachedNode should be our firstNode,
- // so be sure to initialize the firstNode
- firstDocumentRegion = getCachedDocumentRegion();
- // be sure to use 'getNext' for this initial finding of the last
- // node,
- // since the implementation of node.getLastNode may simply call
- // structuredDocument.getLastStructuredDocumentRegion!
- IStructuredDocumentRegion aNode = firstDocumentRegion;
- if (aNode == null) {
- // defect 254607: to handle empty documents right, if
- // firstnode is
- // null, make sure last node is null too
- lastDocumentRegion = null;
- }
- else {
- while (aNode != null) {
- lastDocumentRegion = aNode;
- aNode = aNode.getNext();
- }
- }
- }
-
- /**
- * @see IDocument#insertPositionUpdater
- */
- public void insertPositionUpdater(IPositionUpdater updater, int index) {
- getPositionManager().insertPositionUpdater(updater, index);
- }
-
- private void internal_addPositionCategory(String category) {
- getPositionManager().addPositionCategory(category);
- }
-
- private void internal_addPositionUpdater(IPositionUpdater updater) {
- getPositionManager().addPositionUpdater(updater);
- }
-
- private void internal_setParser(RegionParser newParser) {
- fParser = newParser;
- }
-
- String internalGet(int offset, int length) {
- String result = null;
- // int myLength = getLength();
- // if ((0 > offset) || (0 > length) || (offset + length > myLength))
- // throw new BadLocationException();
- result = getStore().get(offset, length);
- return result;
- }
-
- /**
- * @param requester
- * @param start
- * @param replacementLength
- * @param changes
- * @return
- */
- private StructuredDocumentEvent internalReplaceText(Object requester, int start, int replacementLength, String changes, boolean ignoreReadOnlySettings) {
- StructuredDocumentEvent result = null;
-
- stopPostNotificationProcessing();
- if (changes == null)
- changes = ""; //$NON-NLS-1$
- //
- if (Debug.debugStructuredDocument)
- System.out.println(getClass().getName() + "::replaceText(" + start + "," + replacementLength + "," + changes + ")"); //$NON-NLS-4$//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
- if (Debug.perfTestStructuredDocumentOnly || Debug.perfTest || Debug.perfTestRawStructuredDocumentOnly) {
- startStreamTime = System.currentTimeMillis();
- }
- try {
- // Note: event must be computed before 'fire' method called
- fDocumentEvent = new DocumentEvent(this, start, replacementLength, changes);
- fireDocumentAboutToChanged();
-
- try {
- acquireLock();
-
- if (!ignoreReadOnlySettings && (containsReadOnly(start, replacementLength))) {
- NoChangeEvent noChangeEvent = new NoChangeEvent(this, requester, changes, start, replacementLength);
- noChangeEvent.reason = NoChangeEvent.READ_ONLY_STATE_CHANGE;
- result = noChangeEvent;
- }
- else {
- result = updateModel(requester, start, replacementLength, changes);
- }
- }
- finally {
- releaseLock();
- }
-
-
- if (Debug.perfTestRawStructuredDocumentOnly || Debug.perfTest) {
- long stopStreamTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t Time for IStructuredDocument raw replaceText: " + (stopStreamTime - startStreamTime)); //$NON-NLS-1$
- }
- if (Debug.debugStructuredDocument) {
- System.out.println("event type returned by replaceTextWithNoDebuggingThread: " + result); //$NON-NLS-1$
- }
- }
- finally {
- // FUTURE_TO_DO: implement callback mechanism? to avoid instanceof
- // and casting
- // fireStructuredDocumentEvent must be called in order to end
- // documentAboutToBeChanged state
- if (result == null) {
- // result should not be null, but if an exception was thrown,
- // it will be
- // so send a noChangeEvent and log the problem
- NoChangeEvent noChangeEvent = new NoChangeEvent(this, requester, changes, start, replacementLength);
- noChangeEvent.reason = NoChangeEvent.NO_EVENT;
- fireStructuredDocumentEvent(noChangeEvent);
- Logger.log(Logger.ERROR, "Program Error: invalid structured document event"); //$NON-NLS-1$
- }
- else {
- if (result instanceof RegionChangedEvent) {
- fireStructuredDocumentEvent((RegionChangedEvent) result);
- }
- else {
- if (result instanceof RegionsReplacedEvent) {
- fireStructuredDocumentEvent((RegionsReplacedEvent) result);
- }
- else {
- if (result instanceof StructuredDocumentRegionsReplacedEvent) {
- // probably more efficient to mark old regions as
- // 'deleted' at the time
- // that are determined to be deleted, but I'll do
- // here
- // in then central spot
- // for programming ease.
- updateDeletedFields((StructuredDocumentRegionsReplacedEvent) result);
- fireStructuredDocumentEvent((StructuredDocumentRegionsReplacedEvent) result);
- }
- else {
- if (result instanceof NoChangeEvent) {
- fireStructuredDocumentEvent((NoChangeEvent) result);
- }
- else {
- // if here, this means a new event was created
- // and not handled here
- // just send a no event until this issue is
- // resolved.
- NoChangeEvent noChangeEvent = new NoChangeEvent(this, requester, changes, start, replacementLength);
- noChangeEvent.reason = NoChangeEvent.NO_EVENT;
- fireStructuredDocumentEvent(noChangeEvent);
- Logger.log(Logger.INFO, "Program Error: unexpected structured document event: " + result); //$NON-NLS-1$
- }
- }
- }
- }
- }
- if (Debug.perfTest || Debug.perfTestStructuredDocumentOnly) {
- long stopStreamTime = System.currentTimeMillis();
- System.out.println("\n\t\t\t\t Total Time for IStructuredDocument event signaling/processing in replaceText: " + (stopStreamTime - startStreamTime)); //$NON-NLS-1$
- }
- resumePostNotificationProcessing();
- }
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.CharSequence#length()
- */
- public int length() {
-
- return getLength();
- }
-
- public void makeReadOnly(int startOffset, int length) {
-
- // doesn't make sense to have a readonly region of 0 length,
- // so we'll ignore those requests
- if (length <= 0)
- return;
- String affectedText = this.get(startOffset, length);
- // a document event for "read only" change ... must
- // be followed by "no change" structuredDocument event
- // fDocumentEvent = new DocumentEvent(this, startOffset, length,
- // affectedText);
- fireReadOnlyAboutToBeChanged();
- // if (containsReadOnly(startOffset, length)) {
- // adjustReadOnlyRegions(startOffset, length);
- // } else {
- // we can blindly add category, since no harm done if already
- // exists.
- addPositionCategory(READ_ONLY_REGIONS_CATEGORY);
- Position newPosition = new Position(startOffset, length);
- try {
- addPosition(READ_ONLY_REGIONS_CATEGORY, newPosition);
- // FIXME: need to change API to pass in requester, so this event
- // can be
- // created correctly, instead of using null.
- NoChangeEvent noChangeEvent = new NoChangeEvent(this, null, affectedText, startOffset, length);
- noChangeEvent.reason = NoChangeEvent.READ_ONLY_STATE_CHANGE;
- fireReadOnlyStructuredDocumentEvent(noChangeEvent);
- }
- catch (BadLocationException e) {
- // for now, log and ignore. Perhaps later we
- // could adjust to handle some cases?
- Logger.logException(("could not create readonly region at " + startOffset + " to " + length), e); //$NON-NLS-1$ //$NON-NLS-2$
- }
- catch (BadPositionCategoryException e) {
- // should never occur, since we add category
- Logger.logException(e);
- }
- }
-
- public IStructuredDocument newInstance() {
- IStructuredDocument newInstance = StructuredDocumentFactory.getNewStructuredDocumentInstance(getParser().newInstance());
- ((BasicStructuredDocument) newInstance).setReParser(getReParser().newInstance());
- if (getDocumentPartitioner() instanceof StructuredTextPartitioner) {
- newInstance.setDocumentPartitioner(((StructuredTextPartitioner) getDocumentPartitioner()).newInstance());
- newInstance.getDocumentPartitioner().connect(newInstance);
- }
- newInstance.setLineDelimiter(getLineDelimiter());
- if (getEncodingMemento() != null) {
- newInstance.setEncodingMemento((EncodingMemento) getEncodingMemento().clone());
- }
- return newInstance;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.wst.sse.core.internal.text.IRegionComparible#regionMatches(int,
- * int, java.lang.String)
- */
- public boolean regionMatches(int offset, int length, String stringToCompare) {
- boolean result = false;
- ITextStore store = getStore();
- if (store instanceof IRegionComparible) {
- result = ((IRegionComparible) store).regionMatches(offset, length, stringToCompare);
- }
- else {
- result = get(offset, length).equals(stringToCompare);
- }
- return result;
- }
-
- public boolean regionMatchesIgnoreCase(int offset, int length, String stringToCompare) {
- boolean result = false;
- ITextStore store = getStore();
- if (store instanceof IRegionComparible) {
- result = ((IRegionComparible) store).regionMatchesIgnoreCase(offset, length, stringToCompare);
- }
- else {
- result = get(offset, length).equalsIgnoreCase(stringToCompare);
- }
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.text.IDocumentExtension#registerPostNotificationReplace(org.eclipse.jface.text.IDocumentListener,
- * org.eclipse.jface.text.IDocumentExtension.IReplace)
- */
- public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) {
- if (fAcceptPostNotificationReplaces) {
- if (fPostNotificationChanges == null)
- fPostNotificationChanges = new ArrayList(1);
- fPostNotificationChanges.add(new RegisteredReplace(owner, replace));
- }
- }
-
- protected void releaseLock() {
- // do nothing here in super class
- }
-
- public void removeDocumentAboutToChangeListener(IModelAboutToBeChangedListener listener) {
- synchronized (listenerLock) {
-
- if ((fStructuredDocumentAboutToChangeListeners != null) && (listener != null)) {
- // if its not in the listeners, we'll ignore the request
- if (Utilities.contains(fStructuredDocumentAboutToChangeListeners, listener)) {
- int oldSize = fStructuredDocumentAboutToChangeListeners.length;
- int newSize = oldSize - 1;
- Object[] newListeners = new Object[newSize];
- int index = 0;
- for (int i = 0; i < oldSize; i++) {
- if (fStructuredDocumentAboutToChangeListeners[i] == listener) { // ignore
- }
- else {
- // copy old to new if its not the one we are
- // removing
- newListeners[index++] = fStructuredDocumentAboutToChangeListeners[i];
- }
- }
- // now that we have a new array, let's switch it for the
- // old
- // one
- fStructuredDocumentAboutToChangeListeners = newListeners;
- }
- }
- }
- }
-
- /**
- * removeModelChangedListener method comment.
- */
- public void removeDocumentChangedListener(IStructuredDocumentListener listener) {
- synchronized (listenerLock) {
-
- if ((fStructuredDocumentChangedListeners != null) && (listener != null)) {
- // if its not in the listeners, we'll ignore the request
- if (Utilities.contains(fStructuredDocumentChangedListeners, listener)) {
- int oldSize = fStructuredDocumentChangedListeners.length;
- int newSize = oldSize - 1;
- Object[] newListeners = new Object[newSize];
- int index = 0;
- for (int i = 0; i < oldSize; i++) {
- if (fStructuredDocumentChangedListeners[i] == listener) { // ignore
- }
- else {
- // copy old to new if its not the one we are
- // removing
- newListeners[index++] = fStructuredDocumentChangedListeners[i];
- }
- }
- // now that we have a new array, let's switch it for the
- // old
- // one
- fStructuredDocumentChangedListeners = newListeners;
- }
- }
- }
- }
-
- public void removeDocumentChangingListener(IStructuredDocumentListener listener) {
- synchronized (listenerLock) {
-
- if ((fStructuredDocumentChangingListeners != null) && (listener != null)) {
- // if its not in the listeners, we'll ignore the request
- if (Utilities.contains(fStructuredDocumentChangingListeners, listener)) {
- int oldSize = fStructuredDocumentChangingListeners.length;
- int newSize = oldSize - 1;
- Object[] newListeners = new Object[newSize];
- int index = 0;
- for (int i = 0; i < oldSize; i++) {
- if (fStructuredDocumentChangingListeners[i] == listener) { // ignore
- }
- else {
- // copy old to new if its not the one we are
- // removing
- newListeners[index++] = fStructuredDocumentChangingListeners[i];
- }
- }
- // now that we have a new array, let's switch it for the
- // old
- // one
- fStructuredDocumentChangingListeners = newListeners;
- }
- }
- }
- }
-
- public void removeDocumentListener(IDocumentListener listener) {
- synchronized (listenerLock) {
-
- if ((fDocumentListeners != null) && (listener != null)) {
- // if its not in the listeners, we'll ignore the request
- if (Utilities.contains(fDocumentListeners, listener)) {
- int oldSize = fDocumentListeners.length;
- int newSize = oldSize - 1;
- IDocumentListener[] newListeners = new IDocumentListener[newSize];
- int index = 0;
- for (int i = 0; i < oldSize; i++) {
- if (fDocumentListeners[i] == listener) { // ignore
- }
- else {
- // copy old to new if its not the one we are
- // removing
- newListeners[index++] = fDocumentListeners[i];
- }
- }
- // now that we have a new array, let's switch it for the
- // old
- // one
- fDocumentListeners = newListeners;
- }
- }
- }
- }
-
- /*
- * @see org.eclipse.jface.text.IDocument#removeDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
- */
- public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) {
- synchronized (listenerLock) {
-
- Assert.isNotNull(listener);
- if (fDocumentPartitioningListeners != null)
- fDocumentPartitioningListeners.remove(listener);
- }
- }
-
- /**
- * Removes the given <code>Position</code> from the document's default
- * position category. The default position category is to be defined by
- * the implementers. If the position is not part of the document's default
- * category nothing happens.
- */
- public void removePosition(Position position) {
- getPositionManager().removePosition(position);
- }
-
- /**
- * @see IDocument#removePosition
- * @exception BadPositionCategoryException
- * If the category is not defined for the document
- */
- public void removePosition(String category, Position position) throws BadPositionCategoryException {
- getPositionManager().removePosition(category, position);
- }
-
- /**
- * @see IDocument#removePositionCategory
- * @exception BadPositionCategoryException
- * If the category is not defined for the document
- */
- public void removePositionCategory(String category) throws BadPositionCategoryException {
- getPositionManager().removePositionCategory(category);
- }
-
- /**
- * @see IDocument#removePositionUpdater
- */
- public void removePositionUpdater(IPositionUpdater updater) {
- getPositionManager().removePositionUpdater(updater);
- }
-
- /**
- * Removes the given document listener from teh document's list of
- * prenotified document listeners. If the listener is not registered with
- * the document nothing happens.
- * <p>
- *
- * This method is not for public use, it may only be called by
- * implementers of <code>IDocumentAdapter</code> and only if those
- * implementers need to implement <code>IDocumentListener</code>.
- *
- * @param documentAdapter
- * the listener to be removed
- *
- * @see #addPrenotifiedDocumentListener(IDocumentListener)
- */
- public void removePrenotifiedDocumentListener(org.eclipse.jface.text.IDocumentListener documentAdapter) {
- synchronized (listenerLock) {
-
- if (Utilities.contains(fPrenotifiedDocumentListeners, documentAdapter)) {
- int previousSize = fPrenotifiedDocumentListeners.length;
- if (previousSize > 1) {
- IDocumentListener[] listeners = new IDocumentListener[previousSize - 1];
- int previousIndex = 0;
- int newIndex = 0;
- while (previousIndex < previousSize) {
- if (fPrenotifiedDocumentListeners[previousIndex] != documentAdapter)
- listeners[newIndex++] = fPrenotifiedDocumentListeners[previousIndex];
- previousIndex++;
- }
- fPrenotifiedDocumentListeners = listeners;
- }
- else {
- fPrenotifiedDocumentListeners = null;
- }
- }
- }
- }
-
- /**
- * This method is for INTERNAL USE ONLY and is NOT API.
- *
- * Rebuilds the StructuredDocumentRegion chain from the existing text.
- * FileBuffer support does not allow clients to know the document's
- * location before the text contents are set.
- *
- * @see set(String)
- */
- public void reparse(Object requester) {
- stopPostNotificationProcessing();
- clearReadOnly();
-
- acquireLock();
- try {
- CharSequenceReader subSetTextStoreReader = new CharSequenceReader((CharSequence) getStore(), 0, getStore().getLength());
- resetParser(subSetTextStoreReader, 0);
- //
- setCachedDocumentRegion(getParser().getDocumentRegions());
- // when starting afresh, our cachedNode should be our firstNode,
- // so be sure to initialize the firstNode and lastNode
- initializeFirstAndLastDocumentRegion();
- StructuredDocumentRegionIterator.setParentDocument(getCachedDocumentRegion(), this);
- }
- finally {
- releaseLock();
- }
-
- resumePostNotificationProcessing();
- }
-
- /**
- * @see IDocument#replace
- * @exception BadLocationException
- * If position is not a valid range in the document
- */
- public void replace(int pos, int length, String string) throws BadLocationException {
- if (Debug.displayWarnings) {
- System.out.println("Note: IStructuredDocument::replace(int, int, String) .... its better to use replaceText(source, string, int, int) API for structuredDocument updates"); //$NON-NLS-1$
- }
- replaceText(this, pos, length, string);
- }
-
- /**
- * Replace the text with "newText" starting at position "start" for a
- * length of "replaceLength".
- * <p>
- *
- * @param start
- * start offset of text to replace None of the offsets include
- * delimiters of preceeding lines. Offset 0 is the first
- * character of the document.
- * @param replaceLength
- * start offset of text to replace
- * @param newText
- * start offset of text to replace
- * <p>
- * Implementors have to notify TextChanged listeners after the
- * content has been updated. The TextChangedEvent should be set
- * as follows:
- *
- * event.type = SWT.TextReplaced event.start = start of the replaced text
- * event.numReplacedLines = number of replaced lines event.numNewLines =
- * number of new lines event.replacedLength = length of the replaced text
- * event.newLength = length of the new text
- *
- * NOTE: numNewLines is the number of inserted lines and numReplacedLines
- * is the number of deleted lines based on the change that occurs
- * visually. For example:
- *
- * replacedText newText numReplacedLines numNewLines "" "\n" 0 1 "\n\n"
- * "a" 2 0 "a" "\n\n" 0 2
- */
- /**
- * One of the APIs to manipulate the IStructuredDocument in terms of text.
- */
- public StructuredDocumentEvent replaceText(Object requester, int start, int replacementLength, String changes) {
- return replaceText(requester, start, replacementLength, changes, false);
- }
-
- public StructuredDocumentEvent replaceText(Object requester, int start, int replacementLength, String changes, boolean ignoreReadOnlySettings) {
- return internalReplaceText(requester, start, replacementLength, changes, ignoreReadOnlySettings);
- }
-
- void resetParser(int startOffset, int endOffset) {
-
- RegionParser parser = getParser();
- ITextStore textStore = getStore();
- if (textStore instanceof CharSequence) {
- CharSequenceReader subSetTextStoreReader = new CharSequenceReader((CharSequence) textStore, startOffset, endOffset - startOffset);
- parser.reset(subSetTextStoreReader, startOffset);
- }
- else {
- String newNodeText = get(startOffset, endOffset - startOffset);
- parser.reset(newNodeText, startOffset);
-
- }
-
- }
-
- void resetParser(Reader reader, int startOffset) {
- RegionParser parser = getParser();
- parser.reset(reader, startOffset);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.text.IDocumentExtension#resumePostNotificationProcessing()
- */
- public void resumePostNotificationProcessing() {
- --fStoppedCount;
- if (fStoppedCount == 0 && fReentranceCount == 0)
- executePostNotificationChanges();
- }
-
- /**
- * @deprecated in superclass in 3.0 - use a FindReplaceDocumentAdapter
- * directly
- * @see IDocument#search
- */
- public int search(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord) throws BadLocationException {
- // (dmw) I added this warning, to know if still being used. I'm not
- // sure it
- // works as expected any longer.
- // but the warning should be removed, once know.
- Logger.log(Logger.INFO, "WARNING: using unsupported deprecated method 'search'"); //$NON-NLS-1$
- int offset = -1;
- IRegion match = new FindReplaceDocumentAdapter(this).find(startPosition, findString, forwardSearch, caseSensitive, wholeWord, false);
- if (match != null) {
- offset = match.getOffset();
- }
- return offset;
- }
-
- /**
- * @see IDocument#setText
- */
- public void set(String string) {
- if (Debug.displayInfo) {
- System.out.println("Note: IStructuredDocument::setText(String) .... its better to use setText(source, string) API for structuredDocument updates"); //$NON-NLS-1$
- }
- setText(null, string);
- }
-
- /**
- * This may be marked public, but should be packaged protected, once
- * refactoring is complete (in other words, not for client use).
- */
- public void setCachedDocumentRegion(IStructuredDocumentRegion structuredRegion) {
- if (USE_LOCAL_THREAD) {
- fCurrentDocumnetRegionCache.set(structuredRegion);
- }
- else {
- cachedDocumentRegion = structuredRegion;
- }
- }
-
- /**
- * Sets the document's partitioner.
- *
- * @see IDocumentPartitioner
- */
- public void setDocumentPartitioner(IDocumentPartitioner partitioner) {
- setDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING, partitioner);
- }
-
-
- public void setDocumentPartitioner(String partitioning, IDocumentPartitioner partitioner) {
- if (partitioner == null) {
- if (fDocumentPartitioners != null) {
- fDocumentPartitioners.remove(partitioning);
- if (fDocumentPartitioners.size() == 0)
- fDocumentPartitioners = null;
- }
- }
- else {
- if (fDocumentPartitioners == null)
- fDocumentPartitioners = new HashMap();
- fDocumentPartitioners.put(partitioning, partitioner);
- }
- DocumentPartitioningChangedEvent event = new DocumentPartitioningChangedEvent(this);
- event.setPartitionChange(partitioning, 0, getLength());
- fireDocumentPartitioningChanged(event);
- }
-
- public void setEncodingMemento(EncodingMemento encodingMemento) {
- this.encodingMemento = encodingMemento;
- }
-
- void setFirstDocumentRegion(IStructuredDocumentRegion region) {
- firstDocumentRegion = region;
-
- }
-
- /*
- * This method can be used when this class implements IDocumentExtension4.
- *
- * @see org.eclipse.jface.text.IDocumentExtension4#setInitialLineDelimiter(String)
- */
- private void setInitialLineDelimiter(String delimiter) {
- // make sure our preferred delimiter is
- // one of the legal ones
- if (Utilities.containsString(getLegalLineDelimiters(), delimiter)) {
- preferedDelimiter = delimiter;
- }
- else {
- if (Logger.DEBUG_DOCUMENT)
- Logger.log(Logger.INFO, "Attempt to set linedelimiter to non-legal delimiter"); //$NON-NLS-1$ //$NON-NLS-2$
- preferedDelimiter = PlatformLineDelimiter;
- }
- }
-
- void setLastDocumentRegion(IStructuredDocumentRegion region) {
- lastDocumentRegion = region;
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument#setLineDelimiter(java.lang.String)
- */
- public void setLineDelimiter(String delimiter) {
- setInitialLineDelimiter(delimiter);
- }
-
- /**
- * Sets the document's line tracker. Must be called at the beginning of
- * the constructor.
- *
- * @param tracker
- * the document's line tracker
- */
- private void setLineTracker(ILineTracker tracker) {
- fTracker = tracker;
- }
-
- public void setParser(RegionParser newParser) {
- internal_setParser(newParser);
- }
-
- /**
- * @param positionManager
- * The positionManager to set.
- */
- // TODO: make private is needed, else remove
- void setPositionManager(GenericPositionManager positionManager) {
- fPositionManager = positionManager;
- }
-
- /**
- *
- */
- public void setReParser(IStructuredTextReParser newReParser) {
- fReParser = newReParser;
- if (fReParser != null) {
- fReParser.setStructuredDocument(this);
- }
- }
-
- /**
- * One of the APIs to manipulate the IStructuredDocument in terms of text.
- */
- public StructuredDocumentEvent setText(Object requester, String theString) {
-
- StructuredDocumentEvent result = null;
-
- result = replaceText(requester, 0, getLength(), theString, true);
-
- return result;
- }
-
- /**
- * Sets the document's text store. Must be called at the beginning of the
- * constructor.
- *
- * @param store
- * the document's text store
- */
- private void setTextStore(ITextStore store) {
- fStore = store;
- }
-
- public void setUndoManager(IStructuredTextUndoManager undoManager) {
-
- // if the undo manager has already been set, then
- // fail fast, since changing the undo manager will lead
- // to unusual results (or at least loss of undo stack).
- if (fUndoManager != null && fUndoManager != undoManager) {
- throw new IllegalArgumentException("can not change undo manager once its been set"); //$NON-NLS-1$
- }
- else {
- fUndoManager = undoManager;
- }
- }
-
-
- public void startSequentialRewrite(boolean normalized) {
- ITextStore store = new SequentialRewriteTextStore(getStore());
- setTextStore(store);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.text.IDocumentExtension#stopPostNotificationProcessing()
- */
- public void stopPostNotificationProcessing() {
- ++fStoppedCount;
- }
-
-
- public void stopSequentialRewrite() {
- if (getStore() instanceof SequentialRewriteTextStore) {
- SequentialRewriteTextStore srws = (SequentialRewriteTextStore) getStore();
- ITextStore source = srws.getSourceStore();
- setTextStore(source);
- srws.dispose();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.CharSequence#subSequence(int, int)
- */
- public CharSequence subSequence(int arg0, int arg1) {
- return get(arg0, arg1);
- }
-
- /**
- * @param result
- */
- private void updateDeletedFields(StructuredDocumentRegionsReplacedEvent event) {
- IStructuredDocumentRegionList oldRegions = event.getOldStructuredDocumentRegions();
- for (int i = 0; i < oldRegions.getLength(); i++) {
- IStructuredDocumentRegion structuredDocumentRegion = oldRegions.item(i);
- structuredDocumentRegion.setDeleted(true);
- }
-
- }
-
- /**
- * Called by re-parser. Note: this method may be "public" but should only
- * be called by re-parsers in the right circumstances.
- */
- public void updateDocumentData(int start, int lengthToReplace, String changes) {
- stopPostNotificationProcessing();
- getStore().replace(start, lengthToReplace, changes);
- try {
- getTracker().replace(start, lengthToReplace, changes);
- }
-
- catch (BadLocationException e) {
- // should be impossible here, but will log for now
- Logger.logException(e);
- }
- if (fPositionManager != null) {
- fPositionManager.updatePositions(new DocumentEvent(this, start, lengthToReplace, changes));
- }
- resumePostNotificationProcessing();
- }
-
- private StructuredDocumentEvent updateModel(Object requester, int start, int lengthToReplace, String changes) {
- StructuredDocumentEvent result = null;
- IStructuredTextReParser reParser = getReParser();
- // initialize the IStructuredTextReParser with the standard data
- // that's
- // always needed
- reParser.initialize(requester, start, lengthToReplace, changes);
- result = reParser.reparse();
- // if result is null at this point, then there must be an error, since
- // even if there
- // was no change (either disallow due to readonly, or a person pasted
- // the same thing
- // they had selected) then a "NoChange" event should have been fired.
- Assert.isNotNull(result, "no structuredDocument event was created in IStructuredDocument::updateStructuredDocument"); //$NON-NLS-1$
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.wst.sse.core.internal.provisional.document.IEncodedDocument#getPreferredLineDelimiter()
- */
- public String getPreferredLineDelimiter() {
- return getDefaultLineDelimiter();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.wst.sse.core.internal.provisional.document.IEncodedDocument#setPreferredLineDelimiter(java.lang.String)
- */
- public void setPreferredLineDelimiter(String probableLineDelimiter) {
- setInitialLineDelimiter(probableLineDelimiter);
-
- }
-}

Back to the top