use of de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.AnnotationComparator in project webanno by webanno.
the class SpanOverlapBehavior method onRender.
@Override
public void onRender(TypeAdapter aAdapter, VDocument aResponse, Map<AnnotationFS, VSpan> aAnnoToSpanIdx, int aPageBegin, int aPageEnd) {
if (aAnnoToSpanIdx.isEmpty()) {
return;
}
// The following code requires annotations with the same offsets to be adjacent during
// iteration, so we sort the entries here
AnnotationComparator cmp = new AnnotationComparator();
final List<AnnotationFS> sortedSpans = aAnnoToSpanIdx.keySet().stream().sorted(cmp).collect(Collectors.toList());
switch(aAdapter.getLayer().getOverlapMode()) {
case ANY_OVERLAP:
// Nothing to check
break;
case NO_OVERLAP:
{
Set<AnnotationFS> overlapping = new HashSet<>();
Set<AnnotationFS> stacking = new HashSet<>();
overlappingOrStackingSpans(sortedSpans, stacking, overlapping);
overlapping.forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Overlap is not permitted.")));
stacking.forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Stacking is not permitted.")));
break;
}
case STACKING_ONLY:
// Here, we must find all overlapping relations because they are not permitted
overlappingNonStackingSpans(sortedSpans).forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Only stacking is permitted.")));
break;
case OVERLAP_ONLY:
stackingSpans(sortedSpans).forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Stacking is not permitted.")));
break;
}
}
use of de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.AnnotationComparator in project webanno by webanno.
the class ChainAdapter method addArc.
public int addArc(SourceDocument aDocument, String aUsername, CAS aCas, AnnotationFS aOriginFs, AnnotationFS aTargetFs) {
// Determine if the links are adjacent. If so, just update the arc label
AnnotationFS originNext = getNextLink(aOriginFs);
AnnotationFS targetNext = getNextLink(aTargetFs);
// adjacent - origin links to target
if (WebAnnoCasUtil.isSame(originNext, aTargetFs)) {
} else // adjacent - target links to origin
if (WebAnnoCasUtil.isSame(targetNext, aOriginFs)) {
if (isLinkedListBehavior()) {
throw new IllegalStateException("Cannot change direction of a link within a chain");
} else {
// in set mode there are no arc labels anyway
}
} else // if origin and target are not adjacent
{
FeatureStructure originChain = getChainForLink(aCas, aOriginFs);
FeatureStructure targetChain = getChainForLink(aCas, aTargetFs);
AnnotationFS targetPrev = getPrevLink(targetChain, aTargetFs);
if (!WebAnnoCasUtil.isSame(originChain, targetChain)) {
if (isLinkedListBehavior()) {
// the rest becomes its own chain
if (originNext != null) {
newChain(aCas, originNext);
// we set originNext below
// we set the arc label below
}
// if targetFs has a prev, then split it off
if (targetPrev != null) {
setNextLink(targetPrev, null);
} else // if it has no prev then we fully append the target chain to the origin chain
// and we can remove the target chain head
{
aCas.removeFsFromIndexes(targetChain);
}
// connect the rest of the target chain to the origin chain
setNextLink(aOriginFs, aTargetFs);
} else {
// collect all the links
List<AnnotationFS> links = new ArrayList<>();
links.addAll(collectLinks(originChain));
links.addAll(collectLinks(targetChain));
// sort them ascending by begin and descending by end (default UIMA order)
links.sort(new AnnotationComparator());
// thread them
AnnotationFS prev = null;
for (AnnotationFS link : links) {
if (prev != null) {
// Set next link
setNextLink(prev, link);
// // Clear arc label - it makes no sense in this mode
// setLabel(prev, aFeature, null);
}
prev = link;
}
// make sure the last link terminates the chain
setNextLink(links.get(links.size() - 1), null);
// the chain head needs to point to the first link
setFirstLink(originChain, links.get(0));
// we don't need the second chain head anymore
aCas.removeFsFromIndexes(targetChain);
}
} else {
// if the two links are in the same chain, we just ignore the action
if (isLinkedListBehavior()) {
throw new IllegalStateException("Cannot connect two spans that are already part of the same chain");
}
}
}
publishEvent(new ChainLinkCreatedEvent(this, aDocument, aUsername, getLayer(), aOriginFs));
// We do not actually create a new FS for the arc. Features are set on the originFS.
return WebAnnoCasUtil.getAddr(aOriginFs);
}
use of de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.AnnotationComparator in project webanno by webanno.
the class RelationOverlapBehavior method onRender.
@Override
public void onRender(TypeAdapter aAdapter, VDocument aResponse, Map<AnnotationFS, VArc> aAnnoToArcIdx) {
if (aAnnoToArcIdx.isEmpty()) {
return;
}
final AnnotationLayer layer = aAdapter.getLayer();
final RelationAdapter adapter = (RelationAdapter) aAdapter;
final CAS cas = aAnnoToArcIdx.keySet().iterator().next().getCAS();
final Type type = getType(cas, adapter.getAnnotationTypeName());
final Feature targetFeature = type.getFeatureByBaseName(adapter.getTargetFeatureName());
final Feature sourceFeature = type.getFeatureByBaseName(adapter.getSourceFeatureName());
AnnotationComparator cmp = new AnnotationComparator();
final List<AnnotationFS> sortedRelations = aAnnoToArcIdx.keySet().stream().sorted(cmp).collect(Collectors.toList());
switch(layer.getOverlapMode()) {
case ANY_OVERLAP:
// Nothing to check
break;
case NO_OVERLAP:
{
Set<AnnotationFS> overlapping = new HashSet<>();
Set<AnnotationFS> stacking = new HashSet<>();
overlappingOrStackingRelations(sortedRelations, sourceFeature, targetFeature, stacking, overlapping);
overlapping.forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Overlap is not permitted.")));
stacking.forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Stacking is not permitted.")));
break;
}
case STACKING_ONLY:
{
// Here, we must find all overlapping relations because they are not permitted
overlappingNonStackingRelations(sortedRelations, sourceFeature, targetFeature).forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Only stacking is permitted.")));
break;
}
case OVERLAP_ONLY:
// Here, we must find all stacked relations because they are not permitted.
// We go through all relations based on the their offsets. Stacked relations must have
// the same offsets (at least if we consider relations as having a direction, i.e.
// that a relation A->B does not count as stacked on a relation B->A). But since there
// can be multiple relations going out from the same sourceFS, we need to consider all
// of them for potential stacking.
stackingRelations(sortedRelations, sourceFeature, targetFeature).forEach(fs -> aResponse.add(new VComment(new VID(fs), ERROR, "Stacking is not permitted.")));
break;
}
}
Aggregations