Skip to content

Commit 25f1211

Browse files
committed
Accept non-ambiguous invalid enum values.
When reading from SSSOM/TSV or SSSOM/JSON, accept a `sssom_version` value provided as a floating point value, even though strictly speaking it should be a string. That is, accept `sssom_version: 1.1` as equivalent to `sssom_version: "1.1"`. Likewise, accept `entity_type_enum` values provided as CURIEs. For example, accept `owl:Class` as equivalent to `owl class`. In both cases, this is when parsing only. When writing, the version number is always written as a string and entity type values are alwayrs written using their canonical string form.
1 parent c2e6736 commit 25f1211

File tree

5 files changed

+90
-12
lines changed

5 files changed

+90
-12
lines changed

core/src/main/java/org/incenp/obofoundry/sssom/YAMLConverter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ public MappingSet convertMappingSet(Map<String, Object> rawMap) throws SSSOMForm
173173
if ( String.class.isInstance(rawVersion) ) {
174174
version = Version.fromString(String.class.cast(rawVersion));
175175
rawMap.remove("sssom_version");
176+
} else if ( Double.class.isInstance(rawVersion) ) {
177+
version = Version.fromString(Double.class.cast(rawVersion).toString());
178+
rawMap.remove("sssom_version");
176179
} else {
177180
throw getTypingError("sssom_version");
178181
}

core/src/main/java/org/incenp/obofoundry/sssom/model/EntityType.java

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,42 +28,54 @@
2828
* Represents the type of an entity that is being mapped.
2929
*/
3030
public enum EntityType {
31-
OWL_CLASS("http://www.w3.org/2002/07/owl#Class"),
32-
OWL_OBJECT_PROPERTY("http://www.w3.org/2002/07/owl#ObjectProperty"),
33-
OWL_DATA_PROPERTY("http://www.w3.org/2002/07/owl#DataProperty"),
34-
OWL_ANNOTATION_PROPERTY("http://www.w3.org/2002/07/owl#AnnotationProperty"),
35-
OWL_NAMED_INDIVIDUAL("http://www.w3.org/2002/07/owl#NamedIndividual"),
36-
SKOS_CONCEPT("http://www.w3.org/2004/02/skos/core#Concept"),
37-
RDFS_RESOURCE("http://www.w3.org/2000/01/rdf-schema#Resource"),
38-
RDFS_CLASS("http://www.w3.org/2000/01/rdf-schema#Class"),
39-
RDFS_LITERAL("http://www.w3.org/2000/01/rdf-schema#Literal"),
40-
RDFS_DATATYPE("http://www.w3.org/2000/01/rdf-schema#Datatype"),
41-
RDF_PROPERTY("http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"),
31+
OWL_CLASS("http://www.w3.org/2002/07/owl#Class", "owl:Class"),
32+
OWL_OBJECT_PROPERTY("http://www.w3.org/2002/07/owl#ObjectProperty", "owl:ObjectProperty"),
33+
OWL_DATA_PROPERTY("http://www.w3.org/2002/07/owl#DataProperty", "owl:DataProperty"),
34+
OWL_ANNOTATION_PROPERTY("http://www.w3.org/2002/07/owl#AnnotationProperty", "owl:AnnotationProperty"),
35+
OWL_NAMED_INDIVIDUAL("http://www.w3.org/2002/07/owl#NamedIndividual", "owl:NamedIndividual"),
36+
SKOS_CONCEPT("http://www.w3.org/2004/02/skos/core#Concept", "skos:Concept"),
37+
RDFS_RESOURCE("http://www.w3.org/2000/01/rdf-schema#Resource", "rdfs:Resource"),
38+
RDFS_CLASS("http://www.w3.org/2000/01/rdf-schema#Class", "rdfs:Class"),
39+
RDFS_LITERAL("http://www.w3.org/2000/01/rdf-schema#Literal", "rdfs:Literal"),
40+
RDFS_DATATYPE("http://www.w3.org/2000/01/rdf-schema#Datatype", "rdfs:Datatype"),
41+
RDF_PROPERTY("http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", "rdf:Property"),
4242
COMPOSED_ENTITY_EXPRESSION("https://w3id.org/sssom/ComposedEntityExpression");
4343

4444
private final static Map<String, EntityType> MAP;
4545
private final static Map<String, EntityType> URI_MAP;
46+
private final static Map<String, EntityType> SYN_MAP;
4647

4748
static {
4849
Map<String, EntityType> map = new HashMap<String, EntityType>();
4950
Map<String, EntityType> uri_map = new HashMap<String, EntityType>();
51+
Map<String, EntityType> syn_map = new HashMap<String, EntityType>();
5052
for ( EntityType value : EntityType.values() ) {
5153
map.put(value.toString(), value);
5254
if ( value.iri != null ) {
5355
uri_map.put(value.iri, value);
5456
}
57+
if ( value.synonym != null ) {
58+
syn_map.put(value.synonym, value);
59+
}
5560
}
5661

5762
MAP = Collections.unmodifiableMap(map);
5863
URI_MAP = Collections.unmodifiableMap(uri_map);
64+
SYN_MAP = Collections.unmodifiableMap(syn_map);
5965
}
6066

6167
private String iri;
68+
private String synonym;
6269

6370
EntityType(String iri) {
6471
this.iri = iri;
6572
}
6673

74+
EntityType(String iri, String synonym) {
75+
this.iri = iri;
76+
this.synonym = synonym;
77+
}
78+
6779
@Override
6880
public String toString() {
6981
return name().toLowerCase().replace('_', ' ');
@@ -91,6 +103,26 @@ public static EntityType fromString(String v) {
91103
return MAP.get(v);
92104
}
93105

106+
/**
107+
* Parses a string into a entity type enum value.
108+
* <p>
109+
* This is similar to {@link #fromString(String)}, but optionally allows to
110+
* recognise “synonyms”.
111+
*
112+
* @param v The string to parse.
113+
* @param lax If {@code true}, will attempt to match the provided value against
114+
* known synonyms of the expected values.
115+
* @return The corresponding enumeration value, or {@code null} if the provided
116+
* value does not match any entity type.
117+
*/
118+
public static EntityType fromString(String v, boolean lax) {
119+
EntityType et = MAP.get(v);
120+
if ( et == null && lax ) {
121+
et = SYN_MAP.get(v);
122+
}
123+
return et;
124+
}
125+
94126
/**
95127
* Parses an IRI into the corresponding entity type enum value.
96128
* <p>

core/src/main/java/org/incenp/obofoundry/sssom/slots/EntityTypeSlot.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public void setValue(T object, String value) {
5959
if ( value != null ) {
6060
et = EntityType.fromIRI(value);
6161
if ( et == null ) {
62-
et = EntityType.fromString(value);
62+
et = EntityType.fromString(value, true);
6363
}
6464
if ( et == null ) {
6565
throw new IllegalArgumentException();

core/src/test/java/org/incenp/obofoundry/sssom/TSVReaderTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,27 @@ void testRelativeURIs() throws IOException {
787787
}
788788
}
789789

790+
@Test
791+
void testAcceptingLaxEnumValues() throws IOException {
792+
TSVReader reader = new TSVReader("src/test/resources/sets/test-lax-enum-values.sssom.tsv");
793+
MappingSet ms;
794+
795+
try {
796+
ms = reader.read();
797+
Assertions.assertEquals(Version.SSSOM_1_1, ms.getSssomVersion());
798+
Assertions.assertEquals(EntityType.OWL_CLASS, ms.getMappings().get(0).getSubjectType());
799+
Assertions.assertEquals(EntityType.OWL_ANNOTATION_PROPERTY, ms.getMappings().get(1).getSubjectType());
800+
Assertions.assertEquals(EntityType.OWL_OBJECT_PROPERTY, ms.getMappings().get(2).getSubjectType());
801+
Assertions.assertEquals(EntityType.OWL_DATA_PROPERTY, ms.getMappings().get(3).getSubjectType());
802+
Assertions.assertEquals(EntityType.RDFS_RESOURCE, ms.getMappings().get(4).getSubjectType());
803+
Assertions.assertEquals(EntityType.RDFS_CLASS, ms.getMappings().get(5).getSubjectType());
804+
Assertions.assertEquals(EntityType.RDF_PROPERTY, ms.getMappings().get(6).getSubjectType());
805+
Assertions.assertEquals(EntityType.SKOS_CONCEPT, ms.getMappings().get(7).getSubjectType());
806+
} catch ( SSSOMFormatException e ) {
807+
Assertions.fail(e);
808+
}
809+
}
810+
790811
private void compare(ExtensionDefinition expected, ExtensionDefinition actual) {
791812
Assertions.assertEquals(expected.getSlotName(), actual.getSlotName());
792813
Assertions.assertEquals(expected.getProperty(), actual.getProperty());
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#sssom_version: 1.1
2+
#curie_map:
3+
# COMENT: https://example.com/entities/
4+
# COMPID: https://example.com/people/
5+
# ORGENT: https://example.org/entities/
6+
# ORGPID: https://example.org/people/
7+
#mapping_set_id: https://example.org/sets/exo2c
8+
#mapping_set_title: O2C set
9+
#creator_id:
10+
# - ORGPID:0000-0000-0001-1234
11+
# - COMPID:0000-0000-0002-5678
12+
#license: https://creativecommons.org/licenses/by/4.0/
13+
#publication_date: 2023-09-13
14+
subject_id subject_label predicate_id object_id object_label mapping_justification subject_type
15+
ORGENT:0001 alice skos:closeMatch COMENT:0011 alpha semapv:ManualMappingCuration owl:Class
16+
ORGENT:0002 bob skos:closeMatch COMENT:0012 beta semapv:ManualMappingCuration owl:AnnotationProperty
17+
ORGENT:0004 daphne skos:closeMatch COMENT:0014 delta semapv:ManualMappingCuration owl:ObjectProperty
18+
ORGENT:0005 eve skos:closeMatch COMENT:0015 epsilon semapv:ManualMappingCuration owl:DataProperty
19+
ORGENT:0006 fanny skos:closeMatch COMENT:0016 zeta semapv:ManualMappingCuration rdfs:Resource
20+
ORGENT:0007 gavin skos:exactMatch COMENT:0013 gamma semapv:ManualMappingCuration rdfs:Class
21+
ORGENT:0008 hector skos:closeMatch COMENT:0017 eta semapv:ManualMappingCuration rdf:Property
22+
ORGENT:0009 ivan skos:exactMatch COMENT:0019 iota semapv:ManualMappingCuration skos:Concept

0 commit comments

Comments
 (0)