archimate 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|