Class: Lutaml::Xml::CustomMethodWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/lutaml/xml/transformation/custom_method_wrapper.rb

Overview

Wrapper for custom method compatibility with XmlDataModel.

Custom methods use the old adapter API (doc.create_and_add_element), but the new transformation works with XmlDataModel. This wrapper bridges the gap by implementing the old adapter interface while working with XmlDataModel elements under the hood.

The wrapper tracks a “current context” element. When create_and_add_element is called with a block, the new element becomes the context for the duration of the block, allowing nested element creation.

Defined Under Namespace

Classes: ElementWrapper

Instance Method Summary collapse

Constructor Details

#initialize(parent, rule) ⇒ CustomMethodWrapper

Initialize the wrapper

Parameters:

  • parent (XmlDataModel::XmlElement)

    Parent element to add children to

  • rule (CompiledRule)

    The transformation rule



20
21
22
23
24
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 20

def initialize(parent, rule)
  @parent = parent
  @rule = rule
  @context_stack = [parent] # Stack of context elements for nested creation
end

Instance Method Details

#add_attribute(element, name, value) ⇒ Object

Add attribute to element (mimics old adapter API)

Parameters:

  • element (XmlDataModel::XmlElement)

    Element to add attribute to

  • name (String)

    Attribute name

  • value (String)

    Attribute value



156
157
158
159
160
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 156

def add_attribute(element, name, value)
  attr = Lutaml::Xml::DataModel::XmlAttribute.new(name.to_s,
                                                  value.to_s)
  element.add_attribute(attr)
end

#add_element(parent_or_element, element_or_string = nil) ⇒ XmlDataModel::XmlElement

Add an element to the current context (mimics old adapter API)

Parameters:

  • parent_or_element (XmlDataModel::XmlElement)

    Parent element or element to add

  • element_or_string (XmlDataModel::XmlElement, String, nil) (defaults to: nil)

    Element to add or string content (nil if parent_or_element is the element)

Returns:

  • (XmlDataModel::XmlElement)

    The added element



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 60

def add_element(parent_or_element, element_or_string = nil)
  # Handle overloaded API: add_element(element) or add_element(parent, element)
  if element_or_string.nil?
    # Single argument: parent_or_element is the element to add to current context
    element = parent_or_element
    current_context.add_child(element)
    return element
  end

  parent = parent_or_element

  if element_or_string.is_a?(String)
    add_xml_fragment_or_raw_content(parent, element_or_string)
  else
    # Add as child element
    parent.add_child(element_or_string)
  end
  element_or_string
end

#add_text(element, text) ⇒ Object

Add text to element (mimics old adapter API)

Parameters:

  • element (XmlDataModel::XmlElement, CustomMethodWrapper, nil)

    Element to add text to

  • text (String)

    Text content



140
141
142
143
144
145
146
147
148
149
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 140

def add_text(element, text)
  # Handle case where element is the wrapper itself (for content mapping)
  # or when element is nil (add to current context)
  target = if element.is_a?(CustomMethodWrapper) || element.nil?
             current_context
           else
             element
           end
  target.text_content = text
end

#create_and_add_element(name, attributes: {}) {|ElementWrapper| ... } ⇒ XmlElement

Create and add an element (mimics old adapter API)

When called with a block, the new element becomes the context for nested operations inside the block.

Parameters:

  • name (String)

    Element name

  • attributes (Hash) (defaults to: {})

    Optional attributes to add to the element

Yields:

Returns:



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
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 171

def create_and_add_element(name, attributes: {})
  # Create XmlDataModel element
  element = Lutaml::Xml::DataModel::XmlElement.new(name)

  # Add attributes if provided
  attributes&.each do |attr_name, attr_value|
    attr = Lutaml::Xml::DataModel::XmlAttribute.new(
      attr_name.to_s, attr_value.to_s
    )
    element.add_attribute(attr)
  end

  # Add to current context
  current_context.add_child(element)

  if block_given?
    # Push this element as the new context for nested operations
    push_context(element)

    begin
      # Create wrapper for the element
      wrapped_element = ElementWrapper.new(element, self)

      # Yield for customization (e.g., adding text, more nested elements)
      yield wrapped_element
    ensure
      # Restore previous context
      pop_context
    end
  end

  element
end

#create_element(name) ⇒ XmlDataModel::XmlElement

Create an element (mimics old adapter API)

Parameters:

  • name (String)

    Element name

Returns:

  • (XmlDataModel::XmlElement)

    The created element



51
52
53
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 51

def create_element(name)
  Lutaml::Xml::DataModel::XmlElement.new(name)
end

#current_contextXmlDataModel::XmlElement

Get the current context element (top of stack)

Returns:

  • (XmlDataModel::XmlElement)

    Current context element



29
30
31
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 29

def current_context
  @context_stack.last
end

#pop_contextXmlDataModel::XmlElement

Pop the current context from the stack

Returns:

  • (XmlDataModel::XmlElement)

    The popped context



43
44
45
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 43

def pop_context
  @context_stack.pop if @context_stack.size > 1
end

#push_context(element) ⇒ Object

Push a new context onto the stack

Parameters:

  • element (XmlDataModel::XmlElement)

    New context element



36
37
38
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 36

def push_context(element)
  @context_stack.push(element)
end