class Lutaml::Qea::Validation::ClassValidator

Validates class/object references and structure

def connectors

def connectors
  @connectors ||= context[:connectors] || []
end

def object_exists?(object_id)

def object_exists?(object_id)
  objects.any? { |o| o.ea_object_id == object_id }
end

def objects

def objects
  @objects ||= begin
    # Use database objects for referential integrity checks
    # Filter to only Class and Interface types (exclude Notes, etc.)
    all_objects = context[:db_objects] || context[:objects] || []
    all_objects.select { |obj| obj.uml_class? || obj.interface? }
  end
end

def package_exists?(package_id)

def package_exists?(package_id)
  packages.any? { |p| p.package_id == package_id }
end

def packages

def packages
  # Use database packages for referential integrity checks
  @packages ||= context[:db_packages] || context[:packages] || []
end

def validate

def validate
  validate_package_references
  validate_duplicate_names
  validate_generalization_parents
end

def validate_duplicate_names # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity

rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
def validate_duplicate_names # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  objects_by_package = objects.group_by(&:package_id)
  objects_by_package.each do |package_id, package_objects|
    names = package_objects.map(&:name)
    duplicates = names.select { |name| names.count(name) > 1 }.uniq
    duplicates.each do |dup_name|
      dup_objects = package_objects.select { |o| o.name == dup_name }
      dup_objects.each do |obj|
        class_path = resolve_class_path(obj.ea_object_id, obj.name)
        package_path = if package_id
                         resolve_package_path(package_id)
                       else
                         "Root"
                       end
        result.add_warning(
          category: :duplicate,
          entity_type: :class,
          entity_id: obj.ea_object_id.to_s,
          entity_name: obj.name,
          field: "name",
          message: "Duplicate class name '#{dup_name}' " \
                   "in #{package_path}",
          location: class_path,
        )
      end
    end
  end
end

def validate_generalization_parents # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity

rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
def validate_generalization_parents # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
  connectors.select(&:generalization?).each do |gen|
    parent_id = gen.end_object_id
    unless object_exists?(parent_id)
      child = objects.find { |o| o.ea_object_id == gen.start_object_id }
      child_path = if child
                     resolve_class_path(child.ea_object_id,
                                        child.name)
                   else
                     "Unknown"
                   end
      result.add_error(
        category: :missing_reference,
        entity_type: :generalization,
        entity_id: gen.connector_id.to_s,
        entity_name: child&.name || "Unknown",
        field: "end_object_id",
        reference: parent_id.to_s,
        message: "Generalization parent #{parent_id} does not exist",
        location: child_path,
      )
    end
  end
end

def validate_package_references # rubocop:disable Metrics/AbcSize,Metrics/MethodLength

rubocop:disable Metrics/AbcSize,Metrics/MethodLength
def validate_package_references # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  objects.each do |obj|
    next unless obj.package_id
    unless package_exists?(obj.package_id)
      class_path = resolve_class_path(obj.ea_object_id, obj.name)
      result.add_error(
        category: :missing_reference,
        entity_type: :class,
        entity_id: obj.ea_object_id.to_s,
        entity_name: obj.name,
        field: "package_id",
        reference: obj.package_id.to_s,
        message: "Package #{obj.package_id} does not exist",
        location: class_path,
      )
    end
  end
end