use of de.tudarmstadt.ukp.clarin.webanno.api.AttachedAnnotation in project webanno by webanno.
the class AnnotationDetailEditorPanel method deleteAnnotation.
private void deleteAnnotation(CAS aCas, AnnotatorState state, AnnotationFS fs, AnnotationLayer layer, TypeAdapter adapter) {
RequestCycle.get().find(AjaxRequestTarget.class).ifPresent(_target -> _target.addChildren(getPage(), IFeedback.class));
// point to it directly or indirectly via the attachFeature.
if (adapter instanceof SpanAdapter) {
for (AttachedAnnotation rel : annotationService.getAttachedRels(layer, fs)) {
RelationAdapter relationAdapter = (RelationAdapter) annotationService.findAdapter(state.getProject(), rel.getRelation());
relationAdapter.delete(state.getDocument(), state.getUser().getUsername(), aCas, new VID(rel.getRelation()));
info(generateMessage(relationAdapter.getLayer(), null, true));
}
}
// to be deleted: the link feature must be the type of the FS or it must be generic.
if (adapter instanceof SpanAdapter) {
for (AnnotationFeature linkFeature : annotationService.listAttachedLinkFeatures(layer)) {
Type linkHostType = CasUtil.getType(aCas, linkFeature.getLayer().getName());
for (FeatureStructure linkHostFS : CasUtil.selectFS(aCas, linkHostType)) {
List<LinkWithRoleModel> links = adapter.getFeatureValue(linkFeature, linkHostFS);
Iterator<LinkWithRoleModel> i = links.iterator();
boolean modified = false;
while (i.hasNext()) {
LinkWithRoleModel link = i.next();
if (link.targetAddr == getAddr(fs)) {
i.remove();
info("Cleared slot [" + link.role + "] in feature [" + linkFeature.getUiName() + "] on [" + linkFeature.getLayer().getUiName() + "]");
LOG.debug("Cleared slot [" + link.role + "] in feature [" + linkFeature.getName() + "] on annotation [" + getAddr(linkHostFS) + "]");
modified = true;
}
}
if (modified) {
setFeature(linkHostFS, linkFeature, links);
// If the currently armed slot is part of this link, then we disarm the slot
// to avoid the armed slot no longer pointing at the index which the user
// had selected it to point at.
FeatureState armedFeature = state.getArmedFeature();
if (armedFeature != null && WebAnnoCasUtil.getAddr(linkHostFS) == armedFeature.vid.getId() && armedFeature.feature.equals(linkFeature)) {
state.clearArmedSlot();
}
}
}
}
}
// relation.
if (adapter instanceof RelationAdapter) {
// Do nothing ;)
}
// Actually delete annotation
adapter.delete(state.getDocument(), state.getUser().getUsername(), aCas, state.getSelection().getAnnotation());
info(generateMessage(state.getSelectedAnnotationLayer(), null, true));
}
use of de.tudarmstadt.ukp.clarin.webanno.api.AttachedAnnotation in project webanno by webanno.
the class AttachedAnnotationListPanel method getRelationInfo.
private List<AttachedAnnotationInfo> getRelationInfo() {
Selection selection = getModelObject().getSelection();
if (!selection.isSet() || selection.getAnnotation().getId() == NONE) {
return Collections.emptyList();
}
CAS cas;
try {
cas = page.getEditorCas();
} catch (IOException e) {
// If we have trouble accessing the CAS, we probably never get here anyway...
// the AnnotationPageBase should already have found the issue and displayed some
// error to the user.
LOG.error("Unable to access editor CAS", e);
return Collections.emptyList();
}
AnnotationFS annoFs = selectAnnotationByAddr(cas, selection.getAnnotation().getId());
VID localVid = new VID(annoFs);
List<AttachedAnnotation> attachedAnnotations = new ArrayList<>();
attachedAnnotations.addAll(schemaService.getAttachedRels(getModelObject().getSelectedAnnotationLayer(), annoFs));
attachedAnnotations.addAll(schemaService.getAttachedLinks(getModelObject().getSelectedAnnotationLayer(), annoFs));
Map<AnnotationLayer, List<AnnotationFeature>> featureCache = new HashMap<>();
Map<AnnotationLayer, Renderer> rendererCache = new HashMap<>();
Map<AnnotationLayer, TypeAdapter> adapterCache = new HashMap<>();
List<AttachedAnnotationInfo> result = new ArrayList<>();
for (AttachedAnnotation rel : attachedAnnotations) {
AnnotationLayer layer = rel.getLayer();
List<AnnotationFeature> features = featureCache.get(layer);
TypeAdapter adapter;
Renderer renderer;
if (features == null) {
features = schemaService.listSupportedFeatures(layer);
featureCache.put(layer, features);
adapter = schemaService.getAdapter(layer);
adapterCache.put(layer, adapter);
renderer = layerRegistry.getLayerSupport(layer).createRenderer(layer, () -> featureCache.get(layer));
rendererCache.put(layer, renderer);
} else {
adapter = adapterCache.get(layer);
renderer = rendererCache.get(layer);
}
Map<String, String> renderedFeatures;
if (rel.getRelation() != null) {
renderedFeatures = renderer.renderLabelFeatureValues(adapter, rel.getRelation(), features);
} else {
renderedFeatures = renderer.renderLabelFeatureValues(adapter, rel.getEndpoint(), features);
}
String labelText = TypeUtil.getUiLabelText(adapter, renderedFeatures);
if (isEmpty(labelText)) {
labelText = rel.getLayer().getUiName();
} else {
labelText = rel.getLayer().getUiName() + ": " + labelText;
}
AttachedAnnotationInfo i = new AttachedAnnotationInfo(layer, localVid, rel.getRelation() != null ? new VID(rel.getRelation()) : null, new VID(rel.getEndpoint()), labelText, rel.getEndpoint().getCoveredText(), rel.getDirection());
result.add(i);
}
return result;
}
use of de.tudarmstadt.ukp.clarin.webanno.api.AttachedAnnotation in project webanno by webanno.
the class AnnotationSchemaServiceImpl method getAttachedRels.
@Override
@Transactional
public List<AttachedAnnotation> getAttachedRels(AnnotationLayer aLayer, AnnotationFS aFs) {
CAS cas = aFs.getCAS();
List<AttachedAnnotation> result = new ArrayList<>();
for (AnnotationLayer relationLayer : listAttachedRelationLayers(aLayer)) {
RelationAdapter relationAdapter = (RelationAdapter) getAdapter(relationLayer);
Type relationType = CasUtil.getType(cas, relationLayer.getName());
Feature sourceFeature = relationType.getFeatureByBaseName(relationAdapter.getSourceFeatureName());
Feature targetFeature = relationType.getFeatureByBaseName(relationAdapter.getTargetFeatureName());
// This code is already prepared for the day that relations can go between
// different layers and may have different attach features for the source and
// target layers.
Feature relationSourceAttachFeature = null;
Feature relationTargetAttachFeature = null;
if (relationAdapter.getAttachFeatureName() != null) {
relationSourceAttachFeature = sourceFeature.getRange().getFeatureByBaseName(relationAdapter.getAttachFeatureName());
relationTargetAttachFeature = targetFeature.getRange().getFeatureByBaseName(relationAdapter.getAttachFeatureName());
}
for (AnnotationFS relationFS : CasUtil.select(cas, relationType)) {
if (!(relationFS instanceof AnnotationFS)) {
continue;
}
// Here we get the annotations that the relation is pointing to in the UI
AnnotationFS sourceFS;
if (relationSourceAttachFeature != null) {
sourceFS = (AnnotationFS) relationFS.getFeatureValue(sourceFeature).getFeatureValue(relationSourceAttachFeature);
} else {
sourceFS = (AnnotationFS) relationFS.getFeatureValue(sourceFeature);
}
AnnotationFS targetFS;
if (relationTargetAttachFeature != null) {
targetFS = (AnnotationFS) relationFS.getFeatureValue(targetFeature).getFeatureValue(relationTargetAttachFeature);
} else {
targetFS = (AnnotationFS) relationFS.getFeatureValue(targetFeature);
}
if (sourceFS == null || targetFS == null) {
StringBuilder message = new StringBuilder();
message.append("Relation [" + relationAdapter.getLayer().getName() + "] with id [" + getAddr(relationFS) + "] has loose ends - cannot identify attached annotations.");
if (relationAdapter.getAttachFeatureName() != null) {
message.append("\nRelation [" + relationAdapter.getLayer().getName() + "] attached to feature [" + relationAdapter.getAttachFeatureName() + "].");
}
message.append("\nSource: " + sourceFS);
message.append("\nTarget: " + targetFS);
log.warn("{}", message.toString());
continue;
}
boolean isIncoming = isSame(targetFS, aFs);
boolean isOutgoing = isSame(sourceFS, aFs);
if (isIncoming && isOutgoing) {
result.add(new AttachedAnnotation(relationLayer, relationFS, sourceFS, LOOP));
} else if (isIncoming) {
result.add(new AttachedAnnotation(relationLayer, relationFS, sourceFS, INCOMING));
} else if (isOutgoing) {
result.add(new AttachedAnnotation(relationLayer, relationFS, targetFS, OUTGOING));
}
}
}
return result;
}
use of de.tudarmstadt.ukp.clarin.webanno.api.AttachedAnnotation in project webanno by webanno.
the class AnnotationSchemaServiceImpl method getAttachedLinks.
@Override
@Transactional
public List<AttachedAnnotation> getAttachedLinks(AnnotationLayer aLayer, AnnotationFS aFs) {
CAS cas = aFs.getCAS();
List<AttachedAnnotation> result = new ArrayList<>();
TypeAdapter adapter = getAdapter(aLayer);
if (adapter instanceof SpanAdapter) {
for (AnnotationFeature linkFeature : listAttachedLinkFeatures(aLayer)) {
if (MultiValueMode.ARRAY.equals(linkFeature.getMultiValueMode()) && LinkMode.WITH_ROLE.equals(linkFeature.getLinkMode())) {
// Fetch slot hosts that could link to the current FS and check if any of
// them actually links to the current FS
Type linkHost = CasUtil.getType(cas, linkFeature.getLayer().getName());
for (FeatureStructure linkFS : CasUtil.selectFS(cas, linkHost)) {
if (!(linkFS instanceof AnnotationFS)) {
continue;
}
List<LinkWithRoleModel> links = adapter.getFeatureValue(linkFeature, linkFS);
for (int li = 0; li < links.size(); li++) {
LinkWithRoleModel link = links.get(li);
AnnotationFS linkTarget = selectByAddr(cas, AnnotationFS.class, link.targetAddr);
// our list of attached links.
if (isSame(linkTarget, aFs)) {
result.add(new AttachedAnnotation(linkFeature.getLayer(), (AnnotationFS) linkFS, INCOMING));
}
}
}
}
}
}
return result;
}
use of de.tudarmstadt.ukp.clarin.webanno.api.AttachedAnnotation in project webanno by webanno.
the class AnnotationDetailEditorPanel method checkAttachStatus.
private AttachStatus checkAttachStatus(AjaxRequestTarget aTarget, Project aProject, AnnotationFS aFS) {
AnnotationLayer layer = annotationService.findLayer(aProject, aFS);
AttachStatus attachStatus = new AttachStatus();
List<AttachedAnnotation> attachedRels = annotationService.getAttachedRels(layer, aFS);
boolean attachedToReadOnlyRels = attachedRels.stream().anyMatch(rel -> rel.getLayer().isReadonly());
if (attachedToReadOnlyRels) {
attachStatus.readOnlyAttached |= true;
}
attachStatus.attachCount += attachedRels.size();
// We do not count these atm since they only exist for built-in layers and are not
// visible in the UI for the user.
// Set<AnnotationFS> attachedSpans = getAttachedSpans(aFS, layer);
// boolean attachedToReadOnlySpans = attachedSpans.stream().anyMatch(relFS -> {
// AnnotationLayer relLayer = annotationService.getLayer(aProject, relFS);
// return relLayer.isReadonly();
// });
// if (attachedToReadOnlySpans) {
// attachStatus.readOnlyAttached |= true;
// }
// attachStatus.attachCount += attachedSpans.size();
List<AttachedAnnotation> attachedLinks = annotationService.getAttachedLinks(layer, aFS);
boolean attachedToReadOnlyLinks = attachedLinks.stream().anyMatch(rel -> rel.getLayer().isReadonly());
if (attachedToReadOnlyLinks) {
attachStatus.readOnlyAttached |= true;
}
attachStatus.attachCount += attachedLinks.size();
return attachStatus;
}
Aggregations