Class: Lutaml::Uml::QualifiedName

Inherits:
Object
  • Object
show all
Defined in:
lib/lutaml/uml/qualified_name.rb

Overview

Immutable value object representing a UML qualified class name.

A qualified name consists of a package path and a class name. Examples:

- "i-UR::urf::UrbanPlanningArea"
  (package: "i-UR::urf", class: "UrbanPlanningArea")
- "ModelRoot::CityGML::Building"
  (package: "ModelRoot::CityGML", class: "Building")

QualifiedName objects are immutable and frozen after initialization.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(qualified_name) ⇒ QualifiedName

Create a new QualifiedName.

array of segments

(e.g., "i-UR::urf::UrbanPlanningArea" or
["i-UR", "urf", "UrbanPlanningArea"])

Parameters:

  • qualified_name (String, Array<String>)

    The full qualified name or

Raises:

  • (ArgumentError)

    if qualified_name is nil



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/lutaml/uml/qualified_name.rb', line 27

def initialize(qualified_name) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  if qualified_name.nil?
    raise ArgumentError, "Qualified name cannot be nil"
  end

  # Handle both string and array inputs
  parts = if qualified_name.is_a?(Array)
            qualified_name.reject { |s| s.nil? || s.empty? }
          else
            qualified_name.split(PackagePath::SEPARATOR).reject(&:empty?)
          end

  # Allow empty qualified names
  if parts.empty?
    @class_name = ""
    @package_path = PackagePath.new("")
  else
    @class_name = parts.last.freeze

    # Package path can be empty for unqualified names
    @package_path = if parts.size > 1
                      PackagePath.new(parts[0...-1])
                    else
                      # Create empty package path
                      PackagePath.new("")
                    end
  end

  freeze
end

Instance Attribute Details

#class_nameObject (readonly)

Returns the value of attribute class_name.



18
19
20
# File 'lib/lutaml/uml/qualified_name.rb', line 18

def class_name
  @class_name
end

#package_pathObject (readonly)

Returns the value of attribute package_path.



18
19
20
# File 'lib/lutaml/uml/qualified_name.rb', line 18

def package_path
  @package_path
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Check equality with another QualifiedName.

Parameters:

  • other (Object)

    The object to compare with

Returns:

  • (Boolean)

    true if equal



162
163
164
165
166
# File 'lib/lutaml/uml/qualified_name.rb', line 162

def ==(other)
  other.is_a?(QualifiedName) &&
    @package_path == other.package_path &&
    @class_name == other.class_name
end

#hashInteger

Generate hash code for this qualified name.

Returns:

  • (Integer)

    The hash code



173
174
175
# File 'lib/lutaml/uml/qualified_name.rb', line 173

def hash
  [@package_path, @class_name].hash
end

#in_package?(path) ⇒ Boolean

Check if this class is in the specified package.

Examples:

qname = QualifiedName.new("i-UR::urf::UrbanPlanningArea")
qname.in_package?("i-UR::urf") # => true
qname.in_package?("i-UR") # => false

Parameters:

  • path (String, PackagePath)

    The package path to check

Returns:

  • (Boolean)

    true if the class is in the package



94
95
96
97
# File 'lib/lutaml/uml/qualified_name.rb', line 94

def in_package?(path)
  check_path = path.is_a?(PackagePath) ? path : PackagePath.new(path)
  @package_path == check_path
end

#matches_glob?(pattern) ⇒ Boolean

Check if this qualified name matches a glob pattern.

Examples:

qname = QualifiedName.new("Package1::Package2::ClassName")
qname.matches_glob?("Package1::*::ClassName") # => true

Parameters:

  • pattern (String)

    The glob pattern to match against

Returns:

  • (Boolean)

    true if matches



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/lutaml/uml/qualified_name.rb', line 106

def matches_glob?(pattern)
  # Create a full path for matching (package + class)
  full_segments = if @package_path.respond_to?(:segments) &&
      !@package_path.segments.empty?
                    @package_path.segments + [@class_name]
                  else
                    [@class_name]
                  end

  full_path = PackagePath.new(full_segments)
  full_path.matches_glob?(pattern)
end

#qualified?Boolean

Check if this is a qualified name (has a package path).

Examples:

QualifiedName.new("Package::Class").qualified? # => true
QualifiedName.new("Class").qualified? # => false

Returns:

  • (Boolean)

    true if qualified (has package), false if unqualified



82
83
84
# File 'lib/lutaml/uml/qualified_name.rb', line 82

def qualified?
  !@package_path.nil? && !@package_path.empty?
end

#relative_to(base_path_string) ⇒ QualifiedName

Get the relative qualified name from a base package path.

or self if not relative

Examples:

qname = QualifiedName.new("ModelRoot::i-UR::urf::UrbanPlanningArea")
qname.relative_to("ModelRoot::i-UR")
# => QualifiedName("urf::UrbanPlanningArea")

Parameters:

  • base_path_string (String)

    The base package path

Returns:



144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/lutaml/uml/qualified_name.rb', line 144

def relative_to(base_path_string)
  relative_path = @package_path.relative_to(base_path_string)

  # If package path didn't change, return self
  return self if relative_path == @package_path

  # Otherwise create new qualified name with relative path
  if relative_path.respond_to?(:empty?) && relative_path.empty?
    self.class.new(@class_name)
  else
    self.class.new("#{relative_path}#{PackagePath::SEPARATOR}#{@class_name}")
  end
end

#to_sString

Convert to string representation.

Examples:

qname = QualifiedName.new("i-UR::urf::UrbanPlanningArea")
qname.to_s # => "i-UR::urf::UrbanPlanningArea"

Returns:

  • (String)

    The fully qualified name (empty string for empty name)



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/lutaml/uml/qualified_name.rb', line 64

def to_s
  return "" if @class_name.nil? || @class_name.empty?

  # Check if package path is empty
  if @package_path.nil? ||
      (@package_path.respond_to?(:empty?) && @package_path.empty?)
    return @class_name
  end

  "#{@package_path}#{PackagePath::SEPARATOR}#{@class_name}"
end

#with_package(new_package_path) ⇒ QualifiedName

Create a new qualified name with a different package path.

Examples:

qname = QualifiedName.new("Package1::ClassName")
new_path = PackagePath.new("Package2")
qname.with_package(new_path) # => QualifiedName("Package2::ClassName")

Parameters:

  • new_package_path (PackagePath)

    The new package path

Returns:

  • (QualifiedName)

    A new qualified name with the package replaced



127
128
129
130
131
132
133
# File 'lib/lutaml/uml/qualified_name.rb', line 127

def with_package(new_package_path)
  if new_package_path.respond_to?(:empty?) && new_package_path.empty?
    self.class.new(@class_name)
  else
    self.class.new("#{new_package_path}#{PackagePath::SEPARATOR}#{@class_name}")
  end
end