diff --git a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/BratReader.java b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/BratReader.java index d67fed2fb4..9bd6d58f84 100644 --- a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/BratReader.java +++ b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/BratReader.java @@ -74,6 +74,7 @@ import com.fasterxml.jackson.annotation.Nulls; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import eu.openminted.share.annotations.api.DocumentationResource; @@ -166,6 +167,7 @@ public class BratReader private String mappingJson; private Mapping mapping; + private static Mapping defaultMapping = null; private Map idMap; @@ -177,16 +179,14 @@ public void initialize(UimaContext aContext) { super.initialize(aContext); + try { + mapping = getDefaultMapping(); + } catch (IOException e) { + throw new ResourceInitializationException(e); + } + if (mappingJson != null) { - ObjectMapper mapper = new ObjectMapper(); - mapper.setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY)); - mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); - try { - mapping = mapper.readValue(mappingJson, Mapping.class); - } - catch (IOException e) { - throw new ResourceInitializationException(e); - } + mapping = Mapping.merge(json2Mapping(mappingJson), mapping); } else { Map parsedRelationTypes = new HashMap<>(); @@ -213,7 +213,31 @@ public void initialize(UimaContext aContext) warnings = new LinkedHashSet(); } - @Override + private ObjectMapper mapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY)); + mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + + return mapper; + } + + private Mapping json2Mapping(String mappingJson2) throws ResourceInitializationException { + ObjectMapper mapper = new ObjectMapper(); + mapper.setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY)); + mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + Mapping deserialized = null; + try { + deserialized = mapper.readValue(mappingJson, Mapping.class); + } catch (IOException e) { + throw new ResourceInitializationException(e); + } + + return deserialized; + } + + @Override public void close() throws IOException { @@ -566,4 +590,57 @@ private Feature getFeature(FeatureStructure aFS, String aName) } return f; } + + + ////////////////////////////////////////// + // Start of Improvements to BratReader + // -- Alain Désilets + ////////////////////////////////////////// + + private Mapping getDefaultMapping() throws ResourceInitializationException, IOException { + if (defaultMapping == null) { + + // AD: Couldn't get this to work. + // Serializing/deserializing Mapping object seems to + // be very brittle +// String json = ResourceGetter.readResourceFileToString("org/dkpro/core/io/brat/defaultMapping.json"); +// defaultMapping = json2Mapping(json); + + List textMappingLst = new ArrayList(); + { + + textMappingLst.add(new TypeMapping("CARDINAL","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Cardinal")); + textMappingLst.add(new TypeMapping("Country","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Location")); + textMappingLst.add(new TypeMapping("DATE","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Date")); + textMappingLst.add(new TypeMapping("ORDINAL","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Ordinal")); + textMappingLst.add(new TypeMapping("LOC","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Location")); + textMappingLst.add(new TypeMapping("MERGE-ORG","de.tudarmstadt.ukp.dkpro.core.io.brat.type.MergeOrg")); + textMappingLst.add(new TypeMapping("ORG","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Organization")); + textMappingLst.add(new TypeMapping("Organization","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Organization")); + textMappingLst.add(new TypeMapping("PER","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Person")); + textMappingLst.add(new TypeMapping("TIME","de.tudarmstadt.ukp.dkpro.core.api.ner.type.Time")); + } + TypeMappings textMappings = new TypeMappings(textMappingLst); + + + List relMappingLst = new ArrayList();{ + relMappingLst.add(new TypeMapping("Origin", "de.tudarmstadt.ukp.dkpro.core.io.brat.type.AnnotationRelation")); + } + TypeMappings relationMappings = new TypeMappings(relMappingLst); + + List spans = new ArrayList(); + { + String spanJson = "{'type':'de.tudarmstadt.ukp.dkpro.core.api.ner.type.Location', 'defaultFeatureValues': {'value': 'LOC'}}"; + SpanMapping aSpan = mapper().readValue(spanJson, SpanMapping.class); + spans.add(aSpan); + } + + List relations = new ArrayList(); + List comments = new ArrayList(); + + defaultMapping = new Mapping(textMappings, relationMappings, spans, relations, comments); + } + + return defaultMapping; + } } diff --git a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/Mapping.java b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/Mapping.java index c3e1e55468..2289861965 100644 --- a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/Mapping.java +++ b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/Mapping.java @@ -21,6 +21,7 @@ import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -86,4 +87,56 @@ public Collection getCommentMapping(String aType) { return comments.get(aType); } + + public static Mapping merge(Mapping mapping1, Mapping mapping2) { + + List mergedTxtTMLst = new ArrayList(); + mergedTxtTMLst.addAll(mapping1.getTextTypeMapppings().parsedMappings); + for (TypeMapping tm: mapping2.getTextTypeMapppings().parsedMappings) { + if (!mergedTxtTMLst.contains(tm)) { + mergedTxtTMLst.add(tm); + } + } + TypeMappings mergedTxtTM = new TypeMappings(mergedTxtTMLst); + + List mergedRelTMLst = new ArrayList(); + mergedRelTMLst.addAll(mapping1.getRelationTypeMapppings().parsedMappings); + for (TypeMapping tm: mapping2.getRelationTypeMapppings().parsedMappings) { + if (!mergedRelTMLst.contains(tm)) { + mergedRelTMLst.add(tm); + } + } + TypeMappings mergedRelTM = new TypeMappings(mergedRelTMLst); + + List mergedTxtAnnots = new ArrayList(); + mergedTxtAnnots.addAll(mapping1.textAnnotations.values()); + + // AD: If you uncomment this, test1mapping fails +// for (SpanMapping sm: mapping2.textAnnotations.values()) { +// if (!mergedTxtAnnots.contains(sm)) { +// mergedTxtAnnots.add(sm); +// } +// } + + List mergedRelMapping = new ArrayList(); + mergedRelMapping.addAll(mapping1.relations.values()); + for (RelationMapping rm: mapping2.relations.values()) { + if (!mergedRelMapping.contains(rm)) { + mergedRelMapping.add(rm); + } + } + + List mergedCommMapping = new ArrayList(); + mergedCommMapping.addAll(mapping1.comments.values()); + for (CommentMapping cm: mapping2.comments.values()) { + if (!mergedCommMapping.contains(cm)) { + mergedCommMapping.add(cm); + } + } + + Mapping mergedMapping = + new Mapping(mergedTxtTM, mergedRelTM, mergedTxtAnnots, mergedRelMapping, mergedCommMapping); + + return mergedMapping; + } } diff --git a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMapping.java b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMapping.java index 13883e6596..e706e4cb8a 100644 --- a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMapping.java +++ b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMapping.java @@ -35,9 +35,9 @@ public class TypeMapping private static final String BRAT = "BRAT"; private static final String UIMA = "UIMA"; - private final Pattern bratTypePattern; - private final String uimaType; - private final Map defaultFeatureValues; + public final Pattern bratTypePattern; + public final String uimaType; + public final Map defaultFeatureValues; private Matcher matcher; @@ -52,6 +52,10 @@ public TypeMapping( defaultFeatureValues = aDefaults != null ? aDefaults : Collections.emptyMap(); } + public TypeMapping() { + this(null, null, Collections.emptyMap()); + } + public TypeMapping(String aPattern, String aReplacement) { this(aPattern, aReplacement, Collections.emptyMap()); diff --git a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMappings.java b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMappings.java index d19ab4bff6..0a94502da0 100644 --- a/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMappings.java +++ b/dkpro-core-io-brat-asl/src/main/java/org/dkpro/core/io/brat/internal/mapping/TypeMappings.java @@ -30,27 +30,36 @@ public class TypeMappings { - private final List parsedMappings; - private final Map brat2UimaMappingCache; - private final Map uima2BratMappingCache; + public List parsedMappings; + private Map brat2UimaMappingCache; + private Map uima2BratMappingCache; @JsonCreator - public TypeMappings(List aMappings) + public TypeMappings(List typeMappingList) { - parsedMappings = aMappings; - brat2UimaMappingCache = new HashMap<>(); - uima2BratMappingCache = new HashMap<>(); + initTypeMappings(typeMappingList); } public TypeMappings(String... aMappings) { - parsedMappings = new ArrayList<>(); - + List typeMappingList = new ArrayList(); if (aMappings != null) { for (String m : aMappings) { - parsedMappings.add(TypeMapping.parse(m)); + typeMappingList.add(TypeMapping.parse(m)); } } + + initTypeMappings(typeMappingList); + } + + private void initTypeMappings(List typeMappingList) { + parsedMappings = new ArrayList<>(); + + if (typeMappingList != null) { + for(TypeMapping aMapping: typeMappingList) { + parsedMappings.add(aMapping); + } + } brat2UimaMappingCache = new HashMap<>(); uima2BratMappingCache = new HashMap<>(); @@ -125,4 +134,7 @@ public String getBratType(Type aType) return bratType; } + + public void append(TypeMappings additionalMappings) { + } }