RdfMapEntry class

Specifies the Dart Type that represents each entry in a Map.

This annotation is specifically designed for Map collection properties when a custom structure is needed for key-value pairs in RDF. It's important to note that there are multiple ways to handle Map collections in RDF:

  1. Using standard mapping configurations without RdfMapEntry: Maps are treated as collections of MapEntry instances. If you provide mapping configurations (iri, literal, globalResource, localResource) in your @RdfProperty that work with MapEntry<K,V> and the correct generic type parameters, no RdfMapEntry annotation is required.

    Example with literal mapper for language-tagged strings:

    @RdfProperty(
      IriTerm('http://example.org/book/title'),
      literal: LiteralMapping.mapperInstance(const LocalizedEntryMapper())
    )
    final Map<String, String> translations; // Key=language code, Value=translated text
    
    // The mapper handles conversion to/from language-tagged literals
    class LocalizedEntryMapper implements LiteralTermMapper<MapEntry<String, String>> {
      const LocalizedEntryMapper();
    
      @override
      MapEntry<String, String> fromRdfTerm(LiteralTerm term, DeserializationContext context) =>
          MapEntry(term.language ?? 'en', term.value);
    
      @override
      LiteralTerm toRdfTerm(MapEntry<String, String> value, SerializationContext context) =>
          LiteralTerm.withLanguage(value.value, value.key);
    }
    

    This approach works when standard registered mappers or custom mapping configurations can handle the MapEntry directly.

  2. Using @RdfMapEntry with a dedicated entry class: This approach uses a separate class to represent each entry in the Map. Use this approach when:

    • Map keys and values require separate RDF predicates for complex structures
    • Your map entries need to be represented as resources with multiple properties

    When using @RdfMapEntry, each entry in the Map is fully serialized as a separate resource in the RDF graph according to its own RDF mapping annotations.

    IMPORTANT: All properties in the referenced resource class must either be:

    • Annotated with @RdfProperty for serialization to RDF, or
    • Computed/derived properties that don't need serialization

    Without proper annotations, the full serialization/deserialization roundtrip will fail, as the mapper won't know how to reconstitute the object from RDF data.

    The referenced class structure depends on how you use the map value annotation:

  3. When using property-level @RdfMapValue, the class must have exactly two @RdfProperty annotated properties:

// In your Resource class:
@RdfProperty(ExampleVocab.counts)
@RdfMapEntry(CounterEntry) // Each entry is a CounterEntry
final Map<String, int> counts; // Keys and values extracted from CounterEntry

// The item class with property-level @RdfMapValue.
// Note that we do not specify the rdf:type (classIri) in the @RdfLocalResource
// annotation here, as type actually is optional and not needed in this case:
@RdfLocalResource()
class CounterEntry {
  @RdfProperty(IriTerm('http://example.org/vocab/key'))
  @RdfMapKey() // This property becomes the map key
  final String key;

  @RdfProperty(IriTerm('http://example.org/vocab/count'))
  @RdfMapValue() // This property becomes the map value
  final int count;

  // With property-level @RdfMapValue, no additional @RdfProperty properties are allowed
  // You can have derived properties that don't need serialization:
  bool get isHighValue => count > 1000;

  CounterEntry(this.key, this.count);
}
  1. When using class-level @RdfMapValue, the class can have multiple @RdfProperty annotated properties:
// With class-level @RdfMapValue:
@RdfMapValue() // Class-level annotation
@RdfLocalResource(ExampleVocab.SettingsEntry)
class SettingsEntry {
  @RdfProperty(ExampleVocab.settingKey)
  @RdfMapKey() // The key property
  final String key;

  // Multiple RDF properties can be part of the value
  @RdfProperty(ExampleVocab.settingPriority)
  final int priority;

  @RdfProperty(ExampleVocab.settingEnabled)
  final bool enabled;

  @RdfProperty(ExampleVocab.settingTimestamp)
  final DateTime timestamp;

  // Derived properties are also allowed
  bool get isRecent => DateTime.now().difference(timestamp).inDays < 7;

  SettingsEntry(this.key, this.priority, this.enabled, this.timestamp);
}
Inheritance

Constructors

RdfMapEntry(Type itemClass)
Creates a new RdfMapEntry annotation with the specified item class.
const

Properties

hashCode int
The hash code for this object.
no setterinherited
itemClass Type
The Dart Type that defines the structure for each entry in the Map.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited