annotations library
Annotation library for mapping Dart classes to RDF graphs.
This library provides a set of annotations that can be applied to Dart classes and
properties to declare how they should be mapped to and from RDF graphs. Used in
conjunction with the locorda_rdf_mapper_generator package, these annotations enable
automatic generation of mapper implementations without writing boilerplate code.
Core RDF mapping concepts:
- Resource: An entity in the RDF graph, which can be identified by an IRI (global) or represented as a blank node (local)
- Property: A relation between a resource and a value (another resource or a literal)
- IRI (Internationalized Resource Identifier): A unique identifier for a resource
- Blank Node: An anonymous resource without a global identifier
- Literal: A simple value like a string, number, or date
Integration with locorda_rdf_mapper: You don't need to use annotations for all your classes. You can freely mix and match:
- Annotated classes with automatically generated mappers
- Custom mapper implementations registered directly with
locorda_rdf_mapper
This flexibility allows you to use annotations for standard cases while implementing custom mappers for more complex scenarios. Custom mappers can be registered either:
- Globally after calling
initRdfMapper - Locally for specific operations via the
registerparameter in mapper methods
Example using annotations (recommended for most cases):
import 'package:locorda_rdf_mapper_annotations/annotations.dart';
import 'package:locorda_rdf_terms_common/foaf.dart'; // Contains RDF vocabulary terms
// Define your class with annotations
@RdfGlobalResource(FoafPerson.classIri, IriStrategy('http://example.org/people/{id}'))
class Person {
@RdfIriPart('id')
final String id;
@RdfProperty(FoafPerson.name)
final String name;
@RdfProperty(FoafPerson.age)
final int age;
Person({required this.id, required this.name, required this.age});
}
// The initRdfMapper function is automatically generated, lets use it to get an rdfMapper facade.
final rdfMapper = initRdfMapper();
final personTurtle = rdfMapper.encodeObject(person);
final decodedPerson = rdfMapper.decodeObject<Person>(personTurtle);
Example of manually implementing and registering a mapper:
// Manual mapper implementation
class PersonMapper implements GlobalResourceMapper<Person> {
@override
(IriTerm, List<Triple>) toRdfResource(Person instance, SerializationContext context, {RdfSubject? parentSubject}) {
return context.resourceBuilder(context.createIriTerm(instance.id))
.addValue(FoafPerson.name, instance.name)
.build();
}
@override
Person fromRdfResource(IriTerm subject, DeserializationContext context) {
return Person(
id: subject.value,
name: context.reader.require<String>(FoafPerson.name),
);
}
@override
IriTerm get typeIri => FoafPerson.classIri;
}
// Register globally after initRdfMapper:
final rdfMapper = initRdfMapper(); // From generated code
rdfMapper.registerMapper<Person>(PersonMapper());
// Or register for a specific operation:
final turtle = rdfMapper.encodeObject(
person,
register: (registry) => registry.registerMapper<Person>(PersonMapper()),
);
You can also combine both approaches, using annotations for most classes and manual mappers for special cases:
// For a class with annotations, the mapper is generated automatically
@RdfGlobalResource(FoafPerson.classIri, IriStrategy('http://example.org/people/{id}'))
class Person {
// Properties with annotations...
}
// For a complex class, implement a custom mapper
class CustomEventMapper implements GlobalResourceMapper<Event> {
// Custom implementation...
}
// Use both in your application
final rdfMapper = initRdfMapper();
rdfMapper.registerMapper<Event>(CustomEventMapper());
// Both mappers are now available
final person = rdfMapper.decodeObject<Person>(personTurtle);
final event = rdfMapper.decodeObject<Event>(eventTurtle);
The primary annotations are organized into two categories:
Class-level annotations define how a class is mapped to RDF nodes:
- RdfGlobalResource: For entities with unique IRIs (subjects)
- RdfLocalResource: For nested entities as blank nodes
- RdfIri: For classes representing IRIs
- RdfLiteral: For classes representing literal values
Property-level annotations define how properties are mapped:
- RdfProperty: Main property annotation, links to an RDF predicate
- RdfIriPart: Marks properties that contribute to IRI construction
- RdfValue: Identifies the value source for literal serialization
- RdfMapEntry: Specifies how map entries shall be (de-)serialized
Enum-specific annotations customize enum serialization:
- RdfEnumValue: Customizes individual enum constant serialization values
Enum Support
The library provides comprehensive support for mapping enums to RDF values:
// Literal enum mapping
@RdfLiteral()
enum Priority {
@RdfEnumValue('H')
high, // → "H"
medium, // → "medium"
}
// IRI enum mapping
@RdfIri('http://example.org/status/{value}')
enum Status {
@RdfEnumValue('active-state')
active, // → <http://example.org/status/active-state>
pending, // → <http://example.org/status/pending>
}
// Usage in resource classes
@RdfGlobalResource(...)
class Task {
@RdfProperty('http://example.org/priority')
final Priority priority; // Uses enum's default mapping
@RdfProperty(
'http://example.org/status',
literal: LiteralMapping.namedMapper('customStatusMapper')
)
final Status status; // Override with custom mapper
}
Enums can be annotated with either @RdfLiteral or @RdfIri to define their
default mapping behavior. Individual enum constants can use @RdfEnumValue
to override their serialization value. This enables clean Dart enum names
while supporting domain-specific RDF vocabularies.
For usage examples, see the example directory.
Classes
-
BaseMapping<
M> - Base class for all mapping configurations that share common mapper functionality.
-
BaseMappingAnnotation<
M extends Mapper> - CollectionMapping
- Configures mapping details for collection properties in RDF.
- ContextualMapping
- Configuration for contextual property mapping.
- GlobalResourceMapping
- Configures mapping details for global resources (resources with IRIs) at the property level.
- IriMapping
- Configures mapping details for IRI terms in RDF at the property level.
- IriStrategy
- Defines the strategy for generating IRIs for RDF resources.
- LiteralContent
- Represents the content for building an RDF Literal.
- LiteralMapping
- Configures mapping details for literal values in RDF at the property level.
- LocalResourceMapping
- Configures mapping details for local resources (blank nodes) at the property level.
-
MapperRef<
M> - Base class for type-safe mapper references.
- RdfAnnotation
- Base annotation interface for RDF mapper generation.
- RdfEnumValue
- Annotation for customizing how individual enum constants are serialized in RDF.
- RdfGlobalResource
- Marks a Dart class as an RDF resource with a global IRI.
- RdfIri
- Marks a Dart class or enum as representing an RDF IRI term.
- RdfIriPart
- Marks a property as a part of the IRI for the enclosing class.
- RdfLanguageTag
- Marks a property as providing the language tag for RDF literals.
- RdfLiteral
- Marks a Dart class or enum as representing an RDF literal term.
- RdfLocalResource
- Marks a Dart class as a local RDF resource (referred to via a blank node).
- RdfMapEntry
- Specifies the Dart Type that represents each entry in a Map.
- RdfMapKey
-
Designates a property as the key in a mapped
Map<K,V>collection. - RdfMapValue
-
Designates a property or class as the value in a mapped
Map<K,V>collection. - RdfProperty
- Maps a Dart class property to an RDF predicate.
- RdfProvides
- Marks a property as providing a named value that can be referenced in IRI templates in the RDF mapping system.
- RdfUnmappedTriples
- Marks a property to capture and preserve unmapped RDF triples during lossless mapping.
- RdfValue
- Marks a property within a class as the primary value source for RDF literal conversion.
Enums
- MapperDirection
- Specifies whether a mapper should handle serialization, deserialization, or both.
Constants
- rdfAlt → const CollectionMapping
- Maps Dart collections to RDF Alternative structures (first is preferred).
- rdfBag → const CollectionMapping
- Maps Dart collections to RDF Bag structures (unordered collections).
- rdfList → const CollectionMapping
- Maps Dart collections to RDF List structures (rdf:first/rdf:rest/rdf:nil).
- rdfSeq → const CollectionMapping
- Maps Dart collections to RDF Sequence structures (rdf:_1, rdf:_2, rdf:_3...).
- unorderedItems → const CollectionMapping
- Maps Dart Iterable collections to multiple separate triples.
- unorderedItemsList → const CollectionMapping
- Maps Dart List collections to multiple separate triples.
- unorderedItemsSet → const CollectionMapping
- Maps Dart Set collections to multiple separate triples.