Class: Archimate::Diff::Difference

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/archimate/diff/difference.rb

Direct Known Subclasses

Change, Delete, Insert, Move

Constant Summary collapse

ARRAY_RE =
Regexp.compile(/\[(\d+)\]/)
PATH_ROOT_SORT_ORDER =
%w[elements relationships diagrams organizations].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target, changed_from = nil) ⇒ Difference

Re-thinking.

Requirements:

  1. User friendly display of what is different in context

  2. Able to apply the diff to another model (which was based on the “base” of the diff)

Delete: example

ArchimateNode                 child.bounds
ArchimateNode, attribute      model, "name"
DiffableArray, ArchimateNode  model.elements, element
bendpoint attributes under connection
                              documentation
                              properties
                              child/style/fill_color
                              child/style/font/name

def initialize(changed_from, target)

Parameters:

  • target (Dry::Struct with id attribute)

    the element operated on (why is array treated as a special case?)

  • changed_from (same class as target) (defaults to: nil)

    (optional) for change this is the previous value



44
45
46
47
48
# File 'lib/archimate/diff/difference.rb', line 44

def initialize(target, changed_from = nil)
  # raise TypeError, "Expected target to be an ArchimateNodeReference" unless target.is_a?(ArchimateNodeReference)
  @target = target
  @changed_from = changed_from
end

Instance Attribute Details

#changed_fromObject (readonly)

Returns the value of attribute changed_from.



20
21
22
# File 'lib/archimate/diff/difference.rb', line 20

def changed_from
  @changed_from
end

#targetObject (readonly)

delete: something responds to parent, child attribute (which is thing deleted - and could be sym for archimate nodes or index for array), value insert: something responds to parent, child attribute (or index), value, after value (to help with inserts) change: something responds to parent, child attribute (or index), value, changed from value move: something responds to parent, child index, value, after value) move after a particular value



19
20
21
# File 'lib/archimate/diff/difference.rb', line 19

def target
  @target
end

Instance Method Details

#<=>(other) ⇒ Object

Difference sorting is based on the path. Top level components are sorted in this order: (elements, relationships, diagrams, organizations) Array entries are sorted by numeric order Others are sorted alphabetically TODO: this isn’t complete



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/archimate/diff/difference.rb', line 61

def <=>(other)
  a = path_to_array
  b = other.path_to_array

  part_a = a.shift
  part_b = b.shift
  res = PATH_ROOT_SORT_ORDER.index(part_a) <=> PATH_ROOT_SORT_ORDER.index(part_b)
  return res unless res.zero?

  until a.empty? || b.empty?
    part_a = a.shift
    part_b = b.shift

    return part_a <=> part_b unless (part_a <=> part_b).zero?
  end

  return -1 if a.empty?
  return 1 if b.empty?
  part_a <=> part_b
end

#==(other) ⇒ Object



50
51
52
53
54
# File 'lib/archimate/diff/difference.rb', line 50

def ==(other)
  other.is_a?(self.class) &&
    @target == other.target &&
    @changed_from == other.changed_from
end

#change?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/archimate/diff/difference.rb', line 86

def change?
  false
end

#delete?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/archimate/diff/difference.rb', line 82

def delete?
  false
end

#insert?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/archimate/diff/difference.rb', line 90

def insert?
  false
end

#move?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/archimate/diff/difference.rb', line 94

def move?
  false
end

#path_to_arrayObject



98
99
100
101
102
103
# File 'lib/archimate/diff/difference.rb', line 98

def path_to_array
  path(force_array_index: :index).split("/").map do |p|
    md = ARRAY_RE.match(p)
    md ? md[1].to_i : p
  end
end

#summary_elementObject



105
106
107
108
109
110
# File 'lib/archimate/diff/difference.rb', line 105

def summary_element
  summary_elements = [DataModel::Element, DataModel::Organization, DataModel::Relationship, DataModel::Diagram, DataModel::Model]
  se = target.value.primitive? ? target.parent : target.value
  se = se.parent while summary_elements.none? { |c| se.is_a?(c) }
  se
end