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