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.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.projectile +18 -0
  4. data/.rubocop.yml +13 -0
  5. data/.travis.yml +4 -0
  6. data/.yardocs +15 -0
  7. data/Gemfile +5 -0
  8. data/Guardfile +27 -0
  9. data/LICENSE +201 -0
  10. data/README.md +94 -0
  11. data/Rakefile +29 -0
  12. data/TODOs.org +286 -0
  13. data/archimate.gemspec +51 -0
  14. data/bin/archimate +17 -0
  15. data/bin/console +13 -0
  16. data/bin/setup +8 -0
  17. data/exe/archidiff +7 -0
  18. data/exe/archidiff-summary +7 -0
  19. data/exe/archimate +7 -0
  20. data/exe/archimerge +7 -0
  21. data/exe/fmtxml +7 -0
  22. data/lib/archimate/cli/archi.rb +189 -0
  23. data/lib/archimate/cli/cleanup.rb +54 -0
  24. data/lib/archimate/cli/conflict_resolver.rb +39 -0
  25. data/lib/archimate/cli/convert.rb +39 -0
  26. data/lib/archimate/cli/diff.rb +31 -0
  27. data/lib/archimate/cli/diff_summary.rb +101 -0
  28. data/lib/archimate/cli/duper.rb +85 -0
  29. data/lib/archimate/cli/lint.rb +16 -0
  30. data/lib/archimate/cli/mapper.rb +82 -0
  31. data/lib/archimate/cli/merge.rb +49 -0
  32. data/lib/archimate/cli/merger.rb +109 -0
  33. data/lib/archimate/cli/stats.rb +42 -0
  34. data/lib/archimate/cli/svger.rb +40 -0
  35. data/lib/archimate/color.rb +53 -0
  36. data/lib/archimate/config.rb +35 -0
  37. data/lib/archimate/data_model/any_attribute.rb +13 -0
  38. data/lib/archimate/data_model/any_element.rb +15 -0
  39. data/lib/archimate/data_model/archimate_node.rb +181 -0
  40. data/lib/archimate/data_model/bounds.rb +72 -0
  41. data/lib/archimate/data_model/color.rb +47 -0
  42. data/lib/archimate/data_model/concept.rb +14 -0
  43. data/lib/archimate/data_model/concern.rb +17 -0
  44. data/lib/archimate/data_model/connection.rb +107 -0
  45. data/lib/archimate/data_model/constants.rb +82 -0
  46. data/lib/archimate/data_model/container.rb +17 -0
  47. data/lib/archimate/data_model/diagram.rb +40 -0
  48. data/lib/archimate/data_model/diffable_array.rb +213 -0
  49. data/lib/archimate/data_model/diffable_primitive.rb +83 -0
  50. data/lib/archimate/data_model/documentation.rb +14 -0
  51. data/lib/archimate/data_model/element.rb +87 -0
  52. data/lib/archimate/data_model/font.rb +54 -0
  53. data/lib/archimate/data_model/label.rb +19 -0
  54. data/lib/archimate/data_model/lang_string.rb +41 -0
  55. data/lib/archimate/data_model/location.rb +31 -0
  56. data/lib/archimate/data_model/metadata.rb +14 -0
  57. data/lib/archimate/data_model/model.rb +217 -0
  58. data/lib/archimate/data_model/modeling_note.rb +13 -0
  59. data/lib/archimate/data_model/named_referenceable.rb +14 -0
  60. data/lib/archimate/data_model/organization.rb +40 -0
  61. data/lib/archimate/data_model/property.rb +25 -0
  62. data/lib/archimate/data_model/property_definition.rb +16 -0
  63. data/lib/archimate/data_model/referenceable.rb +29 -0
  64. data/lib/archimate/data_model/relationship.rb +85 -0
  65. data/lib/archimate/data_model/schema_info.rb +18 -0
  66. data/lib/archimate/data_model/style.rb +32 -0
  67. data/lib/archimate/data_model/view.rb +12 -0
  68. data/lib/archimate/data_model/view_concept.rb +18 -0
  69. data/lib/archimate/data_model/view_node.rb +114 -0
  70. data/lib/archimate/data_model/viewpoint.rb +87 -0
  71. data/lib/archimate/data_model.rb +54 -0
  72. data/lib/archimate/diff/archimate_array_reference.rb +113 -0
  73. data/lib/archimate/diff/archimate_identified_node_reference.rb +41 -0
  74. data/lib/archimate/diff/archimate_node_attribute_reference.rb +70 -0
  75. data/lib/archimate/diff/archimate_node_reference.rb +80 -0
  76. data/lib/archimate/diff/change.rb +49 -0
  77. data/lib/archimate/diff/conflict.rb +31 -0
  78. data/lib/archimate/diff/conflicts/base_conflict.rb +53 -0
  79. data/lib/archimate/diff/conflicts/deleted_items_child_updated_conflict.rb +30 -0
  80. data/lib/archimate/diff/conflicts/deleted_items_referenced_conflict.rb +63 -0
  81. data/lib/archimate/diff/conflicts/path_conflict.rb +51 -0
  82. data/lib/archimate/diff/conflicts.rb +89 -0
  83. data/lib/archimate/diff/delete.rb +41 -0
  84. data/lib/archimate/diff/difference.rb +113 -0
  85. data/lib/archimate/diff/insert.rb +43 -0
  86. data/lib/archimate/diff/merge.rb +70 -0
  87. data/lib/archimate/diff/move.rb +51 -0
  88. data/lib/archimate/diff.rb +17 -0
  89. data/lib/archimate/export/csv_export.rb +32 -0
  90. data/lib/archimate/export/cypher.rb +171 -0
  91. data/lib/archimate/export/graph_ml.rb +131 -0
  92. data/lib/archimate/export/n_quads.rb +142 -0
  93. data/lib/archimate/file_format.rb +30 -0
  94. data/lib/archimate/file_formats/archi_file_format.rb +151 -0
  95. data/lib/archimate/file_formats/archi_file_reader.rb +252 -0
  96. data/lib/archimate/file_formats/archi_file_writer.rb +230 -0
  97. data/lib/archimate/file_formats/archimate_v2.rb +461 -0
  98. data/lib/archimate/file_formats/model_exchange_file/xml_lang_string.rb +35 -0
  99. data/lib/archimate/file_formats/model_exchange_file/xml_metadata.rb +115 -0
  100. data/lib/archimate/file_formats/model_exchange_file/xml_property_definitions.rb +28 -0
  101. data/lib/archimate/file_formats/model_exchange_file/xml_property_defs.rb +27 -0
  102. data/lib/archimate/file_formats/model_exchange_file_reader.rb +237 -0
  103. data/lib/archimate/file_formats/model_exchange_file_reader_21.rb +73 -0
  104. data/lib/archimate/file_formats/model_exchange_file_reader_30.rb +134 -0
  105. data/lib/archimate/file_formats/model_exchange_file_writer.rb +157 -0
  106. data/lib/archimate/file_formats/model_exchange_file_writer_21.rb +143 -0
  107. data/lib/archimate/file_formats/model_exchange_file_writer_30.rb +153 -0
  108. data/lib/archimate/file_formats/writer.rb +56 -0
  109. data/lib/archimate/lint/duplicate_entities.rb +121 -0
  110. data/lib/archimate/lint/linter.rb +146 -0
  111. data/lib/archimate/logging.rb +55 -0
  112. data/lib/archimate/maybe_io.rb +34 -0
  113. data/lib/archimate/progress_indicator.rb +29 -0
  114. data/lib/archimate/svg/archimate.css +232 -0
  115. data/lib/archimate/svg/child.rb +29 -0
  116. data/lib/archimate/svg/connection.rb +184 -0
  117. data/lib/archimate/svg/css_style.rb +31 -0
  118. data/lib/archimate/svg/diagram.rb +87 -0
  119. data/lib/archimate/svg/entity/and_junction.rb +14 -0
  120. data/lib/archimate/svg/entity/application_collaboration.rb +14 -0
  121. data/lib/archimate/svg/entity/application_component.rb +41 -0
  122. data/lib/archimate/svg/entity/application_event.rb +13 -0
  123. data/lib/archimate/svg/entity/application_function.rb +13 -0
  124. data/lib/archimate/svg/entity/application_interaction.rb +13 -0
  125. data/lib/archimate/svg/entity/application_interface.rb +13 -0
  126. data/lib/archimate/svg/entity/application_process.rb +13 -0
  127. data/lib/archimate/svg/entity/application_service.rb +13 -0
  128. data/lib/archimate/svg/entity/artifact.rb +39 -0
  129. data/lib/archimate/svg/entity/assessment.rb +14 -0
  130. data/lib/archimate/svg/entity/base_entity.rb +128 -0
  131. data/lib/archimate/svg/entity/business_actor.rb +14 -0
  132. data/lib/archimate/svg/entity/business_collaboration.rb +14 -0
  133. data/lib/archimate/svg/entity/business_event.rb +10 -0
  134. data/lib/archimate/svg/entity/business_function.rb +13 -0
  135. data/lib/archimate/svg/entity/business_interaction.rb +13 -0
  136. data/lib/archimate/svg/entity/business_interface.rb +13 -0
  137. data/lib/archimate/svg/entity/business_object.rb +13 -0
  138. data/lib/archimate/svg/entity/business_process.rb +13 -0
  139. data/lib/archimate/svg/entity/business_role.rb +14 -0
  140. data/lib/archimate/svg/entity/business_service.rb +13 -0
  141. data/lib/archimate/svg/entity/capability.rb +14 -0
  142. data/lib/archimate/svg/entity/communication_network.rb +14 -0
  143. data/lib/archimate/svg/entity/communication_path.rb +14 -0
  144. data/lib/archimate/svg/entity/constraint.rb +15 -0
  145. data/lib/archimate/svg/entity/contract.rb +13 -0
  146. data/lib/archimate/svg/entity/course_of_action.rb +14 -0
  147. data/lib/archimate/svg/entity/data_entity.rb +29 -0
  148. data/lib/archimate/svg/entity/data_object.rb +13 -0
  149. data/lib/archimate/svg/entity/deliverable.rb +13 -0
  150. data/lib/archimate/svg/entity/device.rb +48 -0
  151. data/lib/archimate/svg/entity/diagram_model_reference.rb +22 -0
  152. data/lib/archimate/svg/entity/diagram_object.rb +30 -0
  153. data/lib/archimate/svg/entity/distribution_network.rb +14 -0
  154. data/lib/archimate/svg/entity/driver.rb +14 -0
  155. data/lib/archimate/svg/entity/equipment.rb +16 -0
  156. data/lib/archimate/svg/entity/event_entity.rb +36 -0
  157. data/lib/archimate/svg/entity/facility.rb +16 -0
  158. data/lib/archimate/svg/entity/function_entity.rb +14 -0
  159. data/lib/archimate/svg/entity/gap.rb +21 -0
  160. data/lib/archimate/svg/entity/goal.rb +14 -0
  161. data/lib/archimate/svg/entity/group.rb +24 -0
  162. data/lib/archimate/svg/entity/implementation_event.rb +13 -0
  163. data/lib/archimate/svg/entity/infrastructure_function.rb +13 -0
  164. data/lib/archimate/svg/entity/infrastructure_interface.rb +13 -0
  165. data/lib/archimate/svg/entity/infrastructure_service.rb +13 -0
  166. data/lib/archimate/svg/entity/interaction_entity.rb +14 -0
  167. data/lib/archimate/svg/entity/interface_entity.rb +35 -0
  168. data/lib/archimate/svg/entity/junction.rb +19 -0
  169. data/lib/archimate/svg/entity/location.rb +14 -0
  170. data/lib/archimate/svg/entity/material.rb +14 -0
  171. data/lib/archimate/svg/entity/meaning.rb +40 -0
  172. data/lib/archimate/svg/entity/motivation_entity.rb +40 -0
  173. data/lib/archimate/svg/entity/network.rb +14 -0
  174. data/lib/archimate/svg/entity/node.rb +33 -0
  175. data/lib/archimate/svg/entity/node_shape.rb +64 -0
  176. data/lib/archimate/svg/entity/note.rb +30 -0
  177. data/lib/archimate/svg/entity/or_junction.rb +14 -0
  178. data/lib/archimate/svg/entity/outcome.rb +15 -0
  179. data/lib/archimate/svg/entity/path.rb +14 -0
  180. data/lib/archimate/svg/entity/plateau.rb +15 -0
  181. data/lib/archimate/svg/entity/principle.rb +15 -0
  182. data/lib/archimate/svg/entity/process_entity.rb +63 -0
  183. data/lib/archimate/svg/entity/product.rb +20 -0
  184. data/lib/archimate/svg/entity/rect.rb +13 -0
  185. data/lib/archimate/svg/entity/rect_entity.rb +25 -0
  186. data/lib/archimate/svg/entity/representation.rb +31 -0
  187. data/lib/archimate/svg/entity/requirement.rb +15 -0
  188. data/lib/archimate/svg/entity/resource.rb +14 -0
  189. data/lib/archimate/svg/entity/rounded_rect_entity.rb +23 -0
  190. data/lib/archimate/svg/entity/service_entity.rb +51 -0
  191. data/lib/archimate/svg/entity/sketch_model_sticky.rb +14 -0
  192. data/lib/archimate/svg/entity/stakeholder.rb +15 -0
  193. data/lib/archimate/svg/entity/system_software.rb +14 -0
  194. data/lib/archimate/svg/entity/technology_collaboration.rb +14 -0
  195. data/lib/archimate/svg/entity/technology_event.rb +13 -0
  196. data/lib/archimate/svg/entity/technology_function.rb +13 -0
  197. data/lib/archimate/svg/entity/technology_interaction.rb +13 -0
  198. data/lib/archimate/svg/entity/technology_interface.rb +13 -0
  199. data/lib/archimate/svg/entity/technology_process.rb +13 -0
  200. data/lib/archimate/svg/entity/technology_service.rb +13 -0
  201. data/lib/archimate/svg/entity/value.rb +27 -0
  202. data/lib/archimate/svg/entity/work_package.rb +14 -0
  203. data/lib/archimate/svg/entity.rb +93 -0
  204. data/lib/archimate/svg/entity_factory.rb +17 -0
  205. data/lib/archimate/svg/extents.rb +27 -0
  206. data/lib/archimate/svg/point.rb +7 -0
  207. data/lib/archimate/svg/svg_template.rb +27 -0
  208. data/lib/archimate/svg/svg_template.svg.erb +169 -0
  209. data/lib/archimate/version.rb +4 -0
  210. data/lib/archimate.rb +114 -0
  211. 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