archimate 1.1.0
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 +7 -0
- data/.gitignore +22 -0
- data/.projectile +18 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +4 -0
- data/.yardocs +15 -0
- data/Gemfile +5 -0
- data/Guardfile +27 -0
- data/LICENSE +201 -0
- data/README.md +94 -0
- data/Rakefile +29 -0
- data/TODOs.org +286 -0
- data/archimate.gemspec +51 -0
- data/bin/archimate +17 -0
- data/bin/console +13 -0
- data/bin/setup +8 -0
- data/exe/archidiff +7 -0
- data/exe/archidiff-summary +7 -0
- data/exe/archimate +7 -0
- data/exe/archimerge +7 -0
- data/exe/fmtxml +7 -0
- data/lib/archimate/cli/archi.rb +189 -0
- data/lib/archimate/cli/cleanup.rb +54 -0
- data/lib/archimate/cli/conflict_resolver.rb +39 -0
- data/lib/archimate/cli/convert.rb +39 -0
- data/lib/archimate/cli/diff.rb +31 -0
- data/lib/archimate/cli/diff_summary.rb +101 -0
- data/lib/archimate/cli/duper.rb +85 -0
- data/lib/archimate/cli/lint.rb +16 -0
- data/lib/archimate/cli/mapper.rb +82 -0
- data/lib/archimate/cli/merge.rb +49 -0
- data/lib/archimate/cli/merger.rb +109 -0
- data/lib/archimate/cli/stats.rb +42 -0
- data/lib/archimate/cli/svger.rb +40 -0
- data/lib/archimate/color.rb +53 -0
- data/lib/archimate/config.rb +35 -0
- data/lib/archimate/data_model/any_attribute.rb +13 -0
- data/lib/archimate/data_model/any_element.rb +15 -0
- data/lib/archimate/data_model/archimate_node.rb +181 -0
- data/lib/archimate/data_model/bounds.rb +72 -0
- data/lib/archimate/data_model/color.rb +47 -0
- data/lib/archimate/data_model/concept.rb +14 -0
- data/lib/archimate/data_model/concern.rb +17 -0
- data/lib/archimate/data_model/connection.rb +107 -0
- data/lib/archimate/data_model/constants.rb +82 -0
- data/lib/archimate/data_model/container.rb +17 -0
- data/lib/archimate/data_model/diagram.rb +40 -0
- data/lib/archimate/data_model/diffable_array.rb +213 -0
- data/lib/archimate/data_model/diffable_primitive.rb +83 -0
- data/lib/archimate/data_model/documentation.rb +14 -0
- data/lib/archimate/data_model/element.rb +87 -0
- data/lib/archimate/data_model/font.rb +54 -0
- data/lib/archimate/data_model/label.rb +19 -0
- data/lib/archimate/data_model/lang_string.rb +41 -0
- data/lib/archimate/data_model/location.rb +31 -0
- data/lib/archimate/data_model/metadata.rb +14 -0
- data/lib/archimate/data_model/model.rb +217 -0
- data/lib/archimate/data_model/modeling_note.rb +13 -0
- data/lib/archimate/data_model/named_referenceable.rb +14 -0
- data/lib/archimate/data_model/organization.rb +40 -0
- data/lib/archimate/data_model/property.rb +25 -0
- data/lib/archimate/data_model/property_definition.rb +16 -0
- data/lib/archimate/data_model/referenceable.rb +29 -0
- data/lib/archimate/data_model/relationship.rb +85 -0
- data/lib/archimate/data_model/schema_info.rb +18 -0
- data/lib/archimate/data_model/style.rb +32 -0
- data/lib/archimate/data_model/view.rb +12 -0
- data/lib/archimate/data_model/view_concept.rb +18 -0
- data/lib/archimate/data_model/view_node.rb +114 -0
- data/lib/archimate/data_model/viewpoint.rb +87 -0
- data/lib/archimate/data_model.rb +54 -0
- data/lib/archimate/diff/archimate_array_reference.rb +113 -0
- data/lib/archimate/diff/archimate_identified_node_reference.rb +41 -0
- data/lib/archimate/diff/archimate_node_attribute_reference.rb +70 -0
- data/lib/archimate/diff/archimate_node_reference.rb +80 -0
- data/lib/archimate/diff/change.rb +49 -0
- data/lib/archimate/diff/conflict.rb +31 -0
- data/lib/archimate/diff/conflicts/base_conflict.rb +53 -0
- data/lib/archimate/diff/conflicts/deleted_items_child_updated_conflict.rb +30 -0
- data/lib/archimate/diff/conflicts/deleted_items_referenced_conflict.rb +63 -0
- data/lib/archimate/diff/conflicts/path_conflict.rb +51 -0
- data/lib/archimate/diff/conflicts.rb +89 -0
- data/lib/archimate/diff/delete.rb +41 -0
- data/lib/archimate/diff/difference.rb +113 -0
- data/lib/archimate/diff/insert.rb +43 -0
- data/lib/archimate/diff/merge.rb +70 -0
- data/lib/archimate/diff/move.rb +51 -0
- data/lib/archimate/diff.rb +17 -0
- data/lib/archimate/export/csv_export.rb +32 -0
- data/lib/archimate/export/cypher.rb +171 -0
- data/lib/archimate/export/graph_ml.rb +131 -0
- data/lib/archimate/export/n_quads.rb +142 -0
- data/lib/archimate/file_format.rb +30 -0
- data/lib/archimate/file_formats/archi_file_format.rb +151 -0
- data/lib/archimate/file_formats/archi_file_reader.rb +252 -0
- data/lib/archimate/file_formats/archi_file_writer.rb +230 -0
- data/lib/archimate/file_formats/archimate_v2.rb +461 -0
- data/lib/archimate/file_formats/model_exchange_file/xml_lang_string.rb +35 -0
- data/lib/archimate/file_formats/model_exchange_file/xml_metadata.rb +115 -0
- data/lib/archimate/file_formats/model_exchange_file/xml_property_definitions.rb +28 -0
- data/lib/archimate/file_formats/model_exchange_file/xml_property_defs.rb +27 -0
- data/lib/archimate/file_formats/model_exchange_file_reader.rb +237 -0
- data/lib/archimate/file_formats/model_exchange_file_reader_21.rb +73 -0
- data/lib/archimate/file_formats/model_exchange_file_reader_30.rb +134 -0
- data/lib/archimate/file_formats/model_exchange_file_writer.rb +157 -0
- data/lib/archimate/file_formats/model_exchange_file_writer_21.rb +143 -0
- data/lib/archimate/file_formats/model_exchange_file_writer_30.rb +153 -0
- data/lib/archimate/file_formats/writer.rb +56 -0
- data/lib/archimate/lint/duplicate_entities.rb +121 -0
- data/lib/archimate/lint/linter.rb +146 -0
- data/lib/archimate/logging.rb +55 -0
- data/lib/archimate/maybe_io.rb +34 -0
- data/lib/archimate/progress_indicator.rb +29 -0
- data/lib/archimate/svg/archimate.css +232 -0
- data/lib/archimate/svg/child.rb +29 -0
- data/lib/archimate/svg/connection.rb +184 -0
- data/lib/archimate/svg/css_style.rb +31 -0
- data/lib/archimate/svg/diagram.rb +87 -0
- data/lib/archimate/svg/entity/and_junction.rb +14 -0
- data/lib/archimate/svg/entity/application_collaboration.rb +14 -0
- data/lib/archimate/svg/entity/application_component.rb +41 -0
- data/lib/archimate/svg/entity/application_event.rb +13 -0
- data/lib/archimate/svg/entity/application_function.rb +13 -0
- data/lib/archimate/svg/entity/application_interaction.rb +13 -0
- data/lib/archimate/svg/entity/application_interface.rb +13 -0
- data/lib/archimate/svg/entity/application_process.rb +13 -0
- data/lib/archimate/svg/entity/application_service.rb +13 -0
- data/lib/archimate/svg/entity/artifact.rb +39 -0
- data/lib/archimate/svg/entity/assessment.rb +14 -0
- data/lib/archimate/svg/entity/base_entity.rb +128 -0
- data/lib/archimate/svg/entity/business_actor.rb +14 -0
- data/lib/archimate/svg/entity/business_collaboration.rb +14 -0
- data/lib/archimate/svg/entity/business_event.rb +10 -0
- data/lib/archimate/svg/entity/business_function.rb +13 -0
- data/lib/archimate/svg/entity/business_interaction.rb +13 -0
- data/lib/archimate/svg/entity/business_interface.rb +13 -0
- data/lib/archimate/svg/entity/business_object.rb +13 -0
- data/lib/archimate/svg/entity/business_process.rb +13 -0
- data/lib/archimate/svg/entity/business_role.rb +14 -0
- data/lib/archimate/svg/entity/business_service.rb +13 -0
- data/lib/archimate/svg/entity/capability.rb +14 -0
- data/lib/archimate/svg/entity/communication_network.rb +14 -0
- data/lib/archimate/svg/entity/communication_path.rb +14 -0
- data/lib/archimate/svg/entity/constraint.rb +15 -0
- data/lib/archimate/svg/entity/contract.rb +13 -0
- data/lib/archimate/svg/entity/course_of_action.rb +14 -0
- data/lib/archimate/svg/entity/data_entity.rb +29 -0
- data/lib/archimate/svg/entity/data_object.rb +13 -0
- data/lib/archimate/svg/entity/deliverable.rb +13 -0
- data/lib/archimate/svg/entity/device.rb +48 -0
- data/lib/archimate/svg/entity/diagram_model_reference.rb +22 -0
- data/lib/archimate/svg/entity/diagram_object.rb +30 -0
- data/lib/archimate/svg/entity/distribution_network.rb +14 -0
- data/lib/archimate/svg/entity/driver.rb +14 -0
- data/lib/archimate/svg/entity/equipment.rb +16 -0
- data/lib/archimate/svg/entity/event_entity.rb +36 -0
- data/lib/archimate/svg/entity/facility.rb +16 -0
- data/lib/archimate/svg/entity/function_entity.rb +14 -0
- data/lib/archimate/svg/entity/gap.rb +21 -0
- data/lib/archimate/svg/entity/goal.rb +14 -0
- data/lib/archimate/svg/entity/group.rb +24 -0
- data/lib/archimate/svg/entity/implementation_event.rb +13 -0
- data/lib/archimate/svg/entity/infrastructure_function.rb +13 -0
- data/lib/archimate/svg/entity/infrastructure_interface.rb +13 -0
- data/lib/archimate/svg/entity/infrastructure_service.rb +13 -0
- data/lib/archimate/svg/entity/interaction_entity.rb +14 -0
- data/lib/archimate/svg/entity/interface_entity.rb +35 -0
- data/lib/archimate/svg/entity/junction.rb +19 -0
- data/lib/archimate/svg/entity/location.rb +14 -0
- data/lib/archimate/svg/entity/material.rb +14 -0
- data/lib/archimate/svg/entity/meaning.rb +40 -0
- data/lib/archimate/svg/entity/motivation_entity.rb +40 -0
- data/lib/archimate/svg/entity/network.rb +14 -0
- data/lib/archimate/svg/entity/node.rb +33 -0
- data/lib/archimate/svg/entity/node_shape.rb +64 -0
- data/lib/archimate/svg/entity/note.rb +30 -0
- data/lib/archimate/svg/entity/or_junction.rb +14 -0
- data/lib/archimate/svg/entity/outcome.rb +15 -0
- data/lib/archimate/svg/entity/path.rb +14 -0
- data/lib/archimate/svg/entity/plateau.rb +15 -0
- data/lib/archimate/svg/entity/principle.rb +15 -0
- data/lib/archimate/svg/entity/process_entity.rb +63 -0
- data/lib/archimate/svg/entity/product.rb +20 -0
- data/lib/archimate/svg/entity/rect.rb +13 -0
- data/lib/archimate/svg/entity/rect_entity.rb +25 -0
- data/lib/archimate/svg/entity/representation.rb +31 -0
- data/lib/archimate/svg/entity/requirement.rb +15 -0
- data/lib/archimate/svg/entity/resource.rb +14 -0
- data/lib/archimate/svg/entity/rounded_rect_entity.rb +23 -0
- data/lib/archimate/svg/entity/service_entity.rb +51 -0
- data/lib/archimate/svg/entity/sketch_model_sticky.rb +14 -0
- data/lib/archimate/svg/entity/stakeholder.rb +15 -0
- data/lib/archimate/svg/entity/system_software.rb +14 -0
- data/lib/archimate/svg/entity/technology_collaboration.rb +14 -0
- data/lib/archimate/svg/entity/technology_event.rb +13 -0
- data/lib/archimate/svg/entity/technology_function.rb +13 -0
- data/lib/archimate/svg/entity/technology_interaction.rb +13 -0
- data/lib/archimate/svg/entity/technology_interface.rb +13 -0
- data/lib/archimate/svg/entity/technology_process.rb +13 -0
- data/lib/archimate/svg/entity/technology_service.rb +13 -0
- data/lib/archimate/svg/entity/value.rb +27 -0
- data/lib/archimate/svg/entity/work_package.rb +14 -0
- data/lib/archimate/svg/entity.rb +93 -0
- data/lib/archimate/svg/entity_factory.rb +17 -0
- data/lib/archimate/svg/extents.rb +27 -0
- data/lib/archimate/svg/point.rb +7 -0
- data/lib/archimate/svg/svg_template.rb +27 -0
- data/lib/archimate/svg/svg_template.svg.erb +169 -0
- data/lib/archimate/version.rb +4 -0
- data/lib/archimate.rb +114 -0
- metadata +623 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Archimate
|
|
3
|
+
module DataModel
|
|
4
|
+
module DiffableArray
|
|
5
|
+
using DiffablePrimitive
|
|
6
|
+
|
|
7
|
+
refine Array do
|
|
8
|
+
using DiffablePrimitive
|
|
9
|
+
|
|
10
|
+
attr_writer :parent_attribute_name
|
|
11
|
+
|
|
12
|
+
def in_model
|
|
13
|
+
@in_model if defined?(@in_model)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def parent
|
|
17
|
+
@parent if defined?(@parent)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def id
|
|
21
|
+
object_id.to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def ancestors
|
|
25
|
+
result = [self]
|
|
26
|
+
p = self
|
|
27
|
+
result << p until (p = p.parent).nil?
|
|
28
|
+
result
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def primitive?
|
|
32
|
+
false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def diff(other)
|
|
36
|
+
raise TypeError, "Expected other #{other.class} to be of type #{self.class}" unless other.is_a?(self.class)
|
|
37
|
+
raise "Well Hell other #{other.path} in_model is nil" if other.in_model.nil?
|
|
38
|
+
raise "Well Hell my path `#{path}` in_model is nil" if in_model.nil?
|
|
39
|
+
|
|
40
|
+
result = []
|
|
41
|
+
remaining_content = Array.new(self) # TODO: I want a copy of the array, not a deep clone
|
|
42
|
+
other_enum = other.each_with_index
|
|
43
|
+
|
|
44
|
+
loop do
|
|
45
|
+
if other_enum.peek[0] == remaining_content[0]
|
|
46
|
+
other_enum.next
|
|
47
|
+
remaining_content.shift
|
|
48
|
+
elsif items_are_changed?(other, other_enum, remaining_content)
|
|
49
|
+
result.concat(compute_item_changes(other, other_enum, self, remaining_content[0]))
|
|
50
|
+
remaining_content.shift
|
|
51
|
+
other_enum.next
|
|
52
|
+
elsif !remaining_content.empty? && !other.smart_include?(remaining_content[0])
|
|
53
|
+
result << Diff::Delete.new(Diff::ArchimateArrayReference.new(self, smart_find(remaining_content[0])))
|
|
54
|
+
remaining_content.shift
|
|
55
|
+
elsif !smart_include?(other_enum.peek[0])
|
|
56
|
+
result << Diff::Insert.new(Diff::ArchimateArrayReference.new(other, other_enum.next[1]))
|
|
57
|
+
elsif smart_include?(other_enum.peek[0])
|
|
58
|
+
result << Diff::Move.new(
|
|
59
|
+
Diff::ArchimateArrayReference.new(other, other_enum.peek[1]),
|
|
60
|
+
Diff::ArchimateArrayReference.new(self, smart_find(other_enum.peek[0]))
|
|
61
|
+
)
|
|
62
|
+
remaining_item_idx = remaining_content.smart_find(other_enum.peek[0])
|
|
63
|
+
if remaining_item_idx
|
|
64
|
+
result.concat(compute_item_changes(other, other_enum, self, remaining_content[remaining_item_idx]))
|
|
65
|
+
remaining_content.delete_at(remaining_item_idx) if remaining_content.smart_include?(other_enum.peek[0])
|
|
66
|
+
end
|
|
67
|
+
other_enum.next
|
|
68
|
+
else
|
|
69
|
+
raise "Unhandled diff case for remaining_content: #{remaining_content[0]} and #{other_enum.peek[0]}"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
result.concat(
|
|
74
|
+
remaining_content
|
|
75
|
+
.reject { |item| other.include?(item) }
|
|
76
|
+
.map do |item|
|
|
77
|
+
Diff::Delete.new(Diff::ArchimateArrayReference.new(self, find_index(item)))
|
|
78
|
+
end
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# TODO: This may not continue to live here. Only used by testing.
|
|
83
|
+
def patch(diffs)
|
|
84
|
+
# TODO: Beware, order of diffs could break patching at the moment.
|
|
85
|
+
Array(diffs).each do |diff|
|
|
86
|
+
case diff
|
|
87
|
+
when Diff::Delete
|
|
88
|
+
delete_at(smart_find(diff.target.value))
|
|
89
|
+
when Diff::Insert
|
|
90
|
+
insert(diff.target.array_index, diff.target.value)
|
|
91
|
+
when Diff::Change
|
|
92
|
+
self[smart_find(diff.changed_from.value)] = diff.target.value
|
|
93
|
+
when Diff::Move
|
|
94
|
+
insert(diff.target.array_index, delete_at(smart_find(diff.target.value)))
|
|
95
|
+
else
|
|
96
|
+
raise "Unexpected diff type: #{diff.class}"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
self
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def items_are_changed?(other, other_enum, remaining)
|
|
103
|
+
!remaining.empty? &&
|
|
104
|
+
case remaining[0]
|
|
105
|
+
when DataModel::Referenceable
|
|
106
|
+
remaining[0].id == other_enum.peek[0].id
|
|
107
|
+
when String, DataModel::ArchimateNode
|
|
108
|
+
!other.include?(remaining[0]) && !include?(other_enum.peek[0])
|
|
109
|
+
else
|
|
110
|
+
raise "Unhandled type for #{remaining[0].class}"
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def compute_item_changes(other, other_enum, _myself, my_item)
|
|
115
|
+
case my_item
|
|
116
|
+
when DataModel::ArchimateNode
|
|
117
|
+
my_item.diff(other_enum.peek[0])
|
|
118
|
+
else
|
|
119
|
+
my_item.diff(other_enum.peek[0], self, other, other_enum.peek[1], find_index(my_item))
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def in_model=(model)
|
|
124
|
+
puts "#{self.inspect} is frozen" if self.frozen?
|
|
125
|
+
@in_model = model
|
|
126
|
+
each { |item| item.in_model = model }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def parent=(par)
|
|
130
|
+
@parent = par
|
|
131
|
+
each { |i| i.parent = self }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def parent_attribute_name
|
|
135
|
+
@parent_attribute_name if defined?(@parent_attribute_name)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def build_index(hash_index = {})
|
|
139
|
+
reduce(hash_index) { |hi, array_item| array_item.build_index(hi) }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def path(options = {})
|
|
143
|
+
[
|
|
144
|
+
parent&.path(options),
|
|
145
|
+
parent_attribute_name
|
|
146
|
+
].compact.reject(&:empty?).join("/")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def clone
|
|
150
|
+
map(&:clone)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def dup
|
|
154
|
+
map(&:dup)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def to_s
|
|
158
|
+
"#{parent}/#{parent_attribute_name}"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def referenced_identified_nodes
|
|
162
|
+
reduce([]) do |a, e|
|
|
163
|
+
a.concat(e.referenced_identified_nodes)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def find_by_id(an_id)
|
|
168
|
+
find { |el| el.id == an_id }
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def smart_find(val = nil)
|
|
172
|
+
case val
|
|
173
|
+
when Referenceable
|
|
174
|
+
lazy.map(&:id).find_index(val.id)
|
|
175
|
+
else
|
|
176
|
+
find_index(val)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def smart_include?(val)
|
|
181
|
+
case val
|
|
182
|
+
when Referenceable
|
|
183
|
+
lazy.map(&:id).include?(val.id)
|
|
184
|
+
else
|
|
185
|
+
include?(val)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def smart_intersection(ary)
|
|
190
|
+
select { |item| ary.smart_include?(item) }
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def after(idx)
|
|
194
|
+
return [] if idx >= size - 1
|
|
195
|
+
self[idx + 1..-1]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Given a node in self and ary,
|
|
199
|
+
# return the idx of first node p in self that exists in both self and ary
|
|
200
|
+
# and is previous to node in self
|
|
201
|
+
def previous_item_index(ary, node)
|
|
202
|
+
return -1 unless ary.smart_include?(node)
|
|
203
|
+
initial_idx = smart_find(node)
|
|
204
|
+
return -1 if initial_idx.nil?
|
|
205
|
+
|
|
206
|
+
(initial_idx - 1).downto(0).find(-> { -1 }) do |idx|
|
|
207
|
+
ary.smart_include?(at(idx))
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Archimate
|
|
3
|
+
module DataModel
|
|
4
|
+
module DiffablePrimitive
|
|
5
|
+
module DiffablePrimitiveMethods
|
|
6
|
+
def diff(other, from_parent, to_parent, attribute, from_attribute = nil)
|
|
7
|
+
from_attribute = attribute if from_attribute.nil?
|
|
8
|
+
if other.nil?
|
|
9
|
+
return [Diff::Delete.new(
|
|
10
|
+
Diff::ArchimateNodeAttributeReference.new(from_parent, attribute)
|
|
11
|
+
)]
|
|
12
|
+
end
|
|
13
|
+
raise TypeError, "Expected other #{other.class} to be of type #{self.class}" unless other.is_a?(self.class)
|
|
14
|
+
unless self == other
|
|
15
|
+
return [Diff::Change.new(
|
|
16
|
+
Diff::ArchimateNodeReference.for_node(to_parent, attribute),
|
|
17
|
+
Diff::ArchimateNodeReference.for_node(from_parent, from_attribute)
|
|
18
|
+
)]
|
|
19
|
+
end
|
|
20
|
+
[]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def in_model=(_m); end
|
|
24
|
+
|
|
25
|
+
def parent=(_p); end
|
|
26
|
+
|
|
27
|
+
def parent_attribute_name=(_attr_name); end
|
|
28
|
+
|
|
29
|
+
def build_index(index_hash)
|
|
30
|
+
index_hash
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def primitive?
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def id
|
|
38
|
+
object_id.to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def clone
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def dup
|
|
46
|
+
self
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def compact!
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def referenced_identified_nodes
|
|
54
|
+
[]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
refine Symbol do
|
|
59
|
+
include DiffablePrimitiveMethods
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
refine String do
|
|
63
|
+
include DiffablePrimitiveMethods
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
refine Hash do
|
|
67
|
+
include DiffablePrimitiveMethods
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
refine Integer do
|
|
71
|
+
include DiffablePrimitiveMethods
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
refine Float do
|
|
75
|
+
include DiffablePrimitiveMethods
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
refine NilClass do
|
|
79
|
+
include DiffablePrimitiveMethods
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module DataModel
|
|
5
|
+
# An element that holds documentation.
|
|
6
|
+
# A base string type for multi-language strings that preserves whitespace.
|
|
7
|
+
# PreservedLangStringType in ArchiMate 3 schema
|
|
8
|
+
class Documentation < LangString
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Dry::Types.register_class(Documentation)
|
|
12
|
+
DocumentationGroup = Strict::Array.member(Documentation).default([])
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module DataModel
|
|
5
|
+
ElementTypeEnum = %w[BusinessActor BusinessRole BusinessCollaboration BusinessInterface
|
|
6
|
+
BusinessProcess BusinessFunction BusinessInteraction BusinessEvent BusinessService
|
|
7
|
+
BusinessObject Contract Representation Product
|
|
8
|
+
ApplicationComponent ApplicationCollaboration ApplicationInterface ApplicationFunction
|
|
9
|
+
ApplicationInteraction ApplicationProcess ApplicationEvent ApplicationService DataObject
|
|
10
|
+
Node Device SystemSoftware TechnologyCollaboration TechnologyInterface Path
|
|
11
|
+
CommunicationNetwork TechnologyFunction TechnologyProcess TechnologyInteraction
|
|
12
|
+
TechnologyEvent TechnologyService Artifact Equipment Facility DistributionNetwork Material
|
|
13
|
+
Stakeholder Driver Assessment Goal Outcome
|
|
14
|
+
Principle Requirement Constraint Meaning Value
|
|
15
|
+
Resource Capability CourseOfAction
|
|
16
|
+
WorkPackage Deliverable ImplementationEvent Plateau Gap
|
|
17
|
+
Grouping Location
|
|
18
|
+
AndJunction OrJunction].freeze
|
|
19
|
+
|
|
20
|
+
CompositeTypeEnum = %w[Grouping Location].freeze
|
|
21
|
+
|
|
22
|
+
RelationshipConnectorEnum = %w[AndJunction OrJunction].freeze
|
|
23
|
+
|
|
24
|
+
ElementEnumType = [].concat([ElementTypeEnum, CompositeTypeEnum, RelationshipConnectorEnum]).freeze
|
|
25
|
+
|
|
26
|
+
ElementType = Strict::String.enum(*ElementEnumType)
|
|
27
|
+
|
|
28
|
+
AllowedElementTypes = Strict::Array.member(ElementType).default([])
|
|
29
|
+
|
|
30
|
+
# A base element type that can be extended by concrete ArchiMate types.
|
|
31
|
+
#
|
|
32
|
+
# Note that ElementType is abstract, so one must have derived types of this type. this is indicated in xml
|
|
33
|
+
# by having a tag name of "element" and an attribute of xsi:type="BusinessRole" where BusinessRole is
|
|
34
|
+
# a derived type from ElementType.
|
|
35
|
+
class Element < Concept
|
|
36
|
+
def to_s
|
|
37
|
+
Archimate::Color.layer_color(layer, "#{type}<#{id}>[#{name}]")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def layer
|
|
41
|
+
Constants::ELEMENT_LAYER.fetch(type, "None")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# TODO: move to dynamic method creation
|
|
45
|
+
def composed_by
|
|
46
|
+
in_model
|
|
47
|
+
.relationships.select { |r| r.type == "CompositionRelationship" && r.target == id }
|
|
48
|
+
.map { |r| in_model.lookup(r.source) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# TODO: move to dynamic method creation
|
|
52
|
+
def composes
|
|
53
|
+
in_model
|
|
54
|
+
.relationships
|
|
55
|
+
.select { |r| r.type == "CompositionRelationship" && r.source == id }
|
|
56
|
+
.map { |r| in_model.lookup(r.target) }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Diagrams that this element is referenced in.
|
|
60
|
+
def diagrams
|
|
61
|
+
@diagrams ||= in_model.diagrams.select do |diagram|
|
|
62
|
+
diagram.element_ids.include?(id)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Relationships that this element is referenced in.
|
|
67
|
+
def relationships
|
|
68
|
+
@relationships ||= in_model.relationships.select do |relationship|
|
|
69
|
+
relationship.source == id || relationship.target == id
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Copy any attributes/docs, etc. from each of the others into the original.
|
|
74
|
+
# 1. Child `label`s with different `xml:lang` attribute values
|
|
75
|
+
# 2. Child `documentation` (and different `xml:lang` attribute values)
|
|
76
|
+
# 3. Child `properties`
|
|
77
|
+
# 4. Any other elements
|
|
78
|
+
def merge(element)
|
|
79
|
+
super
|
|
80
|
+
element.diagrams.each { |diagram| diagram.replace(element, self) }
|
|
81
|
+
element.relationships.each { |relationship| relationship.replace(element, self) }
|
|
82
|
+
element.organization.remove(element.id)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
Dry::Types.register_class(Element)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Archimate
|
|
3
|
+
module DataModel
|
|
4
|
+
class Font < ArchimateNode
|
|
5
|
+
attribute :name, Strict::String.optional
|
|
6
|
+
attribute :size, Coercible::Float.constrained(gt: 0.0).optional
|
|
7
|
+
attribute :style, Coercible::Int.optional # TODO: make this an enum
|
|
8
|
+
attribute :font_data, Strict::String.optional
|
|
9
|
+
|
|
10
|
+
# Archi font strings look like this:
|
|
11
|
+
# "1|Arial |14.0|0|WINDOWS|1|0 |0|0|0|0 |0 |0|0|1|0|0|0|0 |Arial"
|
|
12
|
+
# "1|Arial |8.0 |0|WINDOWS|1|0 |0|0|0|0 |0 |0|0|1|0|0|0|0 |Arial"
|
|
13
|
+
# "1|Segoe UI Semibold|12.0|2|WINDOWS|1|-16|0|0|0|600|-1|0|0|0|3|2|1|34|Segoe UI Semibold"
|
|
14
|
+
# "1|Times New Roman |12.0|3|WINDOWS|1|-16|0|0|0|700|-1|0|0|0|3|2|1|18|Times New Roman"
|
|
15
|
+
def self.archi_font_string(str)
|
|
16
|
+
return nil if str.nil?
|
|
17
|
+
font_parts = str.split("|")
|
|
18
|
+
DataModel::Font.new(
|
|
19
|
+
name: font_parts[1],
|
|
20
|
+
size: font_parts[2],
|
|
21
|
+
style: font_parts[3],
|
|
22
|
+
font_data: str
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_s
|
|
27
|
+
"Font(name: #{name}, size: #{size}, style: #{style})"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_archi_font
|
|
31
|
+
font_data ||
|
|
32
|
+
[
|
|
33
|
+
1, font.name, font.size, font.style, "WINDOWS", 1, 0, 0, 0, 0, 0, 0,
|
|
34
|
+
0, 0, 1, 0, 0, 0, 0, font.name
|
|
35
|
+
].map(&:to_s).join("|")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# TODO: this isn't standard
|
|
39
|
+
# Move to file format
|
|
40
|
+
def style_string
|
|
41
|
+
case style
|
|
42
|
+
when 1
|
|
43
|
+
"italic"
|
|
44
|
+
when 2
|
|
45
|
+
"bold"
|
|
46
|
+
when 3
|
|
47
|
+
"bold|italic"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Dry::Types.register_class(Font)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module DataModel
|
|
5
|
+
# Node type to allow a Label in a Artifact. the "label" element holds the info for the Note.
|
|
6
|
+
class Label < ViewNode
|
|
7
|
+
# conceptRef is a reference to an concept for this particular label, along with the attributeRef
|
|
8
|
+
# which references the particular concept's part which this label represents.
|
|
9
|
+
attribute :concept_ref, Identifier
|
|
10
|
+
# conceptRef is a reference to an concept for this particular label, along with the partRef
|
|
11
|
+
# which references the particular concept's part which this label represents. If this attribute
|
|
12
|
+
# is set, then there is no need to add a label tag in the Label parent (since it is contained in the model).
|
|
13
|
+
# the XPATH statement is meant to be interpreted in the context of what the conceptRef points to.
|
|
14
|
+
attribute :xpath_path, Strict::String.optional
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Dry::Types.register_class(Label)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "forwardable"
|
|
3
|
+
|
|
4
|
+
module Archimate
|
|
5
|
+
module DataModel
|
|
6
|
+
# A base string type for multi-language strings.
|
|
7
|
+
class LangString < ArchimateNode
|
|
8
|
+
# include Comparable
|
|
9
|
+
extend Forwardable
|
|
10
|
+
def_delegators :@text, :to_s, :strip, :strip!, :tr, :+, :gsub, :gsub!, :sub!, :downcase!, :empty?, :split
|
|
11
|
+
|
|
12
|
+
attribute :text, Strict::String
|
|
13
|
+
attribute :lang, Strict::String.optional
|
|
14
|
+
|
|
15
|
+
# @param [Hash{Symbol => Object},Dry::Struct, String] attributes
|
|
16
|
+
# @raise [Struct::Error] if the given attributes don't conform {#schema}
|
|
17
|
+
# with given {#constructor_type}
|
|
18
|
+
def self.new(attributes)
|
|
19
|
+
if attributes.instance_of?(String)
|
|
20
|
+
super(text: attributes.strip)
|
|
21
|
+
else
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_str
|
|
27
|
+
@text
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def =~(other)
|
|
31
|
+
if other.is_a?(Regexp)
|
|
32
|
+
other =~ @text
|
|
33
|
+
else
|
|
34
|
+
Regexp.new(Regexp.escape(@text)) =~ other
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Dry::Types.register_class(LangString)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module DataModel
|
|
5
|
+
# TODO: x & y Defined like this in the XSD
|
|
6
|
+
NonNegativeInteger = Coercible::Int.constrained(gteq: 0)
|
|
7
|
+
NonNegativeFloat = Coercible::Float # .constrained(gteq: 0)
|
|
8
|
+
|
|
9
|
+
# Graphical node type. It can contain child node types.
|
|
10
|
+
# This is LocationType/LocationGroup in the XSD.
|
|
11
|
+
class Location < ArchimateNode
|
|
12
|
+
# The x (towards the right, associated with width) attribute from the Top,Left (i.e. 0,0)
|
|
13
|
+
# corner of the diagram to the Top, Left corner of the bounding box of the concept.
|
|
14
|
+
attribute :x, NonNegativeFloat # Note the XSD has this as an Int, NonNegativeInteger
|
|
15
|
+
# The y (towards the bottom, associated with height) attribute from the Top,Left (i.e. 0,0)
|
|
16
|
+
# corner of the diagram to the Top, Left corner of the bounding box of the concept.
|
|
17
|
+
attribute :y, NonNegativeFloat # Note the XSD has this as an Int, NonNegativeInteger
|
|
18
|
+
|
|
19
|
+
# These are holdovers from the archi file format and are only maintained for compatability
|
|
20
|
+
attribute :end_x, Coercible::Int.optional
|
|
21
|
+
attribute :end_y, Coercible::Int.optional
|
|
22
|
+
|
|
23
|
+
def to_s
|
|
24
|
+
"Location(x: #{x}, y: #{y})"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Dry::Types.register_class(Location)
|
|
29
|
+
LocationList = Strict::Array.member(Location).default([])
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module DataModel
|
|
5
|
+
# An instance of the meta-data element contains data structures that declare descriptive information
|
|
6
|
+
# about a meta-data element's parent only.
|
|
7
|
+
#
|
|
8
|
+
# One or more different meta-data models may be declared as child extensions of a meta-data element.
|
|
9
|
+
class Metadata < ArchimateNode
|
|
10
|
+
attribute :schema_infos, Strict::Array.member(SchemaInfo).default([])
|
|
11
|
+
end
|
|
12
|
+
Dry::Types.register_class(Metadata)
|
|
13
|
+
end
|
|
14
|
+
end
|