blob: 662ef6ced12fa79277665f3bdc0fa1aae2a9dd18 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.ruta;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.CASException;
import org.apache.uima.cas.ConstraintFactory;
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.FSMatchConstraint;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.impl.FSIteratorImplBase;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.cas.text.AnnotationIndex;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.ruta.engine.RutaEngine;
import org.apache.uima.ruta.expression.IRutaExpression;
import org.apache.uima.ruta.expression.bool.IBooleanExpression;
import org.apache.uima.ruta.expression.feature.FeatureExpression;
import org.apache.uima.ruta.expression.feature.GenericFeatureExpression;
import org.apache.uima.ruta.expression.feature.SimpleFeatureExpression;
import org.apache.uima.ruta.expression.number.INumberExpression;
import org.apache.uima.ruta.expression.string.IStringExpression;
import org.apache.uima.ruta.expression.type.ITypeExpression;
import org.apache.uima.ruta.rule.AbstractRule;
import org.apache.uima.ruta.rule.AbstractRuleMatch;
import org.apache.uima.ruta.rule.MatchContext;
import org.apache.uima.ruta.type.RutaAnnotation;
import org.apache.uima.ruta.type.RutaBasic;
import org.apache.uima.ruta.utils.UIMAUtils;
import org.apache.uima.ruta.visitor.InferenceCrowd;
public class RutaStream extends FSIteratorImplBase<AnnotationFS> {
private final CAS cas;
private FSIterator<AnnotationFS> basicIt;
private FSIterator<AnnotationFS> currentIt;
private AnnotationFS documentAnnotation;
private Type documentAnnotationType;
private Type basicType;
private NavigableMap<Integer, RutaBasic> beginAnchors = new TreeMap<Integer, RutaBasic>();
private NavigableMap<Integer, RutaBasic> endAnchors = new TreeMap<Integer, RutaBasic>();
private FilterManager filter;
private boolean dynamicAnchoring;
private double indexPenalty = 0;
private double anchoringFactor;
private boolean lowMemoryProfile;
private boolean simpleGreedyForComposed;
private InferenceCrowd crowd;
private Boolean greedyRuleElement;
private Boolean greedyRule;
private boolean onlyOnce = false;
public RutaStream(CAS cas, Type basicType, FilterManager filter, boolean lowMemoryProfile,
boolean simpleGreedyForComposed, InferenceCrowd crowd) {
super();
this.cas = cas;
this.filter = filter;
this.basicType = basicType;
this.lowMemoryProfile = lowMemoryProfile;
this.simpleGreedyForComposed = simpleGreedyForComposed;
this.crowd = crowd;
AnnotationFS additionalWindow = filter.getWindowAnnotation();
updateIterators(cas, basicType, filter, additionalWindow);
// really an if? sub it of basic should fix this
if (additionalWindow == null) {
documentAnnotation = cas.getDocumentAnnotation();
documentAnnotationType = getCas().getDocumentAnnotation().getType();
basicIt.moveToFirst();
} else {
documentAnnotation = additionalWindow;
documentAnnotationType = filter.getWindowType();
}
}
protected RutaStream(CAS cas, Type basicType, NavigableMap<Integer, RutaBasic> beginAnchors,
NavigableMap<Integer, RutaBasic> endAnchors, FilterManager filter,
boolean lowMemoryProfile, boolean simpleGreedyForComposed, InferenceCrowd crowd) {
super();
this.cas = cas;
this.beginAnchors = beginAnchors;
this.endAnchors = endAnchors;
this.filter = filter;
this.basicType = basicType;
this.lowMemoryProfile = lowMemoryProfile;
this.simpleGreedyForComposed = simpleGreedyForComposed;
this.crowd = crowd;
AnnotationFS additionalWindow = filter.getWindowAnnotation();
updateIterators(cas, basicType, filter, additionalWindow);
// really an if? sub it of basic should fix this
if (additionalWindow == null) {
documentAnnotation = cas.getDocumentAnnotation();
documentAnnotationType = getCas().getDocumentAnnotation().getType();
basicIt.moveToFirst();
} else {
documentAnnotation = additionalWindow;
documentAnnotationType = filter.getWindowType();
}
}
private void updateIterators(AnnotationFS additionalWindow) {
updateIterators(cas, basicType, filter, additionalWindow);
}
private void updateIterators(CAS cas, Type basicType, FilterManager filter,
AnnotationFS additionalWindow) {
if (additionalWindow != null) {
this.basicIt = cas.getAnnotationIndex(basicType).subiterator(additionalWindow);
} else {
this.basicIt = cas.getAnnotationIndex(basicType).iterator();
}
currentIt = filter.createFilteredIterator(cas, basicType);
}
public void initalizeBasics() {
AnnotationIndex<AnnotationFS> basicIndex = cas.getAnnotationIndex(basicType);
AnnotationIndex<AnnotationFS> annotationIndex = cas.getAnnotationIndex();
final List<AnnotationFS> allAnnotations = new LinkedList<AnnotationFS>();
for (AnnotationFS a : annotationIndex) {
if (a.getBegin() != a.getEnd()) {
allAnnotations.add(a);
}
}
if (basicIndex.size() == 0) {
TreeSet<Integer> anchors = new TreeSet<Integer>();
for (AnnotationFS a : allAnnotations) {
anchors.add(a.getBegin());
anchors.add(a.getEnd());
}
if (anchors.size() == 1) {
Integer first = anchors.pollFirst();
RutaBasic newTMB = new RutaBasic(getJCas(), first, first);
newTMB.setLowMemoryProfile(lowMemoryProfile);
beginAnchors.put(first, newTMB);
endAnchors.put(first, newTMB);
cas.addFsToIndexes(newTMB);
} else {
while (true) {
Integer first = anchors.pollFirst();
if (first == null || anchors.isEmpty()) {
break;
}
Integer second = anchors.first();
if (first < second) {
RutaBasic newTMB = new RutaBasic(getJCas(), first, second);
newTMB.setLowMemoryProfile(lowMemoryProfile);
beginAnchors.put(first, newTMB);
endAnchors.put(second, newTMB);
cas.addFsToIndexes(newTMB);
}
}
}
for (AnnotationFS a : allAnnotations) {
addAnnotation(a, false, false, null);
}
updateIterators(documentAnnotation);
} else {
for (AnnotationFS e : basicIndex) {
beginAnchors.put(e.getBegin(), (RutaBasic) e);
endAnchors.put(e.getEnd(), (RutaBasic) e);
}
RutaBasic firstBasic = (RutaBasic) basicIndex.iterator().get();
if (firstBasic.isLowMemoryProfile() != lowMemoryProfile) {
for (AnnotationFS each : basicIndex) {
RutaBasic eachBasic = (RutaBasic) each;
eachBasic.setLowMemoryProfile(lowMemoryProfile);
}
}
// TODO: find a better solution for this:
for (AnnotationFS a : allAnnotations) {
Type type = a.getType();
if (!type.equals(basicType)) {
RutaBasic beginAnchor = getBeginAnchor(a.getBegin());
RutaBasic endAnchor = getEndAnchor(a.getEnd());
boolean shouldBeAdded = false;
if (beginAnchor == null || endAnchor == null) {
shouldBeAdded = true;
} else {
Collection<AnnotationFS> set = beginAnchor.getBeginAnchors(type);
if (!set.contains(a)) {
shouldBeAdded = true;
}
}
if (shouldBeAdded) {
addAnnotation(a, false, false, null);
}
}
}
}
}
public void addAnnotation(AnnotationFS annotation, boolean addToIndex,
AbstractRuleMatch<? extends AbstractRule> creator) {
addAnnotation(annotation, addToIndex, true, creator);
}
public void addAnnotation(AnnotationFS annotation,
AbstractRuleMatch<? extends AbstractRule> creator) {
addAnnotation(annotation, false, true, creator);
}
public void addAnnotation(AnnotationFS annotation, boolean addToIndex, boolean updateInternal,
AbstractRuleMatch<? extends AbstractRule> creator) {
Type type = annotation.getType();
if (type.equals(basicType)) {
return;
}
boolean modified = checkSpan(annotation);
if (modified && updateInternal) {
updateIterators(filter.getWindowAnnotation());
}
RutaBasic beginAnchor = getBeginAnchor(annotation.getBegin());
RutaBasic endAnchor = getEndAnchor(annotation.getEnd());
if (beginAnchor != null) {
beginAnchor.addBegin(annotation, type);
}
if (endAnchor != null) {
endAnchor.addEnd(annotation, type);
}
Collection<RutaBasic> basicAnnotationsInWindow = getAllBasicsInWindow(annotation);
for (RutaBasic basic : basicAnnotationsInWindow) {
basic.addPartOf(type);
}
if (addToIndex) {
cas.addFsToIndexes(annotation);
}
crowd.annotationAdded(annotation, creator);
}
private boolean checkSpan(AnnotationFS annotation) {
boolean result = false;
int begin = annotation.getBegin();
int end = annotation.getEnd();
RutaBasic beginAnchor = getBeginAnchor(begin);
RutaBasic endAnchor = getEndAnchor(end);
if (beginAnchor != null && endAnchor != null) {
result = false;
} else {
if (beginAnchor == null) {
result |= checkAnchor(begin);
}
if (endAnchor == null) {
result |= checkAnchor(end);
}
}
return result;
}
private boolean checkAnchor(int anchor) {
Entry<Integer, RutaBasic> floorEntry = endAnchors.floorEntry(anchor);
if (floorEntry == null) {
floorEntry = beginAnchors.floorEntry(anchor);
}
Entry<Integer, RutaBasic> ceilingEntry = endAnchors.ceilingEntry(anchor);
if (floorEntry != null && ceilingEntry != null) {
RutaBasic floor = floorEntry.getValue();
RutaBasic ceiling = ceilingEntry.getValue();
RutaBasic toSplit = null;
if (floor.getEnd() > anchor) {
toSplit = floor;
} else {
toSplit = ceiling;
}
int newEnd = toSplit.getEnd();
if (newEnd == anchor) {
return false;
}
cas.removeFsFromIndexes(toSplit);
toSplit.setEnd(anchor);
RutaBasic newRB = new RutaBasic(getJCas(), anchor, newEnd);
newRB.setLowMemoryProfile(lowMemoryProfile);
newRB.setEndMap(toSplit.getEndMap());
newRB.setPartOf(toSplit.getPartOf());
toSplit.clearEndMap();
cas.addFsToIndexes(toSplit);
cas.addFsToIndexes(newRB);
beginAnchors.put(floor.getBegin(), floor);
beginAnchors.put(newRB.getBegin(), newRB);
beginAnchors.put(ceiling.getBegin(), ceiling);
endAnchors.put(floor.getEnd(), floor);
endAnchors.put(newRB.getEnd(), newRB);
endAnchors.put(ceiling.getEnd(), ceiling);
return true;
} else {
// TODO this should never happen! test it!
}
return false;
}
public void removeAnnotation(AnnotationFS annotationFS) {
removeAnnotation(annotationFS, annotationFS.getType());
}
public void removeAnnotation(AnnotationFS annotation, Type type) {
if (type.getName().equals(UIMAConstants.TYPE_DOCUMENT)) {
// do not remove DocumentAnnotation
return;
}
Collection<RutaBasic> basicAnnotationsInWindow = getAllBasicsInWindow(annotation);
for (RutaBasic basic : basicAnnotationsInWindow) {
basic.removePartOf(type);
}
Type parent = type;
RutaBasic beginAnchor = getBeginAnchor(annotation.getBegin());
RutaBasic endAnchor = getEndAnchor(annotation.getEnd());
if (beginAnchor != null) {
beginAnchor.removeBegin(annotation, parent);
}
if (endAnchor != null) {
endAnchor.removeEnd(annotation, parent);
}
if (!(annotation instanceof RutaBasic)) {
cas.removeFsFromIndexes(annotation);
}
}
public FSIterator<AnnotationFS> getFilteredBasicIterator(FSMatchConstraint constraint) {
ConstraintFactory cf = cas.getConstraintFactory();
FSMatchConstraint matchConstraint = cf.and(constraint, filter.getDefaultConstraint());
return cas.createFilteredIterator(basicIt, matchConstraint);
}
public RutaStream getWindowStream(AnnotationFS windowAnnotation, Type windowType) {
if (windowAnnotation.getBegin() == documentAnnotation.getBegin()
&& windowAnnotation.getEnd() == documentAnnotation.getEnd()) {
return this;
}
FilterManager filterManager = new FilterManager(filter.getDefaultFilterTypes(),
filter.getCurrentFilterTypes(), filter.getCurrentRetainTypes(), windowAnnotation,
windowType, cas);
// NavigableMap<Integer, RutaBasic> newBeginAnchors = beginAnchors.subMap(
// windowAnnotation.getBegin(), true, windowAnnotation.getEnd(), false);
// NavigableMap<Integer, RutaBasic> newEndAnchors =
// endAnchors.subMap(windowAnnotation.getBegin(),
// false, windowAnnotation.getEnd(), true);
RutaStream stream = new RutaStream(cas, basicType, beginAnchors, endAnchors, filterManager,
lowMemoryProfile, simpleGreedyForComposed, crowd);
stream.setDynamicAnchoring(dynamicAnchoring);
stream.setGreedyRuleElement(greedyRuleElement);
stream.setGreedyRule(greedyRule);
return stream;
}
public FSIterator<AnnotationFS> copy() {
RutaStream stream = new RutaStream(cas, basicType, beginAnchors, endAnchors, filter,
lowMemoryProfile, simpleGreedyForComposed, crowd);
stream.setDynamicAnchoring(dynamicAnchoring);
stream.setGreedyRuleElement(greedyRuleElement);
stream.setGreedyRule(greedyRule);
return stream;
}
public AnnotationFS get() throws NoSuchElementException {
return currentIt.get();
}
public boolean isValid() {
return currentIt.isValid();
}
public void moveTo(FeatureStructure fs) {
try {
currentIt.moveTo(fs);
} catch (Exception e) {
// e.printStackTrace();
}
}
public void moveToFirst() {
currentIt.moveToFirst();
}
public void moveToLast() {
currentIt.moveToLast();
}
public void moveToNext() {
currentIt.moveToNext();
}
public void moveToPrevious() {
currentIt.moveToPrevious();
}
public List<AnnotationFS> getOverappingAnnotations(AnnotationFS window, Type type) {
List<AnnotationFS> result = new ArrayList<AnnotationFS>();
AnnotationFS newWindow = cas.createAnnotation(type, window.getBegin(), window.getEnd() - 1);
FSIterator<AnnotationFS> iterator = cas.getAnnotationIndex(type).iterator(newWindow);
if (!iterator.isValid()) {
iterator.moveToLast();
}
while (iterator.isValid()) {
FeatureStructure fs = iterator.get();
if (fs instanceof AnnotationFS) {
AnnotationFS a = (AnnotationFS) fs;
if (a.getEnd() >= window.getEnd() && a.getBegin() <= window.getBegin()) {
result.add(a);
}
}
iterator.moveToPrevious();
}
return result;
}
public List<Annotation> getAnnotationsFollowing(Annotation annotation) {
List<Annotation> result = new ArrayList<Annotation>();
moveTo(annotation);
while (currentIt.isValid()) {
currentIt.moveToNext();
if (currentIt.isValid()) {
Annotation nextAnnotation = (Annotation) currentIt.get();
if (nextAnnotation.getBegin() == annotation.getEnd()) {
result.add(nextAnnotation);
} else if (nextAnnotation.getBegin() >= annotation.getEnd()) {
break;
}
}
}
return result;
}
public CAS getCas() {
return cas;
}
public JCas getJCas() {
try {
return cas.getJCas();
} catch (CASException e) {
// e.printStackTrace();
}
return null;
}
public List<AnnotationFS> getAllofType(Type type) {
List<AnnotationFS> result = new ArrayList<AnnotationFS>();
FSIterator<AnnotationFS> iterator = cas.getAnnotationIndex(type).iterator();
while (iterator.isValid()) {
FeatureStructure featureStructure = iterator.get();
result.add((AnnotationFS) featureStructure);
iterator.moveToNext();
}
return result;
}
public List<AnnotationFS> getAnnotationsInWindow2(AnnotationFS windowAnnotation, Type type) {
List<AnnotationFS> result = new ArrayList<AnnotationFS>();
windowAnnotation = cas.createAnnotation(type, windowAnnotation.getBegin(),
windowAnnotation.getEnd() + 1);
FSIterator<AnnotationFS> completeIt = getCas().getAnnotationIndex(type).iterator();
if (getDocumentAnnotation().getEnd() < windowAnnotation.getEnd()) {
completeIt.moveToLast();
} else {
completeIt.moveTo(windowAnnotation);
}
while (completeIt.isValid()
&& ((Annotation) completeIt.get()).getBegin() >= windowAnnotation.getBegin()) {
completeIt.moveToPrevious();
}
if (completeIt.isValid()) {
completeIt.moveToNext();
} else {
completeIt.moveToFirst();
}
while (completeIt.isValid()
&& ((Annotation) completeIt.get()).getBegin() < windowAnnotation.getBegin()) {
completeIt.moveToNext();
}
while (completeIt.isValid()
&& ((Annotation) completeIt.get()).getBegin() >= windowAnnotation.getBegin()) {
Annotation annotation = (Annotation) completeIt.get();
if (getCas().getTypeSystem().subsumes(type, annotation.getType())
&& annotation.getEnd() <= windowAnnotation.getEnd()) {
result.add(annotation);
}
completeIt.moveToNext();
}
return result;
}
public List<AnnotationFS> getAnnotationsInWindow(AnnotationFS windowAnnotation, Type type) {
if (type == null)
return null;
List<AnnotationFS> result = new ArrayList<AnnotationFS>();
List<AnnotationFS> inWindow = getAnnotationsInWindow2(windowAnnotation, type);
result = inWindow;
return result;
}
public Collection<RutaBasic> getAllBasicsInWindow(AnnotationFS windowAnnotation) {
if (windowAnnotation.getBegin() >= windowAnnotation.getEnd()) {
return Collections.emptySet();
}
RutaBasic beginAnchor = getBeginAnchor(windowAnnotation.getBegin());
if (beginAnchor != null && beginAnchor.getEnd() == windowAnnotation.getEnd()) {
Collection<RutaBasic> result = new ArrayList<RutaBasic>(1);
result.add(beginAnchor);
return result;
}
Collection<RutaBasic> subSet = null;
if (windowAnnotation.getEnd() == cas.getDocumentAnnotation().getEnd()
&& windowAnnotation.getBegin() == 0) {
subSet = beginAnchors.values();
} else {
subSet = beginAnchors.subMap(windowAnnotation.getBegin(), true, windowAnnotation.getEnd(),
false).values();
}
return subSet;
}
public RutaBasic getBasicNextTo(boolean before, AnnotationFS annotation) {
if (annotation == null) {
return beginAnchors.get(0);
}
if (before) {
RutaBasic pointer = beginAnchors.get(annotation.getBegin());
moveTo(pointer);
if (isVisible(pointer) || !isValid()) {
moveToPrevious();
}
if (!isValid()) {
moveToLast();
}
if (isValid()) {
RutaBasic nextBasic = (RutaBasic) get();
// TODO HOTFIX for annotation of length 0
while (isValid() && nextBasic.getEnd() > annotation.getBegin()) {
moveToPrevious();
if (isValid()) {
nextBasic = (RutaBasic) get();
}
}
return nextBasic;
}
} else {
RutaBasic pointer = endAnchors.get(annotation.getEnd());
moveTo(pointer);
if (isVisible(pointer)) {
moveToNext();
}
if (isValid()) {
RutaBasic nextBasic = (RutaBasic) get();
// TODO HOTFIX for annotation of length 0
while (isValid() && nextBasic.getBegin() < annotation.getEnd()) {
moveToNext();
if (isValid()) {
nextBasic = (RutaBasic) get();
}
}
return nextBasic;
}
}
return null;
}
public List<RutaBasic> getBasicsInWindow(AnnotationFS windowAnnotation) {
List<RutaBasic> result = new ArrayList<RutaBasic>();
if (windowAnnotation instanceof RutaBasic) {
result.add((RutaBasic) windowAnnotation);
return result;
}
FSMatchConstraint defaultConstraint = filter.getDefaultConstraint();
FSIterator<AnnotationFS> iterator = cas.createFilteredIterator(cas
.getAnnotationIndex(basicType).subiterator(windowAnnotation), defaultConstraint);
while (iterator.isValid()) {
result.add((RutaBasic) iterator.get());
iterator.moveToNext();
}
return result;
}
public RutaBasic getFirstBasicInWindow(AnnotationFS windowAnnotation) {
return getFirstBasicInWindow(windowAnnotation, currentIt);
}
public RutaBasic getFirstBasicInWindow(AnnotationFS windowAnnotation, FSIterator<AnnotationFS> it) {
if (windowAnnotation instanceof RutaBasic) {
return (RutaBasic) windowAnnotation;
}
it.moveTo(windowAnnotation);
if (it.isValid()) {
return (RutaBasic) it.get();
}
return null;
}
public List<RutaBasic> getAnnotationsOverlappingWindow(AnnotationFS annotation) {
if (annotation != null) {
return getBasicsInWindow(annotation);
} else {
return new ArrayList<RutaBasic>();
}
}
public FSIterator<AnnotationFS> getUnfilteredBasicIterator() {
return basicIt;
}
public AnnotationFS getDocumentAnnotation() {
return documentAnnotation;
}
public RutaAnnotation getCorrectTMA(List<AnnotationFS> annotationsInWindow,
RutaAnnotation heuristicAnnotation) {
for (AnnotationFS annotation : annotationsInWindow) {
if (annotation instanceof RutaAnnotation) {
RutaAnnotation tma = (RutaAnnotation) annotation;
if (tma.getBegin() == heuristicAnnotation.getBegin()
&& tma.getEnd() == heuristicAnnotation.getEnd()
&& tma.getAnnotation().getType()
.equals(heuristicAnnotation.getAnnotation().getType())) {
return tma;
}
}
}
return null;
}
public void retainTypes(List<Type> list) {
filter.retainTypes(list);
currentIt = filter.createFilteredIterator(cas, basicType);
}
public void filterTypes(List<Type> list) {
filter.filterTypes(list);
currentIt = filter.createFilteredIterator(cas, basicType);
}
public void addFilterTypes(List<Type> types) {
filter.addFilterTypes(types);
currentIt = filter.createFilteredIterator(cas, basicType);
}
public void addRetainTypes(List<Type> types) {
filter.addRetainTypes(types);
currentIt = filter.createFilteredIterator(cas, basicType);
}
public void removeFilterTypes(List<Type> types) {
filter.removeFilterTypes(types);
currentIt = filter.createFilteredIterator(cas, basicType);
}
public void removeRetainTypes(List<Type> types) {
filter.removeRetainTypes(types);
currentIt = filter.createFilteredIterator(cas, basicType);
}
public FilterManager getFilter() {
return filter;
}
public RutaBasic getFirstBasicOfAll() {
if (beginAnchors.isEmpty()) {
return null;
}
return beginAnchors.firstEntry().getValue();
}
public RutaBasic getLastBasicOfAll() {
if (endAnchors.isEmpty()) {
return null;
}
return endAnchors.lastEntry().getValue();
}
public Type getDocumentAnnotationType() {
return documentAnnotationType;
}
public RutaBasic getNextBasic2(AnnotationFS previous) {
AnnotationFS pointer = cas
.createAnnotation(basicType, previous.getEnd() - 1, previous.getEnd());
currentIt.moveTo(pointer);
if (currentIt.isValid()) {
RutaBasic basic = (RutaBasic) currentIt.get();
return basic;
}
return null;
}
public long getHistogram(Type type) {
return cas.getAnnotationIndex(type).size();
}
public double getIndexPenalty() {
return indexPenalty;
}
public RutaBasic getEndAnchor(int end) {
return endAnchors.get(end);
}
public RutaBasic getBeginAnchor(int begin) {
return beginAnchors.get(begin);
}
public boolean isDynamicAnchoring() {
return dynamicAnchoring;
}
public void setDynamicAnchoring(boolean dynamicAnchoring) {
this.dynamicAnchoring = dynamicAnchoring;
}
public boolean isGreedyRuleElement() {
return greedyRuleElement;
}
public void setGreedyRuleElement(Boolean greedyAnchoring) {
this.greedyRuleElement = greedyAnchoring;
}
public boolean isGreedyRule() {
return greedyRule;
}
public void setGreedyRule(Boolean greedyAnchoring) {
this.greedyRule = greedyAnchoring;
}
public void setIndexPenalty(double indexPenalty) {
this.indexPenalty = indexPenalty;
}
public double getAnchoringFactor() {
return anchoringFactor;
}
public void setAnchoringFactor(double anchoringFactor) {
this.anchoringFactor = anchoringFactor;
}
public boolean isSimpleGreedyForComposed() {
return simpleGreedyForComposed;
}
public void setSimpleGreedyForComposed(boolean simpleGreedyForComposed) {
this.simpleGreedyForComposed = simpleGreedyForComposed;
}
public boolean isGreedyAnchoring() {
return greedyRule || greedyRuleElement;
}
public boolean isOnlyOnce() {
return onlyOnce;
}
public void setOnlyOnce(Boolean onlyOnce) {
this.onlyOnce = onlyOnce;
}
public boolean isVisible(AnnotationFS annotationFS) {
return isVisible(annotationFS, false);
}
public boolean isVisible(AnnotationFS annotationFS, boolean ignoreWindow) {
if (annotationFS == null) {
return false;
}
if (annotationFS.getBegin() >= annotationFS.getEnd()) {
return false;
}
AnnotationFS windowAnnotation = filter.getWindowAnnotation();
if (!ignoreWindow
&& windowAnnotation != null
&& (annotationFS.getBegin() < windowAnnotation.getBegin() || annotationFS.getEnd() > windowAnnotation
.getEnd())) {
return false;
}
int begin = annotationFS.getBegin();
int end = annotationFS.getEnd();
Set<Type> currentHiddenTypes = filter.getCurrentHiddenTypes();
RutaBasic beginAnchor = getBeginAnchor(begin);
if (beginAnchor != null) {
for (Type type : currentHiddenTypes) {
boolean partOf = beginAnchor.isPartOf(type);
if (partOf) {
return false;
}
}
}
RutaBasic endAnchor = getEndAnchor(end);
if (endAnchor != null) {
for (Type type : currentHiddenTypes) {
boolean partOf = endAnchor.isPartOf(type);
if (partOf) {
return false;
}
}
}
return true;
}
public RutaBasic getAnchor(boolean direction, int pointer) {
if (direction) {
return getBeginAnchor(pointer);
} else {
return getEndAnchor(pointer);
}
}
public RutaBasic getAnchor(boolean direction, AnnotationFS annotation) {
if (direction) {
return getEndAnchor(annotation.getEnd());
} else {
return getBeginAnchor(annotation.getBegin());
}
}
public Collection<AnnotationFS> getAnnotations(Type type) {
Collection<AnnotationFS> result = new LinkedList<AnnotationFS>();
AnnotationFS windowAnnotation = filter.getWindowAnnotation();
if (windowAnnotation != null
&& (windowAnnotation.getBegin() != cas.getDocumentAnnotation().getBegin() || windowAnnotation
.getEnd() != cas.getDocumentAnnotation().getEnd())) {
AnnotationFS frame = cas.createAnnotation(cas.getTypeSystem().getType(RutaEngine.FRAME_TYPE),
windowAnnotation.getBegin(), windowAnnotation.getEnd());
FSIterator<AnnotationFS> subiterator = cas.getAnnotationIndex(type).subiterator(frame);
while (subiterator.hasNext()) {
AnnotationFS each = (AnnotationFS) subiterator.next();
if (isVisible(each)) {
result.add(each);
}
}
} else {
AnnotationIndex<AnnotationFS> annotationIndex = cas.getAnnotationIndex(type);
for (AnnotationFS each : annotationIndex) {
if (isVisible(each)) {
result.add(each);
}
}
}
return result;
}
public String getVisibleCoveredText(AnnotationFS annotationFS) {
StringBuilder result = new StringBuilder();
List<RutaBasic> basicsInWindow = getBasicsInWindow(annotationFS);
for (RutaBasic each : basicsInWindow) {
if (isVisible(each)) {
result.append(each.getCoveredText());
}
}
return result.toString();
}
public void assignFeatureValues(AnnotationFS annotation,
Map<IStringExpression, IRutaExpression> map, MatchContext context) {
Type type = annotation.getType();
Set<Entry<IStringExpression, IRutaExpression>> entrySet = map.entrySet();
for (Entry<IStringExpression, IRutaExpression> entry : entrySet) {
IStringExpression key = entry.getKey();
IRutaExpression value = entry.getValue();
String featureName = key.getStringValue(context, this);
Feature feature = type.getFeatureByBaseName(featureName);
assignFeatureValue(annotation, feature, value, context);
}
}
public void assignFeatureValue(AnnotationFS annotation, Feature feature, IRutaExpression value,
MatchContext context) {
if (feature == null) {
throw new IllegalArgumentException("Not able to assign feature value (e.g., coveredText).");
}
String range = feature.getRange().getName();
if (range.equals(UIMAConstants.TYPE_STRING)) {
if (value instanceof IStringExpression) {
IStringExpression stringExpr = (IStringExpression) value;
String string = stringExpr.getStringValue(context, this);
annotation.setStringValue(feature, string);
}
} else if (value instanceof INumberExpression
&& (range.equals(UIMAConstants.TYPE_INTEGER) || range.equals(UIMAConstants.TYPE_LONG)
|| range.equals(UIMAConstants.TYPE_SHORT) || range
.equals(UIMAConstants.TYPE_BYTE))) {
INumberExpression numberExpr = (INumberExpression) value;
int v = numberExpr.getIntegerValue(context, this);
annotation.setIntValue(feature, v);
} else if (value instanceof INumberExpression && (range.equals(UIMAConstants.TYPE_DOUBLE))) {
INumberExpression numberExpr = (INumberExpression) value;
double v = numberExpr.getDoubleValue(context, this);
annotation.setDoubleValue(feature, v);
} else if (value instanceof INumberExpression && (range.equals(UIMAConstants.TYPE_FLOAT))) {
INumberExpression numberExpr = (INumberExpression) value;
float v = numberExpr.getFloatValue(context, this);
annotation.setFloatValue(feature, v);
} else if (value instanceof IBooleanExpression && (range.equals(UIMAConstants.TYPE_BOOLEAN))) {
IBooleanExpression booleanExpr = (IBooleanExpression) value;
boolean v = booleanExpr.getBooleanValue(context, this);
annotation.setBooleanValue(feature, v);
} else if (value instanceof IBooleanExpression && (range.equals(UIMAConstants.TYPE_BOOLEAN))) {
IBooleanExpression booleanExpr = (IBooleanExpression) value;
boolean v = booleanExpr.getBooleanValue(context, this);
annotation.setBooleanValue(feature, v);
} else if (value instanceof ITypeExpression && !feature.getRange().isPrimitive()) {
ITypeExpression typeExpr = (ITypeExpression) value;
Type t = typeExpr.getType(context, this);
List<AnnotationFS> inWindow = this.getAnnotationsInWindow(context.getAnnotation(), t);
if (feature.getRange().isArray()) {
annotation.setFeatureValue(feature, UIMAUtils.toFSArray(this.getJCas(), inWindow));
} else {
if (inWindow != null && !inWindow.isEmpty()) {
AnnotationFS a = inWindow.get(0);
annotation.setFeatureValue(feature, a);
} else {
annotation.setFeatureValue(feature, null);
}
}
} else if (value instanceof GenericFeatureExpression && !feature.getRange().isPrimitive()) {
FeatureExpression fe = ((GenericFeatureExpression) value).getFeatureExpression();
ITypeExpression typeExpr = fe.getTypeExpr(context, this);
Type t = typeExpr.getType(context, this);
List<AnnotationFS> inWindow = this.getAnnotationsInWindow(context.getAnnotation(), t);
if (fe instanceof SimpleFeatureExpression) {
SimpleFeatureExpression sfe = (SimpleFeatureExpression) fe;
List<AnnotationFS> featureAnnotations = inWindow;
if (fe.getFeatures(context, this) != null) {
featureAnnotations = new ArrayList<AnnotationFS>(sfe.getFeatureAnnotations(inWindow,
this, context, false));
}
if (feature.getRange().isArray()) {
annotation.setFeatureValue(feature,
UIMAUtils.toFSArray(this.getJCas(), featureAnnotations));
} else if (!featureAnnotations.isEmpty()) {
AnnotationFS a = featureAnnotations.get(0);
annotation.setFeatureValue(feature, a);
}
} else {
if (feature.getRange().isArray()) {
annotation.setFeatureValue(feature, UIMAUtils.toFSArray(this.getJCas(), inWindow));
} else {
AnnotationFS a = inWindow.get(0);
annotation.setFeatureValue(feature, a);
}
}
}
}
}