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,
lib/opencdd/entity/name_synthesizer.rb
Direct Known Subclasses
Klass, ListUnit, Property, Relation, Unit, ValueList, ValueTerm, ViewControl
Defined Under Namespace
Modules: FieldReader, FieldRegistry, NameSynthesizer 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.
98 99 100 101 102 103 104 105 |
# File 'lib/opencdd/entity.rb', line 98 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.
68 69 70 |
# File 'lib/opencdd/entity.rb', line 68 def irdi @irdi end |
#meta_class_irdi ⇒ Object (readonly)
Returns the value of attribute meta_class_irdi.
68 69 70 |
# File 'lib/opencdd/entity.rb', line 68 def @meta_class_irdi end |
#properties ⇒ Object (readonly)
Returns the value of attribute properties.
68 69 70 |
# File 'lib/opencdd/entity.rb', line 68 def properties @properties end |
#schema ⇒ Object (readonly)
Returns the value of attribute schema.
68 69 70 |
# File 'lib/opencdd/entity.rb', line 68 def schema @schema end |
#source_location ⇒ Object (readonly)
Returns the value of attribute source_location.
68 69 70 |
# File 'lib/opencdd/entity.rb', line 68 def source_location @source_location end |
Class Method Details
.default_code_property_id(meta_class_irdi) ⇒ Object
94 95 96 |
# File 'lib/opencdd/entity.rb', line 94 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.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/opencdd/entity.rb', line 36 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
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/opencdd/entity.rb', line 70 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
178 179 180 |
# File 'lib/opencdd/entity.rb', line 178 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).
262 263 264 265 |
# File 'lib/opencdd/entity.rb', line 262 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.
253 254 255 256 |
# File 'lib/opencdd/entity.rb', line 253 def attach_version_history(version_history) @version_history = version_history self end |
#code ⇒ Object Also known as: short
111 112 113 |
# File 'lib/opencdd/entity.rb', line 111 def code @irdi&.code end |
#each_property ⇒ Object
190 191 192 193 |
# File 'lib/opencdd/entity.rb', line 190 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: ==
195 196 197 198 199 |
# File 'lib/opencdd/entity.rb', line 195 def eql?(other) other.is_a?(Opencdd::Entity) && irdi == other.irdi && type == other.type end |
#hash ⇒ Object
201 202 203 |
# File 'lib/opencdd/entity.rb', line 201 def hash [irdi, type].hash end |
#inspect ⇒ Object
207 208 209 |
# File 'lib/opencdd/entity.rb', line 207 def inspect "#<#{self.class.name} #{irdi}>" end |
#key?(key) ⇒ Boolean
182 183 184 |
# File 'lib/opencdd/entity.rb', line 182 def key?(key) @properties.key?(key.to_s) end |
#keys ⇒ Object
186 187 188 |
# File 'lib/opencdd/entity.rb', line 186 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.
234 235 236 |
# File 'lib/opencdd/entity.rb', line 234 def read_field(name, lang: nil) Opencdd::Entity::FieldReader.read(self, name, lang: lang) end |
#replace_code_value!(code_property_id, new_code) ⇒ Object
216 217 218 219 220 |
# File 'lib/opencdd/entity.rb', line 216 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
211 212 213 214 |
# File 'lib/opencdd/entity.rb', line 211 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.
282 283 284 |
# File 'lib/opencdd/entity.rb', line 282 def to_yaml(*args) Opencdd::Entity::Yaml.from_entity(self).to_yaml(*args) end |
#type ⇒ Object
107 108 109 |
# File 'lib/opencdd/entity.rb', line 107 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.
242 243 244 245 246 247 |
# File 'lib/opencdd/entity.rb', line 242 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 |