Class: Lutaml::UmlRepository::Queries::ClassQuery

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

Overview

Query service for class/classifier operations.

Provides methods to find and query classes, data types, and enums using the qualified_names and stereotypes indexes.

Examples:

Finding a class by qualified name

query = ClassQuery.new(document, indexes)
klass = query.find_by_qname("ModelRoot::i-UR::urf::Building")

Finding classes by stereotype

classes = query.find_by_stereotype("featureType")

Getting classes in a package

classes = query.in_package("ModelRoot::i-UR::urf")

Instance Method Summary collapse

Methods inherited from BaseQuery

#initialize

Constructor Details

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

Instance Method Details

#find_by_qname(qualified_name_string) ⇒ Lutaml::Uml::Class, ...

Find a class by its qualified name.

Lutaml::Uml::Enum, nil]

The class object, or nil if not found

Examples:

klass = query.find_by_qname("ModelRoot::i-UR::urf::Building")

Parameters:

  • qualified_name_string (String)

    The qualified name (e.g., “ModelRoot::i-UR::urf::Building”)

Returns:



34
35
36
37
38
39
40
# File 'lib/lutaml/uml_repository/queries/class_query.rb', line 34

def find_by_qname(qualified_name_string)
  if qualified_name_string.nil? || qualified_name_string.empty?
    return nil
  end

  indexes[:qualified_names][qualified_name_string]
end

#find_by_stereotype(stereotype) ⇒ Array

Find all classes with a specific stereotype.

Examples:

feature_types = query.find_by_stereotype("featureType")
# => [Class{name: "Building"}, Class{name: "Road"}, ...]

Parameters:

  • stereotype (String)

    The stereotype to search for

Returns:

  • (Array)

    Array of class objects with the stereotype



49
50
51
52
53
# File 'lib/lutaml/uml_repository/queries/class_query.rb', line 49

def find_by_stereotype(stereotype)
  return [] if stereotype.nil? || stereotype.empty?

  indexes[:stereotypes][stereotype] || []
end

#in_package(package_path_string, recursive: false) ⇒ Array

Get classes in a specific package.

Examples:

Non-recursive query

classes = query.in_package(
"ModelRoot::i-UR::urf", recursive: false)
# Returns only classes directly in the urf package

Recursive query

classes = query.in_package("ModelRoot::i-UR", recursive: true)
# Returns classes in i-UR and all nested packages

Parameters:

  • package_path_string (String)

    The package path

  • recursive (Boolean) (defaults to: false)

    Whether to include classes from nested packages (default: false)

Returns:

  • (Array)

    Array of class objects in the package



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/lutaml/uml_repository/queries/class_query.rb', line 69

def in_package(package_path_string, recursive: false) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  return [] if package_path_string.nil? || package_path_string.empty?

  package_path = Lutaml::Uml::PackagePath.new(package_path_string)
  results = []

  # Check if the path is absolute (starts with ModelRoot)
  is_absolute = package_path.absolute?

  indexes[:qualified_names].each do |qname_string, klass| # rubocop:disable Metrics/BlockLength
    qname = Lutaml::Uml::QualifiedName.new(qname_string)

    matched = if is_absolute
                # Absolute path - exact match
                if recursive
                  qname.package_path.starts_with?(package_path)
                else
                  qname.package_path == package_path
                end
              else
                # Relative path - match if the class's package path ends with
                # the given path
                class_pkg_segs = qname.package_path.segments
                search_segs = package_path.segments

                if recursive
                  # For recursive, check if any suffix of the class path
                  # starts with search_segs
                  (0..(class_pkg_segs.size - search_segs.size))
                    .any? do |i|
                    class_pkg_segs[i, search_segs.size] == search_segs
                  end
                else
                  # For non-recursive, check if class path ends with
                  # search_segs
                  class_pkg_segs.size >= search_segs.size &&
                    class_pkg_segs[-search_segs.size..] == search_segs
                end
              end

    results << klass if matched
  end

  results
end