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.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 100 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.
135 136 137 138 139 140 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 135 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.
119 120 121 122 123 124 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 119 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.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 203 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.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 180 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
148 149 150 151 152 153 154 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 148 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.
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 161 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).
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 77 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
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/lutaml/uml_repository/queries/inheritance_query.rb', line 37 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 |