class Lutaml::Hal::Resource
Resource class for all HAL resources
def create_link_class(realize_class_name)
def create_link_class(realize_class_name) parent_klass_name = name.split('::')[0..-2].join('::') child_klass_name = "#{realize_class_name.split('::').last}Link" klass_name = [parent_klass_name, child_klass_name].join('::') Hal.debug_log "Creating link class #{klass_name} for #{realize_class_name}" return Object.const_get(klass_name) if Object.const_defined?(klass_name) # Define the link class dynamically klass = Class.new(Link) do # Define the link class with the specified key and class attribute :type, :string, default: realize_class_name end parent_klass = !parent_klass_name.empty? ? Object.const_get(parent_klass_name) : Object parent_klass.const_set(child_klass_name, klass) klass end
def create_link_set_class
The "links" class holds the `_links` object which contains
def create_link_set_class parent_klass_name = name.split('::')[0..-2].join('::') child_klass_name = "#{name.split('::').last}LinkSet" klass_name = [parent_klass_name, child_klass_name].join('::') Hal.debug_log "Creating link set class #{klass_name}" # Check if the LinkSet class is already defined, return if so return Object.const_get(klass_name) if Object.const_defined?(klass_name) # Define the LinkSet class dynamically as a normal Lutaml::Model class # since it is not a Resource. klass = Class.new(Lutaml::Hal::LinkSet) parent_klass = !parent_klass_name.empty? ? Object.const_get(parent_klass_name) : Object parent_klass.const_set(child_klass_name, klass) # Define the LinkSet class with mapping inside the current class class_eval do attribute :links, klass key_value do map '_links', to: :links end end end
def get_link_set_class
def get_link_set_class parent_klass_name = name.split('::')[0..-2].join('::') child_klass_name = "#{name.split('::').last}LinkSet" klass_name = [parent_klass_name, child_klass_name].join('::') raise unless Object.const_defined?(klass_name) Object.const_get(klass_name) end
def hal_link(attr_key,
is a collection of resources or a single resource
The "collection" is a boolean indicating if the link
The "realize_class" is the class to be realized
The "key" is the name of the attribute in the JSON
The developer defines a link to another resource
def hal_link(attr_key, key:, realize_class:, link_class: nil, link_set_class: nil, collection: false, type: :link) # Use the provided "key" as the attribute name attribute_name = attr_key.to_sym Hal.debug_log "Defining HAL link for `#{attr_key}` with realize class `#{realize_class}`" # Create a dynamic Link subclass name based on "realize_class", the # class to realize for a Link object, if `link_class:` is not provided. link_klass = link_class || create_link_class(realize_class) # Create a dynamic LinkSet class if `link_set_class:` is not provided. unless link_set_class link_set_klass = link_set_class || get_link_set_class link_set_klass.class_eval do # Declare the corresponding lutaml-model attribute attribute attribute_name, link_klass, collection: collection # Define the mapping for the attribute key_value do map key, to: attribute_name end end end # Create a new link definition for future reference link_def = { attribute_name: attribute_name, key: attr_key, klass: link_klass, collection: collection, type: type } @link_definitions ||= {} @link_definitions[key] = link_def end
def inherited(subclass)
def inherited(subclass) super subclass.class_eval do create_link_set_class init_links_definition end end
def init_links_definition
def init_links_definition @link_definitions = {} end