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
@@ -6,9 +6,16 @@ module Archimate
6
6
  # about a meta-data element's parent only.
7
7
  #
8
8
  # One or more different meta-data models may be declared as child extensions of a meta-data element.
9
- class Metadata < ArchimateNode
10
- attribute :schema_infos, Strict::Array.member(SchemaInfo).default([])
9
+ class Metadata
10
+ include Comparison
11
+
12
+ # @!attribute [r] schema_infos
13
+ # @return [Array<SchemaInfo>]
14
+ model_attr :schema_infos
15
+
16
+ def initialize(schema_infos: [])
17
+ @schema_infos = schema_infos
18
+ end
11
19
  end
12
- Dry::Types.register_class(Metadata)
13
20
  end
14
21
  end
@@ -3,39 +3,99 @@
3
3
  module Archimate
4
4
  module DataModel
5
5
  # This is the root model type.
6
- # It is a container for the elements, relationships, diagrams and organizations of the model.
7
- class Model < NamedReferenceable
8
- using DataModel::DiffableArray
9
- using DataModel::DiffablePrimitive
10
-
11
- ARRAY_RE = Regexp.compile(/\[(\d+)\]/)
12
-
13
- attribute :properties, Strict::Array.member(Property).default([]) # Properties.optional
14
- attribute :metadata, Metadata.optional
15
- attribute :elements, Strict::Array.member(Element).default([])
16
- attribute :relationships, Strict::Array.member(Relationship).default([])
17
- attribute :organizations, Strict::Array.member(Organization).default([])
18
- attribute :property_definitions, Strict::Array.member(PropertyDefinition).default([])
19
- attribute :version, Strict::String.optional
20
- attribute :diagrams, Strict::Array.member(Diagram).default([])
21
- attribute :viewpoints, Strict::Array.member(Viewpoint).default([])
6
+ #
7
+ # It is a container for the elements, relationships, diagrams and
8
+ # organizations of the model.
9
+ class Model
10
+ include Comparison
11
+
12
+ # @!attribute [r] id
13
+ # @return [String] unique identifier of this model
14
+ model_attr :id
15
+ # @!attribute [r] name
16
+ # @return [LangString] name of the model
17
+ model_attr :name
18
+
19
+ # @!attribute [r] documentation
20
+ # @return [PreservedLangString, NilClass] model documentation
21
+ model_attr :documentation
22
+ # @!attribute [r] properties
23
+ # @return [Array<Property>] model properties
24
+ model_attr :properties
25
+ # @!attribute [r] metadata
26
+ # @return [Metadata, NilClass] model metadata
27
+ model_attr :metadata
28
+ # @!attribute [r] elements
29
+ # @return [Array<Element>]
30
+ model_attr :elements
31
+ # @!attribute [r] relationships
32
+ # @return [Array<Relationship>]
33
+ model_attr :relationships
34
+ # @!attribute [r] organizations
35
+ # @return [Array<Organization>]
36
+ model_attr :organizations
37
+ # @!attribute [r] property_definitions
38
+ # @return [Array<PropertyDefinition>]
39
+ model_attr :property_definitions
40
+ # @!attribute [r] version
41
+ # @return [String, NilClass]
42
+ model_attr :version
43
+ # @!attribute [r] diagrams
44
+ # @return [Array<Diagram>]
45
+ model_attr :diagrams
46
+ # @!attribute [r] viewpoints
47
+ # @return [Array<Viewpoint>]
48
+ model_attr :viewpoints
49
+
22
50
  # Following attributes are to hold info on where the model came from
23
- attribute :filename, Strict::String.optional
24
- attribute :file_format, Strict::Symbol.enum(*Archimate::SUPPORTED_FORMATS).optional
25
- attribute :archimate_version, Strict::Symbol.default(:archimate_3_0).enum(*Archimate::ARCHIMATE_VERSIONS)
51
+ # @!attribute [r] filename
52
+ # @return [String]
53
+ model_attr :filename
54
+ # @see Archimate::SUPPORTED_FORMATS
55
+ # @!attribute [r] file_format
56
+ # @return [Symbol, NilClass] supported Archimate format [Archimate::SUPPORTED_FORMATS] or +nil+
57
+ model_attr :file_format
58
+ # @!attribute [r] archimate_version
59
+ # @return [Symbol] one of [Archimate::ARCHIMATE_VERSIONS], default +:archimate_3_0+
60
+ model_attr :archimate_version
26
61
 
27
- attribute :namespaces, Strict::Hash.default({})
28
- attribute :schema_locations, Strict::Array.member(Strict::String).default([])
62
+ # @!attribute [r] namespaces
63
+ # @return [Hash]
64
+ model_attr :namespaces
65
+ # @!attribute [r] schema_locations
66
+ # @return [Array<String>]
67
+ model_attr :schema_locations
29
68
 
30
- def initialize(attributes)
31
- super
32
- self.in_model = self
33
- self.parent = nil
34
- rebuild_index
35
- end
69
+ # # @return [Array<AnyElement>]
70
+ # model_attr :other_elements
71
+ # # @return [Array<AnyAttribute>]
72
+ # model_attr :other_attributes
36
73
 
37
- def with(options = {})
38
- super.organize
74
+ # Constructor
75
+ def initialize(id:, name:, documentation: nil, properties: [],
76
+ metadata: nil, elements: [], relationships: [],
77
+ organizations: [], property_definitions: [],
78
+ version: nil, diagrams: [], viewpoints: [],
79
+ filename: nil, file_format: nil, archimate_version: :archimate_3_0,
80
+ namespaces: {}, schema_locations: [])
81
+ @id = id
82
+ @name = name
83
+ @documentation = documentation
84
+ @properties = properties
85
+ @metadata = metadata
86
+ @elements = elements
87
+ @relationships = relationships
88
+ @organizations = organizations
89
+ @property_definitions = property_definitions
90
+ @version = version
91
+ @diagrams = diagrams
92
+ @viewpoints = viewpoints
93
+ @filename = filename
94
+ @file_format = file_format
95
+ @archimate_version = archimate_version
96
+ @namespaces = namespaces
97
+ @schema_locations = schema_locations
98
+ rebuild_index
39
99
  end
40
100
 
41
101
  def lookup(id)
@@ -43,67 +103,27 @@ module Archimate
43
103
  @index_hash[id]
44
104
  end
45
105
 
106
+ # Called only by [Lint::DuplicateEntities]
46
107
  def entities
47
108
  @index_hash.values
48
109
  end
49
110
 
111
+ # Called only by [Diff::Merge]
50
112
  def rebuild_index(missing_id = :model_creation_event)
51
113
  return self unless missing_id
52
114
  @index_hash = build_index
53
115
  self
54
116
  end
55
117
 
56
- def register(node, parent)
57
- node.in_model = self
58
- node.parent = parent
59
- @index_hash[node.id] = node
60
- end
61
-
62
- def deregister(node)
63
- @index_hash.delete(node.id)
64
- end
65
-
66
- def find_by_class(klass)
67
- @index_hash.values.select { |item| item.is_a?(klass) }
68
- end
69
-
70
118
  def to_s
71
- "#{Archimate::Color.data_model('Model')}<#{id}>[#{Archimate::Color.color(name, [:white, :underline])}]"
72
- end
73
-
74
- # TODO: make these DSL like things added dynamically
75
- def application_components
76
- elements.select { |element| element.type == "ApplicationComponent" }
77
- end
78
-
79
- def element_type_names
80
- elements.map(&:type).uniq
81
- end
82
-
83
- def elements_with_type(el_type)
84
- elements.select { |element| element.type == el_type }
85
- end
86
-
87
- # TODO: make these DSL like things added dynamically
88
- def all_properties
89
- @index_hash.values.each_with_object([]) do |i, a|
90
- a.concat(i.properties) if i.respond_to?(:properties)
91
- end
92
- end
93
-
94
- # TODO: refactor to use property def structure instead of separate property objects
95
- def property_keys
96
- all_properties.map(&:key).uniq
97
- end
98
-
99
- # TODO: refactor to use property def structure instead of separate property objects
100
- def property_def_id(key)
101
- "propid-#{property_keys.index(key) + 1}"
119
+ "#{Archimate::Color.data_model('Model')}<#{id}>[#{Archimate::Color.color(name, %i[white underline])}]"
102
120
  end
103
121
 
104
122
  # Iterate through the model and ensure that elements, relationships, and
105
123
  # diagrams are all present in the model's organizations. If an item is missing
106
124
  # then move it into the default top-level element for the item type.
125
+ #
126
+ # @note this is only called by [Diff::Merge]
107
127
  def organize
108
128
  []
109
129
  .concat(elements)
@@ -117,34 +137,82 @@ module Archimate
117
137
  self
118
138
  end
119
139
 
120
- def find_in_organizations(item, _fs = nil)
121
- result = find_by_class(DataModel::Organization).select { |f| f.items.include?(item.id) }
122
- # raise "Program Error! #{item.id} is located in more than one organization. #{result.map(&:to_s).inspect}\n#{item}\n" if result.size > 1
123
- result.empty? ? nil : result.first
140
+ # Only used by [Diff::DeletedItemsReferencedConflict]
141
+ def referenced_identified_nodes
142
+ classes = [Diagram, ViewNode, Connection, Organization, Relationship].freeze
143
+ @index_hash
144
+ .values
145
+ .select { |entity| classes.include?(entity.class) }
146
+ .map(&:referenced_identified_nodes)
147
+ .flatten
148
+ .uniq
149
+ end
150
+
151
+ # This is used only by the model [Cli::Cleanup] class.
152
+ def unreferenced_nodes
153
+ identified_nodes - referenced_identified_nodes
154
+ end
155
+
156
+ # def merge_entities(master_entity, copies)
157
+ # copies.delete(master_entity)
158
+ # copies.each do |copy|
159
+ # entities.each do |entity|
160
+ # case entity
161
+ # when entity == master_entity
162
+ # master_entity.merge(copy)
163
+ # when Organization
164
+ # entity.remove(copy.id)
165
+ # when ViewNode, Relationship, Connection
166
+ # entity.replace(copy, master_entity)
167
+ # end
168
+ # end
169
+ # deregister(copy)
170
+ # end
171
+ # end
172
+
173
+ private
174
+
175
+ # Only used by [#find_default_organization]
176
+ def add_organization(type, name)
177
+ raise "Program Error: #{organizations.inspect}" unless organizations.none? { |f| f.type == type || f.name == name }
178
+ organization = Organization.new(id: make_unique_id, name: LangString.create(name), type: type, items: [], organizations: [], documentation: nil)
179
+ register(organization, organizations)
180
+ organizations.push(organization)
181
+ organization
182
+ end
183
+
184
+ def build_index
185
+ @index_hash = { id => self }
186
+ elements.each { |ref| @index_hash[ref.id] = ref }
187
+ relationships.each { |ref| @index_hash[ref.id] = ref }
188
+ diagrams.each { |dia| @index_hash[dia.id] = index_view_nodes(dia) }
189
+ property_definitions.each { |ref| @index_hash[ref.id] = ref }
190
+ index_organizations(self)
191
+ @index_hash
124
192
  end
125
193
 
126
194
  def default_organization_for(item)
127
195
  case item
128
196
  when Element
129
197
  case item.layer
130
- when "Strategy"
198
+ when Layers::Strategy
131
199
  find_default_organization("strategy", "Strategy")
132
- when "Business"
200
+ when Layers::Business
133
201
  find_default_organization("business", "Business")
134
- when "Application"
202
+ when Layers::Application
135
203
  find_default_organization("application", "Application")
136
- when "Technology"
204
+ when Layers::Technology
137
205
  find_default_organization("technology", "Technology")
138
- when "Physical"
206
+ when Layers::Physical
139
207
  find_default_organization("physical", "Physical")
140
- when "Motivation"
208
+ when Layers::Motivation
141
209
  find_default_organization("motivation", "Motivation")
142
- when "Implementation and Migration"
210
+ when Layers::Implementation_and_migration
143
211
  find_default_organization("implementation_migration", "Implementation & Migration")
144
- when "Connectors"
212
+ when Layers::Connectors
145
213
  find_default_organization("connectors", "Connectors")
146
214
  else
147
- raise StandardError, "Unexpected Element Layer: #{item.layer.inspect} for item type #{item.type.inspect}"
215
+ raise StandardError, "Unexpected Element Layer: #{item.layer} for item type #{item.type}"
148
216
  end
149
217
  when Relationship
150
218
  find_default_organization("relations", "Relations")
@@ -155,6 +223,10 @@ module Archimate
155
223
  end
156
224
  end
157
225
 
226
+ def find_by_class(klass)
227
+ @index_hash.values.select { |item| item.is_a?(klass) }
228
+ end
229
+
158
230
  def find_default_organization(type, name)
159
231
  result = organizations.find { |f| f.type == type }
160
232
  return result unless result.nil?
@@ -163,55 +235,50 @@ module Archimate
163
235
  add_organization(type, name)
164
236
  end
165
237
 
166
- def add_organization(type, name)
167
- raise "Program Error: #{organizations.inspect}" unless organizations.none? { |f| f.type == type || f.name == name }
168
- organization = Organization.new(id: make_unique_id, name: name, type: type, items: [], organizations: [])
169
- register(organization, organizations)
170
- organizations.push(organization)
171
- organization
172
- end
173
-
174
- def make_unique_id
175
- unique_id = random_id
176
- unique_id = random_id while @index_hash.key?(unique_id)
177
- unique_id
178
- end
179
-
180
- def referenced_identified_nodes
181
- super.uniq
238
+ def find_in_organizations(item, _fs = nil)
239
+ find_by_class(DataModel::Organization).select { |f| f.items.include?(item.id) }.first
182
240
  end
183
241
 
242
+ # Only used by [#unreferenced_nodes]
184
243
  def identified_nodes
185
- @index_hash.values.select { |node| node.is_a? Referenceable }
244
+ @index_hash.values.select { |node| node.respond_to? :id }
186
245
  end
187
246
 
188
- def unreferenced_nodes
189
- identified_nodes - referenced_identified_nodes
247
+ # @todo make this private - maybe move to [Organization]
248
+ def index_organizations(ref)
249
+ ref.organizations.each do |org|
250
+ @index_hash[org.id] = index_organizations(org)
251
+ end
252
+ ref
190
253
  end
191
254
 
192
- def merge_entities(master_entity, copies)
193
- copies.delete(master_entity)
194
- copies.each do |copy|
195
- entities.each do |entity|
196
- case entity
197
- when entity == master_entity
198
- master_entity.merge(copy)
199
- when Organization
200
- entity.remove(copy.id)
201
- when ViewNode, Relationship, Connection
202
- entity.replace(copy, master_entity)
203
- end
204
- end
205
- deregister(copy)
255
+ # @todo make this private - maybe move to [ViewNode]
256
+ def index_view_nodes(ref)
257
+ ref.nodes.each do |node|
258
+ @index_hash[node.id] = index_view_nodes(node)
206
259
  end
260
+ ref.connections.each { |con| @index_hash[con.id] = con }
261
+ ref
207
262
  end
208
263
 
209
- private
264
+ def make_unique_id
265
+ unique_id = random_id
266
+ unique_id = random_id while @index_hash.key?(unique_id)
267
+ unique_id
268
+ end
210
269
 
211
270
  def random_id
212
271
  @random ||= Random.new
213
272
  format("%08x", @random.rand(0xffffffff))
214
273
  end
274
+
275
+ def register(node, _parent)
276
+ @index_hash[node.id] = node
277
+ end
278
+
279
+ def deregister(node)
280
+ @index_hash.delete(node.id)
281
+ end
215
282
  end
216
283
  end
217
284
  end
@@ -4,10 +4,21 @@ module Archimate
4
4
  module DataModel
5
5
  # This is a set of notes to the modeler on how to use and model with this viewpoint. Could contain rules
6
6
  # or constraints. The part hold the information for this element.
7
- class ModelingNote < ArchimateNode
8
- attribute :documentation, DocumentationGroup # .constrained(min_size: 1)
7
+ class ModelingNote
8
+ include Comparison
9
+
10
+ # @!attribute [r] documentation
11
+ # @return [PreservedLangString]
12
+ model_attr :documentation
9
13
  # `type` attribute expresses a type for the notes, e.g. OCL for OCL rules.
10
- attribute :type, Strict::String.optional
14
+ # @!attribute [r] type
15
+ # @return [String, NilClass]
16
+ model_attr :type
17
+
18
+ def initialize(documentation:, type: nil)
19
+ @documentation = documentation
20
+ @type = type
21
+ end
11
22
  end
12
23
  end
13
24
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Archimate
3
4
  module DataModel
4
5
  # An organization element represents a structural node in a particular organization of the model concepts.
@@ -10,19 +11,50 @@ module Archimate
10
11
  #
11
12
  # An organization has no meaning unless it has at least child organization element.
12
13
  #
13
- # Note that Organization must fit into a tree structure (so strictly nested).
14
- class Organization < ArchimateNode # was Referenceable
15
- attribute :id, Identifier.optional # .constrained(format: /[[[:alpha:]]_][w-.]*/)
16
- attribute :name, LangString.optional # LabelGroup in the XSD, TODO: this is a LangString collection
17
- attribute :type, Strict::String.optional # I believe this is used only for Archi formats
18
- attribute :documentation, DocumentationGroup
19
- attribute :items, Strict::Array.member(Identifier).default([]) # TODO: Convert this to referenceable
20
- attribute :organizations, Strict::Array.member(Organization).default([]) # item in the XSD
21
- # attribute :other_elements, Strict::Array.member(AnyElement).default([])
22
- # attribute :other_attributes, Strict::Array.member(AnyAttribute).default([])
14
+ # @note that Organization must fit into a tree structure (so strictly nested).
15
+ class Organization
16
+ include Comparison
17
+
18
+ # Format should match +/[[[:alpha:]]_][w-.]*/+ to be valid for Archimate
19
+ # Model exchange format
20
+ # @!attribute [r] id
21
+ # @return [String, NilClass]
22
+ model_attr :id
23
+ # LabelGroup in the XSD
24
+ # @!attribute [r] name
25
+ # @return [LangString, NilClass]
26
+ model_attr :name
27
+ # I believe this is used only for Archi formats
28
+ # @!attribute [r] type
29
+ # @return [String, NilClass]
30
+ model_attr :type
31
+ # @!attribute [r] documentation
32
+ # @return [PreservedLangString, NilClass]
33
+ model_attr :documentation
34
+ # @!attribute [rw] items
35
+ # @return [Array<Object>]
36
+ model_attr :items, writable: true
37
+ # item in the XSD
38
+ # @!attribute [rw] organizations
39
+ # @return [Array<Organization>]
40
+ model_attr :organizations, writable: true
41
+ # # @return [Array<AnyElement>]
42
+ # model_attr :other_elements
43
+ # # @return [Array<AnyAttribute>]
44
+ # model_attr :other_attributes
45
+
46
+ def initialize(id: nil, name: nil, type: nil, documentation: nil,
47
+ items: [], organizations: [])
48
+ @id = id
49
+ @name = name
50
+ @type = type
51
+ @documentation = documentation
52
+ @items = items
53
+ @organizations = organizations
54
+ end
23
55
 
24
56
  def to_s
25
- "#{Archimate::Color.data_model('Organization')}<#{id}>[#{Archimate::Color.color(name, [:white, :underline])}]"
57
+ "#{Archimate::Color.data_model('Organization')}<#{id}>[#{Archimate::Color.color(name, %i[white underline])}]"
26
58
  end
27
59
 
28
60
  def referenced_identified_nodes
@@ -32,9 +64,8 @@ module Archimate
32
64
  end
33
65
 
34
66
  def remove(id)
35
- items.delete(id)
67
+ items.delete_if { |item| item.id == id }
36
68
  end
37
69
  end
38
- Dry::Types.register_class(Organization)
39
70
  end
40
71
  end