archimate 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +0 -47
- data/lib/archimate.rb +0 -11
- data/lib/archimate/cli/archi.rb +0 -8
- data/lib/archimate/data_model/diffable_array.rb +64 -64
- data/lib/archimate/version.rb +1 -1
- metadata +2 -32
- data/exe/archidiff +0 -7
- data/exe/archidiff-summary +0 -7
- data/exe/archimerge +0 -7
- data/exe/fmtxml +0 -7
- data/lib/archimate/cli/conflict_resolver.rb +0 -39
- data/lib/archimate/cli/diff.rb +0 -31
- data/lib/archimate/cli/diff_summary.rb +0 -101
- data/lib/archimate/cli/merge.rb +0 -49
- data/lib/archimate/cli/merger.rb +0 -109
- data/lib/archimate/diff.rb +0 -17
- data/lib/archimate/diff/archimate_array_reference.rb +0 -113
- data/lib/archimate/diff/archimate_identified_node_reference.rb +0 -41
- data/lib/archimate/diff/archimate_node_attribute_reference.rb +0 -70
- data/lib/archimate/diff/archimate_node_reference.rb +0 -80
- data/lib/archimate/diff/change.rb +0 -49
- data/lib/archimate/diff/conflict.rb +0 -31
- data/lib/archimate/diff/conflicts.rb +0 -89
- data/lib/archimate/diff/conflicts/base_conflict.rb +0 -53
- data/lib/archimate/diff/conflicts/deleted_items_child_updated_conflict.rb +0 -30
- data/lib/archimate/diff/conflicts/deleted_items_referenced_conflict.rb +0 -63
- data/lib/archimate/diff/conflicts/path_conflict.rb +0 -51
- data/lib/archimate/diff/delete.rb +0 -41
- data/lib/archimate/diff/difference.rb +0 -113
- data/lib/archimate/diff/insert.rb +0 -43
- data/lib/archimate/diff/merge.rb +0 -70
- data/lib/archimate/diff/move.rb +0 -51
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Archimate
|
3
|
-
module Diff
|
4
|
-
class Change < Difference
|
5
|
-
using DataModel::DiffableArray
|
6
|
-
|
7
|
-
# Create a new Change difference
|
8
|
-
#
|
9
|
-
# @param target [Archimate::Diff::ArchimateNodeReference] reference to
|
10
|
-
# ArchimateNode that was changed
|
11
|
-
# @param changed_from [Archimate::Diff::ArchimateNodeReference] Element
|
12
|
-
# that was changed
|
13
|
-
def initialize(target, changed_from)
|
14
|
-
super(target, changed_from)
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
# Note - the explicit to_s is required to access the DiffableArray
|
19
|
-
# implementation if the parent is an Array.
|
20
|
-
"#{diff_type} #{changed_from.parent&.to_s} #{Color.color(target.to_s, :change)} changed to #{target.value}"
|
21
|
-
end
|
22
|
-
|
23
|
-
def apply(to_model)
|
24
|
-
unless to_model.is_a?(DataModel::Model)
|
25
|
-
throw(
|
26
|
-
TypeError,
|
27
|
-
"Expected a Archimate::DataModel::Model, was a #{to_model.class}"
|
28
|
-
)
|
29
|
-
end
|
30
|
-
target.change(to_model, changed_from.value)
|
31
|
-
to_model
|
32
|
-
end
|
33
|
-
|
34
|
-
def change?
|
35
|
-
true
|
36
|
-
end
|
37
|
-
|
38
|
-
def kind
|
39
|
-
"Change"
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def diff_type
|
45
|
-
Color.color('CHANGE:', :change)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Archimate
|
3
|
-
module Diff
|
4
|
-
class Conflict
|
5
|
-
attr_reader :base_local_diffs
|
6
|
-
attr_reader :base_remote_diffs
|
7
|
-
attr_reader :reason
|
8
|
-
attr_reader :diffs
|
9
|
-
|
10
|
-
def initialize(base_local_diffs, base_remote_diffs, reason)
|
11
|
-
@base_local_diffs = Array(base_local_diffs)
|
12
|
-
@base_remote_diffs = Array(base_remote_diffs)
|
13
|
-
@diffs = @base_local_diffs + @base_remote_diffs
|
14
|
-
@reason = reason
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_s
|
18
|
-
"#{Color.color('CONFLICT:', [:black, :on_red])} #{reason}\n" \
|
19
|
-
"\tBase->Local Diff(s):\n\t\t#{base_local_diffs.map(&:to_s).join("\n\t\t")}" \
|
20
|
-
"\n\tBase->Remote Diffs(s):\n\t\t#{base_remote_diffs.map(&:to_s).join("\n\t\t")}"
|
21
|
-
end
|
22
|
-
|
23
|
-
def ==(other)
|
24
|
-
other.is_a?(self.class) &&
|
25
|
-
base_local_diffs == other.base_local_diffs &&
|
26
|
-
base_remote_diffs == other.base_remote_diffs &&
|
27
|
-
reason == other.reason
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
require 'parallel'
|
5
|
-
require 'archimate/diff/conflicts/base_conflict'
|
6
|
-
require 'archimate/diff/conflicts/deleted_items_child_updated_conflict'
|
7
|
-
require 'archimate/diff/conflicts/deleted_items_referenced_conflict'
|
8
|
-
require 'archimate/diff/conflicts/path_conflict'
|
9
|
-
|
10
|
-
module Archimate
|
11
|
-
module Diff
|
12
|
-
class Conflicts
|
13
|
-
extend Forwardable
|
14
|
-
|
15
|
-
attr_reader :base_local_diffs
|
16
|
-
attr_reader :base_remote_diffs
|
17
|
-
|
18
|
-
def_delegator :@conflicts, :empty?
|
19
|
-
def_delegator :@conflicts, :size
|
20
|
-
def_delegator :@conflicts, :first
|
21
|
-
def_delegator :@conflicts, :map
|
22
|
-
def_delegator :@conflicts, :each
|
23
|
-
|
24
|
-
include Archimate::Logging
|
25
|
-
|
26
|
-
def initialize(base_local_diffs, base_remote_diffs)
|
27
|
-
@base_local_diffs = base_local_diffs
|
28
|
-
@base_remote_diffs = base_remote_diffs
|
29
|
-
@conflict_finders = [PathConflict, DeletedItemsChildUpdatedConflict, DeletedItemsReferencedConflict]
|
30
|
-
@conflicts = nil
|
31
|
-
@conflicting_diffs = nil
|
32
|
-
@unconflicted_diffs = nil
|
33
|
-
# TODO: consider making this an argument
|
34
|
-
@conflict_resolver = Cli::ConflictResolver.new
|
35
|
-
end
|
36
|
-
|
37
|
-
# TODO: refactor this method elsewhere
|
38
|
-
# resolve iterates through the set of conflicting diffs asking the user
|
39
|
-
# (if running interactively) and return the set of diffs that can be applied.
|
40
|
-
#
|
41
|
-
# To keep diffs reasonably human readable in logs, the local diffs should
|
42
|
-
# be applied first followed by the remote diffs.
|
43
|
-
def resolve
|
44
|
-
debug do
|
45
|
-
<<~MSG
|
46
|
-
Filtering out #{conflicts.size} conflicts from #{base_local_diffs.size + base_remote_diffs.size} diffs
|
47
|
-
Remaining diffs #{unconflicted_diffs.size}
|
48
|
-
MSG
|
49
|
-
end
|
50
|
-
|
51
|
-
conflicts.each_with_object(unconflicted_diffs) do |conflict, diffs|
|
52
|
-
# TODO: this will result in diffs being out of order from their
|
53
|
-
# original order. diffs should be flagged as conflicted and
|
54
|
-
# this method should instead remove the conflicted flag.
|
55
|
-
diffs.concat(@conflict_resolver.resolve(conflict))
|
56
|
-
# TODO: if the conflict is resolved, it should be removed from the
|
57
|
-
# @conflicts array.
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def conflicts
|
62
|
-
@conflicts ||= find_conflicts
|
63
|
-
end
|
64
|
-
|
65
|
-
def conflicting_diffs
|
66
|
-
@conflicting_diffs ||= conflicts.map(&:diffs).flatten
|
67
|
-
end
|
68
|
-
|
69
|
-
def unconflicted_diffs
|
70
|
-
@unconflicted_diffs ||=
|
71
|
-
(base_local_diffs + base_remote_diffs) - conflicting_diffs
|
72
|
-
end
|
73
|
-
|
74
|
-
def to_s
|
75
|
-
"Conflicts:\n\n#{conflicts.map(&:to_s).join("\n\n")}\n"
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
def find_conflicts
|
81
|
-
# TODO: Running this in parallel breaks currently.
|
82
|
-
# @conflicts = Parallel.map(@conflict_finders, in_processes: 3) { |cf_class|
|
83
|
-
@conflicts = @conflict_finders.map { |cf_class|
|
84
|
-
cf_class.new(base_local_diffs, base_remote_diffs).conflicts
|
85
|
-
}.flatten
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Archimate
|
3
|
-
module Diff
|
4
|
-
class Conflicts
|
5
|
-
# BaseConflict
|
6
|
-
# @abstract
|
7
|
-
class BaseConflict
|
8
|
-
def initialize(base_local_diffs, base_remote_diffs)
|
9
|
-
@base_local_diffs = base_local_diffs
|
10
|
-
@base_remote_diffs = base_remote_diffs
|
11
|
-
@associative = false
|
12
|
-
@diff_iterations = nil
|
13
|
-
end
|
14
|
-
|
15
|
-
def filter1
|
16
|
-
->(_diff) { true }
|
17
|
-
end
|
18
|
-
|
19
|
-
def filter2
|
20
|
-
->(_diff) { true }
|
21
|
-
end
|
22
|
-
|
23
|
-
def conflicts
|
24
|
-
progressbar = ProgressIndicator.new(total: diff_iterations.size, title: "Analyzing Conflicts")
|
25
|
-
diff_iterations.each_with_object([]) do |(md1, md2), conflicts|
|
26
|
-
progressbar.increment
|
27
|
-
conflicts.concat(
|
28
|
-
md1.map { |diff1| [diff1, md2.select(&method(:diff_conflicts).curry[diff1])] }
|
29
|
-
.reject { |_diff1, diff2| diff2.empty? }
|
30
|
-
.map { |diff1, diff2_ary| Conflict.new(diff1, diff2_ary, describe) }
|
31
|
-
)
|
32
|
-
end
|
33
|
-
ensure
|
34
|
-
progressbar.finish
|
35
|
-
end
|
36
|
-
|
37
|
-
def diff_combinations
|
38
|
-
combos = [@base_local_diffs, @base_remote_diffs]
|
39
|
-
@associative ? [combos] : combos.permutation(2)
|
40
|
-
end
|
41
|
-
|
42
|
-
# By default our conflict tests are not associative to we need to run
|
43
|
-
# [local, remote] and [remote, local] through the tests.
|
44
|
-
def diff_iterations
|
45
|
-
@diff_iterations ||=
|
46
|
-
diff_combinations.map do |local_diffs, remote_diffs|
|
47
|
-
[local_diffs.select(&filter1), remote_diffs.select(&filter2)]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Archimate
|
3
|
-
module Diff
|
4
|
-
class Conflicts
|
5
|
-
class DeletedItemsChildUpdatedConflict < BaseConflict
|
6
|
-
def describe
|
7
|
-
"Checking for Deleted items in one change set have children that are inserted or changed in the other change set"
|
8
|
-
end
|
9
|
-
|
10
|
-
def filter1
|
11
|
-
->(diff) { diff.delete? }
|
12
|
-
end
|
13
|
-
|
14
|
-
def filter2
|
15
|
-
->(diff) { !diff.delete? }
|
16
|
-
end
|
17
|
-
|
18
|
-
# TODO: This is simple, but might be slow.
|
19
|
-
def diff_conflicts(diff1, diff2)
|
20
|
-
da1 = diff1.path.split("/")
|
21
|
-
da2 = diff2.path.split("/")
|
22
|
-
|
23
|
-
cmp_size = [da1, da2].map(&:size).min - 1
|
24
|
-
return false if da2.size == cmp_size + 1
|
25
|
-
da1[0..cmp_size] == da2[0..cmp_size]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Archimate
|
3
|
-
module Diff
|
4
|
-
class Conflicts
|
5
|
-
# DeletedItemsReferencedConflict
|
6
|
-
#
|
7
|
-
# This sort of conflict occurs when one change set has deleted an element
|
8
|
-
# that is referenced by id in the other change set.
|
9
|
-
#
|
10
|
-
# For example:
|
11
|
-
#
|
12
|
-
# In the local change set, an element with id "abc123" is deleted.
|
13
|
-
# In the remote change set, a child is inserted into a diagram with
|
14
|
-
# archimate_element = "abc123". These two changes are in conflict.
|
15
|
-
class DeletedItemsReferencedConflict < BaseConflict
|
16
|
-
using DataModel::DiffableArray
|
17
|
-
using DataModel::DiffablePrimitive
|
18
|
-
|
19
|
-
def describe
|
20
|
-
"Checking for Deleted items in one change set are referenced in the other change set"
|
21
|
-
end
|
22
|
-
|
23
|
-
# Filters a changeset to potentially conflicting diffs (making the set
|
24
|
-
# of combinations to check smaller)
|
25
|
-
#
|
26
|
-
# @return [lambda] a filter to limit diffs to Delete type
|
27
|
-
def filter1
|
28
|
-
->(diff) { diff.delete? && diff.target.value.is_a?(DataModel::Referenceable) }
|
29
|
-
end
|
30
|
-
|
31
|
-
# Filters a changeset to potentially conflicting diffs (making the set
|
32
|
-
# of combinations to check smaller)
|
33
|
-
#
|
34
|
-
# @return [lambda] a filter to limit diffs to other
|
35
|
-
# than Delete type
|
36
|
-
def filter2
|
37
|
-
->(diff) { !diff.delete? }
|
38
|
-
end
|
39
|
-
|
40
|
-
# Determine the set of conflicts between the given diffs
|
41
|
-
# def conflicts
|
42
|
-
# progressbar = ProgressIndicator.new(total: diff_iterations.size)
|
43
|
-
# diff_iterations.each_with_object([]) do |(md1, md2), a|
|
44
|
-
# progressbar.increment
|
45
|
-
# a.concat(
|
46
|
-
# md1.map { |diff1| [diff1, md2.select(&method(:diff_conflicts).curry[diff1])] }
|
47
|
-
# .reject { |_diff1, diff2| diff2.empty? }
|
48
|
-
# .map { |diff1, diff2_ary| Conflict.new(diff1, diff2_ary, describe) }
|
49
|
-
# )
|
50
|
-
# end
|
51
|
-
# ensure
|
52
|
-
# progressbar&.finish
|
53
|
-
# end
|
54
|
-
|
55
|
-
# TODO: This is simple, but might be slow. If it is, then override
|
56
|
-
# the conflicts method to prevent calculating referenced_identified_nodes methods
|
57
|
-
def diff_conflicts(diff1, diff2)
|
58
|
-
diff2.target.value.referenced_identified_nodes.include?(diff1.target.value.id)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Archimate
|
3
|
-
module Diff
|
4
|
-
class Conflicts
|
5
|
-
class PathConflict < BaseConflict
|
6
|
-
def initialize(base_local_diffs, base_remote_diffs)
|
7
|
-
super
|
8
|
-
@associative = true
|
9
|
-
end
|
10
|
-
|
11
|
-
def describe
|
12
|
-
"Checking for Differences in one change set that conflict with changes in other change set at the same path"
|
13
|
-
end
|
14
|
-
|
15
|
-
def diff_conflicts(diff1, diff2)
|
16
|
-
same_path_but_diff(diff1, diff2) && in_conflict?(diff1, diff2)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def same_path_but_diff(a, b)
|
22
|
-
a.path == b.path && a != b
|
23
|
-
end
|
24
|
-
|
25
|
-
# I'm in conflict if:
|
26
|
-
# 1. ld and rd are both changes to the same path (but not the same change)
|
27
|
-
# 2. one is a change, the other a delete and changed_from is the same
|
28
|
-
# 3. both are inserts of the different identifyable nodes with the same id
|
29
|
-
#
|
30
|
-
# If I'm not an identifyable node and my parent is an array, then two inserts are ok
|
31
|
-
def in_conflict?(local_diff, remote_diff)
|
32
|
-
return true if
|
33
|
-
local_diff.target.parent.is_a?(Array) &&
|
34
|
-
local_diff.target.value.is_a?(DataModel::Referenceable) &&
|
35
|
-
local_diff.target.value.id == remote_diff.target.value.id &&
|
36
|
-
local_diff != remote_diff
|
37
|
-
|
38
|
-
case [local_diff, remote_diff].map { |d| d.class.name.split('::').last }.sort
|
39
|
-
when %w(Change Change)
|
40
|
-
local_diff.changed_from.value == remote_diff.changed_from.value &&
|
41
|
-
local_diff.target.value != remote_diff.target.value
|
42
|
-
when %w(Change Delete)
|
43
|
-
true
|
44
|
-
else
|
45
|
-
false
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Archimate
|
3
|
-
module Diff
|
4
|
-
class Delete < Difference
|
5
|
-
using DataModel::DiffablePrimitive
|
6
|
-
using DataModel::DiffableArray
|
7
|
-
|
8
|
-
# Create a new Delete difference
|
9
|
-
#
|
10
|
-
# @param target [ArchimateNodeReference] Element that was deleted
|
11
|
-
def initialize(target)
|
12
|
-
super
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_s
|
16
|
-
# Note - the explicit to_s is required to access the DiffableArray
|
17
|
-
# implementation if the parent is an Array.
|
18
|
-
"#{diff_type} #{target} from #{target.parent.to_s}"
|
19
|
-
end
|
20
|
-
|
21
|
-
def apply(el)
|
22
|
-
target.delete(el)
|
23
|
-
el
|
24
|
-
end
|
25
|
-
|
26
|
-
def delete?
|
27
|
-
true
|
28
|
-
end
|
29
|
-
|
30
|
-
def kind
|
31
|
-
"Delete"
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def diff_type
|
37
|
-
Color.color('DELETE:', :delete)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "forwardable"
|
4
|
-
|
5
|
-
module Archimate
|
6
|
-
module Diff
|
7
|
-
class Difference
|
8
|
-
using DataModel::DiffableArray
|
9
|
-
using DataModel::DiffablePrimitive
|
10
|
-
extend Forwardable
|
11
|
-
|
12
|
-
ARRAY_RE = Regexp.compile(/\[(\d+)\]/)
|
13
|
-
PATH_ROOT_SORT_ORDER = %w[elements relationships diagrams organizations].freeze
|
14
|
-
|
15
|
-
# delete: something responds to parent, child attribute (which is thing deleted - and could be sym for archimate nodes or index for array), value
|
16
|
-
# insert: something responds to parent, child attribute (or index), value, after value (to help with inserts)
|
17
|
-
# change: something responds to parent, child attribute (or index), value, changed from value
|
18
|
-
# move: something responds to parent, child index, value, after value) move after a particular value
|
19
|
-
attr_reader :target
|
20
|
-
attr_reader :changed_from
|
21
|
-
|
22
|
-
def_delegator :@target, :path
|
23
|
-
|
24
|
-
# Re-thinking.
|
25
|
-
#
|
26
|
-
# Requirements:
|
27
|
-
#
|
28
|
-
# 1. User friendly display of what is different in context
|
29
|
-
# 2. Able to apply the diff to another model (which was based on the "base" of the diff)
|
30
|
-
#
|
31
|
-
# Delete: example
|
32
|
-
# ArchimateNode child.bounds
|
33
|
-
# ArchimateNode, attribute model, "name"
|
34
|
-
# DiffableArray, ArchimateNode model.elements, element
|
35
|
-
# bendpoint attributes under connection
|
36
|
-
# documentation
|
37
|
-
# properties
|
38
|
-
# child/style/fill_color
|
39
|
-
# child/style/font/name
|
40
|
-
#
|
41
|
-
# @param target [Dry::Struct with id attribute] the element operated on (why is array treated as a special case?)
|
42
|
-
# @param changed_from [same class as target] (optional) for change this is the previous value
|
43
|
-
# def initialize(changed_from, target)
|
44
|
-
def initialize(target, changed_from = nil)
|
45
|
-
# raise TypeError, "Expected target to be an ArchimateNodeReference" unless target.is_a?(ArchimateNodeReference)
|
46
|
-
@target = target
|
47
|
-
@changed_from = changed_from
|
48
|
-
end
|
49
|
-
|
50
|
-
def ==(other)
|
51
|
-
other.is_a?(self.class) &&
|
52
|
-
@target == other.target &&
|
53
|
-
@changed_from == other.changed_from
|
54
|
-
end
|
55
|
-
|
56
|
-
# Difference sorting is based on the path.
|
57
|
-
# Top level components are sorted in this order: (elements, relationships, diagrams, organizations)
|
58
|
-
# Array entries are sorted by numeric order
|
59
|
-
# Others are sorted alphabetically
|
60
|
-
# TODO: this isn't complete
|
61
|
-
def <=>(other)
|
62
|
-
a = path_to_array
|
63
|
-
b = other.path_to_array
|
64
|
-
|
65
|
-
part_a = a.shift
|
66
|
-
part_b = b.shift
|
67
|
-
res = PATH_ROOT_SORT_ORDER.index(part_a) <=> PATH_ROOT_SORT_ORDER.index(part_b)
|
68
|
-
return res unless res.zero?
|
69
|
-
|
70
|
-
until a.empty? || b.empty?
|
71
|
-
part_a = a.shift
|
72
|
-
part_b = b.shift
|
73
|
-
|
74
|
-
return part_a <=> part_b unless (part_a <=> part_b).zero?
|
75
|
-
end
|
76
|
-
|
77
|
-
return -1 if a.empty?
|
78
|
-
return 1 if b.empty?
|
79
|
-
part_a <=> part_b
|
80
|
-
end
|
81
|
-
|
82
|
-
def delete?
|
83
|
-
false
|
84
|
-
end
|
85
|
-
|
86
|
-
def change?
|
87
|
-
false
|
88
|
-
end
|
89
|
-
|
90
|
-
def insert?
|
91
|
-
false
|
92
|
-
end
|
93
|
-
|
94
|
-
def move?
|
95
|
-
false
|
96
|
-
end
|
97
|
-
|
98
|
-
def path_to_array
|
99
|
-
path(force_array_index: :index).split("/").map do |p|
|
100
|
-
md = ARRAY_RE.match(p)
|
101
|
-
md ? md[1].to_i : p
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def summary_element
|
106
|
-
summary_elements = [DataModel::Element, DataModel::Organization, DataModel::Relationship, DataModel::Diagram, DataModel::Model]
|
107
|
-
se = target.value.primitive? ? target.parent : target.value
|
108
|
-
se = se.parent while summary_elements.none? { |c| se.is_a?(c) }
|
109
|
-
se
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|