Class: Lutaml::UmlRepository::Queries::InheritanceQuery
- 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.
Instance Method Summary collapse
-
#ancestors(class_or_qname) ⇒ Array
Get all ancestor classes up to the root.
-
#descendants(class_or_qname, max_depth: nil) ⇒ Array
Get all descendant classes.
-
#find_ancestors(class_xmi_id) ⇒ Array
Get all ancestor classes up to the root by class XMI ID.
-
#has_circular_inheritance?(class_or_id, visited: Set.new) ⇒ Boolean
Check if a class has circular inheritance.
-
#inheritance_tree(class_or_id) ⇒ Hash?
Build inheritance tree for a class.
-
#resolve_class(class_or_qname) ⇒ Lutaml::Uml::Class?
Resolve a class or qualified name to a class object.
-
#resolve_qname(class_or_qname) ⇒ String?
Resolve a class or qualified name to a qualified name string.
-
#subtypes(class_or_qname, recursive: false) ⇒ Array
(also: #find_children)
Get direct child classes (subtypes).
-
#supertype(class_or_qname) ⇒ Lutaml::Uml::Class?
(also: #find_parent)
Get the direct parent class (supertype).
Methods inherited from BaseQuery
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.
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.
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.
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 |
#has_circular_inheritance?(class_or_id, visited: Set.new) ⇒ Boolean
Check if a class has circular inheritance.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 202 def has_circular_inheritance?(class_or_id, visited: Set.new) qname = if class_or_id.is_a?(String) && indexes[:qualified_names].key?(class_or_id) class_or_id else resolve_qname(class_or_id) end return false unless qname return true if visited.include?(qname) visited.add(qname) child_qnames = indexes[:inheritance_graph][qname] || [] child_qnames.any? do |child_qname| has_circular_inheritance?(child_qname, visited: visited.dup) end end |
#inheritance_tree(class_or_id) ⇒ Hash?
Build inheritance tree for a class.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 179 def inheritance_tree(class_or_id) klass = resolve_by_id_or_qname(class_or_id) return nil unless klass qname = resolve_qname(klass) return nil unless qname child_qnames = indexes[:inheritance_graph][qname] || [] child_trees = child_qnames.filter_map do |child_qname| inheritance_tree(child_qname) end { class: klass, children: child_trees, } end |
#resolve_class(class_or_qname) ⇒ Lutaml::Uml::Class?
Resolve a class or qualified name to a class object.
or nil if not found
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.
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).
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
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 |