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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent) ⇒ CustomMethodWrapper

Returns a new instance of CustomMethodWrapper.

Parameters:

  • parent (XmlDataModel::XmlElement)

    Parent element to add children to



17
18
19
20
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 17

def initialize(parent)
  @parent = parent
  @context_stack = [parent]
end

Class Method Details

.build_element(name, attributes) ⇒ DataModel::XmlElement

Shared factory: create an XmlElement with optional attributes. Public so ElementWrapper can call it without an instance.

Parameters:

  • name (String)

    Element name

  • attributes (Hash)

    Optional attributes

Returns:



229
230
231
232
233
234
235
236
237
238
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 229

def self.build_element(name, attributes)
  element = Lutaml::Xml::DataModel::XmlElement.new(name)
  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
  element
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



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

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



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

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)
  elsif element_or_string.is_a?(::Lutaml::Xml::DataModel::XmlElement)
    parent.add_child(element_or_string)
  else
    raise TypeError,
          "add_element expects a String or XmlElement, got " \
          "#{element_or_string.class}. Call .to_xml on the element first."
  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. When the wrapper itself or nil is passed, text is added to the current context element.

  • text (String)

    Text content



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

def add_text(element, text)
  target = if element == self || 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:



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 170

def create_and_add_element(name, attributes: {})
  element = self.class.build_element(name, attributes)
  current_context.add_child(element)

  if block_given?
    push_context(element)
    begin
      yield ElementWrapper.new(element, self)
    ensure
      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



47
48
49
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 47

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



25
26
27
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 25

def current_context
  @context_stack.last
end

#pop_contextXmlDataModel::XmlElement

Pop the current context from the stack

Returns:

  • (XmlDataModel::XmlElement)

    The popped context



39
40
41
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 39

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



32
33
34
# File 'lib/lutaml/xml/transformation/custom_method_wrapper.rb', line 32

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