class Lutaml::Qea::Factory::PackageTransformer

Transforms EA packages to UML packages

def appears_on_diagram?(object_id)

Returns:
  • (Boolean) - True if object appears on a diagram

Parameters:
  • object_id (Integer) -- Object ID
def appears_on_diagram?(object_id)
  return false if object_id.nil?
  return false unless database.diagram_objects
  # Check if object appears in any diagram's objects
  database.diagram_objects.any? do |dobj|
    dobj.ea_object_id == object_id
  end
end

def class_object?(ea_obj)

Check if an EA object should be classified as a class.
def class_object?(ea_obj)
  return false if enum_object?(ea_obj) || data_type_object?(ea_obj)
  ea_obj.uml_class? || ea_obj.interface? ||
    ea_obj.object_type == "Text" ||
    ea_obj.object_type == "ProxyConnector"
end

def data_type_object?(ea_obj)

Check if an EA object should be classified as a data type.
def data_type_object?(ea_obj)
  ea_obj.data_type?
end

def enum_object?(ea_obj)

object_type="Class" with stereotype="enumeration".
EA stores enums as either object_type="Enumeration" or
Check if an EA object should be classified as an enum.
def enum_object?(ea_obj)
  ea_obj.enumeration? || stereotype_is?(ea_obj, "enumeration")
end

def load_child_packages(parent_id)

Returns:
  • (Array) - Child packages

Parameters:
  • parent_id (Integer) -- Parent package ID
def load_child_packages(parent_id)
  return [] if parent_id.nil?
  database.child_packages_for(parent_id)
    .sort_by { |p| p.tpos || 0 }
end

def load_package_contents(pkg, package_id)

Parameters:
  • package_id (Integer) -- EA package ID
  • pkg (Lutaml::Uml::Package) -- UML package to populate
def load_package_contents(pkg, package_id)
  return if package_id.nil?
  # Load objects (classes, etc.) in this package
  load_package_objects(pkg, package_id)
  # Load diagrams in this package
  load_package_diagrams(pkg, package_id)
end

def load_package_diagrams(pkg, package_id)

Parameters:
  • package_id (Integer) -- Package ID
  • pkg (Lutaml::Uml::Package) -- UML package
def load_package_diagrams(pkg, package_id)
  diagram_transformer = DiagramTransformer.new(database)
  ea_diagrams = database.diagrams_in_package(package_id)
  pkg.diagrams = diagram_transformer.transform_collection(ea_diagrams)
end

def load_package_objects(pkg, package_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity

Parameters:
  • package_id (Integer) -- Package ID
  • pkg (Lutaml::Uml::Package) -- UML package
def load_package_objects(pkg, package_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  ea_objects = database.objects_in_package(package_id)
  class_transformer = ClassTransformer.new(database)
  enum_transformer = EnumTransformer.new(database)
  data_type_transformer = DataTypeTransformer.new(database)
  instance_transformer = InstanceTransformer.new(database)
  ea_objects.each do |ea_obj|
    if enum_object?(ea_obj)
      uml_enum = enum_transformer.transform(ea_obj)
      pkg.enums << uml_enum if uml_enum
    elsif data_type_object?(ea_obj)
      uml_dt = data_type_transformer.transform(ea_obj)
      pkg.data_types << uml_dt if uml_dt
    elsif class_object?(ea_obj)
      uml_class = class_transformer.transform(ea_obj)
      pkg.classes << uml_class if uml_class
    elsif ea_obj.instance?
      uml_instance = instance_transformer.transform(ea_obj)
      pkg.instances << uml_instance if uml_instance
    end
  end
end

def load_stereotype(ea_guid) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity

Returns:
  • (String, nil) - Stereotype value (as string to match XMI format)

Parameters:
  • ea_guid (String) -- Element GUID
def load_stereotype(ea_guid) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  return nil if ea_guid.nil?
  return nil unless database.xrefs
  # Find stereotype xref from the in-memory collection
  xref = database.xrefs.find do |x|
    x.client == ea_guid &&
      x.name == "Stereotypes" && x.type == "element property"
  end
  return nil unless xref
  # Parse stereotype from Description field
  # Format: @STEREO;Name=ApplicationSchema;FQName=GML::ApplicationSchema;@ENDSTEREO;
  description = xref.description
  return nil if description.nil? || description.empty?
  # Extract the Name value from the @STEREO format
  if description =~ /@STEREO;Name=([^;]+);/
    return $1
  end
  nil
end

def load_tagged_values(ea_guid)

Returns:
  • (Array) - UML tagged values

Parameters:
  • ea_guid (String) -- Element GUID
def load_tagged_values(ea_guid)
  return [] if ea_guid.nil?
  return [] unless database.tagged_values
  # Filter tagged values for this element from the in-memory collection
  ea_tags = database.tagged_values.select do |tag|
    tag.element_id == ea_guid
  end
  # Transform to UML tagged values
  tag_transformer = TaggedValueTransformer.new(database)
  tag_transformer.transform_collection(ea_tags)
end

def stereotype_is?(ea_obj, expected)

Check if an object's stereotype matches (case-insensitive).
def stereotype_is?(ea_obj, expected)
  return false unless ea_obj.stereotype
  ea_obj.stereotype.downcase == expected
end

def transform(ea_package) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength

Returns:
  • (Lutaml::Uml::Package) - UML package

Parameters:
  • ea_package (EaPackage) -- EA package model
def transform(ea_package) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  return nil if ea_package.nil?
  Lutaml::Uml::Package.new.tap do |pkg|
    # Map basic properties
    pkg.name = ea_package.name
    pkg.xmi_id = normalize_guid_to_xmi_format(ea_package.ea_guid,
                                              "EAPK")
    # Map definition/notes
    pkg.definition = ea_package.notes unless
      ea_package.notes.nil? || ea_package.notes.empty?
    # Load and transform tagged values
    pkg.tagged_values = load_tagged_values(ea_package.ea_guid)
    # Load stereotype from t_xref
    stereotype = load_stereotype(ea_package.ea_guid)
    pkg.stereotype = [stereotype] if stereotype
    # Note: Child packages and contents will be loaded separately
    # to avoid circular dependencies and allow lazy loading
    # Don't initialize collections - they have default values
  end
end

def transform_with_hierarchy(ea_package, include_children: true)

Returns:
  • (Lutaml::Uml::Package) - Complete UML package with hierarchy

Parameters:
  • include_children (Boolean) -- Whether to recursively load children
  • ea_package (EaPackage) -- Root EA package
def transform_with_hierarchy(ea_package, include_children: true)
  pkg = transform(ea_package)
  return pkg unless include_children
  # Load child packages
  child_packages = load_child_packages(ea_package.package_id)
  pkg.packages = child_packages.map do |child_pkg|
    transform_with_hierarchy(child_pkg, include_children: true)
  end
  # Load package contents (classes, diagrams, etc.)
  load_package_contents(pkg, ea_package.package_id)
  pkg
end