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,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "singleton"
5
+ require "observer"
6
+
7
+ module Archimate
8
+ # This is the singleton class that contains application configuration.
9
+ class Config
10
+ include Singleton
11
+ include Observable
12
+
13
+ attr_reader :interactive
14
+ attr_reader :logger
15
+
16
+ def initialize
17
+ @interactive = true
18
+ @logger ||= Logger.new(STDERR, progname: "archimate")
19
+ end
20
+
21
+ def interactive=(interactive)
22
+ return @interactive unless @interactive != interactive
23
+ @interactive = interactive
24
+ changed
25
+ notify_observers(:interactive, @interactive)
26
+ end
27
+
28
+ def logger=(logger)
29
+ return @logger unless @logger != logger
30
+ @logger = logger
31
+ changed
32
+ notify_observers(:logger, @logger)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ # An instance of any XML attribute for arbitrary content like metadata
6
+ class AnyAttribute < ArchimateNode
7
+ attribute :attribute, Strict::String
8
+ attribute :prefix, Strict::String
9
+ attribute :value, Strict::String
10
+ end
11
+ Dry::Types.register_class(AnyAttribute)
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ # An instance of any XML element for arbitrary content like metadata
6
+ class AnyElement < ArchimateNode
7
+ attribute :element, Strict::String
8
+ attribute :prefix, Strict::String.optional
9
+ attribute :attributes, Strict::Array.member(AnyAttribute).default([])
10
+ attribute :content, Strict::String.optional
11
+ attribute :children, Strict::Array.member(AnyElement).default([])
12
+ end
13
+ Dry::Types.register_class(AnyElement)
14
+ end
15
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+ module Archimate
3
+ module DataModel
4
+ class ArchimateNode < Dry::Struct
5
+ using DiffablePrimitive
6
+ using DiffableArray
7
+
8
+ constructor_type :schema # specifies constructor style for Dry::Struct
9
+
10
+ attr_writer :parent_attribute_name
11
+ attr_reader :struct_instance_variables
12
+
13
+ def initialize(attributes)
14
+ super
15
+ @struct_instance_variables = self.class.schema.keys
16
+ end
17
+
18
+ # TODO: Schedule this for eliminations
19
+ # Outside of test code, this is only used for the Bounds class
20
+ def with(options = {})
21
+ self.class.new(
22
+ struct_instance_variables
23
+ .each_with_object({}) { |i, a| a[i] = self[i] }
24
+ .merge(options)
25
+ .each_with_object({}) { |(k, v), a| a[k] = v.dup }
26
+ )
27
+ end
28
+
29
+ # Note: my clone method does one non-idiomatic thing - it does not clone the
30
+ # frozen state. TODO: respect the frozen state of the clone'd object.
31
+ def clone
32
+ self.class.new(
33
+ struct_instance_variables
34
+ .each_with_object({}) do |i, a|
35
+ a[i] = self[i].primitive? ? self[i] : self[i].clone
36
+ end
37
+ )
38
+ end
39
+
40
+ # Makes a copy of the archimate node which is not frozen
41
+ def dup
42
+ self.class.new(
43
+ struct_instance_variables
44
+ .each_with_object({}) do |i, a|
45
+ a[i] = self[i].primitive? ? self[i] : self[i].dup
46
+ end
47
+ )
48
+ end
49
+
50
+ def in_model
51
+ @in_model if defined?(@in_model)
52
+ end
53
+
54
+ def parent
55
+ @parent if defined?(@parent)
56
+ end
57
+
58
+ # TODO: this is used only such that every item has an id for sticking in the index.
59
+ # Is this really needed still?
60
+ def id
61
+ object_id
62
+ end
63
+
64
+ def ancestors
65
+ result = [self]
66
+ p = self
67
+ result << p until (p = p.parent).nil?
68
+ result
69
+ end
70
+
71
+ def primitive?
72
+ false
73
+ end
74
+
75
+ def parent=(par)
76
+ @parent = par
77
+ struct_instance_variables.each do |attrname|
78
+ self[attrname].parent = self
79
+ end
80
+ end
81
+
82
+ def parent_attribute_name
83
+ return @parent_attribute_name if defined?(@parent_attribute_name)
84
+ parent.find_index(self) if parent&.is_a?(Array)
85
+ end
86
+
87
+ def in_model=(model)
88
+ @in_model = model unless is_a?(Model)
89
+ struct_instance_variables.each { |attrname|
90
+ puts "#{attrname} is frozen in #{self.class}" if self[attrname].frozen? && self[attrname].is_a?(Array)
91
+ self[attrname].in_model = model }
92
+ end
93
+
94
+ def build_index(hash_index = {})
95
+ hash_index[id] = self unless id.nil?
96
+ struct_instance_variables.reduce(hash_index) do |a, e|
97
+ self[e].parent_attribute_name = e
98
+ self[e].build_index(a)
99
+ end
100
+ end
101
+
102
+ def diff(other)
103
+ raise ArgumentError, "other expected to be not nil" if other.nil?
104
+ raise TypeError, "Expected other <#{other.class} to be of type #{self.class}" unless other.is_a?(self.class)
105
+ struct_instance_variables.each_with_object([]) do |k, a|
106
+ val = self[k]
107
+ if val.nil?
108
+ a.concat([Diff::Insert.new(Diff::ArchimateNodeAttributeReference.new(other, k))]) unless other[k].nil?
109
+ elsif val.primitive?
110
+ a.concat(val.diff(other[k], self, other, k))
111
+ else
112
+ a.concat(val.diff(other[k]))
113
+ end
114
+ end
115
+ end
116
+
117
+ def path(options = {})
118
+ [
119
+ parent&.path(options),
120
+ path_identifier
121
+ ].compact.map(&:to_s).reject(&:empty?).join("/")
122
+ end
123
+
124
+ def compact!
125
+ struct_instance_variables.each { |attrname| self[attrname].compact! }
126
+ self
127
+ end
128
+
129
+ def delete(attrname)
130
+ if !attrname || attrname.empty?
131
+ raise(
132
+ ArgumentError,
133
+ "attrname was blank must be one of: #{struct_instance_variables.map(&:to_s).join(',')}"
134
+ )
135
+ end
136
+ in_model&.deregister(self[attrname])
137
+ instance_variable_set("@#{attrname}".to_sym, nil)
138
+ self
139
+ end
140
+
141
+ def set(attrname, value)
142
+ if !attrname
143
+ raise(
144
+ ArgumentError,
145
+ "attrname was blank must be one of: #{struct_instance_variables.map(&:to_s).join(',')}"
146
+ )
147
+ end # || attrname.empty?
148
+ # value = value.clone
149
+ in_model&.register(value, self)
150
+ instance_variable_set("@#{attrname}".to_sym, value)
151
+ self
152
+ end
153
+
154
+ def referenced_identified_nodes
155
+ struct_instance_variables.reduce([]) do |a, e|
156
+ a.concat(self[e].referenced_identified_nodes)
157
+ end
158
+ end
159
+
160
+ def element_by_id(element_id)
161
+ return nil unless element_id
162
+ in_model&.lookup(element_id)
163
+ end
164
+
165
+ private
166
+
167
+ def path_identifier
168
+ case parent
169
+ when Array
170
+ find_my_index
171
+ else
172
+ parent_attribute_name
173
+ end
174
+ end
175
+
176
+ def find_my_index
177
+ parent.find_index(self)
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+ module Archimate
3
+ module DataModel
4
+ class Bounds < ArchimateNode
5
+ attribute :x, Coercible::Float.optional
6
+ attribute :y, Coercible::Float.optional
7
+ attribute :width, Coercible::Float
8
+ attribute :height, Coercible::Float
9
+
10
+ def self.zero
11
+ Archimate::DataModel::Bounds.new(x: 0, y: 0, width: 0, height: 0)
12
+ end
13
+
14
+ def to_s
15
+ "Bounds(x: #{x}, y: #{y}, width: #{width}, height: #{height})"
16
+ end
17
+
18
+ def x_range
19
+ Range.new(left, right)
20
+ end
21
+
22
+ def y_range
23
+ Range.new(top, bottom)
24
+ end
25
+
26
+ def top
27
+ y || 0
28
+ end
29
+
30
+ def bottom
31
+ top + height
32
+ end
33
+
34
+ def right
35
+ left + width
36
+ end
37
+
38
+ def left
39
+ x || 0
40
+ end
41
+
42
+ def is_above?(other)
43
+ bottom < other.top
44
+ end
45
+
46
+ def is_below?(other)
47
+ top > other.bottom
48
+ end
49
+
50
+ def is_right_of?(other)
51
+ left > other.right
52
+ end
53
+
54
+ def is_left_of?(other)
55
+ right < other.left
56
+ end
57
+
58
+ def reduced_by(val)
59
+ Bounds.new(x: left + val, y: top + val, width: width - val * 2, height: height - val * 2)
60
+ end
61
+
62
+ def inside?(other)
63
+ left > other.left &&
64
+ right < other.right &&
65
+ top > other.top &&
66
+ bottom < other.bottom
67
+ end
68
+ end
69
+
70
+ Dry::Types.register_class(Bounds)
71
+ end
72
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ module Archimate
3
+ module DataModel
4
+ # RGBColorType in the XSD
5
+ # RGB Color type.
6
+ # The r, g, b attributes range from 0 - 255.
7
+ # The a (alpha) transparency attribute is optional. 0 = full transparency, 100 = opaque.
8
+ class Color < ArchimateNode
9
+ attribute :r, Coercible::Int.constrained(lt: 256, gt: -1)
10
+ attribute :g, Coercible::Int.constrained(lt: 256, gt: -1)
11
+ attribute :b, Coercible::Int.constrained(lt: 256, gt: -1)
12
+ attribute :a, Coercible::Int.constrained(lt: 101, gt: -1).optional
13
+
14
+ def self.rgba(str)
15
+ return nil if str.nil?
16
+ md = str.match(/#([\da-f]{2})([\da-f]{2})([\da-f]{2})([\da-f]{2})?/)
17
+ return nil unless md
18
+ new(
19
+ r: md[1].to_i(16),
20
+ g: md[2].to_i(16),
21
+ b: md[3].to_i(16),
22
+ a: md[4].nil? ? 100 : (md[4].to_i(16) / 256.0 * 100.0).to_i
23
+ )
24
+ end
25
+
26
+ def self.black
27
+ new(r: 0, g: 0, b: 0, a: 100)
28
+ end
29
+
30
+ def to_s
31
+ "Color(r: #{r}, g: #{g}, b: #{b}, a: #{a})"
32
+ end
33
+
34
+ def to_rgba
35
+ a == 100 ? format("#%02x%02x%02x", r, g, b) : format("#%02x%02x%02x%02x", r, g, b, scaled_alpha)
36
+ end
37
+
38
+ private
39
+
40
+ def scaled_alpha(max = 255)
41
+ (max * (a / 100.0)).round
42
+ end
43
+ end
44
+
45
+ Dry::Types.register_class(Color)
46
+ end
47
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ # This is an abstract class for Concepts (Elements, Relationships, Composites, and RelationConnectors).
6
+ class Concept < Referenceable
7
+ attribute :properties, PropertiesList
8
+ # group -> ConceptGroup # Empty. Available for Extension purposes.
9
+ # attributeGroup -> ConceptAttributeGroup # Empty. Available for Extension purposes.
10
+ end
11
+
12
+ Dry::Types.register_class(Concept)
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ # document attribute holds all the concern information.
6
+ #
7
+ # This is ConcernType in the XSD
8
+ class Concern < ArchimateNode
9
+ attribute :labels, Strict::Array.member(LangString).constrained(min_size: 1)
10
+ attribute :documentation, DocumentationGroup
11
+ attribute :stakeholders, Strict::Array.member(LangString)
12
+ end
13
+
14
+ Dry::Types.register_class(Concern)
15
+ ConcernList = Strict::Array.member(Concern).default([])
16
+ end
17
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ # Graphical connection type.
6
+ #
7
+ # If the 'relationshipRef' attribute is present, the connection should reference an existing ArchiMate relationship.
8
+ #
9
+ # If the connection is an ArchiMate relationship type, the connection's label, documentation and properties may be determined
10
+ # (i.e inherited) from those in the referenced ArchiMate relationship. Otherwise the connection's label, documentation and properties
11
+ # can be provided and will be additional to (or over-ride) those contained in the referenced ArchiMate relationship.
12
+ #
13
+ # This is ConnectionType in the XSD
14
+ # ViewConceptType > ConnectionType > SourcedConnectionType > Relationship > NestingRelationship
15
+ # > Line
16
+ # > ViewNodeType >
17
+ # Label
18
+ # Container > Element
19
+ class Connection < Referenceable # ViewConcept
20
+ using DiffableArray
21
+
22
+ attribute :source_attachment, Location.optional
23
+ attribute :bendpoints, LocationList
24
+ attribute :target_attachment, Location.optional
25
+ attribute :source, Identifier.optional
26
+ attribute :target, Identifier.optional
27
+ attribute :type, Strict::String.optional
28
+
29
+ # This is under Relationship
30
+ attribute :relationship, Strict::String.optional
31
+
32
+ # Note: this is added under ViewConcept
33
+ attribute :style, Style.optional
34
+ attribute :properties, PropertiesList
35
+
36
+ def replace(entity, with_entity)
37
+ @relationship = with_entity.id if (relationship == entity.id)
38
+ @source = with_entity.id if (source == entity.id)
39
+ @target = with_entity.id if (target == entity.id)
40
+ end
41
+
42
+ def type_name
43
+ Archimate::Color.color("#{Archimate::Color.data_model('Connection')}[#{Archimate::Color.color(@name || '', [:white, :underline])}]", :on_light_magenta)
44
+ end
45
+
46
+ def relationship_element
47
+ in_model.lookup(relationship)
48
+ end
49
+
50
+ def element
51
+ relationship_element
52
+ end
53
+
54
+ def source_element
55
+ in_model.lookup(source)
56
+ end
57
+
58
+ def target_element
59
+ in_model.lookup(target)
60
+ end
61
+
62
+ def to_s
63
+ if in_model
64
+ s = in_model.lookup(source) unless source.nil?
65
+ t = in_model.lookup(target) unless target.nil?
66
+ else
67
+ s = source
68
+ t = target
69
+ end
70
+ "#{type_name} #{s.nil? ? 'nothing' : s} -> #{t.nil? ? 'nothing' : t}"
71
+ end
72
+
73
+ def description
74
+ [
75
+ name.nil? ? nil : "#{name}: ",
76
+ source_element&.description,
77
+ relationship_element&.description,
78
+ target_element&.description
79
+ ].compact.join(" ")
80
+ end
81
+
82
+ def referenced_identified_nodes
83
+ [@source, @target, @relationship].compact
84
+ end
85
+
86
+ # This is used when rendering a connection to connection relationship.
87
+ def nodes
88
+ []
89
+ end
90
+
91
+ # TODO: Is this true for all or only Archi models?
92
+ def absolute_position
93
+ # offset = bounds || Archimate::DataModel::Bounds.zero
94
+ offset = Archimate::DataModel::Bounds.zero
95
+ el = parent.parent
96
+ while el.respond_to?(:bounds) && el.bounds
97
+ bounds = el.bounds
98
+ offset = offset.with(x: (offset.x || 0) + (bounds.x || 0), y: (offset.y || 0) + (bounds.y || 0))
99
+ el = el.parent.parent
100
+ end
101
+ offset
102
+ end
103
+ end
104
+ Dry::Types.register_class(Connection)
105
+ ConnectionList = Strict::Array.member("archimate.data_model.connection").default([])
106
+ end
107
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+ module Archimate
3
+ module DataModel
4
+ # The Constants module contains constants for ArchiMate standards
5
+ # TODO: This should be namespaced for the ArchiMate version in effect
6
+ module Constants
7
+ ELEMENTS = %w(BusinessActor BusinessCollaboration BusinessEvent BusinessFunction
8
+ BusinessInteraction BusinessInterface BusinessObject BusinessProcess
9
+ BusinessRole BusinessService Contract Location Meaning Value Product
10
+ Representation ApplicationCollaboration ApplicationComponent
11
+ ApplicationFunction ApplicationInteraction ApplicationInterface
12
+ ApplicationService DataObject Artifact CommunicationPath Device
13
+ InfrastructureFunction InfrastructureInterface InfrastructureService
14
+ Network Node SystemSoftware Assessment Constraint Driver Goal Principle
15
+ Requirement Stakeholder Deliverable Gap Plateau WorkPackage AndJunction
16
+ Junction OrJunction Capability CourseOfAction Resource
17
+ ApplicationProcess ApplicationEvent TechnologyCollaboration
18
+ TechnologyInterface Path CommunicationNetwork
19
+ TechnologyFunction TechnologyProcess TechnologyInteraction
20
+ TechnologyEvent TechnologyService
21
+ TechnologyObject Equipment Facility DistributionNetwork Material
22
+ Outcome ImplementationEvent).freeze
23
+
24
+ RELATIONSHIPS = %w(AssociationRelationship AccessRelationship UsedByRelationship
25
+ RealisationRelationship AssignmentRelationship AggregationRelationship
26
+ CompositionRelationship FlowRelationship TriggeringRelationship
27
+ GroupingRelationship SpecialisationRelationship InfluenceRelationship).freeze
28
+
29
+ LAYER_ELEMENTS = {
30
+ "Strategy" =>
31
+ %w(Capability CourseOfAction Resource),
32
+ "Business" =>
33
+ %w(BusinessActor BusinessCollaboration
34
+ BusinessEvent BusinessFunction
35
+ BusinessInteraction BusinessInterface
36
+ BusinessObject BusinessProcess
37
+ BusinessRole BusinessService
38
+ Contract Location
39
+ Meaning Value
40
+ Product Representation),
41
+ "Application" =>
42
+ %w(ApplicationCollaboration ApplicationComponent
43
+ ApplicationFunction ApplicationInteraction
44
+ ApplicationInterface ApplicationService
45
+ DataObject ApplicationProcess ApplicationEvent),
46
+ "Technology" =>
47
+ %w(Artifact CommunicationPath
48
+ Device InfrastructureFunction
49
+ InfrastructureInterface InfrastructureService
50
+ Network Node SystemSoftware TechnologyCollaboration
51
+ TechnologyInterface Path CommunicationNetwork
52
+ TechnologyFunction TechnologyProcess TechnologyInteraction
53
+ TechnologyEvent TechnologyService
54
+ TechnologyObject),
55
+ "Physical" =>
56
+ %w(Equipment Facility DistributionNetwork Material),
57
+ "Motivation" =>
58
+ %w(Assessment Constraint Driver
59
+ Goal Principle Requirement
60
+ Stakeholder Outcome),
61
+ "Implementation and Migration" =>
62
+ %w(Deliverable Gap Plateau
63
+ WorkPackage ImplementationEvent),
64
+ "Connectors" =>
65
+ %w(AndJunction Junction OrJunction)
66
+ }.freeze
67
+
68
+ ELEMENT_LAYER = LAYER_ELEMENTS.each_with_object({}) do |(layer, elements), el_layer_hash|
69
+ elements.each_with_object(el_layer_hash) { |element, a| a[element] = layer }
70
+ end
71
+
72
+ VIEWPOINTS = ["Total", "Actor Co-operation", "Application Behaviour",
73
+ "Application Co-operation", "Application Structure", "Application Usage",
74
+ "Business Function", "Business Process Co-operation", "Business Process",
75
+ "Business Product", "Implementation and Deployment", "Information Structure",
76
+ "Infrastructure Usage", "Infrastructure", "Layered", "Organisation",
77
+ "Service Realization", "Stakeholder", "Goal Realization", "Goal Contribution",
78
+ "Principles", "Requirements Realisation", "Motivation", "Project",
79
+ "Migration", "Implementation and Migration"].freeze
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ # Node type to allow a Container in a Artifact. This is a visual grouping container.
6
+ class Container < ViewNode
7
+ # This is to support Nested Nodes on the Diagram
8
+ # The order of sibling nodes in their parent View or Node container as declared in the model
9
+ # instance dictates the z-order of the nodes. Given nodes A, B, and C as declared in that order,
10
+ # node B is considered to be in front of node A, node C is considered to be in front of node B, and
11
+ # node C is considered to be in front of nodes A and B.
12
+ attribute :nodes, Strict::Array.member(ViewNode)
13
+ end
14
+
15
+ Dry::Types.register_class(Container)
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ module Archimate
3
+ module DataModel
4
+ class Diagram < View
5
+ attribute :nodes, Strict::Array.member(ViewNode).default([])
6
+ attribute :connection_router_type, Coercible::Int.optional # TODO: Archi formats only fill this in, should be an enum
7
+ attribute :background, Coercible::Int.optional # value of 0 on Archi Sketch Model
8
+ attribute :connections, Strict::Array.member(Connection).default([])
9
+
10
+ def all_nodes
11
+ nodes.inject(Array.new(nodes)) { |child_ary, child| child_ary.concat(child.all_nodes) }
12
+ end
13
+
14
+ def elements
15
+ @elements ||= all_nodes.map(&:element).compact
16
+ end
17
+
18
+ def element_ids
19
+ @element_ids ||= all_nodes.map(&:archimate_element).compact
20
+ end
21
+
22
+ def relationships
23
+ @relationships ||= connections.map(&:element).compact
24
+ end
25
+
26
+ def relationship_ids
27
+ @relationship_ids ||= connections.map(&:relationship).compact
28
+ end
29
+
30
+ def to_s
31
+ "#{Archimate::Color.data_model('Diagram')}<#{id}>[#{Archimate::Color.color(name, [:white, :underline])}]"
32
+ end
33
+
34
+ def total_viewpoint?
35
+ viewpoint_type.nil? || viewpoint_type.empty?
36
+ end
37
+ end
38
+ Dry::Types.register_class(Diagram)
39
+ end
40
+ end