archimate 1.2.1 → 2.0.0

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