Class: Lutaml::UmlRepository::IndexBuilder

Inherits:
Object
  • Object
show all
Includes:
Lutaml::UmlRepository::IndexBuilders::AssociationIndex, Lutaml::UmlRepository::IndexBuilders::ClassIndex, Lutaml::UmlRepository::IndexBuilders::PackageIndex
Defined in:
lib/lutaml/uml_repository/index_builder.rb

Overview

IndexBuilder builds fast lookup indexes from a Lutaml::Uml::Document

This class creates immutable hash indexes that enable O(1) lookups for:

  • Package paths (e.g., “ModelRoot::i-UR::urf”)

  • Qualified names (e.g., “ModelRoot::i-UR::urf::Building”)

  • Stereotypes (e.g., “featureType” => [Class, Class, …])

  • Inheritance graph (parent_qname => [child_qname, …])

  • Diagram index (package_id => [Diagram, …])

  • Package to path mapping (package_id => path)

  • Class to qualified name mapping (class_id => qualified_name)

  • Classes (class_id => Class)

  • Associations (association_id => Association)

All indexes are frozen to ensure immutability.

Examples:

Building all indexes from a document

indexes = IndexBuilder.build_all(document)
package = indexes[:package_paths]["ModelRoot::i-UR"]
klass = indexes[:qualified_names]["ModelRoot::i-UR::Building"]

Constant Summary collapse

ROOT_PACKAGE_NAME =
"ModelRoot"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Lutaml::UmlRepository::IndexBuilders::AssociationIndex

#build_association_index, #build_inheritance_graph_index, #extract_parent_name, #index_class_level_associations, #index_document_associations, #index_generalization_edge, #index_inheritance_assoc_edges, #index_inheritance_edge, #klassifiable?, #name_from_general, #process_generalizations, #resolve_parent_name_from_assoc, #resolve_qualified_name

Methods included from Lutaml::UmlRepository::IndexBuilders::ClassIndex

#build_qualified_name_index, #build_stereotype_index, #has_stereotype?, #index_by_stereotype, #index_classifier, #index_classifiers, #index_document_classifiers, #index_document_stereotypes, #index_package_classifiers, #index_package_stereotypes

Methods included from Lutaml::UmlRepository::IndexBuilders::PackageIndex

#build_package_path, #build_package_path_index, #traverse_packages

Constructor Details

#initialize(document) ⇒ IndexBuilder

Returns a new instance of IndexBuilder.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/lutaml/uml_repository/index_builder.rb', line 139

def initialize(document)
  @document = document
  @package_paths = {}
  @qualified_names = {}
  @stereotypes = {}
  @inheritance_graph = {}
  @diagram_index = {}
  @package_to_path = {}
  @class_to_qname = {}
  @classes = {}
  @associations = {}
  @simple_name_to_qnames = {}
  @package_to_classes = {}
end

Instance Attribute Details

#associationsObject (readonly)

Returns the value of attribute associations.



155
156
157
# File 'lib/lutaml/uml_repository/index_builder.rb', line 155

def associations
  @associations
end

#class_to_qnameObject (readonly)

Returns the value of attribute class_to_qname.



155
156
157
# File 'lib/lutaml/uml_repository/index_builder.rb', line 155

def class_to_qname
  @class_to_qname
end

#classesObject (readonly)

Returns the value of attribute classes.



155
156
157
# File 'lib/lutaml/uml_repository/index_builder.rb', line 155

def classes
  @classes
end

#diagram_indexObject (readonly)

Returns the value of attribute diagram_index.



155
156
157
# File 'lib/lutaml/uml_repository/index_builder.rb', line 155

def diagram_index
  @diagram_index
end

#inheritance_graphObject (readonly)

Returns the value of attribute inheritance_graph.



155
156
157
# File 'lib/lutaml/uml_repository/index_builder.rb', line 155

def inheritance_graph
  @inheritance_graph
end

#package_pathsObject

Returns the value of attribute package_paths.



154
155
156
# File 'lib/lutaml/uml_repository/index_builder.rb', line 154

def package_paths
  @package_paths
end

#package_to_pathObject (readonly)

Returns the value of attribute package_to_path.



155
156
157
# File 'lib/lutaml/uml_repository/index_builder.rb', line 155

def package_to_path
  @package_to_path
end

#qualified_namesObject

Returns the value of attribute qualified_names.



154
155
156
# File 'lib/lutaml/uml_repository/index_builder.rb', line 154

def qualified_names
  @qualified_names
end

#stereotypesObject (readonly)

Returns the value of attribute stereotypes.



155
156
157
# File 'lib/lutaml/uml_repository/index_builder.rb', line 155

def stereotypes
  @stereotypes
end

Class Method Details

.build_all(document) ⇒ Hash

Build all indexes from a UML document

Parameters:

Returns:

  • (Hash)

    A frozen hash containing all indexes with keys:

    • :package_paths - Maps package paths to Package objects

    • :qualified_names - Maps qualified names to Class/DataType/Enum objects

    • :stereotypes - Groups classes by stereotype

    • :inheritance_graph - Maps parent qualified names to child qualified names

    • :diagram_index - Maps package IDs/paths to Diagram objects

    • :package_to_path - Maps package XMI IDs to paths

    • :class_to_qname - Maps class XMI IDs to qualified names

    • :classes - Maps class XMI IDs to Class objects

    • :associations - Maps association XMI IDs to Association objects



46
47
48
# File 'lib/lutaml/uml_repository/index_builder.rb', line 46

def self.build_all(document)
  new(document).build_all
end

.build_associations(document) ⇒ Object



88
89
90
91
92
93
94
95
# File 'lib/lutaml/uml_repository/index_builder.rb', line 88

def self.build_associations(document)
  builder = new(document)
  # build_association_index needs @qualified_names to collect
  # class-level associations
  builder.build_qualified_name_index
  builder.build_association_index
  builder.associations.freeze
end

.build_class_to_qname(document) ⇒ Object



76
77
78
79
80
# File 'lib/lutaml/uml_repository/index_builder.rb', line 76

def self.build_class_to_qname(document)
  builder = new(document)
  builder.build_qualified_name_index
  builder.class_to_qname.freeze
end

.build_classes(document) ⇒ Object



82
83
84
85
86
# File 'lib/lutaml/uml_repository/index_builder.rb', line 82

def self.build_classes(document)
  builder = new(document)
  builder.build_qualified_name_index
  builder.classes.freeze
end

.build_diagram_index(document, indexes) ⇒ Hash

Build diagram index

Parameters:

  • document (Lutaml::Uml::Document)

    The UML document

  • indexes (Hash, nil)

    Existing indexes (requires :package_paths)

Returns:

  • (Hash)

    Frozen hash mapping package IDs to Diagram objects



128
129
130
131
132
133
134
135
136
137
# File 'lib/lutaml/uml_repository/index_builder.rb', line 128

def self.build_diagram_index(document, indexes)
  builder = new(document)
  if indexes && indexes[:package_paths]
    builder.package_paths = indexes[:package_paths]
  else
    builder.build_package_path_index
  end
  builder.build_diagram_index
  builder.diagram_index.freeze
end

.build_inheritance_graph(document, indexes) ⇒ Hash

Build inheritance graph index

Parameters:

  • document (Lutaml::Uml::Document)

    The UML document

  • indexes (Hash, nil)

    Existing indexes (requires :qualified_names)

Returns:

  • (Hash)

    Frozen hash mapping parent qnames to child qnames



112
113
114
115
116
117
118
119
120
121
# File 'lib/lutaml/uml_repository/index_builder.rb', line 112

def self.build_inheritance_graph(document, indexes)
  builder = new(document)
  if indexes && indexes[:qualified_names]
    builder.qualified_names = indexes[:qualified_names]
  else
    builder.build_qualified_name_index
  end
  builder.build_inheritance_graph_index
  builder.inheritance_graph.freeze
end

.build_package_paths(document) ⇒ Hash

Build package paths index

Parameters:

Returns:

  • (Hash)

    Frozen hash mapping package paths to Package objects



54
55
56
57
58
# File 'lib/lutaml/uml_repository/index_builder.rb', line 54

def self.build_package_paths(document)
  builder = new(document)
  builder.build_package_path_index
  builder.package_paths.freeze
end

.build_package_to_path(document) ⇒ Object



60
61
62
63
64
# File 'lib/lutaml/uml_repository/index_builder.rb', line 60

def self.build_package_to_path(document)
  builder = new(document)
  builder.build_package_path_index
  builder.package_to_path.freeze
end

.build_qualified_names(document) ⇒ Hash

Build qualified names index

Parameters:

Returns:

  • (Hash)

    Frozen hash mapping qualified names to Class objects



70
71
72
73
74
# File 'lib/lutaml/uml_repository/index_builder.rb', line 70

def self.build_qualified_names(document)
  builder = new(document)
  builder.build_qualified_name_index
  builder.qualified_names.freeze
end

.build_stereotypes(document) ⇒ Hash

Build stereotypes index

Parameters:

Returns:

  • (Hash)

    Frozen hash grouping classes by stereotype



101
102
103
104
105
# File 'lib/lutaml/uml_repository/index_builder.rb', line 101

def self.build_stereotypes(document)
  builder = new(document)
  builder.build_stereotype_index
  builder.stereotypes.freeze
end

Instance Method Details

#build_allHash

Build all indexes and return them as a frozen hash

Returns:

  • (Hash)

    Frozen hash containing all indexes



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/lutaml/uml_repository/index_builder.rb', line 161

def build_all # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  build_package_path_index
  build_qualified_name_index
  build_stereotype_index
  build_inheritance_graph_index
  build_diagram_index
  build_association_index

  {
    package_paths: @package_paths.freeze,
    qualified_names: @qualified_names.freeze,
    stereotypes: @stereotypes.freeze,
    inheritance_graph: @inheritance_graph.freeze,
    diagram_index: @diagram_index.freeze,
    package_to_path: @package_to_path.freeze,
    class_to_qname: @class_to_qname.freeze,
    classes: @classes.freeze,
    associations: @associations.freeze,
    package_to_classes: plain_hash(@package_to_classes).freeze,
  }.freeze
end

#build_diagram_indexObject

Build the diagram index

Creates a hash mapping package IDs/paths to arrays of Diagram objects:

"package_id" => [Diagram{}, Diagram{}]


188
189
190
191
192
193
194
195
196
197
198
# File 'lib/lutaml/uml_repository/index_builder.rb', line 188

def build_diagram_index
  # Traverse packages and collect diagrams
  traverse_packages(@document.packages) do |package, path|
    next unless package.diagrams && !package.diagrams.empty?

    # Index by package ID if available, otherwise by path
    key = package.xmi_id || path
    @diagram_index[key] ||= []
    @diagram_index[key].concat(package.diagrams)
  end
end