in uimafit-core/src/main/java/org/apache/uima/fit/util/CasUtil.java [1137:1204]
public static AnnotationFS selectSingleRelative(CAS cas, Type type, AnnotationFS aAnchor,
int aPosition) {
requireAnnotationType(cas, type);
// move to first previous annotation
FSIterator<AnnotationFS> itr = cas.getAnnotationIndex(type).iterator();
itr.moveTo(aAnchor);
if (aPosition < 0) {
// If the insertion point is beyond the index, move back to the last.
if (!itr.isValid()) {
itr.moveToLast();
if (!itr.isValid()) {
throw new IndexOutOfBoundsException("Reached end of index while seeking.");
}
}
// No need to do additional seeks here (as done in selectCovered) because the current method
// does not have to worry about type priorities - it never returns annotations that have
// the same offset as the reference annotation.
// make sure we're past the beginning of the reference annotation
while (itr.isValid() && itr.get().getEnd() > aAnchor.getBegin()) {
itr.moveToPrevious();
}
for (int i = 0; i < (-aPosition - 1) && itr.isValid(); ++i, itr.moveToPrevious()) {
// Seeking
}
if (!itr.isValid()) {
throw new IndexOutOfBoundsException("Reached end of index while seeking.");
} else {
return itr.get();
}
} else if (aPosition > 0) {
// When seeking forward, there is no need to check if the insertion point is beyond the
// index. If it was, there would be nothing beyond it that could be found and returned.
// The moveTo operation also does not yield an iterator being invalid because it points
// *before the first* index entry, at max it points *to the first* index entry, so this
// case also does not need to be handled.
// No need to do additional seeks here (as done in selectCovered) because the current method
// does not have to worry about type priorities - it never returns annotations that have
// the same offset as the reference annotation.
// make sure we're past the end of the reference annotation
while (itr.isValid() && itr.get().getBegin() < aAnchor.getEnd()) {
itr.moveToNext();
}
for (int i = 0; i < (aPosition - 1) && itr.isValid(); ++i, itr.moveToPrevious()) {
// Seeking
}
if (!itr.isValid()) {
throw new IndexOutOfBoundsException("Reached end of index while seeking.");
} else {
return itr.get();
}
} else if (cas.getTypeSystem().subsumes(aAnchor.getType(), type)) {
return aAnchor;
} else {
throw new IllegalArgumentException(
"Relative position cannot be 0 if the type of the anchor annotator does not subsume "
+ "the selected type.");
}
}