Class ConverterContext
- java.lang.Object
-
- org.incenp.linkml.core.ConverterContext
-
public class ConverterContext extends Object
Global context for converting LinkML objects (as parsed from a JSON/YAML document) into their corresponding Java objects, and the other way round.Purposes
An object of this class serves mostly three purposes:
- providing
IConverterobjects as needed; - allow dereferencing “global” LinkML objects;
- providing a resolution/compaction service for CURIEs.
Provider of
IConverterobjectsThe context holds a list of all the known LinkML classes and types, along with their respective converter objects. So whenever converting an object of type Foo is required, the appropriate converter needed for such a conversion can be obtained from the context (through either
getConverter(Class)orgetConverter(Slot)).The context has built-in knowledge of LinkML’s basic scalar types. For the other types (classes or enumerations), the client code can provide its own converters through the
addConverter(IConverter)method. In the absence of an explicitly registered converter for a type, the context will automatically provide a default. It is expected that in most cases, the default converter should be enough.Dereferencing global LinkML objects
“Dereferencing” is what must happen when converting the value of a LinkML slot that (1) is expected to contain a globally unique object (an object belonging to a class that has an
identifierslot) and (2) is not “inlined”. In such a case, in JSON/YAML serialisations the slot will actually contain only the identifier of the object, the actual object expectedly being represented elsewhere in the instance data. Dereferencing is the process of finding the global object corresponding to a given identifier, so that it can be assigned to the slot.One problem that may arise when dereferencing is that an identifier may point to a global object that has not been parsed and converted yet, depending on (1) where the global object is defined and (2) the order in which we process the JSON/YAML tree. For example, when parsing/converting a LinkML schema: when parsing a class definition, we are likely to encounter a reference to a slot definition, but we may not have parsed that slot definition yet. (And we cannot solve that problem simply by ensuring that we always parse slot definitions first, because slot definitions may in turn contains references to a class definitions.)
This context object maintains a cache (implemented by the
ObjectCacheclass) of all the global objects, and will take care of resolving references to those objects – either immediately if possible (if the referenced object has been seen before and therefore is already in the cache), or in a post-parsing finalisation step (when we are sure that all objects contained in the parsed document have been seen, so all references should be resolvable).CURIE resolution
It is expected that short identifiers, otherwise known as “CURIEs”, will be used a lot within LinkML instance data. This context object acts as a prefix manager to help automatically resolve CURIEs into their full-length form (when deserialising) and conversely compact IRIs into their short form (when serialising).
Lifecycle
As can be inferred from the duties outlined in the previous section, the converter object has a central role throughout the LinkML-Java runtime. One such object must be created before doing virtually anything with LinkML instance data.
The same converter object must be used for all operations pertaining to the same set of LinkML instance data, even if the instance data is physically spread over several JSON or YAML files. For example, when parsing a LinkML schema, the same context must be used for the root schema and for all the imported schemas, if any.
Conversely, in most cases it will not be desirable to reuse an existing context to manipulate instance data that are not related to the instance data for which the existing context has already been used.
Of note, once instance data have been parsed, the parsed objects are self-sufficient; that is, they do not require the context to be kept around. However, if the data is to be serialised back, it might be a good idea to reuse the same context for serialisation as the one that was used for deserialisation, because it will ensure that the same prefixes are used for the compaction of CURIEs.
- providing
-
-
Constructor Summary
Constructors Constructor Description ConverterContext()
-
Method Summary
All Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description voidaddConverter(Class<?> type)Deprecated.Use eitheraddConverter(IConverter)with an explicitly instantiatedObjectConverter, orgetConverter(Class)(which will automatically trigger the registration of a newly instantiated converter if needed).voidaddConverter(IConverter converter)Registers a pre-built converter.voidaddPrefix(String name, String prefix)Registers a prefix.Stringcompact(String iri)Compacts an IRI into a shortened identifier (“CURIE“).voidfinalizeAssignments()Performs all delayed assignments.voidfinalizeAssignments(boolean failOnMissing)Performs all delayed assignments, optionally failing if an assignment refers to a missing object.IConvertergetConverter(Class<?> type)Gets the converter for objects of the given type.IConvertergetConverter(Slot slot)Gets the converter for the type of object expected by the given slot.<T> TgetObject(Class<T> type, String name, boolean create)Dereferences a global object, optionally creating it if does not already exist.ObjectgetObject(Slot slot, String name, Object target)Dereferences a global object and assigns it to a slot on another object.voidgetObjects(Class<?> type, List<String> names, List<Object> target)Dereferences several global objects and assigns them to a list.Stringresolve(String name)Resolves a shortened identifier (“CURIE”) into a full-length IRI.
-
-
-
Method Detail
-
addConverter
@Deprecated public void addConverter(Class<?> type)
Deprecated.Use eitheraddConverter(IConverter)with an explicitly instantiatedObjectConverter, orgetConverter(Class)(which will automatically trigger the registration of a newly instantiated converter if needed).Registers a converter for objects of the given class.- Parameters:
type- The class for which to register a converter. A default converter will be automatically created.
-
addConverter
public void addConverter(IConverter converter)
Registers a pre-built converter.This may be used to override the default converter that would normally be automatically instantiated the first time a converter for a given type is requested through
getConverter(Class).- Parameters:
converter- The converter to register.
-
getConverter
public IConverter getConverter(Class<?> type) throws LinkMLRuntimeException
Gets the converter for objects of the given type.If no converter able to handle the type has been previously registered, then the context will attempt to automatically instantiate and register a default converter. The default converter will be either:
- the custom converter as indicated by a
Converterannotation on the type (or any parent type); - the default
EnumConverterif the type is an enumeration type; - the default
ObjectConverterif the type is anything else.
- Parameters:
type- The type to query.- Returns:
- The registered converter for the type.
- Throws:
LinkMLRuntimeException- If the type is configured to use a custom converter that could not be instantiated.
- the custom converter as indicated by a
-
getConverter
public IConverter getConverter(Slot slot) throws LinkMLRuntimeException
Gets the converter for the type of object expected by the given slot.This is mostly equivalent to calling
getConverter(Class)on the “inner type” of the slot, except that it takes into account anyConverterannotation carried by the slot.- Parameters:
slot- The slot for which a converter is needed.- Returns:
- The appropriate converter.
- Throws:
LinkMLRuntimeException- If the slot (or its type) is configured to use a custom converter, but the custom converter could not be instantiated.
-
addPrefix
public void addPrefix(String name, String prefix)
Registers a prefix. Any prefix declared here will become resolvable by theresolve(String)method, or conversely usable by thecompact(String)method.One of the responsibilities of the
ConverterContextis to provide a prefix resolution service, so that any shortened identifier (“CURIE“) found within LinkML instance data can be resolved into a full-length identifier.This method is used internally throughout LinkML-Java to feed the prefix resolution service. Client code may also use it as needed to provide its own prefixes (for example, if the client code has out-of-band knowledge of which prefixes will be used within the instance data it will manipulate).
- Parameters:
name- The prefix name.prefix- The corresponding IRI prefix.
-
resolve
public String resolve(String name)
Resolves a shortened identifier (“CURIE”) into a full-length IRI.- Parameters:
name- The shortened identifier to resolve.- Returns:
- The resolved IRI, or the original string if (1) it was not a shortened identifier to begin with or (2) the prefix is unknown.
-
compact
public String compact(String iri)
Compacts an IRI into a shortened identifier (“CURIE“).- Parameters:
iri- The IRI to shorten.- Returns:
- The shortened identifier, or the original string if there no known suitable prefix for the given IRI.
-
getObject
public <T> T getObject(Class<T> type, String name, boolean create) throws LinkMLRuntimeException
Dereferences a global object, optionally creating it if does not already exist.- Type Parameters:
T- The type of object to dereference.- Parameters:
type- The type of object to dereference.name- The name to resolve into a dereferenced object.create- Iftrue, a new object of the given type and with the given name will be created and added to the global context if an object with that name did not already exist.- Returns:
- The dereferenced object, or
nullif the object did not already exist andcreateisfalse. - Throws:
LinkMLRuntimeException- If the object type is not suitable for global objects, or if we cannot create the object as needed.
-
getObject
public Object getObject(Slot slot, String name, Object target) throws LinkMLRuntimeException
Dereferences a global object and assigns it to a slot on another object.If the desired object does not exist in the context, the assignment will take place when the
finalizeAssignments()method is called.- Parameters:
slot- The slot to which to assign the dereferenced object.name- The name to resolve into a dereferenced object.target- The object to which to assign the dereferenced object.- Returns:
- The dereferenced object, or
nullif the object does not exist in the context at the time this method is called. - Throws:
LinkMLRuntimeException- If the object type is not suitable for global objects, or if the retrieved object cannot be assigned to the slot.
-
getObjects
public void getObjects(Class<?> type, List<String> names, List<Object> target) throws LinkMLRuntimeException
Dereferences several global objects and assigns them to a list.If any of the referenced objects does not exist in the context, it will be assigned to the target list when the
finalizeAssignments()method is called.- Parameters:
type- The type of the objects to dereference.names- The names to resolve into dereferenced objects.target- The list to which the dereferenced objects should be assigned.- Throws:
LinkMLRuntimeException- If the object type is not suitable for global objects.
-
finalizeAssignments
public void finalizeAssignments() throws LinkMLRuntimeExceptionPerforms all delayed assignments.A delayed assignment is an assignment requested through the
getObject(Slot, String, Object)orgetObjects(Class, List, List)methods, which could not be performed at the time that method was called because the requested object was not known to the context yet.If a referenced object is still unknown when delayed assignments are performed, an empty object of the desired type and with the referenced identifier will be automatically created. Use
finalizeAssignments(boolean)to treat missing references as an error instead.It is safe to call this method repeatedly – delayed assignments that were already performed by a previous call will not be repeated.
- Throws:
LinkMLRuntimeException- If an assignment cannot be performed.
-
finalizeAssignments
public void finalizeAssignments(boolean failOnMissing) throws LinkMLRuntimeExceptionPerforms all delayed assignments, optionally failing if an assignment refers to a missing object.- Parameters:
failOnMissing- Iftrueand a delayed assignment refers to an object that is either unknown in the global context, or of a different type than expected, this will be treated as a fatal error.- Throws:
LinkMLRuntimeException- If an assignment cannot be performed (including for an invalid reference, iffailOnMissingistrue.
-
-