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
@@ -3,14 +3,24 @@ require "nokogiri"
3
3
 
4
4
  module Archimate
5
5
  module FileFormats
6
- class ArchiFileWriter < Writer
7
- using DataModel::DiffableArray
8
- using DataModel::DiffablePrimitive
6
+ class ArchiFileWriter < Serializer::Writer
7
+ include Serializer::Archi::Bounds
8
+ include Serializer::Archi::Connection
9
+ include Serializer::Archi::Diagram
10
+ include Serializer::Archi::Documentation
11
+ include Serializer::Archi::Element
12
+ include Serializer::Archi::Location
13
+ include Serializer::Archi::Model
14
+ include Serializer::Archi::Organization
15
+ include Serializer::Archi::Property
16
+ include Serializer::Archi::Relationship
17
+ include Serializer::Archi::ViewNode
9
18
 
10
19
  TEXT_SUBSTITUTIONS = [
11
20
  ['&#13;', '&#xD;'],
12
21
  ['"', '&quot;'],
13
- ['&gt;', '>']
22
+ ['&gt;', '>'],
23
+ ['&#38;', '&amp;']
14
24
  ].freeze
15
25
 
16
26
  def initialize(model)
@@ -19,7 +29,7 @@ module Archimate
19
29
  end
20
30
 
21
31
  def process_text(doc_str)
22
- %w(documentation content).each do |tag|
32
+ %w(documentation content name).each do |tag|
23
33
  TEXT_SUBSTITUTIONS.each do |from, to|
24
34
  doc_str.gsub!(%r{<#{tag}>([^<]*#{from}[^<]*)</#{tag}>}) do |str|
25
35
  str.gsub(from, to)
@@ -35,7 +45,7 @@ module Archimate
35
45
 
36
46
  def write(archifile_io)
37
47
  builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
38
- serialize_model(xml)
48
+ serialize_model(xml, model)
39
49
  end
40
50
  archifile_io.write(
41
51
  process_text(
@@ -43,188 +53,6 @@ module Archimate
43
53
  )
44
54
  )
45
55
  end
46
-
47
- def serialize_model(xml)
48
- xml["archimate"].model(
49
- "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
50
- "xmlns:archimate" => "http://www.archimatetool.com/archimate",
51
- "name" => model.name,
52
- "id" => model.id,
53
- "version" => @version
54
- ) do
55
- serialize(xml, model.organizations)
56
- serialize(xml, model.properties)
57
- model.documentation.each { |d| serialize_documentation(xml, d, "purpose") }
58
- end
59
- end
60
-
61
- def serialize_organization(xml, organization)
62
- xml.folder(
63
- remove_nil_values(name: organization.name, id: organization.id, type: organization.type)
64
- ) do
65
- serialize(xml, organization.organizations)
66
- serialize(xml, organization.documentation)
67
- organization.items.each { |i| serialize_item(xml, i) }
68
- end
69
- end
70
-
71
- def serialize_property(xml, property)
72
- xml.property(remove_nil_values(key: property.key, value: property.value))
73
- end
74
-
75
- def serialize_documentation(xml, documentation, element_name = "documentation")
76
- xml.send(element_name) { xml.text(documentation.text) }
77
- end
78
-
79
- def serialize_item(xml, item)
80
- item_instance = model.lookup(item)
81
- $stderr.puts "serialize_item item `#{item.inspect}` could not found." if item_instance.nil?
82
- serialize(xml, item_instance)
83
- end
84
-
85
- def serialize_element(xml, element)
86
- xml.element(
87
- remove_nil_values(
88
- "xsi:type" => "archimate:#{element.type}",
89
- "id" => element.id,
90
- "name" => element.name
91
- )
92
- ) do
93
- serialize(xml, element.documentation)
94
- serialize(xml, element.properties)
95
- end
96
- end
97
-
98
- def serialize_relationship(xml, rel)
99
- xml.element(
100
- remove_nil_values(
101
- "xsi:type" => "archimate:#{rel.type}",
102
- "id" => rel.id,
103
- "name" => rel.name,
104
- "source" => rel.source,
105
- "target" => rel.target,
106
- "accessType" => serialize_access_type(rel.access_type)
107
- )
108
- ) do
109
- serialize(xml, rel.documentation)
110
- serialize(xml, rel.properties)
111
- end
112
- end
113
-
114
- def serialize_access_type(val)
115
- case val
116
- when nil
117
- nil
118
- else
119
- DataModel::AccessType.index(val)
120
- end
121
- end
122
-
123
- def serialize_diagram(xml, diagram)
124
- xml.element(
125
- remove_nil_values(
126
- "xsi:type" => diagram.type || "archimate:ArchimateDiagramModel",
127
- "id" => diagram.id,
128
- "name" => diagram.name,
129
- "connectionRouterType" => diagram.connection_router_type,
130
- "viewpoint" => ArchiFileFormat::VIEWPOINTS.index(diagram.viewpoint_type)&.to_s,
131
- "background" => diagram.background
132
- )
133
- ) do
134
- serialize(xml, diagram.nodes)
135
- serialize(xml, diagram.documentation)
136
- serialize(xml, diagram.properties)
137
- end
138
- end
139
-
140
- def archi_style_hash(style)
141
- {
142
- "fillColor" => style&.fill_color&.to_rgba,
143
- "font" => style&.font&.to_archi_font,
144
- "fontColor" => style&.font_color&.to_rgba,
145
- "lineColor" => style&.line_color&.to_rgba,
146
- "lineWidth" => style&.line_width&.to_s,
147
- "textAlignment" => style&.text_alignment&.to_s,
148
- "textPosition" => style&.text_position
149
- }
150
- end
151
-
152
- def serialize_view_node(xml, child)
153
- style_hash = archi_style_hash(child.style)
154
- fill_color = style_hash.delete("fillColor")
155
- xml.child(
156
- remove_nil_values(
157
- {
158
- "xsi:type" => child.type,
159
- "id" => child.id,
160
- "name" => child.name
161
- }.merge(
162
- style_hash.merge(
163
- "targetConnections" => child.target_connections.empty? ? nil : child.target_connections.join(" "),
164
- "fillColor" => fill_color,
165
- "model" => child.model,
166
- "archimateElement" => child.archimate_element,
167
- "type" => child.child_type
168
- )
169
- )
170
- )
171
- ) do
172
- serialize(xml, child.bounds) unless child.bounds.nil?
173
- serialize(xml, child.connections)
174
- xml.content { xml.text child.content } unless child.content.nil?
175
- serialize(xml, child.nodes)
176
- serialize(xml, child.documentation)
177
- serialize(xml, child.properties)
178
- end
179
- end
180
-
181
- def serialize_bounds(xml, bounds)
182
- xml.bounds(
183
- remove_nil_values(
184
- x: bounds.x&.to_i,
185
- y: bounds.y&.to_i,
186
- width: bounds.width&.to_i,
187
- height: bounds.height&.to_i
188
- )
189
- )
190
- end
191
-
192
- def serialize_connection(xml, connection)
193
- xml.sourceConnection(
194
- remove_nil_values(
195
- {
196
- "xsi:type" => connection.type,
197
- "id" => connection.id,
198
- "name" => connection.name
199
- }.merge(
200
- archi_style_hash(connection.style).merge(
201
- "source" => connection.source,
202
- "target" => connection.target,
203
- "relationship" => connection.relationship
204
- )
205
- )
206
- )
207
- ) do
208
- serialize(xml, connection.bendpoints)
209
- serialize(xml, connection.documentation)
210
- serialize(xml, connection.properties)
211
- end
212
- end
213
-
214
- # startX = location.x - source_attachment.x
215
- # startY = location.y - source_attachment.y
216
- # endX = location.x - target_attachment.x
217
- # endY = location.y - source_attachment.y
218
- def serialize_location(xml, bendpoint)
219
- xml.bendpoint(
220
- remove_nil_values(
221
- startX: bendpoint.x == 0 ? nil : bendpoint.x&.to_i,
222
- startY: bendpoint.y == 0 ? nil : bendpoint.y&.to_i,
223
- endX: bendpoint.end_x&.to_i,
224
- endY: bendpoint.end_y&.to_i
225
- )
226
- )
227
- end
228
56
  end
229
57
  end
230
58
  end
@@ -3,234 +3,16 @@ require "nokogiri"
3
3
 
4
4
  module Archimate
5
5
  module FileFormats
6
- # This class implements common methods for the ArchiMate Model Exchange Format
7
6
  class ModelExchangeFileReader
8
- # Parses a Nokogiri document into an Archimate::Model
9
- def parse(doc)
10
- return unless doc
11
- @property_defs = []
12
- @viewpoints = []
13
- parse_model(doc.root)
7
+ def initialize(doc)
8
+ @string_or_io = doc
14
9
  end
15
10
 
16
- def parse_model(root)
17
- @property_defs = parse_property_defs(root)
18
- @viewpoints = parse_viewpoints(root)
19
- DataModel::Model.new(
20
- index_hash: {},
21
- id: identifier_to_id(root["identifier"]),
22
- name: ModelExchangeFile::XmlLangString.parse(root.at_css(">name")),
23
- version: root["version"],
24
- metadata: ModelExchangeFile::XmlMetadata.parse(root.at_css(">metadata")),
25
- documentation: parse_documentation(root),
26
- properties: parse_properties(root),
27
- elements: parse_elements(root),
28
- relationships: parse_relationships(root),
29
- organizations: parse_organizations(root.css(organizations_root_selector)),
30
- diagrams: parse_diagrams(root),
31
- viewpoints: @viewpoints,
32
- property_definitions: @property_defs,
33
- schema_locations: root.attr("xsi:schemaLocation").split(" "),
34
- namespaces: root.namespaces,
35
- archimate_version: parse_archimate_version(root)
36
- )
37
- end
38
-
39
- def parse_viewpoints(_node)
40
- return []
41
- end
42
-
43
- def parse_documentation(node, element_name = "documentation")
44
- node.css(">#{element_name}").map do |doc|
45
- DataModel::Documentation.new(text: doc.content, lang: doc["xml:lang"])
46
- end
47
- end
48
-
49
- def parse_properties(node)
50
- node.css("> properties > property").map do |i|
51
- parse_property(i)
52
- end
53
- end
54
-
55
- def parse_property(node)
56
- property_def = @property_defs.find { |prop_def| prop_def.id == node.attr(property_def_attr_name) }
57
- DataModel::Property.new(
58
- property_definition: property_def,
59
- values: [ModelExchangeFile::XmlLangString.parse(node.at_css("value"))].compact
60
- )
61
- end
62
-
63
- def parse_property_defs(node)
64
- @property_defs = node.css(property_defs_selector).map do |i|
65
- DataModel::PropertyDefinition.new(
66
- id: i["identifier"],
67
- name: property_def_name(i),
68
- documentation: parse_documentation(i),
69
- value_type: i["type"]
70
- )
71
- end
72
- end
73
-
74
- def parse_elements(model)
75
- model.css(">elements>element").map do |i|
76
- DataModel::Element.new(
77
- id: identifier_to_id(i["identifier"]),
78
- name: parse_element_name(i),
79
- type: i["xsi:type"],
80
- documentation: parse_documentation(i),
81
- properties: parse_properties(i)
82
- )
83
- end
84
- end
85
-
86
- def parse_organizations(nodes)
87
- nodes.map do |i|
88
- child_items = i.css(">item")
89
- ref_items = child_items.select { |ci| ci.has_attribute?(identifier_ref_name) }
90
- DataModel::Organization.new(
91
- id: i["identifier"], # TODO: model exchange doesn't assign ids to organization items
92
- name: ModelExchangeFile::XmlLangString.parse(i.at_css(">label")),
93
- documentation: parse_documentation(i),
94
- items: ref_items.map { |ri| identifier_to_id(ri[identifier_ref_name]) },
95
- organizations: parse_organizations(child_items.reject { |ci| ci.has_attribute?(identifier_ref_name) })
96
- )
97
- end
98
- end
99
-
100
- def parse_relationships(model)
101
- model.css(">relationships>relationship").map do |i|
102
- DataModel::Relationship.new(
103
- id: identifier_to_id(i["identifier"]),
104
- type: i.attr("xsi:type"),
105
- source: identifier_to_id(i.attr("source")),
106
- target: identifier_to_id(i.attr("target")),
107
- name: parse_element_name(i),
108
- access_type: i["accessType"],
109
- documentation: parse_documentation(i),
110
- properties: parse_properties(i)
111
- )
112
- end
113
- end
114
-
115
- def parse_diagrams(model)
116
- model.css(diagrams_path).map do |i|
117
- nodes = parse_nodes(i)
118
- connections = parse_connections(i)
119
- child_id_hash = nodes.each_with_object({}) { |i2, a| a.merge!(i2.child_id_hash) }
120
- connections.each do |c|
121
- child_id_hash[c.source].connections << c
122
- end
123
- DataModel::Diagram.new(
124
- id: identifier_to_id(i["identifier"]),
125
- name: parse_element_name(i),
126
- viewpoint_type: i["viewpoint"],
127
- viewpoint: nil, # TODO: support this for ArchiMate v3
128
- documentation: parse_documentation(i),
129
- properties: parse_properties(i),
130
- nodes: nodes,
131
- connections: connections,
132
- connection_router_type: i["connectionRouterType"],
133
- type: i.attr("xsi:type"),
134
- background: i.attr("background")
135
- )
136
- end
137
- end
138
-
139
- def parse_nodes(node)
140
- node.css("> node").map do |i|
141
- DataModel::ViewNode.new(
142
- id: identifier_to_id(i["identifier"]),
143
- type: i.attr(view_node_type_attr),
144
- model: nil,
145
- name: ModelExchangeFile::XmlLangString.parse(i.at_css(">label")),
146
- target_connections: [], # TODO: needed? "targetConnections",
147
- archimate_element: identifier_to_id(i[view_node_element_ref]),
148
- bounds: parse_bounds(i),
149
- nodes: parse_nodes(i),
150
- connections: parse_connections(i),
151
- documentation: parse_documentation(i),
152
- properties: parse_properties(i),
153
- style: parse_style(i),
154
- content: i.at_css("> content")&.text,
155
- child_type: nil
156
- )
157
- end
158
- end
159
-
160
- def parse_style(node)
161
- style = node.at_css(">style")
162
- return nil unless style
163
- DataModel::Style.new(
164
- text_alignment: style["textAlignment"],
165
- fill_color: parse_color(style, "fillColor"),
166
- line_color: parse_color(style, "lineColor"),
167
- font_color: parse_color(style.at_css(">font"), "color"),
168
- font: parse_font(style),
169
- line_width: style["lineWidth"],
170
- text_position: style.at_css("textPosition")
171
- )
172
- end
173
-
174
- def parse_font(node)
175
- font_node = node.at_css(">font")
176
- return unless font_node && font_node["name"] && font_node["size"]
177
- DataModel::Font.new(
178
- name: font_node["name"],
179
- size: font_node["size"],
180
- style: style_to_int(font_node["style"]),
181
- font_data: nil
182
- )
183
- end
184
-
185
- def parse_color(node, el_name)
186
- return unless node
187
- color_node = node.at_css(el_name)
188
- return unless color_node
189
- DataModel::Color.new(
190
- r: color_node["r"]&.to_i,
191
- g: color_node["g"]&.to_i,
192
- b: color_node["b"]&.to_i,
193
- a: color_node["a"]&.to_i
194
- )
195
- end
196
-
197
- def parse_bounds(node)
198
- DataModel::Bounds.new(
199
- x: node.attr("x"),
200
- y: node.attr("y"),
201
- width: node.attr("w"),
202
- height: node.attr("h")
203
- )
204
- end
205
-
206
- def parse_connections(node)
207
- node.css("> connection").map do |i|
208
- DataModel::Connection.new(
209
- id: identifier_to_id(i["identifier"]),
210
- type: i.attr(view_node_type_attr),
211
- source: identifier_to_id(i["source"]),
212
- target: identifier_to_id(i["target"]),
213
- relationship: identifier_to_id(i[connection_relationship_ref]),
214
- name: i.at_css("label")&.content,
215
- style: parse_style(i),
216
- bendpoints: parse_bendpoints(i),
217
- documentation: parse_documentation(i),
218
- properties: parse_properties(i)
219
- )
220
- end
221
- end
222
-
223
- def parse_bendpoints(node)
224
- node.css("bendpoint").map do |i|
225
- DataModel::Location.new(
226
- x: i.attr("x"), y: i.attr("y")
227
- )
228
- end
229
- end
230
-
231
- def identifier_to_id(str)
232
- # str&.sub(/^id-/, "")
233
- str
11
+ def parse()
12
+ handler_factory = Sax::ModelExchangeFile::ModelExchangeHandlerFactory.new
13
+ parser = Nokogiri::XML::SAX::Parser.new(Sax::Document.new(handler_factory))
14
+ parser.parse(@string_or_io)
15
+ parser.document.model
234
16
  end
235
17
  end
236
18
  end