Class: Opencdd::Entity::Yaml

Inherits:
Lutaml::Model::Serializable
  • Object
show all
Defined in:
lib/opencdd/entity/yaml.rb

Overview

CDD-native YAML serialization model.

This is the deepened YAML adapter: the conversion logic that translates between semantic CDD attribute names (preferred_name, superclass, class_type) and IEC 62656-1 wire-format keys (MDC_P004, MDC_P010, MDC_P011) lives here, inside Entity's namespace. Entity delegates to_yaml / from_yaml to this class.

Why a separate class? lutaml-model serialization calls public_send(attr_name) during to_format, which invokes the getter method. Entity's field DSL getters read from @properties and return domain objects (IRDI, source-language String, parsed Array). The YAML attrs need flat types (String, Hash, Array). Sharing the same name would make the getter return the wrong type for serialization. Keeping the YAML model here avoids that conflict while keeping the adapter "inside" Entity.

Canonical YAML shape:

---
irdi: 0112/2///61360_4#AAA001
type: class
code: AAA001
preferred_name:
en: Vehicle
fr: Véhicule
class_type: ITEM_CLASS
superclass: 0112/2///61360_4#AAA000
applicable_properties:
- 0112/2///61360_4#AAAP001
extra:
C016: released

Constant Summary collapse

KNOWN_WIRE_IDS =
%w[
  MDC_P002_1 MDC_P002_2 MDC_P066
  MDC_P004 MDC_P005 MDC_P006 MDC_P008 MDC_P009 MDC_P112
  MDC_P011 MDC_P010 MDC_P010_1
  MDC_P013 MDC_P014 MDC_P090 MDC_P016
  MDC_P022 MDC_P024 MDC_P021 MDC_P041 MDC_P028 MDC_P020
  MDC_P023 MDC_P023_1
  MDC_P046 MDC_P044 MDC_P043
  MDC_P200 MDC_P203 MDC_P204
  EXT_P002 EXT_P003
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_entity(entity) ⇒ Object

── Conversion: Entity → Entity::Yaml ───────────────────



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/opencdd/entity/yaml.rb', line 100

def self.from_entity(entity)
  attrs = {
    irdi: entity.irdi&.to_s,
    type: entity.type&.to_s,
    code: entity.code,
    guid: entity[Opencdd::PropertyIds::MDC_P066],
    version: entity[Opencdd::PropertyIds::MDC_P002_1],
    revision: entity[Opencdd::PropertyIds::MDC_P002_2],
  }

  attrs[:preferred_name] = extract_ml(entity, Opencdd::PropertyIds::MDC_P004)
  attrs[:short_name]     = extract_ml(entity, Opencdd::PropertyIds::MDC_P005)
  attrs[:definition]     = extract_ml(entity, Opencdd::PropertyIds::MDC_P006)
  attrs[:note]           = extract_ml(entity, Opencdd::PropertyIds::MDC_P008)
  attrs[:remark]         = extract_ml(entity, Opencdd::PropertyIds::MDC_P009)
  attrs[:description]    = extract_ml(entity, Opencdd::PropertyIds::MDC_P112)

  case entity.type
  when :class
    attrs[:class_type] = entity.read_field(:class_type)&.to_s
    attrs[:superclass] = entity.read_field(:superclass_irdi)&.to_s
    attrs[:is_case_of] = entity.read_field(:is_case_of_irdis)&.map(&:to_s) || []
    attrs[:applicable_properties] = entity.read_field(:applicable_property_irdis)&.map(&:to_s) || []
    attrs[:imported_properties] = entity.read_field(:imported_property_irdis)&.map(&:to_s) || []
    attrs[:sub_class_selection] = entity.read_field(:sub_class_selection_irdis)&.map(&:to_s) || []
  when :property
    attrs[:data_type] = entity.read_field(:parsed_data_type)&.to_s
    attrs[:value_format] = entity.read_field(:parsed_value_format)&.to_s
    attrs[:definition_class] = entity.read_field(:definition_class_irdi)&.to_s
    attrs[:unit] = entity.read_field(:unit_irdi)&.to_s
    attrs[:condition] = entity.read_field(:condition)&.to_s
    attrs[:property_data_element_type] = entity.read_field(:property_data_element_type)&.to_s
  when :unit
    attrs[:unit_structure] = entity.read_field(:structure)
    attrs[:unit_text] = entity.read_field(:text_representation)
  when :value_list
    attrs[:list_type] = entity.read_field(:list_type)&.to_s
    attrs[:code_list] = entity.read_field(:code_list) || []
    attrs[:term_irdis] = entity.read_field(:term_irdis)&.map(&:to_s) || []
  when :value_term
    attrs[:enumeration_code] = entity.read_field(:enumeration_code)
  when :relation
    attrs[:relation_type] = entity.read_field(:relation_type)&.to_s
    attrs[:codomain] = entity.read_field(:codomain_irdi)&.to_s
    attrs[:formula] = entity.read_field(:formula)
  when :view_control
    attrs[:controlled_classes] = entity.read_field(:controlled_class_irdis)&.map(&:to_s) || []
    attrs[:shown_properties] = entity.read_field(:shown_property_irdis)&.map(&:to_s) || []
  end

  extra = extract_extra(entity)
  attrs[:extra] = extra if extra

  new(**attrs.compact)
end

.merge_ml(props, pid, hash) ⇒ Object



251
252
253
254
# File 'lib/opencdd/entity/yaml.rb', line 251

def self.merge_ml(props, pid, hash)
  return unless hash&.any?
  hash.each { |lang, val| props["#{pid}.#{lang}"] = val }
end

Instance Method Details

#to_entity(_database = nil) ⇒ Object

── Conversion: Entity::Yaml → Entity ───────────────────



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/opencdd/entity/yaml.rb', line 157

def to_entity(_database = nil)
  props = {}

  props[Opencdd::PropertyIds::MDC_P066] = guid if guid
  props[Opencdd::PropertyIds::MDC_P002_1] = version if version
  props[Opencdd::PropertyIds::MDC_P002_2] = revision if revision

  merge_ml_into(props, Opencdd::PropertyIds::MDC_P004, preferred_name)
  merge_ml_into(props, Opencdd::PropertyIds::MDC_P005, short_name)
  merge_ml_into(props, Opencdd::PropertyIds::MDC_P006, definition)
  merge_ml_into(props, Opencdd::PropertyIds::MDC_P008, note)
  merge_ml_into(props, Opencdd::PropertyIds::MDC_P009, remark)
  merge_ml_into(props, Opencdd::PropertyIds::MDC_P112, description)

  props[Opencdd::PropertyIds::MDC_P011] = class_type if class_type
  props[Opencdd::PropertyIds::MDC_P010] = superclass if superclass
  props[Opencdd::PropertyIds::MDC_P013] = rejoin_set(is_case_of) if is_case_of&.any?
  props[Opencdd::PropertyIds::MDC_P014] = rejoin_set(applicable_properties) if applicable_properties&.any?
  props[Opencdd::PropertyIds::MDC_P090] = rejoin_set(imported_properties) if imported_properties&.any?
  props[Opencdd::PropertyIds::MDC_P016] = rejoin_set(sub_class_selection) if sub_class_selection&.any?

  props[Opencdd::PropertyIds::MDC_P022] = data_type if data_type
  props[Opencdd::PropertyIds::MDC_P024] = value_format if value_format
  props[Opencdd::PropertyIds::MDC_P021] = definition_class if definition_class
  props[Opencdd::PropertyIds::MDC_P041] = unit if unit
  props[Opencdd::PropertyIds::MDC_P028] = condition if condition
  props[Opencdd::PropertyIds::MDC_P020] = property_data_element_type if property_data_element_type

  props[Opencdd::PropertyIds::MDC_P023] = unit_structure if unit_structure
  props[Opencdd::PropertyIds::MDC_P023_1] = unit_text if unit_text

  props[Opencdd::PropertyIds::MDC_P046] = list_type if list_type
  props[Opencdd::PropertyIds::MDC_P044] = rejoin_set(code_list) if code_list&.any?
  props[Opencdd::PropertyIds::MDC_P043] = rejoin_set(term_irdis) if term_irdis&.any?

  props[Opencdd::PropertyIds::MDC_P044] = enumeration_code if enumeration_code

  props[Opencdd::PropertyIds::MDC_P200] = relation_type if relation_type
  props[Opencdd::PropertyIds::MDC_P203] = codomain if codomain
  props[Opencdd::PropertyIds::MDC_P204] = formula if formula

  props[Opencdd::PropertyIds::EXT_P002] = rejoin_set(controlled_classes) if controlled_classes&.any?
  props[Opencdd::PropertyIds::EXT_P003] = rejoin_set(shown_properties) if shown_properties&.any?

  extra&.each { |k, v| props[k.to_s] = v }

  entity_class = Opencdd::MetaClasses.entity_class_for_type(type&.to_sym) || Opencdd::Klass
  meta_code = Opencdd::MetaClasses.meta_class_for_type(type&.to_sym) || Opencdd::MetaClasses::MDC_C002

  entity_class.new(
    irdi: irdi ? Opencdd::IRDI.parse(irdi) : nil,
    properties: props,
    meta_class_irdi: Opencdd::IRDI.parse(meta_code),
  )
end