Class: Diagrams::ClassDiagram

Inherits:
Base
  • Object
show all
Defined in:
lib/diagrams/class_diagram.rb

Overview

Represents a UML Class Diagram consisting of classes and relationships between them.

Instance Attribute Summary collapse

Attributes inherited from Base

#checksum, #version

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#diff, from_hash, from_json, #to_h, #to_json

Constructor Details

#initialize(classes: [], relationships: [], version: 1) ⇒ ClassDiagram

Initializes a new ClassDiagram.

Parameters:

  • classes (Array<Element::ClassEntity>) (defaults to: [])

    An array of class entity objects.

  • relationships (Array<Element::Relationship>) (defaults to: [])

    An array of relationship objects.

  • version (String, Integer, nil) (defaults to: 1)

    User-defined version identifier.



13
14
15
16
17
18
19
# File 'lib/diagrams/class_diagram.rb', line 13

def initialize(classes: [], relationships: [], version: 1)
  super(version:)
  @classes = Array(classes)
  @relationships = Array(relationships)
  validate_elements!
  update_checksum!
end

Instance Attribute Details

#classesObject (readonly)

Returns the value of attribute classes.



6
7
8
# File 'lib/diagrams/class_diagram.rb', line 6

def classes
  @classes
end

#relationshipsObject (readonly)

Returns the value of attribute relationships.



6
7
8
# File 'lib/diagrams/class_diagram.rb', line 6

def relationships
  @relationships
end

Class Method Details

.from_h(data_hash, version:, checksum:) ⇒ ClassDiagram

Class method to create a ClassDiagram from a hash. Used by the deserialization factory in ‘Diagrams::Base`.

Parameters:

  • data_hash (Hash)

    Hash containing ‘:classes` and `:relationships` arrays.

  • version (String, Integer, nil)

    Diagram version.

  • checksum (String, nil)

    Expected checksum (optional, for verification).

Returns:



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/diagrams/class_diagram.rb', line 94

def self.from_h(data_hash, version:, checksum:)
  classes_data = data_hash[:classes] || data_hash['classes'] || []
  relationships_data = data_hash[:relationships] || data_hash['relationships'] || []

  classes = classes_data.map { |class_h| Diagrams::Elements::ClassEntity.new(class_h.transform_keys(&:to_sym)) }
  relationships = relationships_data.map do |rel_h|
    Diagrams::Elements::Relationship.new(rel_h.transform_keys(&:to_sym))
  end

  diagram = new(classes:, relationships:, version:)

  if checksum && diagram.checksum != checksum
    warn "Checksum mismatch for loaded ClassDiagram (version: #{version}). Expected #{checksum}, got #{diagram.checksum}."
    # Or raise an error: raise "Checksum mismatch..."
  end

  diagram
end

Instance Method Details

#add_class(class_entity) ⇒ Element::ClassEntity

Adds a class entity to the diagram.

Parameters:

  • class_entity (Element::ClassEntity)

    The class entity object to add.

Returns:

  • (Element::ClassEntity)

    The added class entity.

Raises:

  • (ArgumentError)

    if a class with the same name already exists.



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/diagrams/class_diagram.rb', line 26

def add_class(class_entity)
  unless class_entity.is_a?(Diagrams::Elements::ClassEntity)
    raise ArgumentError,
          'Class entity must be a Diagrams::Elements::ClassEntity'
  end
  raise ArgumentError, "Class with name '#{class_entity.name}' already exists" if find_class(class_entity.name)

  @classes << class_entity
  update_checksum!
  class_entity
end

#add_relationship(relationship) ⇒ Element::Relationship

Adds a relationship to the diagram.

Parameters:

  • relationship (Element::Relationship)

    The relationship object to add.

Returns:

  • (Element::Relationship)

    The added relationship.

Raises:

  • (ArgumentError)

    if the relationship refers to non-existent class names.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/diagrams/class_diagram.rb', line 43

def add_relationship(relationship)
  unless relationship.is_a?(Diagrams::Elements::Relationship)
    raise ArgumentError,
          'Relationship must be a Diagrams::Elements::Relationship'
  end
  unless find_class(relationship.source_class_name) && find_class(relationship.target_class_name)
    raise ArgumentError,
          "Relationship refers to non-existent class names ('#{relationship.source_class_name}' or '#{relationship.target_class_name}')"
  end

  @relationships << relationship
  update_checksum!
  relationship
end

#find_class(class_name) ⇒ Element::ClassEntity?

Finds a class entity by its name.

Parameters:

  • class_name (String)

    The name of the class to find.

Returns:

  • (Element::ClassEntity, nil)

    The found class entity or nil.



62
63
64
# File 'lib/diagrams/class_diagram.rb', line 62

def find_class(class_name)
  @classes.find { |c| c.name == class_name }
end

#identifiable_elementsHash{Symbol => Array<Diagrams::Elements::ClassEntity | Diagrams::Elements::Relationship>}

Returns a hash mapping element types to their collections for diffing.



80
81
82
83
84
85
# File 'lib/diagrams/class_diagram.rb', line 80

def identifiable_elements
  {
    classes: @classes,
    relationships: @relationships
  }
end

#to_h_contentHash{Symbol => Array<Hash>}

Returns the specific content of the class diagram as a hash. Called by ‘Diagrams::Base#to_h`.

Returns:

  • (Hash{Symbol => Array<Hash>})


70
71
72
73
74
75
# File 'lib/diagrams/class_diagram.rb', line 70

def to_h_content
  {
    classes: @classes.map(&:to_h),
    relationships: @relationships.map(&:to_h)
  }
end