archimate 1.2.1 → 2.0.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 (182) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +47 -0
  3. data/TODOs.org +219 -0
  4. data/archimate.gemspec +2 -1
  5. data/exe/archidiff +7 -0
  6. data/exe/archidiff-summary +7 -0
  7. data/exe/archimerge +7 -0
  8. data/exe/fmtxml +7 -0
  9. data/lib/archimate.rb +10 -21
  10. data/lib/archimate/cli/archi.rb +2 -1
  11. data/lib/archimate/cli/cleanup.rb +8 -9
  12. data/lib/archimate/cli/convert.rb +3 -1
  13. data/lib/archimate/cli/mapper.rb +1 -1
  14. data/lib/archimate/cli/stats.rb +1 -1
  15. data/lib/archimate/config.rb +4 -1
  16. data/lib/archimate/data_model.rb +11 -24
  17. data/lib/archimate/data_model/any_attribute.rb +18 -5
  18. data/lib/archimate/data_model/any_element.rb +30 -7
  19. data/lib/archimate/data_model/bounds.rb +34 -7
  20. data/lib/archimate/data_model/color.rb +32 -7
  21. data/lib/archimate/data_model/comparison.rb +87 -0
  22. data/lib/archimate/data_model/concern.rb +20 -7
  23. data/lib/archimate/data_model/connection.rb +71 -51
  24. data/lib/archimate/data_model/connector_type.rb +23 -0
  25. data/lib/archimate/data_model/diagram.rb +72 -10
  26. data/lib/archimate/data_model/diagram_type.rb +17 -0
  27. data/lib/archimate/data_model/differentiable.rb +142 -0
  28. data/lib/archimate/data_model/element.rb +39 -45
  29. data/lib/archimate/data_model/element_type.rb +89 -0
  30. data/lib/archimate/data_model/font.rb +30 -12
  31. data/lib/archimate/data_model/lang_string.rb +89 -16
  32. data/lib/archimate/data_model/layer.rb +55 -0
  33. data/lib/archimate/data_model/layers.rb +62 -0
  34. data/lib/archimate/data_model/location.rb +27 -11
  35. data/lib/archimate/data_model/metadata.rb +10 -3
  36. data/lib/archimate/data_model/model.rb +188 -121
  37. data/lib/archimate/data_model/modeling_note.rb +14 -3
  38. data/lib/archimate/data_model/organization.rb +44 -13
  39. data/lib/archimate/data_model/{documentation.rb → preserved_lang_string.rb} +1 -5
  40. data/lib/archimate/data_model/property.rb +17 -11
  41. data/lib/archimate/data_model/property_definition.rb +34 -4
  42. data/lib/archimate/data_model/referenceable.rb +0 -9
  43. data/lib/archimate/data_model/referenceable_collection.rb +201 -0
  44. data/lib/archimate/data_model/relationship.rb +52 -33
  45. data/lib/archimate/data_model/relationship_type.rb +43 -0
  46. data/lib/archimate/data_model/schema_info.rb +17 -6
  47. data/lib/archimate/data_model/style.rb +41 -11
  48. data/lib/archimate/data_model/view_node.rb +153 -59
  49. data/lib/archimate/data_model/viewpoint.rb +56 -80
  50. data/lib/archimate/data_model/viewpoint_type.rb +429 -0
  51. data/lib/archimate/export/csv_export.rb +2 -2
  52. data/lib/archimate/export/cypher.rb +2 -2
  53. data/lib/archimate/export/graph_ml.rb +7 -5
  54. data/lib/archimate/export/jsonl.rb +166 -0
  55. data/lib/archimate/export/n_quads.rb +8 -5
  56. data/lib/archimate/file_format.rb +4 -5
  57. data/lib/archimate/file_formats/archi_file_reader.rb +7 -240
  58. data/lib/archimate/file_formats/archi_file_writer.rb +16 -188
  59. data/lib/archimate/file_formats/model_exchange_file_reader.rb +7 -225
  60. data/lib/archimate/file_formats/model_exchange_file_writer_21.rb +22 -114
  61. data/lib/archimate/file_formats/model_exchange_file_writer_30.rb +22 -122
  62. data/lib/archimate/file_formats/sax.rb +55 -0
  63. data/lib/archimate/file_formats/sax/any_element.rb +64 -0
  64. data/lib/archimate/file_formats/sax/archi/archi_handler_factory.rb +48 -0
  65. data/lib/archimate/file_formats/sax/archi/bounds.rb +25 -0
  66. data/lib/archimate/file_formats/sax/archi/connection.rb +47 -0
  67. data/lib/archimate/file_formats/sax/archi/content.rb +28 -0
  68. data/lib/archimate/file_formats/sax/archi/diagram.rb +66 -0
  69. data/lib/archimate/file_formats/sax/archi/element.rb +36 -0
  70. data/lib/archimate/file_formats/sax/archi/location.rb +25 -0
  71. data/lib/archimate/file_formats/sax/archi/model.rb +109 -0
  72. data/lib/archimate/file_formats/sax/archi/organization.rb +60 -0
  73. data/lib/archimate/file_formats/sax/archi/property.rb +54 -0
  74. data/lib/archimate/file_formats/sax/archi/relationship.rb +50 -0
  75. data/lib/archimate/file_formats/sax/archi/style.rb +35 -0
  76. data/lib/archimate/file_formats/sax/archi/view_node.rb +76 -0
  77. data/lib/archimate/file_formats/sax/capture_content.rb +20 -0
  78. data/lib/archimate/file_formats/sax/capture_documentation.rb +19 -0
  79. data/lib/archimate/file_formats/sax/capture_properties.rb +20 -0
  80. data/lib/archimate/file_formats/sax/content_element.rb +19 -0
  81. data/lib/archimate/file_formats/sax/document.rb +80 -0
  82. data/lib/archimate/file_formats/sax/handler.rb +54 -0
  83. data/lib/archimate/file_formats/sax/lang_string.rb +28 -0
  84. data/lib/archimate/file_formats/sax/model_exchange_file/color.rb +36 -0
  85. data/lib/archimate/file_formats/sax/model_exchange_file/connection.rb +67 -0
  86. data/lib/archimate/file_formats/sax/model_exchange_file/diagram.rb +60 -0
  87. data/lib/archimate/file_formats/sax/model_exchange_file/element.rb +43 -0
  88. data/lib/archimate/file_formats/sax/model_exchange_file/font.rb +44 -0
  89. data/lib/archimate/file_formats/sax/model_exchange_file/item.rb +64 -0
  90. data/lib/archimate/file_formats/sax/model_exchange_file/location.rb +23 -0
  91. data/lib/archimate/file_formats/sax/model_exchange_file/metadata.rb +66 -0
  92. data/lib/archimate/file_formats/sax/model_exchange_file/model.rb +124 -0
  93. data/lib/archimate/file_formats/sax/model_exchange_file/model_exchange_handler_factory.rb +53 -0
  94. data/lib/archimate/file_formats/sax/model_exchange_file/property.rb +32 -0
  95. data/lib/archimate/file_formats/sax/model_exchange_file/property_definition.rb +36 -0
  96. data/lib/archimate/file_formats/sax/model_exchange_file/relationship.rb +49 -0
  97. data/lib/archimate/file_formats/sax/model_exchange_file/schema_info.rb +47 -0
  98. data/lib/archimate/file_formats/sax/model_exchange_file/style.rb +66 -0
  99. data/lib/archimate/file_formats/sax/model_exchange_file/view_node.rb +86 -0
  100. data/lib/archimate/file_formats/sax/no_op.rb +17 -0
  101. data/lib/archimate/file_formats/sax/preserved_lang_string.rb +28 -0
  102. data/lib/archimate/file_formats/serializer.rb +57 -0
  103. data/lib/archimate/file_formats/serializer/archi/bounds.rb +23 -0
  104. data/lib/archimate/file_formats/serializer/archi/connection.rb +33 -0
  105. data/lib/archimate/file_formats/serializer/archi/diagram.rb +28 -0
  106. data/lib/archimate/file_formats/serializer/archi/documentation.rb +16 -0
  107. data/lib/archimate/file_formats/serializer/archi/element.rb +24 -0
  108. data/lib/archimate/file_formats/serializer/archi/location.rb +26 -0
  109. data/lib/archimate/file_formats/serializer/archi/model.rb +25 -0
  110. data/lib/archimate/file_formats/serializer/archi/organization.rb +21 -0
  111. data/lib/archimate/file_formats/serializer/archi/property.rb +15 -0
  112. data/lib/archimate/file_formats/serializer/archi/relationship.rb +36 -0
  113. data/lib/archimate/file_formats/serializer/archi/view_node.rb +52 -0
  114. data/lib/archimate/file_formats/serializer/archi/viewpoint_type.rb +45 -0
  115. data/lib/archimate/file_formats/serializer/model_exchange_file/element.rb +25 -0
  116. data/lib/archimate/file_formats/serializer/model_exchange_file/location.rb +15 -0
  117. data/lib/archimate/file_formats/serializer/model_exchange_file/model_exchange_file_writer.rb +32 -0
  118. data/lib/archimate/file_formats/serializer/model_exchange_file/organization.rb +23 -0
  119. data/lib/archimate/file_formats/serializer/model_exchange_file/properties.rb +15 -0
  120. data/lib/archimate/file_formats/serializer/model_exchange_file/relationship.rb +19 -0
  121. data/lib/archimate/file_formats/serializer/model_exchange_file/style.rb +48 -0
  122. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/connection.rb +25 -0
  123. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/diagram.rb +27 -0
  124. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/item.rb +17 -0
  125. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/label.rb +17 -0
  126. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/model.rb +36 -0
  127. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/organization_body.rb +25 -0
  128. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/property.rb +19 -0
  129. data/lib/archimate/file_formats/serializer/model_exchange_file/v21/view_node.rb +44 -0
  130. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/connection.rb +26 -0
  131. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/diagram.rb +27 -0
  132. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/item.rb +17 -0
  133. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/label.rb +17 -0
  134. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/model.rb +41 -0
  135. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/organization_body.rb +25 -0
  136. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/property.rb +19 -0
  137. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/property_definitions.rb +34 -0
  138. data/lib/archimate/file_formats/serializer/model_exchange_file/v30/view_node.rb +45 -0
  139. data/lib/archimate/file_formats/serializer/named_collection.rb +21 -0
  140. data/lib/archimate/file_formats/serializer/writer.rb +56 -0
  141. data/lib/archimate/file_formats/serializer/xml_lang_string.rb +30 -0
  142. data/lib/archimate/file_formats/serializer/xml_metadata.rb +64 -0
  143. data/lib/archimate/file_formats/{model_exchange_file → serializer}/xml_property_defs.rb +2 -2
  144. data/lib/archimate/lint/duplicate_entities.rb +3 -3
  145. data/lib/archimate/lint/linter.rb +24 -29
  146. data/lib/archimate/svg/connection.rb +13 -103
  147. data/lib/archimate/svg/diagram.rb +1 -1
  148. data/lib/archimate/svg/entity/base_entity.rb +12 -8
  149. data/lib/archimate/svg/entity/data_entity.rb +2 -2
  150. data/lib/archimate/svg/entity/diagram_model_reference.rb +1 -1
  151. data/lib/archimate/svg/entity/event_entity.rb +2 -2
  152. data/lib/archimate/svg/entity/gap.rb +1 -1
  153. data/lib/archimate/svg/entity/group.rb +1 -1
  154. data/lib/archimate/svg/entity/motivation_entity.rb +1 -1
  155. data/lib/archimate/svg/entity/node.rb +1 -1
  156. data/lib/archimate/svg/entity/rect_entity.rb +1 -1
  157. data/lib/archimate/svg/entity/rounded_rect_entity.rb +1 -1
  158. data/lib/archimate/svg/entity/service_entity.rb +2 -2
  159. data/lib/archimate/svg/entity/value.rb +2 -2
  160. data/lib/archimate/svg/path.rb +153 -0
  161. data/lib/archimate/svg/point.rb +8 -1
  162. data/lib/archimate/version.rb +1 -1
  163. metadata +118 -36
  164. data/lib/archimate/data_model/archimate_node.rb +0 -181
  165. data/lib/archimate/data_model/concept.rb +0 -14
  166. data/lib/archimate/data_model/constants.rb +0 -82
  167. data/lib/archimate/data_model/container.rb +0 -17
  168. data/lib/archimate/data_model/diffable_array.rb +0 -213
  169. data/lib/archimate/data_model/diffable_primitive.rb +0 -83
  170. data/lib/archimate/data_model/label.rb +0 -19
  171. data/lib/archimate/data_model/named_referenceable.rb +0 -14
  172. data/lib/archimate/data_model/view.rb +0 -12
  173. data/lib/archimate/data_model/view_concept.rb +0 -18
  174. data/lib/archimate/file_formats/archi_file_format.rb +0 -151
  175. data/lib/archimate/file_formats/archimate_v2.rb +0 -461
  176. data/lib/archimate/file_formats/model_exchange_file/xml_lang_string.rb +0 -35
  177. data/lib/archimate/file_formats/model_exchange_file/xml_metadata.rb +0 -115
  178. data/lib/archimate/file_formats/model_exchange_file/xml_property_definitions.rb +0 -28
  179. data/lib/archimate/file_formats/model_exchange_file_reader_21.rb +0 -73
  180. data/lib/archimate/file_formats/model_exchange_file_reader_30.rb +0 -134
  181. data/lib/archimate/file_formats/model_exchange_file_writer.rb +0 -157
  182. data/lib/archimate/file_formats/writer.rb +0 -56
@@ -2,13 +2,9 @@
2
2
 
3
3
  module Archimate
4
4
  module DataModel
5
- # An element that holds documentation.
6
5
  # A base string type for multi-language strings that preserves whitespace.
7
6
  # PreservedLangStringType in ArchiMate 3 schema
8
- class Documentation < LangString
7
+ class PreservedLangString < LangString
9
8
  end
10
-
11
- Dry::Types.register_class(Documentation)
12
- DocumentationGroup = Strict::Array.member(Documentation).default([])
13
9
  end
14
10
  end
@@ -1,10 +1,23 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Archimate
3
4
  module DataModel
4
- # A Property instance type declaring the reference to a Property definition and containing the Property value.
5
- class Property < ArchimateNode
6
- attribute :values, Strict::Array.member(LangString).default([]) # .constrained(min_size: 1)
7
- attribute :property_definition, PropertyDefinition
5
+ # A Property instance type declaring the reference to a [PropertyDefinition]
6
+ # and containing the property value.
7
+ class Property
8
+ include Comparison
9
+
10
+ # @!attribute [r] value
11
+ # @return [LangString, NilClass] value of the property, default +nil+
12
+ model_attr :value
13
+ # @!attribute [rw] property_definition
14
+ # @return [PropertyDefinition] property definition of the property
15
+ model_attr :property_definition, writable: true
16
+
17
+ def initialize(property_definition:, value: nil)
18
+ @property_definition = property_definition
19
+ @value = value
20
+ end
8
21
 
9
22
  def to_s
10
23
  "Property(key: #{property_definition.name}, value: #{value || 'no value'})"
@@ -13,13 +26,6 @@ module Archimate
13
26
  def key
14
27
  property_definition.name
15
28
  end
16
-
17
- def value
18
- values.first
19
- end
20
29
  end
21
-
22
- Dry::Types.register_class(Property)
23
- PropertiesList = Strict::Array.member(Property).default([])
24
30
  end
25
31
  end
@@ -2,15 +2,45 @@
2
2
 
3
3
  module Archimate
4
4
  module DataModel
5
+ # An enumeration of data types.
6
+ # @todo consider making this an enumeration
7
+ PROPERTY_DEFINITION_TYPES = %w[string boolean currency date time number].freeze
8
+
5
9
  # A Property definition type containing its unique identifier, name, and data type.
6
- class PropertyDefinition < NamedReferenceable
7
- attribute :value_type, DataType
10
+ class PropertyDefinition
11
+ include Comparison
12
+
13
+ # @!attribute [r] id
14
+ # @return [String]
15
+ model_attr :id
16
+ # @!attribute [r] name
17
+ # @return [LangString]
18
+ model_attr :name
19
+ # @!attribute [r] documentation
20
+ # @return [PreservedLangString, NilClass]
21
+ model_attr :documentation
22
+ # # @!attribute [r] other_elements
23
+ # @return [Array<AnyElement>]
24
+ model_attr :other_elements
25
+ # # @!attribute [r] other_attributes
26
+ # @return [Array<AnyAttribute>]
27
+ model_attr :other_attributes
28
+ # @!attribute [r] type
29
+ # @note if +type+ is nil, then type "string" is assumed
30
+ # @see Archimate::DataModel::PROPERTY_DEFINITION_TYPES
31
+ # @return [String, NilClass]
32
+ model_attr :type
8
33
 
9
34
  def self.identifier_for_key(key)
10
35
  (self.class.hash ^ key.hash).to_s(16)
11
36
  end
12
- end
13
37
 
14
- Dry::Types.register_class(PropertyDefinition)
38
+ def initialize(id:, name:, documentation: nil, type: nil)
39
+ @id = id
40
+ @name = name
41
+ @documentation = documentation
42
+ @type = type
43
+ end
44
+ end
15
45
  end
16
46
  end
@@ -4,15 +4,6 @@ module Archimate
4
4
  module DataModel
5
5
  # Something that can be referenced in the model.
6
6
  class Referenceable < ArchimateNode
7
- attribute :id, Identifier
8
- attribute :name, LangString.optional # TODO: Strict::Array.member(LangString).constrained(min_size: 1)
9
-
10
- attribute :documentation, DocumentationGroup
11
- # attribute :grp_any, Strict::Array.member(AnyNode).default([])
12
- # attribute :other_attributes, Strict::Array.member(AnyAttribute).default([])
13
- # attribute :properties, PropertiesList # Note: Referenceable doesn't have properties in the spec
14
- attribute :type, Strict::String.optional # Note: type here was used for the Element/Relationship/Diagram type
15
-
16
7
  private
17
8
 
18
9
  def find_my_index
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+ module Archimate
3
+ module DataModel
4
+ # This class represents a collection of referenceable objects (i.e. have an `id`)
5
+ class ReferenceableCollection
6
+ attr_writer :parent_attribute_name
7
+
8
+ def in_model
9
+ @in_model if defined?(@in_model)
10
+ end
11
+
12
+ def parent
13
+ @parent if defined?(@parent)
14
+ end
15
+
16
+ def id
17
+ object_id.to_s
18
+ end
19
+
20
+ def primitive?
21
+ false
22
+ end
23
+
24
+ def diff(other)
25
+ raise TypeError, "Expected other #{other.class} to be of type #{self.class}" unless other.is_a?(self.class)
26
+ raise "Well Hell other #{other.path} in_model is nil" if other.in_model.nil?
27
+ raise "Well Hell my path `#{path}` in_model is nil" if in_model.nil?
28
+
29
+ result = []
30
+ remaining_content = Array.new(self) # @todo I want a copy of the array, not a deep clone
31
+ other_enum = other.each_with_index
32
+
33
+ loop do
34
+ if other_enum.peek[0] == remaining_content[0]
35
+ other_enum.next
36
+ remaining_content.shift
37
+ elsif items_are_changed?(other, other_enum, remaining_content)
38
+ result.concat(compute_item_changes(other, other_enum, self, remaining_content[0]))
39
+ remaining_content.shift
40
+ other_enum.next
41
+ elsif !remaining_content.empty? && !other.smart_include?(remaining_content[0])
42
+ result << Diff::Delete.new(Diff::ArchimateArrayReference.new(self, smart_find(remaining_content[0])))
43
+ remaining_content.shift
44
+ elsif !smart_include?(other_enum.peek[0])
45
+ result << Diff::Insert.new(Diff::ArchimateArrayReference.new(other, other_enum.next[1]))
46
+ elsif smart_include?(other_enum.peek[0])
47
+ result << Diff::Move.new(
48
+ Diff::ArchimateArrayReference.new(other, other_enum.peek[1]),
49
+ Diff::ArchimateArrayReference.new(self, smart_find(other_enum.peek[0]))
50
+ )
51
+ remaining_item_idx = remaining_content.smart_find(other_enum.peek[0])
52
+ if remaining_item_idx
53
+ result.concat(compute_item_changes(other, other_enum, self, remaining_content[remaining_item_idx]))
54
+ remaining_content.delete_at(remaining_item_idx) if remaining_content.smart_include?(other_enum.peek[0])
55
+ end
56
+ other_enum.next
57
+ else
58
+ raise "Unhandled diff case for remaining_content: #{remaining_content[0]} and #{other_enum.peek[0]}"
59
+ end
60
+ end
61
+
62
+ result.concat(
63
+ remaining_content
64
+ .reject { |item| other.include?(item) }
65
+ .map do |item|
66
+ Diff::Delete.new(Diff::ArchimateArrayReference.new(self, find_index(item)))
67
+ end
68
+ )
69
+ end
70
+
71
+ # @todo This may not continue to live here. Only used by testing.
72
+ def patch(diffs)
73
+ # @todo Beware, order of diffs could break patching at the moment.
74
+ Array(diffs).each do |diff|
75
+ case diff
76
+ when Diff::Delete
77
+ delete_at(smart_find(diff.target.value))
78
+ when Diff::Insert
79
+ insert(diff.target.array_index, diff.target.value)
80
+ when Diff::Change
81
+ self[smart_find(diff.changed_from.value)] = diff.target.value
82
+ when Diff::Move
83
+ insert(diff.target.array_index, delete_at(smart_find(diff.target.value)))
84
+ else
85
+ raise "Unexpected diff type: #{diff.class}"
86
+ end
87
+ end
88
+ self
89
+ end
90
+
91
+ def items_are_changed?(other, other_enum, remaining)
92
+ !remaining.empty? &&
93
+ case remaining[0]
94
+ when DataModel::Referenceable
95
+ remaining[0].id == other_enum.peek[0].id
96
+ when String, DataModel::ArchimateNode
97
+ !other.include?(remaining[0]) && !include?(other_enum.peek[0])
98
+ else
99
+ raise "Unhandled type for #{remaining[0].class}"
100
+ end
101
+ end
102
+
103
+ def compute_item_changes(other, other_enum, _myself, my_item)
104
+ case my_item
105
+ when DataModel::ArchimateNode
106
+ my_item.diff(other_enum.peek[0])
107
+ else
108
+ my_item.diff(other_enum.peek[0], self, other, other_enum.peek[1], find_index(my_item))
109
+ end
110
+ end
111
+
112
+ def in_model=(model)
113
+ puts "#{self.inspect} is frozen" if self.frozen?
114
+ @in_model = model
115
+ each { |item| item.in_model = model }
116
+ end
117
+
118
+ def parent=(par)
119
+ @parent = par
120
+ each { |i| i.parent = self }
121
+ end
122
+
123
+ def parent_attribute_name
124
+ @parent_attribute_name if defined?(@parent_attribute_name)
125
+ end
126
+
127
+ def build_index(hash_index = {})
128
+ reduce(hash_index) { |hi, array_item| array_item.build_index(hi) }
129
+ end
130
+
131
+ def path(options = {})
132
+ [
133
+ parent&.path(options),
134
+ parent_attribute_name
135
+ ].compact.reject(&:empty?).join("/")
136
+ end
137
+
138
+ def clone
139
+ map(&:clone)
140
+ end
141
+
142
+ def dup
143
+ map(&:dup)
144
+ end
145
+
146
+ def to_s
147
+ "#{parent}/#{parent_attribute_name}"
148
+ end
149
+
150
+ def referenced_identified_nodes
151
+ reduce([]) do |a, e|
152
+ a.concat(e.referenced_identified_nodes)
153
+ end
154
+ end
155
+
156
+ def find_by_id(an_id)
157
+ find { |el| el.id == an_id }
158
+ end
159
+
160
+ def smart_find(val = nil)
161
+ case val
162
+ when Referenceable
163
+ lazy.map(&:id).find_index(val.id)
164
+ else
165
+ find_index(val)
166
+ end
167
+ end
168
+
169
+ def smart_include?(val)
170
+ case val
171
+ when Referenceable
172
+ lazy.map(&:id).include?(val.id)
173
+ else
174
+ include?(val)
175
+ end
176
+ end
177
+
178
+ def smart_intersection(ary)
179
+ select { |item| ary.smart_include?(item) }
180
+ end
181
+
182
+ def after(idx)
183
+ return [] if idx >= size - 1
184
+ self[idx + 1..-1]
185
+ end
186
+
187
+ # Given a node in self and ary,
188
+ # return the idx of first node p in self that exists in both self and ary
189
+ # and is previous to node in self
190
+ def previous_item_index(ary, node)
191
+ return -1 unless ary.smart_include?(node)
192
+ initial_idx = smart_find(node)
193
+ return -1 if initial_idx.nil?
194
+
195
+ (initial_idx - 1).downto(0).find(-> { -1 }) do |idx|
196
+ ary.smart_include?(at(idx))
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -2,34 +2,60 @@
2
2
 
3
3
  module Archimate
4
4
  module DataModel
5
- RelationshipTypeEnum = %w[
6
- Composition
7
- Aggregation
8
- Assignment
9
- Realization
10
- Serving
11
- Access
12
- Influence
13
- Triggering
14
- Flow
15
- Specialization
16
- Association
17
- ].freeze
18
- RelationshipType = Strict::String.enum(*RelationshipTypeEnum)
19
- AllowedRelationshipTypes = Strict::Array.member(RelationshipType).default([])
20
-
21
- AccessType = %w[Access Read Write ReadWrite]
22
- AccessTypeEnum = Strict::String.enum(*AccessType)
5
+ ACCESS_TYPE = %w[Access Read Write ReadWrite].freeze
6
+ AccessTypeEnum = String #String.enum(*ACCESS_TYPE)
23
7
 
24
8
  # A base relationship type that can be extended by concrete ArchiMate types.
25
9
  #
26
10
  # Note that RelationshipType is abstract, so one must have derived types of this type. this is indicated in xml
27
11
  # by having a tag name of "relationship" and an attribute of xsi:type="AccessRelationship" where AccessRelationship is
28
12
  # a derived type from RelationshipType.
29
- class Relationship < Concept
30
- attribute :source, Identifier
31
- attribute :target, Identifier
32
- attribute :access_type, AccessTypeEnum.optional
13
+ class Relationship
14
+ include Comparison
15
+
16
+ # @!attribute [r] id
17
+ # @return [String]
18
+ model_attr :id
19
+ # @!attribute [r] name
20
+ # @return [LangString, NilClass]
21
+ model_attr :name
22
+ # @!attribute [r] documentation
23
+ # @return [PreservedLangString, NilClass]
24
+ model_attr :documentation
25
+ # # @return [Array<AnyElement>]
26
+ # model_attr :other_elements
27
+ # # @return [Array<AnyAttribute>]
28
+ # model_attr :other_attributes
29
+ # @note type here was used for the Element/Relationship/Diagram type
30
+ # @!attribute [r] type
31
+ # @return [String, NilClass]
32
+ model_attr :type
33
+ # @!attribute [r] properties
34
+ # @return [Array<Property>]
35
+ model_attr :properties
36
+ # @todo is this optional?
37
+ # @!attribute [rw] source
38
+ # @return [Element, Relationship]
39
+ model_attr :source, comparison_attr: :id, writable: true
40
+ # @todo is this optional?
41
+ # @!attribute [rw] target
42
+ # @return [Element, Relationship]
43
+ model_attr :target, comparison_attr: :id, writable: true
44
+ # @!attribute [r] access_type
45
+ # @return [AccessTypeEnum, NilClass]
46
+ model_attr :access_type
47
+
48
+ def initialize(id:, name: nil, documentation: nil, type: nil,
49
+ properties: [], source:, target:, access_type: nil)
50
+ @id = id
51
+ @name = name
52
+ @documentation = documentation
53
+ @type = type
54
+ @properties = properties
55
+ @source = source
56
+ @target = target
57
+ @access_type = access_type
58
+ end
33
59
 
34
60
  def replace(entity, with_entity)
35
61
  @source = with_entity.id if source == entity.id
@@ -40,28 +66,22 @@ module Archimate
40
66
  Archimate::Color.color(
41
67
  "#{Archimate::Color.data_model(type)}<#{id}>[#{Archimate::Color.color(name&.strip || '', %i[black underline])}]",
42
68
  :on_light_magenta
43
- ) + " #{source_element} -> #{target_element}"
69
+ ) + " #{source} -> #{target}"
44
70
  end
45
71
 
46
72
  def description
47
73
  [
48
74
  name.nil? ? nil : "#{name}:",
49
- FileFormats::ArchimateV2::RELATION_VERBS.fetch(type, nil)
75
+ RELATION_VERBS.fetch(type, nil)
50
76
  ].compact.join(" ")
51
77
  end
52
78
 
79
+ # @todo remove when it doesn't break diff merge conflicts
80
+ # @deprecated
53
81
  def referenced_identified_nodes
54
82
  [@source, @target].compact
55
83
  end
56
84
 
57
- def source_element
58
- element_by_id(source)
59
- end
60
-
61
- def target_element
62
- element_by_id(target)
63
- end
64
-
65
85
  # Diagrams that this element is referenced in.
66
86
  def diagrams
67
87
  @diagrams ||= in_model.diagrams.select do |diagram|
@@ -80,6 +100,5 @@ module Archimate
80
100
  access_type ||= relationship.access_type
81
101
  end
82
102
  end
83
- Dry::Types.register_class(Relationship)
84
103
  end
85
104
  end