Class: Ea::Qea::Factory::EaToUmlFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/ea/qea/factory/ea_to_uml_factory.rb

Overview

Main factory for orchestrating EA to UML transformation Implements Facade pattern for complete model transformation

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(database, options = {}) ⇒ EaToUmlFactory

Initialize factory with EA database (default: true)

Parameters:

  • database (Ea::Qea::Database)

    Loaded EA database

  • options (Hash) (defaults to: {})

    Transformation options

Options Hash (options):

  • :include_diagrams (Boolean)

    Include diagrams

  • :validate (Boolean)

    Validate output (default: true)

  • :document_name (String)

    Document name



18
19
20
21
22
23
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 18

def initialize(database, options = {})
  @database = database
  @options = default_options.merge(options)
  @resolver = ReferenceResolver.new
  @transformers = {}
end

Instance Attribute Details

#databaseObject (readonly)

Returns the value of attribute database.



9
10
11
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 9

def database
  @database
end

#optionsObject (readonly)

Returns the value of attribute options.



9
10
11
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 9

def options
  @options
end

#resolverObject (readonly)

Returns the value of attribute resolver.



9
10
11
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 9

def resolver
  @resolver
end

Instance Method Details

#create_documentLutaml::Uml::Document

Create complete UML document from EA database

Returns:

  • (Lutaml::Uml::Document)

    Complete UML document



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
57
58
59
60
61
62
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 27

def create_document # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  builder = DocumentBuilder.new(
    name: options[:document_name] || "EA Model",
  )

  # Transform packages with hierarchy (includes all classes)
  packages = transform_packages

  # Transform associations (references classes by xmi_id)
  associations = transform_associations

  # Collect class-level associations from packages
  # class-level associations contain associations with both directions
  # and it may include associations in connector level
  # i.e. owner_end -> member_end and member_end -> owner_end
  class_associations = collect_class_association(packages)

  # Orphaned classes: EA class objects whose package_id does not
  # resolve to a known package. Attach them to the document root so
  # their associations can resolve.
  orphan_classes = transform_orphan_classes

  # Build document with both connector-level and
  # class-level associations
  builder.add_packages(packages)
    .add_classes(orphan_classes)
    .add_associations(associations)
    .add_associations(class_associations)

  # Add diagrams if requested
  if options[:include_diagrams]
    builder.add_diagrams(transform_diagrams)
  end

  builder.build(validate: options[:validate])
end

#ea_class_objectsArray<Ea::Qea::Models::EaObject>

All EA class-like objects (classes and interfaces)

Returns:



107
108
109
110
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 107

def ea_class_objects
  database.objects.find_by_type("Class") +
    database.objects.find_by_type("Interface")
end

#package_known?(package_id) ⇒ Boolean

Whether a package_id resolves to a known package in t_package

Parameters:

  • package_id (Integer, nil)

Returns:

  • (Boolean)


115
116
117
118
119
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 115

def package_known?(package_id)
  return false if package_id.nil?

  !database.find_package(package_id).nil?
end

#transform_associationsArray<Lutaml::Uml::Association>

Transform all associations

Returns:

  • (Array<Lutaml::Uml::Association>)

    All UML associations



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 123

def transform_associations # rubocop:disable Metrics/MethodLength
  association_transformer = get_transformer(:association)

  ea_associations = database.connectors.select(&:association?)

  uml_associations = association_transformer.transform_collection(
    ea_associations,
  )

  uml_associations.each do |uml_assoc|
    register_element(uml_assoc)
  end

  uml_associations
end

#transform_diagramsArray<Lutaml::Uml::Diagram>

Transform all diagrams

Returns:

  • (Array<Lutaml::Uml::Diagram>)

    All UML diagrams



141
142
143
144
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 141

def transform_diagrams
  diagram_transformer = get_transformer(:diagram)
  diagram_transformer.transform_collection(database.diagrams)
end

#transform_orphan_classesArray<Lutaml::Uml::UmlClass>

Transform EA class objects that have no resolvable parent package.

EA occasionally stores class rows whose package_id does not correspond to any row in t_package (typically the result of a deleted package whose children were not reparented). These classes would otherwise be silently dropped, breaking any associations that reference them. Attach them to the document root instead.

Returns:

  • (Array<Lutaml::Uml::UmlClass>)

    Orphaned UML classes



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 93

def transform_orphan_classes
  class_transformer = get_transformer(:class)

  orphans = ea_class_objects.reject do |ea_object|
    package_known?(ea_object.package_id)
  end

  uml_classes = class_transformer.transform_collection(orphans)
  uml_classes.each { |uml_class| register_element(uml_class) }
  uml_classes
end

#transform_packagesArray<Lutaml::Uml::Package>

Transform all packages with hierarchy

Returns:

  • (Array<Lutaml::Uml::Package>)

    Root packages



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 66

def transform_packages # rubocop:disable Metrics/MethodLength
  root_packages = database.packages.select do |pkg|
    pkg.parent_id.nil? || pkg.parent_id.zero?
  end

  package_transformer = get_transformer(:package)
  root_packages.filter_map do |ea_package|
    uml_package = package_transformer.transform_with_hierarchy(
      ea_package,
      include_children: true,
    )

    register_package_hierarchy(uml_package)

    uml_package
  end
end

#with_transformers(transformers) ⇒ self

Register custom transformers, overriding registry defaults

Parameters:

  • transformers (Hash)

    Custom transformer instances keyed by type

Returns:

  • (self)

    For method chaining



149
150
151
152
# File 'lib/ea/qea/factory/ea_to_uml_factory.rb', line 149

def with_transformers(transformers)
  @transformers.merge!(transformers)
  self
end