use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.
the class RemoveDanglingChainLinksRepair method repair.
@Override
public void repair(Project aProject, CAS aCas, List<LogMessage> aMessages) {
for (AnnotationLayer layer : annotationService.listAnnotationLayer(aProject)) {
if (!WebAnnoConst.CHAIN_TYPE.equals(layer.getType())) {
continue;
}
List<FeatureStructure> chains = new ArrayList<>(selectFS(aCas, getType(aCas, layer.getName() + "Chain")));
List<AnnotationFS> links = new ArrayList<>(select(aCas, getType(aCas, layer.getName() + "Link")));
for (FeatureStructure chain : chains) {
AnnotationFS link = FSUtil.getFeature(chain, "first", AnnotationFS.class);
while (link != null) {
links.remove(link);
link = FSUtil.getFeature(link, "next", AnnotationFS.class);
}
}
// Delete those relations that pointed to deleted spans
if (!links.isEmpty()) {
links.forEach(aCas::removeFsFromIndexes);
aMessages.add(new LogMessage(this, LogLevel.INFO, "Removed [%d] dangling links in layer [" + layer.getName() + "].", links.size()));
}
}
}
use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.
the class RemoveDanglingRelationsRepair method repair.
@Override
public void repair(Project aProject, CAS aCas, List<LogMessage> aMessages) {
Set<FeatureStructure> nonIndexed = getNonIndexedFSes(aCas);
Set<FeatureStructure> toDelete = new LinkedHashSet<>();
for (AnnotationFS fs : aCas.getAnnotationIndex()) {
Type t = fs.getType();
Feature sourceFeat = t.getFeatureByBaseName(FEAT_REL_SOURCE);
Feature targetFeat = t.getFeatureByBaseName(FEAT_REL_TARGET);
// Is this a relation?
if (!(sourceFeat != null && targetFeat != null)) {
continue;
}
FeatureStructure source = fs.getFeatureValue(sourceFeat);
FeatureStructure target = fs.getFeatureValue(targetFeat);
// Are there null end-points or does it point to deleted spans?
if (source == null || target == null || nonIndexed.contains(source) || nonIndexed.contains(target)) {
toDelete.add(fs);
continue;
}
RelationAdapter relationAdapter = (RelationAdapter) annotationService.findAdapter(aProject, fs);
Feature relationSourceAttachFeature = null;
Feature relationTargetAttachFeature = null;
if (relationAdapter.getAttachFeatureName() != null) {
relationSourceAttachFeature = sourceFeat.getRange().getFeatureByBaseName(relationAdapter.getAttachFeatureName());
relationTargetAttachFeature = targetFeat.getRange().getFeatureByBaseName(relationAdapter.getAttachFeatureName());
}
// Here we get the annotations that the relation is pointing to in the UI
if (relationSourceAttachFeature != null) {
source = (AnnotationFS) source.getFeatureValue(relationSourceAttachFeature);
}
if (relationTargetAttachFeature != null) {
target = (AnnotationFS) target.getFeatureValue(relationTargetAttachFeature);
}
// annotations linked to in the UI?
if (source == null || target == null || nonIndexed.contains(source) || nonIndexed.contains(target)) {
toDelete.add(fs);
continue;
}
}
// Delete those relations that pointed to deleted spans
if (!toDelete.isEmpty()) {
toDelete.forEach(aCas::removeFsFromIndexes);
aMessages.add(new LogMessage(this, INFO, "Removed [%d] dangling relations.", toDelete.size()));
}
}
use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.
the class RemoveDanglingRelationsRepairTest method test.
@Test
public void test() throws Exception {
JCas jcas = JCasFactory.createJCas();
jcas.setDocumentText("This is a test.");
Token span1 = new Token(jcas, 0, 4);
span1.addToIndexes();
Token span2 = new Token(jcas, 6, 8);
Dependency dep = new Dependency(jcas, 0, 8);
dep.setGovernor(span1);
dep.setDependent(span2);
dep.addToIndexes();
List<LogMessage> messages = new ArrayList<>();
CasDoctor cd = new CasDoctor(RemoveDanglingRelationsRepair.class, AllFeatureStructuresIndexedCheck.class);
// A project is not required for this check
boolean result = cd.analyze(null, jcas.getCas(), messages);
// A project is not required for this repair
cd.repair(null, jcas.getCas(), messages);
assertFalse(result);
messages.forEach(System.out::println);
}
use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.
the class NoMultipleIncomingRelationsCheckTest method testOK.
@Test
public void testOK() throws Exception {
AnnotationLayer relationLayer = new AnnotationLayer();
relationLayer.setName(Dependency.class.getName());
relationLayer.setType(WebAnnoConst.RELATION_TYPE);
Mockito.when(annotationService.listAnnotationLayer(Mockito.isNull())).thenReturn(Arrays.asList(relationLayer));
JCas jcas = JCasFactory.createJCas();
jcas.setDocumentText("This is a test.");
Token spanThis = new Token(jcas, 0, 4);
spanThis.addToIndexes();
Token spanIs = new Token(jcas, 6, 8);
spanIs.addToIndexes();
Token spanA = new Token(jcas, 9, 10);
spanA.addToIndexes();
Dependency dep1 = new Dependency(jcas, 0, 8);
dep1.setGovernor(spanThis);
dep1.setDependent(spanIs);
dep1.addToIndexes();
Dependency dep2 = new Dependency(jcas, 6, 10);
dep2.setGovernor(spanIs);
dep2.setDependent(spanA);
dep2.addToIndexes();
List<LogMessage> messages = new ArrayList<>();
boolean result = check.check(null, jcas.getCas(), messages);
messages.forEach(System.out::println);
assertTrue(result);
}
use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.
the class NoMultipleIncomingRelationsCheck method check.
@Override
public boolean check(Project aProject, CAS aCas, List<LogMessage> aMessages) {
boolean ok = true;
if (annotationService == null) {
return ok;
}
List<AnnotationLayer> allAnnoLayers = annotationService.listAnnotationLayer(aProject);
if (allAnnoLayers != null) {
for (AnnotationLayer layer : allAnnoLayers) {
if (!WebAnnoConst.RELATION_TYPE.equals(layer.getType())) {
continue;
}
if (!Dependency.class.getName().equals(layer.getName())) {
continue;
}
Type type;
try {
type = getType(aCas, layer.getName());
} catch (IllegalArgumentException e) {
// can skip checking the layer because there will be no annotations anyway.
continue;
}
// Remember all nodes that already have a known incoming relation.
// Map from the target to the existing source, so the source can be used
// to provide a better debugging output.
Map<AnnotationFS, AnnotationFS> incoming = new HashMap<>();
for (AnnotationFS rel : select(aCas, type)) {
AnnotationFS source = getFeature(rel, FEAT_REL_SOURCE, AnnotationFS.class);
AnnotationFS target = getFeature(rel, FEAT_REL_TARGET, AnnotationFS.class);
AnnotationFS existingSource = incoming.get(target);
if (existingSource != null) {
// Debug output should include sentence number to make the orientation
// easier
Optional<Integer> sentenceNumber = Optional.empty();
try {
sentenceNumber = Optional.of(WebAnnoCasUtil.getSentenceNumber(target.getCAS(), target.getBegin()));
} catch (IndexOutOfBoundsException e) {
// ignore this error and don't output sentence number
sentenceNumber = Optional.empty();
}
if (sentenceNumber.isPresent()) {
aMessages.add(new LogMessage(this, LogLevel.WARN, "Sentence %d: Relation [%s] -> [%s] points to span that already has an " + "incoming relation [%s] -> [%s].", sentenceNumber.get(), source.getCoveredText(), target.getCoveredText(), existingSource.getCoveredText(), target.getCoveredText()));
} else {
aMessages.add(new LogMessage(this, LogLevel.WARN, "Relation [%s] -> [%s] points to span that already has an " + "incoming relation [%s] -> [%s].", source.getCoveredText(), target.getCoveredText(), existingSource.getCoveredText(), target.getCoveredText()));
}
// This check only logs warnings - it should not fail. Having multiple
// incoming edges is not a serious problem.
// ok = false;
} else {
incoming.put(target, source);
}
}
}
}
return ok;
}
Aggregations