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
@@ -9,73 +9,95 @@ module Archimate
9
9
  # If the connection is an ArchiMate relationship type, the connection's label, documentation and properties may be determined
10
10
  # (i.e inherited) from those in the referenced ArchiMate relationship. Otherwise the connection's label, documentation and properties
11
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
12
+ class Connection
13
+ include Comparison
28
14
 
29
- # This is under Relationship
30
- attribute :relationship, Strict::String.optional
15
+ # @!attribute [r] id
16
+ # @return [String]
17
+ model_attr :id
18
+ # @!attribute [r] name
19
+ # @return [LangString, NilClass]
20
+ model_attr :name
21
+ # @!attribute [r] documentation
22
+ # @return [PreservedLangString, NilClass]
23
+ model_attr :documentation
24
+ # # @!attribute [r] other_elements
25
+ # @return [Array<AnyElement>]
26
+ model_attr :other_elements
27
+ # # @!attribute [r] other_attributes
28
+ # @return [Array<AnyAttribute>]
29
+ model_attr :other_attributes
30
+ # @note type here was used for the Element/Relationship/Diagram type
31
+ # @!attribute [r] type
32
+ # @return [String, NilClass]
33
+ model_attr :type
34
+ # @!attribute [r] source_attachment
35
+ # @return [Location, NilClass]
36
+ model_attr :source_attachment
37
+ # @!attribute [r] bendpoints
38
+ # @return [Array<Location>]
39
+ model_attr :bendpoints
40
+ # @!attribute [r] target_attachment
41
+ # @return [Location, NilClass]
42
+ model_attr :target_attachment
43
+ # @!attribute [rw] source
44
+ # @return [ViewNode, NilClass]
45
+ model_attr :source, comparison_attr: :id, writable: true
46
+ # @!attribute [rw] target
47
+ # @return [ViewNode, NilClass]
48
+ model_attr :target, comparison_attr: :id, writable: true
49
+ # @!attribute [rw] relationship
50
+ # @return [Relationship, NilClass]
51
+ model_attr :relationship, comparison_attr: :id, writable: true
52
+ # @!attribute [r] style
53
+ # @return [Style, NilClass]
54
+ model_attr :style
55
+ # @!attribute [r] properties
56
+ # @return [Array<Property>]
57
+ model_attr :properties
31
58
 
32
- # Note: this is added under ViewConcept
33
- attribute :style, Style.optional
34
- attribute :properties, PropertiesList
59
+ def initialize(id:, name: nil, documentation: nil, type: nil,
60
+ source_attachment: nil, bendpoints: [], target_attachment: nil,
61
+ source: nil, target: nil, relationship: nil, style: nil,
62
+ properties: nil)
63
+ @id = id
64
+ @name = name
65
+ @documentation = documentation
66
+ @type = type
67
+ @source_attachment = source_attachment
68
+ @bendpoints = bendpoints
69
+ @target_attachment = target_attachment
70
+ @source = source
71
+ @target = target
72
+ @relationship = relationship
73
+ @style = style
74
+ @properties = properties
75
+ end
35
76
 
36
77
  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)
78
+ @relationship = with_entity.id if relationship == entity.id
79
+ @source = with_entity.id if source == entity.id
80
+ @target = with_entity.id if target == entity.id
40
81
  end
41
82
 
42
83
  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)
84
+ Archimate::Color.color("#{Archimate::Color.data_model('Connection')}[#{Archimate::Color.color(@name || '', %i[white underline])}]", :on_light_magenta)
48
85
  end
49
86
 
50
87
  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)
88
+ relationship
60
89
  end
61
90
 
62
91
  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}"
92
+ "#{type_name} #{source.nil? ? 'nothing' : source} -> #{target.nil? ? 'nothing' : target}"
71
93
  end
72
94
 
73
95
  def description
74
96
  [
75
97
  name.nil? ? nil : "#{name}: ",
76
- source_element&.description,
77
- relationship_element&.description,
78
- target_element&.description
98
+ source&.description,
99
+ relationship&.description,
100
+ target&.description
79
101
  ].compact.join(" ")
80
102
  end
81
103
 
@@ -101,7 +123,5 @@ module Archimate
101
123
  offset
102
124
  end
103
125
  end
104
- Dry::Types.register_class(Connection)
105
- ConnectionList = Strict::Array.member("archimate.data_model.connection").default([])
106
126
  end
107
127
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ require "ruby-enum"
3
+
4
+ module Archimate
5
+ module DataModel
6
+ # An enumeration of the connector types available in Archimate
7
+ # @example Reference an "And" Junction.
8
+ # ConnectorType::AndJunction #=> "AndJunction"
9
+ class ConnectorType
10
+ include Ruby::Enum
11
+
12
+ define :AndJunction, "AndJunction"
13
+ define :Junction, "Junction"
14
+ define :OrJunction, "OrJunction"
15
+
16
+ # Returns true if {other} is a +ConnectorType+
17
+ # @param other [String]
18
+ def self.===(other)
19
+ values.include?(other)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,11 +1,67 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Archimate
3
4
  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([])
5
+ class Diagram
6
+ include Comparison
7
+
8
+ # @!attribute [r] id
9
+ # @return [String]
10
+ model_attr :id
11
+ # @!attribute [rw] name
12
+ # @return [LangString]
13
+ model_attr :name, writable: true
14
+ # @!attribute [rw] documentation
15
+ # @return [PreservedLangString, NilClass]
16
+ model_attr :documentation, writable: true
17
+ # # @return [Array<AnyElement>]
18
+ # model_attr :other_elements
19
+ # # @return [Array<AnyAttribute>]
20
+ # model_attr :other_attributes
21
+ # @note type here was used for the Element/Relationship/Diagram type
22
+ # @!attribute [r] type
23
+ # @return [String, NilClass]
24
+ model_attr :type
25
+ # @!attribute [rw] properties
26
+ # @return [Array<Property>]
27
+ model_attr :properties, writable: true
28
+ # @todo make this a ViewpointType is better but is Archimate specification version dependent
29
+ # @!attribute [r] viewpoint_type
30
+ # @return [String, NilClass]
31
+ model_attr :viewpoint_type
32
+ # @!attribute [r] viewpoint
33
+ # @return [Viewpoint, NilClass]
34
+ model_attr :viewpoint
35
+ # @!attribute [rw] nodes
36
+ # @return [Array<ViewNode>]
37
+ model_attr :nodes, writable: true
38
+ # @todo Archi formats only fill this in, should be an enum
39
+ # @!attribute [r] connection_router_type
40
+ # @return [Int, NilClass]
41
+ model_attr :connection_router_type
42
+ # value of 0 on Archi Sketch Model
43
+ # @!attribute [r] background
44
+ # @return [Int, NilClass]
45
+ model_attr :background
46
+ # @!attribute [rw] connections
47
+ # @return [Array<Connection>]
48
+ model_attr :connections, writable: true
49
+
50
+ def initialize(id:, name: nil, documentation: nil, type: nil, properties: [],
51
+ viewpoint_type: nil, viewpoint: nil, nodes: [],
52
+ connection_router_type: nil, background: nil, connections: [])
53
+ @id = id
54
+ @name = name
55
+ @documentation = documentation
56
+ @type = type
57
+ @properties = properties
58
+ @viewpoint_type = viewpoint_type
59
+ @viewpoint = viewpoint
60
+ @nodes = nodes
61
+ @connection_router_type = connection_router_type
62
+ @background = background
63
+ @connections = connections
64
+ end
9
65
 
10
66
  def all_nodes
11
67
  nodes.inject(Array.new(nodes)) { |child_ary, child| child_ary.concat(child.all_nodes) }
@@ -16,25 +72,31 @@ module Archimate
16
72
  end
17
73
 
18
74
  def element_ids
19
- @element_ids ||= all_nodes.map(&:archimate_element).compact
75
+ @element_ids ||= elements.map(&:id)
20
76
  end
21
77
 
22
78
  def relationships
23
- @relationships ||= connections.map(&:element).compact
79
+ @relationships ||= connections.map(&:relationship).compact
24
80
  end
25
81
 
26
82
  def relationship_ids
27
- @relationship_ids ||= connections.map(&:relationship).compact
83
+ @relationship_ids ||= relationships.map(&:id)
28
84
  end
29
85
 
30
86
  def to_s
31
- "#{Archimate::Color.data_model('Diagram')}<#{id}>[#{Archimate::Color.color(name, [:white, :underline])}]"
87
+ "#{Archimate::Color.data_model('Diagram')}<#{id}>[#{Archimate::Color.color(name, %i[white underline])}]"
32
88
  end
33
89
 
34
90
  def total_viewpoint?
35
91
  viewpoint_type.nil? || viewpoint_type.empty?
36
92
  end
93
+
94
+ def referenced_identified_nodes
95
+ (nodes + connections)
96
+ .map(&:referenced_identified_nodes)
97
+ .flatten
98
+ .uniq
99
+ end
37
100
  end
38
- Dry::Types.register_class(Diagram)
39
101
  end
40
102
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ require "ruby-enum"
3
+
4
+ module Archimate
5
+ module DataModel
6
+ class DiagramType
7
+ include Ruby::Enum
8
+
9
+ define :ArchimateDiagramModel, "ArchimateDiagramModel"
10
+ define :SketchModel, "SketchModel"
11
+
12
+ def self.===(other)
13
+ values.include?(other)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Archimate
4
+ module DataModel
5
+ # Let's talk about diff...
6
+ #
7
+ # Here are my expectations of diff:
8
+ #
9
+ # = Preconditions:
10
+ #
11
+ # 1. self is non-nil
12
+ # 2. self is a class that includes Comparison
13
+ #
14
+ # = Requirements for other
15
+ #
16
+ # Not matching one of these is a programming error.
17
+ #
18
+ # 1. Other is nil
19
+ # 2. Other is an instance of the same class as self
20
+ #
21
+ # = Diff results
22
+ #
23
+ # * Diffing results in a list of Diff instances between +self+ and +other+
24
+ # * Patching the list of diffs against self results in an instance that == +other+
25
+ #
26
+ # = Diff Container
27
+ #
28
+ # A diff container is a top level entity that is meaningful in the user domain
29
+ # for example: [Element], [Relationship], [Diagram]. It collects and groups
30
+ # the smaller diffs into the things that changed by an entity tha makes sense
31
+ # to the user.
32
+ #
33
+ # = Diff structure
34
+ #
35
+ # A diff contains a change to be applied in a particular context.
36
+ #
37
+ # Use cases:
38
+ #
39
+ # 1. Delete a value that is a member of this class. Example: Delete the
40
+ # +a+ member of a [Color] instance.
41
+ # 2. A non-reference value replacing a value in a class. Example:
42
+ # Changing the +r+ value of a [Color] with a different value.
43
+ # 3. Updating the value of an attribute of a child. (or child's child)
44
+ # 4. Deleting the value of an attribute of a child. (or child's child)
45
+ # 5. For Array attributes with non-referenceable contents
46
+ # 1. Deleting a value from an array attribute
47
+ # 2. Inserting a value into an array attribute
48
+ # 3. Changing a value in an array attribute
49
+ # 6. For Array attributes with referenceable contents
50
+ # 1. Deleting a value from an array attribute (has an implication on
51
+ # if the entity is deleted from the model entirely)
52
+ # 2. Inserting a value into an array attribute (may need addtion to the
53
+ # model)
54
+ # 3. Changing a value in an array attribute (changing the entity id may
55
+ # require the implications of deletion and insertion as above)
56
+ #
57
+ # When to stop?
58
+ #
59
+ # When digging down into a diff operation, there are some natural stopping
60
+ # points:
61
+ #
62
+ # 1. When there is no more depth to dig
63
+ # 2. When the objects being compared are references to other entities, but
64
+ # do not belong to the current object being diffed.
65
+ # 3. When the object being diffed is a Diff container unto itself. For
66
+ # example: When diffing a model, the diff should include the order
67
+ # of elements referenced in the +elements+ attribute, but shouldn't
68
+ # continue with the diff of each element itself.
69
+ #
70
+ # = Complications
71
+ #
72
+ # == Object references
73
+ #
74
+ # Since a patch operation produces an new replacement object, object
75
+ # references need to be handled. For example, given an +Element+ with +id=3+
76
+ # if a patch changes this +Element+'s name, then the +Element+ in
77
+ # the model under +Model#elements+ is replaced with a different instance,
78
+ # but a +Relationship+ that references the +Element+ is still pointing at
79
+ # a different instance and needs to be updated.
80
+ Insert = Struct.new(:path, :value)
81
+ Delete = Struct.new(:path)
82
+ Change = Struct.new(:path, :from, :to)
83
+
84
+ module Differentiable
85
+ # Computes the diffs between this object and another object of the same type
86
+ #
87
+ # @param other [self.class] another object to compare
88
+ # @return [Array<Diff::Difference>]
89
+ # @raise
90
+ def diff(other)
91
+ return [] if other.nil?
92
+ raise TypeError, "Expected other <#{other.class} to be of type #{self.class}" unless other.is_a?(self.class)
93
+
94
+ self.class.attr_names.each_with_object([]) do |k, a|
95
+ val = send(k)
96
+ case val
97
+ when NilClass
98
+ a << Insert.new(k, other[k]) unless other[k].nil?
99
+ when Integer, Float, Hash, String, Symbol
100
+ a.concat(Differentiable.diff_primitive(val, other[k], self, other, k))
101
+ when Differentiable
102
+ a.concat(val.diff(other[k]))
103
+ else
104
+ raise "Unexpected Type for Diff don't know how to diff a #{val.class}"
105
+ end
106
+ end
107
+ end
108
+
109
+ def patch(diffs)
110
+ ary = diffs.is_a?(Array) ? diffs : [diffs]
111
+ self.class.new(
112
+ ary.each_with_object(to_h) do |diff, args|
113
+ case diff
114
+ when Delete
115
+ args[diff.path] = nil
116
+ when Insert
117
+ args[diff.path] = diff.value
118
+ when Change
119
+ args[diff.path] = diff.to
120
+ else
121
+ raise "Unexpected diff type #{diff.class} #{diff.inspect}"
122
+ end
123
+ end
124
+ )
125
+ end
126
+
127
+ private
128
+
129
+ def self.diff_primitive(val, other, from_parent, to_parent, attribute, from_attribute = nil)
130
+ from_attribute = attribute if from_attribute.nil?
131
+ if other.nil?
132
+ return [Delete.new(attribute)]
133
+ end
134
+ raise TypeError, "Expected other #{other.class} to be of type #{val.class}" unless other.is_a?(val.class)
135
+ unless val == other
136
+ return [Change.new(attribute, val, other)]
137
+ end
138
+ []
139
+ end
140
+ end
141
+ end
142
+ end
@@ -2,58 +2,53 @@
2
2
 
3
3
  module Archimate
4
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
5
+ # A base element type that can be extended by concrete ArchiMate types.
6
+ #
7
+ # Note that ElementType is abstract, so one must have derived types of this
8
+ # type. This is indicated in xml by having a tag name of +element+ and an
9
+ # attribute of +xsi:type="BusinessRole"+ where +BusinessRole+ is a derived
10
+ # type from [ElementType].
11
+ #
12
+ # @todo Possible Make this abstract with concrete implementations for all
13
+ # valid element types
14
+ class Element
15
+ include Comparison
25
16
 
26
- ElementType = Strict::String.enum(*ElementEnumType)
17
+ # @!attribute [r] id
18
+ # @return [String]
19
+ model_attr :id
20
+ # @!attribute [r] name
21
+ # @return [LangString, NilClass]
22
+ model_attr :name
23
+ # @!attribute [rw] documentation
24
+ # @return [PreservedLangString, NilClass]
25
+ model_attr :documentation, writable: true
26
+ # # @return [Array<AnyElement>]
27
+ # model_attr :other_elements
28
+ # # @return [Array<AnyAttribute>]
29
+ # model_attr :other_attributes
30
+ # @note type here was used for the Element/Relationship/Diagram type
31
+ # @!attribute [r] type
32
+ # @return [String, NilClass]
33
+ model_attr :type
34
+ # @!attribute [r] properties
35
+ # @return [Array<Property>]
36
+ model_attr :properties
27
37
 
28
- AllowedElementTypes = Strict::Array.member(ElementType).default([])
38
+ def initialize(id:, name:, documentation: nil, type: nil, properties: [])
39
+ @id = id
40
+ @name = name
41
+ @documentation = documentation
42
+ @type = type
43
+ @properties = properties
44
+ end
29
45
 
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
46
  def to_s
37
47
  Archimate::Color.layer_color(layer, "#{type}<#{id}>[#{name}]")
38
48
  end
39
49
 
40
50
  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) }
51
+ Layers.for_element(type)
57
52
  end
58
53
 
59
54
  # Diagrams that this element is referenced in.
@@ -82,6 +77,5 @@ module Archimate
82
77
  element.organization.remove(element.id)
83
78
  end
84
79
  end
85
- Dry::Types.register_class(Element)
86
80
  end
87
81
  end