Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Anton Leherbauer - [implementation] AnnotationModel.fModificationStamp leaks annotations - http://bugs.eclipse.org/345715
* Sebastian Zarnekow - [bug 401391] ConcurrentModificationException in AnnotationModel.getAnnotationIterator
*******************************************************************************/
package org.eclipse.jface.text.source;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.Position;
/**
* Standard implementation of {@link IAnnotationModel} and its extension
* interfaces. This class can directly be used by clients. Subclasses may adapt
* this annotation model to other existing annotation mechanisms. This class
* also implements {@link org.eclipse.jface.text.ISynchronizable}. All
* modifications of the model's internal annotation map are synchronized using
* the model's lock object.
*/
public class AnnotationModel implements IAnnotationModel, IAnnotationModelExtension, IAnnotationModelExtension2, ISynchronizable {
/**
* Iterator that returns the annotations for a given region.
*
* @since 3.4
* @see AnnotationModel.RegionIterator#RegionIterator(Iterator, IAnnotationModel, int, int, boolean, boolean)
*/
private static final class RegionIterator implements Iterator {
private final Iterator fParentIterator;
private final boolean fCanEndAfter;
private final boolean fCanStartBefore;
private final IAnnotationModel fModel;
private Annotation fNext;
private Position fRegion;
/**
* Iterator that returns all annotations from the parent iterator which
* have a position in the given model inside the given region.
*
* See {@link IAnnotationModelExtension2} for a definition of inside.
*
*
* @param parentIterator iterator containing all annotations
* @param model the model to use to retrieve positions from for each
* annotation
* @param offset start position of the region
* @param length length of the region
* @param canStartBefore include annotations starting before region
* @param canEndAfter include annotations ending after region
* @see IAnnotationModelExtension2
*/
public RegionIterator(Iterator parentIterator, IAnnotationModel model, int offset, int length, boolean canStartBefore, boolean canEndAfter) {
fParentIterator= parentIterator;
fModel= model;
fRegion= new Position(offset, length);
fCanEndAfter= canEndAfter;
fCanStartBefore= canStartBefore;
fNext= findNext();
}
@Override
public boolean hasNext() {
return fNext != null;
}
@Override
public Annotation next() {
if (!hasNext())
throw new NoSuchElementException();
Annotation result= fNext;
fNext= findNext();
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private Annotation findNext() {
while (fParentIterator.hasNext()) {
Annotation next= fParentIterator.next();
Position position= fModel.getPosition(next);
if (position != null) {
int offset= position.getOffset();
if (isWithinRegion(offset, position.getLength()))
return next;
}
}
return null;
}
private boolean isWithinRegion(int start, int length) {
if (fCanStartBefore && fCanEndAfter)
return fRegion.overlapsWith(start, length);
else if (fCanStartBefore)
return fRegion.includes(start + length - (length > 0 ? 1 : 0));
else if (fCanEndAfter)
return fRegion.includes(start);
else
return fRegion.includes(start) && fRegion.includes(start + length - (length > 0 ? 1 : 0));
}
}
/**
* An iterator iteration over a Positions and mapping positions to
* annotations using a provided map if the provided map contains the element.
*
* @since 3.4
*/
private static final class AnnotationsInterator implements Iterator {
private Annotation fNext;
private final Position[] fPositions;
private int fIndex;
private final Map fMap;
/**
* @param positions positions to iterate over
* @param map a map to map positions to annotations
*/
public AnnotationsInterator(Position[] positions, Map map) {
fPositions= positions;
fIndex= 0;
fMap= map;
fNext= findNext();
}
@Override
public boolean hasNext() {
return fNext != null;
}
@Override
public Annotation next() {
Annotation result= fNext;
fNext= findNext();
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private Annotation findNext() {
while (fIndex < fPositions.length) {
Position position= fPositions[fIndex];
fIndex++;
if (fMap.containsKey(position))
return fMap.get(position);
}
return null;
}
}
/**
* A single iterator builds its behavior based on a sequence of iterators.
*
* @param the type of elements returned by this iterator
* @since 3.1
*/
private static class MetaIterator implements Iterator {
/** The iterator over a list of iterators. */
private Iterator extends Iterator extends E>> fSuperIterator;
/** The current iterator. */
private Iterator extends E> fCurrent;
/** The current element. */
private E fCurrentElement;
public MetaIterator(Iterator extends Iterator extends E>> iterator) {
fSuperIterator= iterator;
fCurrent= fSuperIterator.next(); // there is at least one.
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public boolean hasNext() {
if (fCurrentElement != null)
return true;
if (fCurrent.hasNext()) {
fCurrentElement= fCurrent.next();
return true;
} else if (fSuperIterator.hasNext()) {
fCurrent= fSuperIterator.next();
return hasNext();
} else
return false;
}
@Override
public E next() {
if (!hasNext())
throw new NoSuchElementException();
E element= fCurrentElement;
fCurrentElement= null;
return element;
}
}
/**
* Internal annotation model listener for forwarding annotation model changes from the attached models to the
* registered listeners of the outer most annotation model.
*
* @since 3.0
*/
private class InternalModelListener implements IAnnotationModelListener, IAnnotationModelListenerExtension {
@Override
public void modelChanged(IAnnotationModel model) {
AnnotationModel.this.fireModelChanged(new AnnotationModelEvent(model, true));
}
@Override
public void modelChanged(AnnotationModelEvent event) {
AnnotationModel.this.fireModelChanged(event);
}
}
/**
* The list of managed annotations
* @deprecated since 3.0 use getAnnotationMap instead
*/
@Deprecated
protected Map fAnnotations;
/**
* The map which maps {@link Position} to {@link Annotation}.
* @since 3.4
**/
private IdentityHashMap fPositions;
/** The list of annotation model listeners */
protected ArrayList fAnnotationModelListeners;
/** The document connected with this model */
protected IDocument fDocument;
/** The number of open connections to the same document */
private int fOpenConnections= 0;
/** The document listener for tracking whether document positions might have been changed. */
private IDocumentListener fDocumentListener;
/** The flag indicating whether the document positions might have been changed. */
private boolean fDocumentChanged= true;
/**
* The model's attachment.
* @since 3.0
*/
private Map