Class: Lutaml::UmlRepository::Queries::InheritanceQuery

Inherits:
BaseQuery
  • Object
show all
Defined in:
lib/lutaml/uml_repository/queries/inheritance_query.rb

Overview

Query service for inheritance operations.

Provides methods to navigate class inheritance hierarchies using the inheritance_graph index, which maps parent qualified names to arrays of child qualified names.

Examples:

Getting a class’s parent

query = InheritanceQuery.new(document, indexes)
parent = query.supertype("ModelRoot::Child")

Getting all ancestors

ancestors = query.ancestors("ModelRoot::GrandChild")
# => [Parent, GrandParent, ...]

Getting descendants

descendants = query.descendants("ModelRoot::Parent", max_depth: 2)

Instance Method Summary collapse

Methods inherited from BaseQuery

#initialize

Constructor Details

This class inherits a constructor from Lutaml::UmlRepository::Queries::BaseQuery

Instance Method Details

#ancestors(class_or_qname) ⇒ Array

Get all ancestor classes up to the root.

Returns ancestors in order from immediate parent to root.

Examples:

ancestors = query.ancestors("ModelRoot::GrandChild")
# => [Parent, GrandParent]

Parameters:

  • class_or_qname (Lutaml::Uml::Class, String)

    The class object or qualified name string

Returns:

  • (Array)

    Array of ancestor class objects, ordered from nearest to furthest



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 99

def ancestors(class_or_qname)
  result = []
  current = class_or_qname

  loop do
    parent = supertype(current)
    break unless parent

    result << parent
    current = parent
  end

  result
end

#descendants(class_or_qname, max_depth: nil) ⇒ Array

Get all descendant classes.

Examples:

descendants = query.descendants("ModelRoot::Parent", max_depth: 2)

Parameters:

  • class_or_qname (Lutaml::Uml::Class, String)

    The class object or qualified name string

  • max_depth (Integer, nil) (defaults to: nil)

    Maximum depth to traverse (nil for unlimited)

Returns:

  • (Array)

    Array of descendant class objects



134
135
136
137
138
139
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 134

def descendants(class_or_qname, max_depth: nil)
  qname_string = resolve_qname(class_or_qname)
  return [] unless qname_string

  collect_descendants(qname_string, max_depth, 0)
end

#find_ancestors(class_xmi_id) ⇒ Array

Get all ancestor classes up to the root by class XMI ID.

Parameters:

  • class_xmi_id (String)

    The XMI ID of the class

Returns:

  • (Array)

    Array of ancestor class objects



118
119
120
121
122
123
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 118

def find_ancestors(class_xmi_id)
  qualified_name, _klass = find_class_by_id(class_xmi_id)
  return [] unless qualified_name

  ancestors(qualified_name)
end

#resolve_class(class_or_qname) ⇒ Lutaml::Uml::Class?

Resolve a class or qualified name to a class object.

or nil if not found

Parameters:

  • class_or_qname (Lutaml::Uml::Class, String)

    The class object or qualified name string

Returns:



147
148
149
150
151
152
153
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 147

def resolve_class(class_or_qname)
  if class_or_qname.is_a?(String)
    indexes[:qualified_names][class_or_qname]
  else
    class_or_qname
  end
end

#resolve_qname(class_or_qname) ⇒ String?

Resolve a class or qualified name to a qualified name string.

Parameters:

  • class_or_qname (Lutaml::Uml::Class, String)

    The class object or qualified name string

Returns:

  • (String, nil)

    The qualified name string, or nil if not found



160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 160

def resolve_qname(class_or_qname)
  if class_or_qname.is_a?(String) &&
      indexes[:qualified_names].key?(class_or_qname)
    return class_or_qname
  end

  # Search for the class in the index
  qname, _klass = indexes[:qualified_names].find do |_name, entity|
    entity == class_or_qname
  end

  qname.nil? ? nil : qname
end

#subtypes(class_or_qname, recursive: false) ⇒ Array Also known as: find_children

Get direct child classes (subtypes).

Examples:

Direct children only

children = query.subtypes("ModelRoot::Parent", recursive: false)

All descendants

all_descendants = query.subtypes(
"ModelRoot::Parent", recursive: true)

Parameters:

  • class_or_qname (Lutaml::Uml::Class, String)

    The class object or qualified name string

  • recursive (Boolean) (defaults to: false)

    Whether to include all descendants (default: false)

Returns:

  • (Array)

    Array of child class objects



76
77
78
79
80
81
82
83
84
85
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 76

def subtypes(class_or_qname, recursive: false)
  qname_string = resolve_qname(class_or_qname)
  return [] unless qname_string

  if recursive
    descendants(class_or_qname)
  else
    direct_subtypes(qname_string)
  end
end

#supertype(class_or_qname) ⇒ Lutaml::Uml::Class? Also known as: find_parent

Get the direct parent class (supertype).

or nil if no parent

Examples:

parent = query.supertype("ModelRoot::Child")
# Or
parent = query.supertype(child_class)

Parameters:

  • class_or_qname (Lutaml::Uml::Class, String)

    The class object or qualified name string

Returns:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 36

def supertype(class_or_qname) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  klass = resolve_class(class_or_qname)
  return nil unless klass
  return nil unless klass.respond_to?(:generalization)
  return nil unless klass.generalization

  parent_name = extract_parent_name(klass.generalization)
  return nil unless parent_name
  # avoid self-references
  return nil if parent_name == klass.name

  # Try to find in qualified_names index
  qname_string = resolve_qname(class_or_qname)
  return nil unless qname_string

  qname = Lutaml::Uml::QualifiedName.new(qname_string)
  package_path = qname.package_path.to_s

  # Try to resolve parent qualified name
  parent_qname = resolve_parent_qualified_name(parent_name,
                                               package_path)
  return nil unless parent_qname

  indexes[:qualified_names][parent_qname]
end