Maniulating mappings
- 1. Basic manipulations
- 2. Visiting the slots of a mapping or a mapping set
- 3. Other manipulations on mappings
- 4. Dealing with non-standard slots
1. Basic manipulations
A mapping set is represented by the MappingSet class. That class has read/write accessors for all metadata slots defined in the SSSOM schema. When obtaining a mapping set from a TSV file, any slot not explicitly set in the file will be set to null
.
Get the individual mappings of a mapping set with MappingSet.getMappings()
. An individual mapping is represented by the Mapping class. Again, that class has read/write accessors for all mapping-level metadata slot defined in the SSSOM schema.
To create a new mapping from scratch, either call the default constructor of the Mapping
class and then set the various slots by calling the appropriate “setter” methods:
Mapping mapping = new Mapping(); mapping.setSubjectId("http://example.org/EX_0001"); mapping.setPredicateId("http://www.w3.org/2004/02/skos/core#exactMatch"); mapping.setObjectId("http://example.org/EX_9999"); mapping.setMappingJustification("https://w3id.org/semapv/vocab/LexicalMatching");
or use the static builder()
method as follows:
Mapping mapping = Mapping.builder() .subjectId("http://example.org/EX_0001") .predicateId("http://www.w3.org/2004/02/skos/core#exactMatch") .objectId("http://example.org/EX_9999") .mappingJustification("https://w3id.org/semapv/vocab/LexicalMatching") .build();
To create a new mapping from a pre-existing mapping, you can use the toBuilder()
method to obtain a builder object initialised with all the current metadata of a given mapping. You can then use the builder methods to change the desired slots before building the new mapping. For example, to create a new mapping from the one above but with a different mapping predicate:
Mapping mapping2 = mapping.toBuilder() .predicateId("http://www.w3.org/2004/02/skos/core#narrowMatch") .build();
For convenience, all read accessors to complex fields have an overloaded variant that takes a boolean argument; when that argument is true
, the accessor will initialise the underlying field with the proper complex structure and return it. This allows to do simply, for example:
mapping.getAuthorLabel(true).add("A. U. Thor");
to add a new author label to a mapping, regardless of whether the underlying field has been initialised or not; this is basically a shortcut for:
if ( mapping.getAuthorLabel() == null ) { mapping = new ArrayList<>(); } mapping.getAuthorLabel().add("A. U. Thor");
2. Visiting the slots of a mapping or a mapping set
A common need when manipulating mapping is to apply an operation on all slots (in the LinkML sense; basically, the attributes, or the fields) of the Mapping
or MappingSet
classes (for example for serialising or deserialising).
Since there are many such slots, the library provides a pseudo-visitor pattern to make it somewhat less cumbersome to “visit” all slots in a SSSOM object.
To use that pattern, you must first create an implementation of the ISlotVisitor interface. The interface is generic with one type parameter for the type of objects whose slots you want to visit (either Mapping
or MappingSet
). It must implement a visit()
method for each possible type of slot (String-typed slot, URI-typed slot, Date-typed slot, Double-typed slots, etc.).
Then, you must obtain a SlotHelper object using one of the static methods on that class (either getMappingHelper()
or getMappingSetHelper()
, depending on whether you want to visit the slots of a mapping or of a mapping set), and simply call the visitSlots()
method on that object.
3. Other manipulations on mappings
To invert a mapping (switching the subject and the object), use the invert()
method on the Mapping
class:
Mapping inverted = mapping.invert();
The method will return a new mapping with inverted values, or null
if the mapping cannot be inverted (a mapping can only be inverted if its predicate is invertible or if it has an associated reverse predicate). Note that for now at least, the list of invertible predicates is built-in and not modifiable, client code cannot add its own predicates. This may change in the future.
To invert a mapping that uses a predicate that is not one of the built-in invertible predicates, but for which you know the proper inverse predicate, provide the predicate as an argument to the invert()
method:
Mapping inverted = mapping.invert("custom predicate");
To compute the cardinality of mappings in a set, use the inferCardinality()
static method in MappingCardinality:
import org.incenp.obofoundry.sssom.model.MappingCardinality; MappingSet mappingSet = ...; MappingCardinality.inferCardinality(mappingSet.getMappings());
This will replace any previously set value for the mapping cardinality (e.g. original values from the SSSOM file from which the mapping set was read) for each mapping.
4. Dealing with non-standard slots
The SSSOM specification defines a mechanism of extension slots to allow storing in a mapping set supplementary metadata beyond the metadata defined by SSSOM itself. This mechanism if fully supported by SSSOM-Java.
Extension slots are represented, both in the MappingSet
and the Mapping
class, by a String dictionary that can be accessed with getExtensions()
and setExtensions()
. Each key in that dictionary is intended to be a property identifying the non-standard metadata represented by a non-standard slot.
All SSSOM parsers and readers (for both the TSV and the JSON format) by default ignore all non-standard slots. Call their setExtraMetadataPolicy()
method to change that behaviour: the allowed value for the parameter of that method are:
- NONE
- Ignore all non-standard slots. This is the default.
- DEFINED
- When parsing, only recognise non-standard slots that are defined in the mapping set
extension_definitions
slot. When writing, write all non-standard slots as defined extensions. - UNDEFINED
- When parsing, accept all non-standard slots even if they are not defined as extensions. When writing, write all non-standard slots without defining them.