Search in sources :

Example 1 with LogMessage

use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.

the class CasDoctor method analyze.

public boolean analyze(Project aProject, CAS aCas, List<LogMessage> aMessages, boolean aFatalChecks) throws CasDoctorException {
    long tStart = System.currentTimeMillis();
    boolean ok = true;
    for (Class<? extends Check> checkClass : checkClasses) {
        try {
            long tStartTask = System.currentTimeMillis();
            Check check = checkClass.newInstance();
            if (context != null) {
                context.getAutowireCapableBeanFactory().autowireBean(check);
            }
            LOG.debug("CasDoctor analysis [" + checkClass.getSimpleName() + "] running...");
            ok &= check.check(aProject, aCas, aMessages);
            LOG.debug("CasDoctor analysis [" + checkClass.getSimpleName() + "] completed in " + (System.currentTimeMillis() - tStartTask) + "ms");
        } catch (InstantiationException | IllegalAccessException e) {
            aMessages.add(new LogMessage(this, LogLevel.ERROR, "Cannot instantiate [%s]: %s", checkClass.getSimpleName(), ExceptionUtils.getRootCauseMessage(e)));
            LOG.error("Error running check", e);
        }
    }
    if (!ok) {
        aMessages.forEach(s -> LOG.error("{}", s));
    }
    if (!ok && aFatalChecks) {
        throw new CasDoctorException(aMessages);
    }
    LOG.debug("CasDoctor completed all analyses in " + (System.currentTimeMillis() - tStart) + "ms");
    return ok;
}
Also used : LogMessage(de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage) Check(de.tudarmstadt.ukp.clarin.webanno.diag.checks.Check)

Example 2 with LogMessage

use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.

the class CasMerge method reMergeCas.

/**
 * Using {@code DiffResult}, determine the annotations to be deleted from the randomly generated
 * MergeCase. The initial Merge CAs is stored under a name {@code CurationPanel#CURATION_USER}.
 * <p>
 * Any similar annotations stacked in a {@code CasDiff2.Position} will be assumed a difference
 * <p>
 * Any two annotation with different value will be assumed a difference
 * <p>
 * Any non stacked empty/null annotations are assumed agreement
 * <p>
 * Any non stacked annotations with similar values for each of the features are assumed
 * agreement
 * <p>
 * Any two link mode / slotable annotations which agree on the base features are assumed
 * agreement
 *
 * @param aDiff
 *            the {@link DiffResult}
 * @param aCases
 *            a map of {@code CAS}s for each users and the random merge
 */
public void reMergeCas(DiffResult aDiff, SourceDocument aTargetDocument, String aTargetUsername, CAS aTargetCas, Map<String, CAS> aCases) throws AnnotationException, UIMAException {
    silenceEvents = true;
    int updated = 0;
    int created = 0;
    Set<LogMessage> messages = new LinkedHashSet<>();
    // Remove any annotations from the target CAS - keep type system, sentences and tokens
    clearAnnotations(aTargetCas);
    // If there is nothing to merge, bail out
    if (aCases.isEmpty()) {
        return;
    }
    // Set up a cache for resolving type to layer to avoid hammering the DB as we process each
    // position
    Map<String, AnnotationLayer> type2layer = aDiff.getPositions().stream().map(Position::getType).distinct().map(type -> schemaService.findLayer(aTargetDocument.getProject(), type)).collect(toMap(AnnotationLayer::getName, identity()));
    List<String> layerNames = new ArrayList<>(type2layer.keySet());
    // Move token layer to front
    if (layerNames.contains(Token.class.getName())) {
        layerNames.remove(Token.class.getName());
        layerNames.add(0, Token.class.getName());
    }
    // Move sentence layer to front
    if (layerNames.contains(Sentence.class.getName())) {
        layerNames.remove(Sentence.class.getName());
        layerNames.add(0, Sentence.class.getName());
    }
    // and sentences before the others)
    for (String layerName : layerNames) {
        List<SpanPosition> positions = aDiff.getPositions().stream().filter(pos -> layerName.equals(pos.getType())).filter(pos -> pos instanceof SpanPosition).map(pos -> (SpanPosition) pos).filter(pos -> pos.getFeature() == null).collect(Collectors.toList());
        if (positions.isEmpty()) {
            continue;
        }
        LOG.debug("Processing {} span positions on layer {}", positions.size(), layerName);
        // Slots are also excluded for the moment
        for (SpanPosition position : positions) {
            LOG.trace(" |   processing {}", position);
            ConfigurationSet cfgs = aDiff.getConfigurationSet(position);
            if (!shouldMerge(aDiff, cfgs)) {
                continue;
            }
            try {
                Map<String, List<CAS>> casMap = new LinkedHashMap<>();
                aCases.forEach((k, v) -> casMap.put(k, asList(v)));
                AnnotationFS sourceFS = (AnnotationFS) cfgs.getConfigurations().get(0).getRepresentative(casMap);
                CasMergeOperationResult result = mergeSpanAnnotation(aTargetDocument, aTargetUsername, type2layer.get(position.getType()), aTargetCas, sourceFS, false);
                LOG.trace(" `-> merged annotation with agreement");
                switch(result.getState()) {
                    case CREATED:
                        created++;
                        break;
                    case UPDATED:
                        updated++;
                        break;
                }
            } catch (AnnotationException e) {
                LOG.trace(" `-> not merged annotation: {}", e.getMessage());
                messages.add(LogMessage.error(this, "%s", e.getMessage()));
            }
        }
    }
    // After the spans are in place, we can merge the slot features
    for (String layerName : layerNames) {
        List<SpanPosition> positions = aDiff.getPositions().stream().filter(pos -> layerName.equals(pos.getType())).filter(pos -> pos instanceof SpanPosition).map(pos -> (SpanPosition) pos).filter(pos -> pos.getFeature() != null).collect(Collectors.toList());
        if (positions.isEmpty()) {
            continue;
        }
        LOG.debug("Processing {} slot positions on layer [{}]", positions.size(), layerName);
        for (SpanPosition position : positions) {
            LOG.trace(" |   processing {}", position);
            ConfigurationSet cfgs = aDiff.getConfigurationSet(position);
            if (!shouldMerge(aDiff, cfgs)) {
                continue;
            }
            try {
                Map<String, List<CAS>> casMap = new LinkedHashMap<>();
                aCases.forEach((k, v) -> casMap.put(k, asList(v)));
                AnnotationFS sourceFS = (AnnotationFS) cfgs.getConfigurations().get(0).getRepresentative(casMap);
                AID sourceFsAid = cfgs.getConfigurations().get(0).getRepresentativeAID();
                mergeSlotFeature(aTargetDocument, aTargetUsername, type2layer.get(position.getType()), aTargetCas, sourceFS, sourceFsAid.feature, sourceFsAid.index);
                LOG.trace(" `-> merged annotation with agreement");
            } catch (AnnotationException e) {
                LOG.trace(" `-> not merged annotation: {}", e.getMessage());
                messages.add(LogMessage.error(this, "%s", e.getMessage()));
            }
        }
    }
    // Finally, we merge the relations
    for (String layerName : layerNames) {
        List<RelationPosition> positions = aDiff.getPositions().stream().filter(pos -> layerName.equals(pos.getType())).filter(pos -> pos instanceof RelationPosition).map(pos -> (RelationPosition) pos).collect(Collectors.toList());
        if (positions.isEmpty()) {
            continue;
        }
        LOG.debug("Processing {} relation positions on layer [{}]", positions.size(), layerName);
        for (RelationPosition position : positions) {
            LOG.trace(" |   processing {}", position);
            ConfigurationSet cfgs = aDiff.getConfigurationSet(position);
            if (!shouldMerge(aDiff, cfgs)) {
                continue;
            }
            try {
                Map<String, List<CAS>> casMap = new LinkedHashMap<>();
                aCases.forEach((k, v) -> casMap.put(k, asList(v)));
                AnnotationFS sourceFS = (AnnotationFS) cfgs.getConfigurations().get(0).getRepresentative(casMap);
                CasMergeOperationResult result = mergeRelationAnnotation(aTargetDocument, aTargetUsername, type2layer.get(position.getType()), aTargetCas, sourceFS, false);
                LOG.trace(" `-> merged annotation with agreement");
                switch(result.getState()) {
                    case CREATED:
                        created++;
                        break;
                    case UPDATED:
                        updated++;
                        break;
                }
            } catch (AnnotationException e) {
                LOG.trace(" `-> not merged annotation: {}", e.getMessage());
                messages.add(LogMessage.error(this, "%s", e.getMessage()));
            }
        }
    }
    if (eventPublisher != null) {
        eventPublisher.publishEvent(new BulkAnnotationEvent(this, aTargetDocument, aTargetUsername, null));
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) WebAnnoCasUtil.isBasicFeature(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.isBasicFeature) TypeAdapter(de.tudarmstadt.ukp.clarin.webanno.api.annotation.adapter.TypeAdapter) Configuration(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.CasDiff.Configuration) ConfigurationSet(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.CasDiff.ConfigurationSet) SpanAdapter(de.tudarmstadt.ukp.clarin.webanno.api.annotation.adapter.SpanAdapter) LoggerFactory(org.slf4j.LoggerFactory) WebAnnoCasUtil(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil) Sentence(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Sentence) AnnotationException(de.tudarmstadt.ukp.clarin.webanno.api.annotation.exception.AnnotationException) LinkMode(de.tudarmstadt.ukp.clarin.webanno.model.LinkMode) FSUtil(org.apache.uima.fit.util.FSUtil) Type(org.apache.uima.cas.Type) TypeSystemDescription(org.apache.uima.resource.metadata.TypeSystemDescription) DocumentMetaData(de.tudarmstadt.ukp.dkpro.core.api.metadata.type.DocumentMetaData) CASImpl(org.apache.uima.cas.impl.CASImpl) Collectors.toMap(java.util.stream.Collectors.toMap) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) ApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) WebAnnoCasUtil.selectAnnotationByAddr(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.selectAnnotationByAddr) FeatureStructure(org.apache.uima.cas.FeatureStructure) Position(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.api.Position) WebAnnoCasUtil.createToken(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.createToken) UIMAException(org.apache.uima.UIMAException) MultiValueMode(de.tudarmstadt.ukp.clarin.webanno.model.MultiValueMode) WebAnnoCasUtil.isEquivalentSpanAnnotation(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.isEquivalentSpanAnnotation) LoadingCache(com.github.benmanes.caffeine.cache.LoadingCache) DiffResult(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.CasDiff.DiffResult) WebAnnoCasUtil.copyDocumentMetadata(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.copyDocumentMetadata) Set(java.util.Set) CASCompleteSerializer(org.apache.uima.cas.impl.CASCompleteSerializer) WebAnnoCasUtil.exists(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.exists) Collectors(java.util.stream.Collectors) WebAnnoCasUtil.selectSentences(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.selectSentences) Serialization.serializeCASComplete(org.apache.uima.cas.impl.Serialization.serializeCASComplete) List(java.util.List) RelationPosition(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.relation.RelationPosition) AnnotationLayer(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer) FSUtil.getFeature(org.apache.uima.fit.util.FSUtil.getFeature) SourceDocument(de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument) Function.identity(java.util.function.Function.identity) WebAnnoCasUtil.isPrimitiveType(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.isPrimitiveType) CasUtil.getType(org.apache.uima.fit.util.CasUtil.getType) SpanPosition(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.span.SpanPosition) AnnotationFS(org.apache.uima.cas.text.AnnotationFS) WebAnnoCasUtil.selectTokens(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.selectTokens) FEAT_REL_SOURCE(de.tudarmstadt.ukp.clarin.webanno.api.WebAnnoConst.FEAT_REL_SOURCE) FEAT_REL_TARGET(de.tudarmstadt.ukp.clarin.webanno.api.WebAnnoConst.FEAT_REL_TARGET) AID(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.internal.AID) LogMessage(de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage) CAS(org.apache.uima.cas.CAS) Feature(org.apache.uima.cas.Feature) HashMap(java.util.HashMap) WebAnnoCasUtil.setFeature(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.setFeature) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) AnnotationSchemaService(de.tudarmstadt.ukp.clarin.webanno.api.AnnotationSchemaService) Token(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token) CasFactory(org.apache.uima.fit.factory.CasFactory) WebAnnoCasUtil.createSentence(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.createSentence) Serialization.deserializeCASComplete(org.apache.uima.cas.impl.Serialization.deserializeCASComplete) LinkedHashSet(java.util.LinkedHashSet) LinkWithRoleModel(de.tudarmstadt.ukp.clarin.webanno.api.annotation.model.LinkWithRoleModel) WebAnnoCasUtil.getAddr(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.getAddr) Caffeine(com.github.benmanes.caffeine.cache.Caffeine) Logger(org.slf4j.Logger) CasUtil.selectAt(org.apache.uima.fit.util.CasUtil.selectAt) WebAnnoCasUtil.getRealCas(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.getRealCas) RelationAdapter(de.tudarmstadt.ukp.clarin.webanno.api.annotation.adapter.RelationAdapter) CasUtil(org.apache.uima.fit.util.CasUtil) CasUtil.selectCovered(org.apache.uima.fit.util.CasUtil.selectCovered) Collectors.toList(java.util.stream.Collectors.toList) BulkAnnotationEvent(de.tudarmstadt.ukp.clarin.webanno.api.annotation.event.BulkAnnotationEvent) AnnotationFeature(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature) IllegalFeatureValueException(de.tudarmstadt.ukp.clarin.webanno.api.annotation.exception.IllegalFeatureValueException) VID(de.tudarmstadt.ukp.clarin.webanno.api.annotation.model.VID) ArrayList(java.util.ArrayList) WebAnnoCasUtil.createToken(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.createToken) Token(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token) AnnotationLayer(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer) LinkedHashMap(java.util.LinkedHashMap) AnnotationFS(org.apache.uima.cas.text.AnnotationFS) AnnotationException(de.tudarmstadt.ukp.clarin.webanno.api.annotation.exception.AnnotationException) Arrays.asList(java.util.Arrays.asList) List(java.util.List) ArrayList(java.util.ArrayList) Collectors.toList(java.util.stream.Collectors.toList) AID(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.internal.AID) RelationPosition(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.relation.RelationPosition) Sentence(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Sentence) WebAnnoCasUtil.createSentence(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.createSentence) ConfigurationSet(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.CasDiff.ConfigurationSet) LogMessage(de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage) BulkAnnotationEvent(de.tudarmstadt.ukp.clarin.webanno.api.annotation.event.BulkAnnotationEvent) SpanPosition(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.span.SpanPosition)

Example 3 with LogMessage

use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.

the class AllFeatureStructuresIndexedCheck method check.

@Override
public boolean check(Project aProject, CAS aCas, List<LogMessage> aMessages) {
    Map<FeatureStructure, FeatureStructure> nonIndexed = getNonIndexedFSesWithOwner(aCas);
    if (!nonIndexed.isEmpty()) {
        aMessages.add(new LogMessage(this, LogLevel.ERROR, "Unindexed feature structures: %d", nonIndexed.size()));
        int count = 0;
        for (Entry<FeatureStructure, FeatureStructure> e : nonIndexed.entrySet()) {
            if (count >= 100) {
                break;
            }
            aMessages.add(LogMessage.error(this, "Non-indexed feature structure [%s] reachable through [%s]", e.getKey(), e.getValue()));
            count++;
        }
        if (count >= 100) {
            aMessages.add(LogMessage.error(this, "In total [%d] annotations were reachable but not indexed", count));
        }
    }
    return nonIndexed.isEmpty();
}
Also used : FeatureStructure(org.apache.uima.cas.FeatureStructure) LogMessage(de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage)

Example 4 with LogMessage

use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.

the class NoMultipleIncomingRelationsCheckTest method testFail.

@Test
public void testFail() 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, 5, 7);
    spanIs.addToIndexes();
    Token spanA = new Token(jcas, 8, 9);
    spanA.addToIndexes();
    Dependency dep1 = new Dependency(jcas, 0, 7);
    dep1.setGovernor(spanThis);
    dep1.setDependent(spanIs);
    dep1.addToIndexes();
    Dependency dep2 = new Dependency(jcas, 0, 9);
    dep2.setGovernor(spanA);
    dep2.setDependent(spanIs);
    dep2.addToIndexes();
    List<LogMessage> messages = new ArrayList<>();
    boolean result = check.check(null, jcas.getCas(), messages);
    messages.forEach(System.out::println);
    assertTrue(result);
    // also check the message itself
    assertEquals(1, messages.size());
    assertEquals("[NoMultipleIncomingRelationsCheck] Relation [This] -> [is] points to span that already has an incoming relation [a] -> [is].", messages.get(0).toString());
}
Also used : LogMessage(de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage) ArrayList(java.util.ArrayList) JCas(org.apache.uima.jcas.JCas) Token(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token) Dependency(de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.Dependency) AnnotationLayer(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer) Test(org.junit.Test)

Example 5 with LogMessage

use of de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage in project webanno by webanno.

the class NoMultipleIncomingRelationsCheckTest method testOkBecauseCoref.

@Test
public void testOkBecauseCoref() throws Exception {
    AnnotationLayer relationLayer = new AnnotationLayer();
    relationLayer.setName(CoreferenceChain.class.getName());
    relationLayer.setType(WebAnnoConst.CHAIN_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, 0, 10);
    dep2.setGovernor(spanA);
    dep2.setDependent(spanIs);
    dep2.addToIndexes();
    List<LogMessage> messages = new ArrayList<>();
    boolean result = check.check(null, jcas.getCas(), messages);
    messages.forEach(System.out::println);
    assertTrue(result);
}
Also used : CoreferenceChain(de.tudarmstadt.ukp.dkpro.core.api.coref.type.CoreferenceChain) LogMessage(de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage) ArrayList(java.util.ArrayList) JCas(org.apache.uima.jcas.JCas) Token(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token) Dependency(de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.Dependency) AnnotationLayer(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer) Test(org.junit.Test)

Aggregations

LogMessage (de.tudarmstadt.ukp.clarin.webanno.support.logging.LogMessage)26 AnnotationFS (org.apache.uima.cas.text.AnnotationFS)16 ArrayList (java.util.ArrayList)13 AnnotationLayer (de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer)12 Type (org.apache.uima.cas.Type)11 FeatureStructure (org.apache.uima.cas.FeatureStructure)7 CAS (org.apache.uima.cas.CAS)6 Test (org.junit.Test)6 CasDoctor (de.tudarmstadt.ukp.clarin.webanno.diag.CasDoctor)5 Token (de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token)5 CasUtil.getType (org.apache.uima.fit.util.CasUtil.getType)5 Dependency (de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.Dependency)4 WebAnnoConst (de.tudarmstadt.ukp.clarin.webanno.api.WebAnnoConst)3 List (java.util.List)3 Collectors (java.util.stream.Collectors)3 CasStorageService (de.tudarmstadt.ukp.clarin.webanno.api.CasStorageService)2 DocumentService (de.tudarmstadt.ukp.clarin.webanno.api.DocumentService)2 ImportExportService (de.tudarmstadt.ukp.clarin.webanno.api.ImportExportService)2 CORRECTION_USER (de.tudarmstadt.ukp.clarin.webanno.api.WebAnnoConst.CORRECTION_USER)2 CURATION_USER (de.tudarmstadt.ukp.clarin.webanno.api.WebAnnoConst.CURATION_USER)2