RutaBasic beginAnchor = stream.getBeginAnchor(annotation.getBegin());
RutaBasic endAnchor = stream.getEndAnchor(annotation.getEnd());
if (beginAnchor == null || endAnchor == null || !beginAnchor.isPartOf(t)
|| !endAnchor.isPartOf(t)) {
return new EvaluatedCondition(this, false);
}
boolean relatively = relative == null ? true : relative.getBooleanValue(element.getParent(),
annotation, stream);
FSIterator<AnnotationFS> iterator = stream.getCas().getAnnotationIndex(t).iterator(beginAnchor);
if (!iterator.isValid()) {
iterator.moveToNext();
}
if (!iterator.isValid()) {
iterator.moveToLast();
}
AnnotationFS window = null;
while (iterator.isValid()) {
AnnotationFS annotationFS = iterator.get();
if (annotationFS.getBegin() <= annotation.getBegin()
&& annotationFS.getEnd() >= annotation.getEnd()) {
window = annotationFS;
break;
}
iterator.moveToPrevious();
}
List<Type> targetTypes = new ArrayList<Type>();
if (element instanceof RutaRuleElement) {
RutaRuleElement re = (RutaRuleElement) element;
targetTypes.addAll(re.getMatcher().getTypes(element.getParent(), stream));
} else {
targetTypes.add(annotation.getType());
}
if (window == null) {
return new EvaluatedCondition(this, false);
}
int integerValue = position.getIntegerValue(element.getParent(), annotation, stream);
if (relatively) {
int counter = 0;
List<RutaBasic> inWindow = stream.getBasicsInWindow(window);
for (RutaBasic each : inWindow) {
if (beginsWith(each, targetTypes)) {
counter++;
if (counter == integerValue) {
if (each.getBegin() == beginAnchor.getBegin()) {
return new EvaluatedCondition(this, true);
} else {
return new EvaluatedCondition(this, false);
}
} else if (counter > integerValue) {
return new EvaluatedCondition(this, false);
}
}
}
return new EvaluatedCondition(this, false);
} else {
int counter = 0;
List<RutaBasic> inWindow = stream.getBasicsInWindow(window);
for (RutaBasic each : inWindow) {
counter++;
boolean beginsWith = beginsWith(each, targetTypes);
if (each.getBegin() == beginAnchor.getBegin() && beginsWith && counter == integerValue) {
return new EvaluatedCondition(this, true);
} else if (counter > integerValue) {
return new EvaluatedCondition(this, false);
}
}
return new EvaluatedCondition(this, false);
}
}