Class: Opencdd::Entity
- Inherits:
-
Lutaml::Model::Serializable
- Object
- Lutaml::Model::Serializable
- Opencdd::Entity
- Includes:
- ParseHelpers
- Defined in:
- lib/opencdd/entity.rb,
lib/opencdd/entity/yaml.rb,
lib/opencdd/entity/field_reader.rb,
lib/opencdd/entity/field_registry.rb,
lib/opencdd/entity/version_history.rb
Defined Under Namespace
Modules: FieldReader, FieldRegistry Classes: Dates, VersionHistory, Yaml
Constant Summary collapse
- META_CLASS_CODE =
nil
Instance Attribute Summary collapse
-
#irdi ⇒ Object
readonly
Returns the value of attribute irdi.
-
#meta_class_irdi ⇒ Object
readonly
Returns the value of attribute meta_class_irdi.
-
#properties ⇒ Object
readonly
Returns the value of attribute properties.
-
#schema ⇒ Object
readonly
Returns the value of attribute schema.
-
#source_location ⇒ Object
readonly
Returns the value of attribute source_location.
Class Method Summary collapse
- .default_code_property_id(meta_class_irdi) ⇒ Object
-
.field(name, property_id = nil, value_kind = nil, multilingual: nil, synthetic: false, reader: nil, as: nil, &block) ⇒ Object
Declare a typed field on this entity class.
- .from_row(row, schema:, meta_class_irdi:, code_property_id: nil) ⇒ Object
- .from_yaml(yaml_str) ⇒ Object
Instance Method Summary collapse
- #[](key) ⇒ Object
-
#attach_source_location(loc) ⇒ Object
Attach source location (file:line) where this entity was declared.
-
#attach_version_history(version_history) ⇒ Object
Attach per-version provenance captured in _entity.json.
- #code ⇒ Object (also: #short)
- #each_property ⇒ Object
- #eql?(other) ⇒ Boolean (also: #==)
- #hash ⇒ Object
-
#initialize(irdi: nil, properties: nil, schema: nil, meta_class_irdi: nil) ⇒ Entity
constructor
A new instance of Entity.
- #inspect ⇒ Object
- #key?(key) ⇒ Boolean
- #keys ⇒ Object
-
#read_field(name, lang: nil) ⇒ Object
Read a declared field by name.
- #replace_code_value!(code_property_id, new_code) ⇒ Object
- #replace_irdi!(new_irdi) ⇒ Object
-
#to_yaml(*args) ⇒ Object
── YAML persistence via Entity::Yaml ────────────────────── Entity extends Lutaml::Model::Serializable but its own attribute set is empty — the typed YAML model lives in Entity::Yaml (the deepened adapter).
- #type ⇒ Object
-
#write_property!(id, value) ⇒ Object
Write a value to a property ID, routing through canonical-id alias resolution so writes are consistent with reads.
Methods included from ParseHelpers
brace_wrapped?, paren_wrapped?, parse_irdi_list, parse_pair_list, parse_string_list, parse_synonym_tuples, unwrap_delimiters, unwrap_parens
Constructor Details
#initialize(irdi: nil, properties: nil, schema: nil, meta_class_irdi: nil) ⇒ Entity
Returns a new instance of Entity.
97 98 99 100 101 102 103 104 |
# File 'lib/opencdd/entity.rb', line 97 def initialize(irdi: nil, properties: nil, schema: nil, meta_class_irdi: nil) super({}) @irdi = irdi @properties = properties || {} @schema = schema @meta_class_irdi = @version_history = Opencdd::Entity::VersionHistory.new end |
Instance Attribute Details
#irdi ⇒ Object (readonly)
Returns the value of attribute irdi.
67 68 69 |
# File 'lib/opencdd/entity.rb', line 67 def irdi @irdi end |
#meta_class_irdi ⇒ Object (readonly)
Returns the value of attribute meta_class_irdi.
67 68 69 |
# File 'lib/opencdd/entity.rb', line 67 def @meta_class_irdi end |
#properties ⇒ Object (readonly)
Returns the value of attribute properties.
67 68 69 |
# File 'lib/opencdd/entity.rb', line 67 def properties @properties end |
#schema ⇒ Object (readonly)
Returns the value of attribute schema.
67 68 69 |
# File 'lib/opencdd/entity.rb', line 67 def schema @schema end |
#source_location ⇒ Object (readonly)
Returns the value of attribute source_location.
67 68 69 |
# File 'lib/opencdd/entity.rb', line 67 def source_location @source_location end |
Class Method Details
.default_code_property_id(meta_class_irdi) ⇒ Object
93 94 95 |
# File 'lib/opencdd/entity.rb', line 93 def self.default_code_property_id() Opencdd::MetaClasses.code_property_id_for(&.code) end |
.field(name, property_id = nil, value_kind = nil, multilingual: nil, synthetic: false, reader: nil, as: nil, &block) ⇒ Object
Declare a typed field on this entity class. Defaults for
value_kind and multilingual are resolved from
Opencdd::PropertyIds::REGISTRY when the property_id is known
there — the REGISTRY is the SSOT for wire-format metadata,
and re-declaring it here would violate DRY.
Pass an explicit value_kind to override (used when REGISTRY's
kind doesn't match how the field is consumed — e.g. MDC_P023
is :identifier_ref in REGISTRY but Unit#structure uses it as
a raw string).
synthetic: true for computed fields with no MDC_P### —
requires a block (preferred) that returns the value. The
block is evaluated via instance_exec on the entity, so it
has access to private helpers without send dispatch.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/opencdd/entity.rb', line 35 def field(name, property_id = nil, value_kind = nil, multilingual: nil, synthetic: false, reader: nil, as: nil, &block) resolved_kind, resolved_ml = resolve_from_registry(property_id) Opencdd::Entity::FieldRegistry.register( entity_class: self, name: name, property_id: property_id, value_kind: value_kind || resolved_kind || :string, multilingual: multilingual.nil? ? resolved_ml : multilingual, synthetic: synthetic, reader: reader, block: block, json_key: as, ) define_method(name) do |lang = nil| Opencdd::Entity::FieldReader.read(self, name, lang: lang) end end |
.from_row(row, schema:, meta_class_irdi:, code_property_id: nil) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/opencdd/entity.rb', line 69 def self.from_row(row, schema:, meta_class_irdi:, code_property_id: nil) code_property_id ||= default_code_property_id() raw_code = code_property_id && row[code_property_id] # Fall back to other known code property IDs when the entity- # specific one is absent (happens with name-only header sheets # where "Code" synthesizes to MDC_P001_5 regardless of type). if raw_code.nil? || raw_code.to_s.strip.empty? Opencdd::MetaClasses::CODE_PROPERTY_IDS.each_value do |alt_id| val = row[alt_id] next if val.nil? || val.to_s.strip.empty? raw_code = val break end end irdi = raw_code && Opencdd::IRDI.parse(raw_code) props = row.each_with_object({}) do |(k, v), h| next if k == "__row_index__" h[k] = v if v end new(irdi: irdi, properties: props, schema: schema, meta_class_irdi: ) end |
Instance Method Details
#[](key) ⇒ Object
177 178 179 |
# File 'lib/opencdd/entity.rb', line 177 def [](key) @properties[key.to_s] end |
#attach_source_location(loc) ⇒ Object
Attach source location (file:line) where this entity was declared. Set by Opencdd::Cddal::Builder from import/instantiation context. Nil for entities constructed from Parcel readers (which don't have a single source file).
261 262 263 264 |
# File 'lib/opencdd/entity.rb', line 261 def attach_source_location(loc) @source_location = loc self end |
#attach_version_history(version_history) ⇒ Object
Attach per-version provenance captured in _entity.json. Called by Opencdd::Parcel::ShardedDirReader after entity creation — the constructor doesn't take it because FlatDirReader creates entities from .xls rows without version context.
252 253 254 255 |
# File 'lib/opencdd/entity.rb', line 252 def attach_version_history(version_history) @version_history = version_history self end |
#code ⇒ Object Also known as: short
110 111 112 |
# File 'lib/opencdd/entity.rb', line 110 def code @irdi&.code end |
#each_property ⇒ Object
189 190 191 192 |
# File 'lib/opencdd/entity.rb', line 189 def each_property return enum_for(:each_property) unless block_given? @properties.each { |k, v| yield k, v } end |
#eql?(other) ⇒ Boolean Also known as: ==
194 195 196 197 198 |
# File 'lib/opencdd/entity.rb', line 194 def eql?(other) other.is_a?(Opencdd::Entity) && irdi == other.irdi && type == other.type end |
#hash ⇒ Object
200 201 202 |
# File 'lib/opencdd/entity.rb', line 200 def hash [irdi, type].hash end |
#inspect ⇒ Object
206 207 208 |
# File 'lib/opencdd/entity.rb', line 206 def inspect "#<#{self.class.name} #{irdi}>" end |
#key?(key) ⇒ Boolean
181 182 183 |
# File 'lib/opencdd/entity.rb', line 181 def key?(key) @properties.key?(key.to_s) end |
#keys ⇒ Object
185 186 187 |
# File 'lib/opencdd/entity.rb', line 185 def keys @properties.keys end |
#read_field(name, lang: nil) ⇒ Object
Read a declared field by name. Accepts an optional lang: for
multilingual fields. Returns the typed value (parsed IRDI,
Array, etc.) per the field's declared value_kind.
233 234 235 |
# File 'lib/opencdd/entity.rb', line 233 def read_field(name, lang: nil) Opencdd::Entity::FieldReader.read(self, name, lang: lang) end |
#replace_code_value!(code_property_id, new_code) ⇒ Object
215 216 217 218 219 |
# File 'lib/opencdd/entity.rb', line 215 def replace_code_value!(code_property_id, new_code) return self unless code_property_id @properties[code_property_id.to_s] = new_code.to_s self end |
#replace_irdi!(new_irdi) ⇒ Object
210 211 212 213 |
# File 'lib/opencdd/entity.rb', line 210 def replace_irdi!(new_irdi) @irdi = Opencdd::IRDI === new_irdi ? new_irdi : Opencdd::IRDI.parse(new_irdi.to_s) self end |
#to_yaml(*args) ⇒ Object
── YAML persistence via Entity::Yaml ────────────────────── Entity extends Lutaml::Model::Serializable but its own attribute set is empty — the typed YAML model lives in Entity::Yaml (the deepened adapter). This avoids name conflicts between the field DSL getters (which read from @properties and return coerced values like IRDI objects, source-language Strings, parsed Arrays) and lutaml-model serialization attrs (which must return flat types: String, Hash, Array).
lutaml-model serialization calls public_send(attr_name)
during to_format, so any getter with the same name as a
YAML attr is invoked. Keeping the YAML model in Entity::Yaml
lets both worlds coexist: field DSL for domain access,
Entity::Yaml for serialization.
281 282 283 |
# File 'lib/opencdd/entity.rb', line 281 def to_yaml(*args) Opencdd::Entity::Yaml.from_entity(self).to_yaml(*args) end |
#type ⇒ Object
106 107 108 |
# File 'lib/opencdd/entity.rb', line 106 def type Opencdd::Parcel::META_CLASS_TYPES[&.code] end |
#write_property!(id, value) ⇒ Object
Write a value to a property ID, routing through canonical-id
alias resolution so writes are consistent with reads. Use
this in preference to entity.properties[id] = value from
non-infrastructure callers.
241 242 243 244 245 246 |
# File 'lib/opencdd/entity.rb', line 241 def write_property!(id, value) canonical = Opencdd::PropertyIds.canonical_id(id.to_s) || id.to_s base = canonical.to_s.split(".").first @properties[base] = value.to_s self end |