collection property

CollectionMapping? collection
final

Specifies a custom collection mapper for handling collection properties.

This parameter references a Type that implements Mapper<C> and has a constructor with the signature Mapper<C> Function({Deserializer<T>? itemDeserializer, Serializer<T>? itemSerializer}), where:

  • C is the collection type (e.g., List<Person>)
  • T is the item type (e.g., Person)
  • The class implements Mapper<C> to handle collection serialization/deserialization
  • The constructor takes optional item serializer and item deserializer parameters

The collection mapper handles the overall RDF structure of the collection, while the item mapper (derived from iri/literal/globalResource/localResource parameters) is passed as item serializer and item deserializer to the collection mapper and handles individual item conversion.

Default behavior without explicit collection mapper: Unlike other mapping properties (iri, literal, globalResource, localResource) which default to registry lookup when not specified, collections have a different default behavior:

  • List<T> automatically uses UnorderedItemsListMapper (equivalent to CollectionMapping.auto())
  • Set<T> automatically uses UnorderedItemsSetMapper (equivalent to CollectionMapping.auto())
  • Iterable<T> automatically uses UnorderedItemsMapper (equivalent to CollectionMapping.auto())
  • Each item generates a separate triple with the same predicate
  • Not serialized as RDF Collection structures (rdf:first/rdf:rest/rdf:nil)
  • List order is not preserved in RDF representation
  • Map collections continue using existing RdfMapEntry/RdfMapKey/RdfMapValue annotations

To use registry-based mapper lookup (matching the default behavior of other mapping properties), explicitly specify collection: CollectionMapping.fromRegistry()

When to specify a collection mapper:

  1. Custom collection types: When using non-standard collection types
  2. Structured RDF collections: When you need rdf:List, rdf:Seq, or other RDF collection structures
  3. Custom serialization: When you need specialized collection handling

The item type (T) is determined using this fallback strategy:

  1. If itemType is explicitly specified, use it
  2. Try to extract from generic parameters of the field type (e.g., List<Person>Person)
  3. Fall back to Object as last resort

Examples

Default Multi-Triple Collections

// Uses UnorderedItemsListMapper automatically (default) - creates one triple per Person
@RdfProperty(SchemaBook.authors)
final List<Person> authors;

// Uses UnorderedItemsSetMapper automatically (default) - creates one triple per Person
@RdfProperty(SchemaBook.contributors)
final Set<Person> contributors;

// Same with custom item mapping - one triple per ID
@RdfProperty(
  SchemaBook.contributorIds,
  iri: IriMapping('{+baseUri}/person/{contributorId}')
)
final List<String> contributorIds; // Each ID converted to IRI, separate triples

Structured RDF Collections

// Creates an rdf:List structure preserving order - single collection object
@RdfProperty(SchemaBook.chapters, collection: rdfList)
final List<Chapter> chapters;

// rdf:List with custom item mapping - single ordered collection
@RdfProperty(
  SchemaBook.authorIds,
  collection: rdfList,
  iri: IriMapping('{+baseUri}/person/{authorId}')
)
final List<String> authorIds; // Ordered rdf:List of IRIs

Custom Collection Types

// For non-standard collection types, explicit mapper needed
@RdfProperty(
  SchemaBook.metadata,
  collection: (CustomCollectionMapper),
  itemType: MetadataEntry,  // Explicit when type can't be inferred
  globalResource: GlobalResourceMapping.namedMapper('metadataEntryMapper')
  // => We will require a GlobalResourceMapper<MetadataEntry> with the name 'metadataEntryMapper' in the generated initRdfMapper function and pass it as `itemMapper` to `CustomCollectionMapper(itemMapper)`.
)
final CustomCollection metadata;

Single-Value Treatment

// For treating collections as single values, use a custom mapper
// that handles the entire collection as one unit
@RdfProperty(
  SchemaBook.keywords,
  collection: CollectionMapping.mapper(StringListMapper)
)
final List<String> keywords; // Uses a custom literal mapper that serializes entire list

// Alternative RDF collection structures
@RdfProperty(SchemaBook.alternativeFormats, collection: rdfAlt)
final List<String> formats; // Creates rdf:Alt structure

@RdfProperty(SchemaBook.relatedTopics, collection: rdfBag)
final List<String> topics; // Creates rdf:Bag structure

Well-known collection mappers:

Default mappers (automatically applied - create multiple triples):

  • UnorderedItemsListMapper: Default for List<T> - creates separate triple per item
  • UnorderedItemsSetMapper: Default for Set<T> - creates separate triple per item
  • UnorderedItemsMapper: Default for Iterable<T> - creates separate triple per item

Structured RDF collection mappers (create single collection object):

  • RdfListMapper: Creates ordered rdf:List structure (rdf:first/rdf:rest/rdf:nil)
  • RdfSeqMapper: Creates rdf:Seq structure for ordered sequences
  • RdfBagMapper: Creates rdf:Bag structure for unordered collections
  • RdfAltMapper: Creates rdf:Alt structure for alternative values

Custom mappers:

  • Implement Mapper<C> with constructor matching Mapper<C> Function({Deserializer<T>? itemDeserializer, Serializer<T>? itemSerializer}) signature

Implementation

final CollectionMapping? collection;