lutaml-model 0.8.5 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependent-tests.yml +4 -1
  3. data/.rubocop_todo.yml +97 -22
  4. data/docs/_migrations/0-8-0-namespace-restructuring.adoc +90 -0
  5. data/lib/lutaml/model/version.rb +1 -1
  6. data/lib/lutaml/xml/adapter/adapter_helpers.rb +1 -42
  7. data/lib/lutaml/xml/adapter/base_adapter.rb +48 -458
  8. data/lib/lutaml/xml/adapter/namespace_data.rb +0 -17
  9. data/lib/lutaml/xml/adapter/namespace_uri_collector.rb +71 -0
  10. data/lib/lutaml/xml/adapter/nokogiri_adapter.rb +5 -1110
  11. data/lib/lutaml/xml/adapter/oga_adapter.rb +6 -846
  12. data/lib/lutaml/xml/adapter/ox_adapter.rb +7 -884
  13. data/lib/lutaml/xml/adapter/plan_based_builder.rb +929 -0
  14. data/lib/lutaml/xml/adapter/rexml_adapter.rb +10 -864
  15. data/lib/lutaml/xml/adapter/xml_parser.rb +86 -0
  16. data/lib/lutaml/xml/adapter/xml_serializer.rb +291 -0
  17. data/lib/lutaml/xml/adapter.rb +0 -1
  18. data/lib/lutaml/xml/adapter_element.rb +7 -1
  19. data/lib/lutaml/xml/builder/base.rb +0 -1
  20. data/lib/lutaml/xml/data_model.rb +9 -1
  21. data/lib/lutaml/xml/document.rb +3 -1
  22. data/lib/lutaml/xml/element.rb +13 -10
  23. data/lib/lutaml/xml/schema/xsd/schema.rb +8 -5
  24. data/lib/lutaml/xml/serialization/format_conversion.rb +19 -42
  25. data/lib/lutaml/xml/serialization/instance_methods.rb +26 -35
  26. data/lib/lutaml/xml/transformation/custom_method_wrapper.rb +34 -55
  27. data/lib/lutaml/xml/transformation/rule_applier.rb +1 -1
  28. data/lib/lutaml/xml/xml_element.rb +24 -20
  29. data/spec/lutaml/xml/adapter/base_adapter_regression_spec.rb +151 -0
  30. data/spec/lutaml/xml/adapter/order_spec.rb +150 -0
  31. data/spec/lutaml/xml/clear_parse_state_spec.rb +139 -0
  32. data/spec/lutaml/xml/doubly_defined_namespace_spec.rb +0 -2
  33. data/spec/lutaml/xml/schema/compiler_spec.rb +75 -69
  34. data/spec/lutaml/xml/schema/xsd/schema_mapping_spec.rb +20 -0
  35. data/spec/lutaml/xml/schema/xsd/spec_helper.rb +1 -0
  36. data/spec/lutaml/xml/transformation/custom_method_wrapper_spec.rb +213 -14
  37. metadata +9 -3
  38. data/lib/lutaml/xml/adapter/xml_serialization.rb +0 -145
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5
4
+ version: 0.8.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-06 00:00:00.000000000 Z
11
+ date: 2026-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -634,11 +634,14 @@ files:
634
634
  - lib/lutaml/xml/adapter/adapter_helpers.rb
635
635
  - lib/lutaml/xml/adapter/base_adapter.rb
636
636
  - lib/lutaml/xml/adapter/namespace_data.rb
637
+ - lib/lutaml/xml/adapter/namespace_uri_collector.rb
637
638
  - lib/lutaml/xml/adapter/nokogiri_adapter.rb
638
639
  - lib/lutaml/xml/adapter/oga_adapter.rb
639
640
  - lib/lutaml/xml/adapter/ox_adapter.rb
641
+ - lib/lutaml/xml/adapter/plan_based_builder.rb
640
642
  - lib/lutaml/xml/adapter/rexml_adapter.rb
641
- - lib/lutaml/xml/adapter/xml_serialization.rb
643
+ - lib/lutaml/xml/adapter/xml_parser.rb
644
+ - lib/lutaml/xml/adapter/xml_serializer.rb
642
645
  - lib/lutaml/xml/adapter_element.rb
643
646
  - lib/lutaml/xml/adapter_loader.rb
644
647
  - lib/lutaml/xml/attribute_namespace_resolver.rb
@@ -1707,12 +1710,15 @@ files:
1707
1710
  - spec/lutaml/turtle/adapter_spec.rb
1708
1711
  - spec/lutaml/turtle/mapping_spec.rb
1709
1712
  - spec/lutaml/turtle/transform_spec.rb
1713
+ - spec/lutaml/xml/adapter/base_adapter_regression_spec.rb
1710
1714
  - spec/lutaml/xml/adapter/nokogiri_adapter_spec.rb
1711
1715
  - spec/lutaml/xml/adapter/oga_adapter_spec.rb
1716
+ - spec/lutaml/xml/adapter/order_spec.rb
1712
1717
  - spec/lutaml/xml/adapter/ox_adapter_spec.rb
1713
1718
  - spec/lutaml/xml/adapter/rexml_adapter_spec.rb
1714
1719
  - spec/lutaml/xml/adapter/xml_namespace_spec.rb
1715
1720
  - spec/lutaml/xml/builder/builder_spec.rb
1721
+ - spec/lutaml/xml/clear_parse_state_spec.rb
1716
1722
  - spec/lutaml/xml/compiled_rule_namespace_spec.rb
1717
1723
  - spec/lutaml/xml/conformance/xml_namespaces_spec.rb
1718
1724
  - spec/lutaml/xml/conformance/xml_schema_instance_spec.rb
@@ -1,145 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Lutaml
4
- module Xml
5
- module Adapter
6
- # Shared XML serialization logic for all adapters
7
- #
8
- # This module provides the common three-phase XML serialization architecture:
9
- # 1. Collect namespace needs from XmlElement tree
10
- # 2. Plan namespace declarations with hoisting
11
- # 3. Render using parallel traversal (XmlElement + DeclarationPlan)
12
- #
13
- # All adapters follow the same pattern:
14
- # - Case A: Parsed element (adapter-specific) → build_xml
15
- # - Case B: XmlElement → build_xml_element_with_plan
16
- # - Case C: Model instance → transform to XmlElement OR legacy path
17
- #
18
- # @example Include in adapter
19
- # class NokogiriAdapter < BaseAdapter
20
- # include XmlSerialization
21
- #
22
- # private
23
- #
24
- # def build_xml_element_with_plan(xml, xml_element, plan, options)
25
- # # Adapter-specific implementation
26
- # end
27
- # end
28
- module XmlSerialization
29
- # Serialize to XML using three-phase architecture
30
- #
31
- # @param options [Hash] Serialization options
32
- # @option options [Class] :mapper_class Model class for mapping lookup
33
- # @option options [String] :encoding Character encoding
34
- # @option options [Boolean] :declaration Include XML declaration
35
- # @option options [Boolean] :pretty Pretty-print output
36
- # @return [String] XML document
37
- def to_xml(options = {})
38
- # Accept xml_declaration from options if present (for model serialization)
39
- @xml_declaration = options[:xml_declaration] if options[:xml_declaration]
40
-
41
- # Build XML using adapter-specific builder
42
- build_xml_document(options)
43
- end
44
-
45
- private
46
-
47
- # Build the XML document (template method)
48
- #
49
- # Override in adapter to use specific builder
50
- #
51
- # @param options [Hash] Serialization options
52
- # @return [String] XML document
53
- def build_xml_document(options)
54
- raise NotImplementedError,
55
- "Subclasses must implement #build_xml_document"
56
- end
57
-
58
- # Transform model instance to XmlElement tree
59
- #
60
- # @param model [Object] Model instance
61
- # @param mapper_class [Class] Model class
62
- # @param options [Hash] Serialization options
63
- # @return [XmlDataModel::XmlElement] Transformed element tree
64
- def transform_model_to_xml_element(model, mapper_class, options)
65
- transformation = mapper_class.transformation_for(:xml, register)
66
- transformation.transform(model, options)
67
- end
68
-
69
- # Check if model has custom map_all methods
70
- #
71
- # @param xml_mapping [Xml::Mapping] XML mapping
72
- # @return [Boolean] True if custom methods present
73
- def has_custom_map_all_methods?(xml_mapping)
74
- xml_mapping.raw_mapping&.custom_methods &&
75
- xml_mapping.raw_mapping.custom_methods[:to]
76
- end
77
-
78
- # Collect namespace needs from element
79
- #
80
- # @param element [XmlElement, Object] Element to collect from
81
- # @param mapping [Xml::Mapping] XML mapping
82
- # @param mapper_class [Class] Model class
83
- # @return [Hash] Namespace needs
84
- def collect_namespace_needs(element, mapping, mapper_class: nil)
85
- collector = NamespaceCollector.new(register)
86
- collector.collect(element, mapping, mapper_class: mapper_class)
87
- end
88
-
89
- # Plan namespace declarations
90
- #
91
- # @param element [XmlElement, Object] Element to plan for
92
- # @param mapping [Xml::Mapping] XML mapping
93
- # @param needs [Hash] Namespace needs
94
- # @param options [Hash] Serialization options
95
- # @return [DeclarationPlan] Declaration plan with tree structure
96
- def plan_namespace_declarations(element, mapping, needs, options: {})
97
- planner = DeclarationPlanner.new(register)
98
- planner.plan(element, mapping, needs, options: options)
99
- end
100
-
101
- # Determine encoding from options
102
- #
103
- # @param options [Hash] Options hash
104
- # @return [String, nil] Encoding string or nil
105
- def determine_encoding(options)
106
- options[:encoding] ||
107
- options[:parse_encoding] ||
108
- @encoding ||
109
- "UTF-8"
110
- end
111
-
112
- # Check if XML declaration should be included
113
- #
114
- # @param options [Hash] Options hash
115
- # @return [Boolean] True if declaration should be included
116
- def should_include_declaration?(options)
117
- options[:declaration] == true
118
- end
119
-
120
- # Generate final XML output with declaration and doctype
121
- #
122
- # @param xml_data [String] XML content
123
- # @param options [Hash] Serialization options
124
- # @return [String] Complete XML document
125
- def finalize_xml_output(xml_data, options)
126
- result = ""
127
-
128
- # Include declaration when encoding is specified OR when declaration is requested
129
- if (options[:encoding] && !options[:encoding].nil?) || should_include_declaration?(options)
130
- result += generate_declaration(options)
131
- end
132
-
133
- # Add DOCTYPE if present
134
- doctype_to_use = options[:doctype] || @doctype
135
- if doctype_to_use && !options[:omit_doctype]
136
- result += generate_doctype_declaration(doctype_to_use)
137
- end
138
-
139
- result += xml_data
140
- result
141
- end
142
- end
143
- end
144
- end
145
- end