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
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  # This module takes an ArchiMate model and builds GraphML representation of it.
3
3
  require "set"
4
+ require "nokogiri"
4
5
 
5
6
  module Archimate
6
7
  module Export
@@ -81,14 +82,15 @@ module Archimate
81
82
  end
82
83
 
83
84
  def docs(xml, docs)
84
- docs.each do |doc|
85
- data(xml, "documentation", doc)
85
+ return unless docs
86
+ docs.langs.each do |lang|
87
+ data(xml, "documentation", docs.by_lang(lang))
86
88
  end
87
89
  end
88
90
 
89
91
  def nodes(xml, elements)
90
92
  elements.each do |element|
91
- node(xml, element.id, element.name, element.type, element.documentation, element.properties)
93
+ node(xml, element.id, element.name, element.type, docs: element.documentation, properties: element.properties)
92
94
 
93
95
  @layers[element.layer] << element.id
94
96
  end
@@ -106,7 +108,7 @@ module Archimate
106
108
  end
107
109
  end
108
110
 
109
- def node(xml, id, name, type, docs = [], properties = [], other_data = {})
111
+ def node(xml, id, name, type, other_data = {}, docs: nil, properties: [])
110
112
  xml.node(id: id, label: name, labels: "#{type}:#{name}") do
111
113
  data_type(xml, "element-type", type)
112
114
  name(xml, name)
@@ -118,7 +120,7 @@ module Archimate
118
120
  properties(xml, id, properties)
119
121
  end
120
122
 
121
- def edge(xml, id, source, target, type, name = nil, docs = [], properties = [])
123
+ def edge(xml, id, source, target, type, name = nil, docs = nil, properties = [])
122
124
  xml.edge(id: id, source: source, target: target, label: type) do
123
125
  data_type(xml, "relationship-type", type)
124
126
  name(xml, name)
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This module takes an ArchiMate model and builds a JSONL representation of it
4
+ # suitable for import into ArangoDB
5
+ #
6
+ # Node Schema:
7
+ # Properties:
8
+ # name: Element.name
9
+ # nodelId: Element.id
10
+ # layer: Element.layer
11
+ # documentation: Element.documentation
12
+ # Element.properties
13
+ # ("prop:#{Property.key}"): Property.value
14
+ # Labels:
15
+ # Element.type
16
+ #
17
+ # Edge Schema:
18
+ # Properties:
19
+ # weight (of Relationship Type as in table below)
20
+ # relationshipId: Relationship.id
21
+ # name: Relationship.name
22
+ # documentation: Relationship.documentation
23
+ # accessType: Relationship.access_type
24
+ # Labels:
25
+ # Relationship.type
26
+ #
27
+ # | Weight | Name |
28
+ # |--------+----------------|
29
+ # | 1 | Association |
30
+ # | 2 | Access |
31
+ # | 3 | Used by |
32
+ # | 4 | Realization |
33
+ # | 5 | Assignment |
34
+ # | 6 | Aggregation |
35
+ # | 7 | Composition |
36
+ # | 8 | Flow |
37
+ # | 9 | Triggering |
38
+ # | 10 | Grouping |
39
+ # | 11 | Junction |
40
+ # | 12 | Specialization |
41
+ # Structural stronger than Dependency Relationships
42
+ # ServingRelationship == UsedByRelationship
43
+ require "json"
44
+
45
+ module Archimate
46
+ module Export
47
+ def self.clean_json(hash)
48
+ JSON.generate(hash.delete_if { |_k,v| v.nil? || (v.is_a?(String) && v.empty?) })
49
+ end
50
+
51
+ class PropertiesHash
52
+ attr_reader :properties
53
+
54
+ def initialize(properties)
55
+ @properties = properties
56
+ end
57
+
58
+ def to_h
59
+ properties.each_with_object({}) do |property, hash|
60
+ hash[property.key.to_s] = property.value.to_s
61
+ end
62
+ end
63
+ end
64
+
65
+ class JsonlNode
66
+ attr_reader :element
67
+
68
+ def initialize(element)
69
+ @element = element
70
+ end
71
+
72
+ # n:BusinessActor
73
+ # `layer`: "Business",
74
+ # `name`: Felix,
75
+ # `nodeId`: "d8e75068-df75-4c21-a2af-fab5c195687a"
76
+ def to_jsonl
77
+ Export.clean_json(
78
+ {
79
+ _key: element.id,
80
+ name: element.name&.to_s,
81
+ layer: element.layer&.delete(" "),
82
+ type: element.type,
83
+ documentation: element.documentation&.to_s,
84
+ properties: PropertiesHash.new(element.properties).to_h
85
+ }
86
+ )
87
+ end
88
+ end
89
+
90
+ class JsonlEdge
91
+ WEIGHTS = {
92
+ 'GroupingRelationship' => 0,
93
+ 'JunctionRelationship' => 0,
94
+ 'AssociationRelationship' => 0,
95
+ 'SpecialisationRelationship' => 1,
96
+ 'FlowRelationship' => 2,
97
+ 'TriggeringRelationship' => 3,
98
+ 'InfluenceRelationship' => 4,
99
+ 'AccessRelationship' => 5,
100
+ 'UsedByRelationship' => 6,
101
+ 'RealisationRelationship' => 7,
102
+ 'AssignmentRelationship' => 8,
103
+ 'AggregationRelationship' => 9,
104
+ 'CompositionRelationship' => 10
105
+ }
106
+
107
+ attr_reader :relationship
108
+
109
+ def initialize(relationship)
110
+ @relationship = relationship
111
+ end
112
+
113
+ def to_jsonl
114
+ Export.clean_json(
115
+ {
116
+ _key: relationship.id,
117
+ _from: relationship.source,
118
+ _to: relationship.target,
119
+ name: relationship.name&.to_s,
120
+ type: relationship.type,
121
+ accessType: relationship.access_type,
122
+ documentation: relationship.documentation&.to_s,
123
+ properties: PropertiesHash.new(relationship.properties).to_h,
124
+ weight: weight
125
+ }
126
+ )
127
+ end
128
+
129
+ private
130
+ def weight
131
+ unless WEIGHTS.include?(relationship.type)
132
+ raise "Relationship type not found: \"#{relationship.type}\""
133
+ return 0
134
+ end
135
+ WEIGHTS[relationship.type]
136
+ end
137
+ end
138
+
139
+ class Jsonl
140
+ attr_reader :output_io
141
+
142
+ def initialize(output_io)
143
+ @output_io = output_io
144
+ end
145
+
146
+ def to_jsonl(model)
147
+ write_nodes(model.elements)
148
+ write_relationships(model.relationships)
149
+ end
150
+
151
+ def write_nodes(elements)
152
+ elements.each { |element| write(JsonlNode.new(element).to_jsonl) }
153
+ end
154
+
155
+ def write_relationships(relationships)
156
+ relationships.each { |relationship| write(JsonlEdge.new(relationship).to_jsonl) }
157
+ end
158
+
159
+ private
160
+
161
+ def write(str)
162
+ @output_io.puts(str)
163
+ end
164
+ end
165
+ end
166
+ end
@@ -94,17 +94,18 @@ module Archimate
94
94
 
95
95
  def documentation(el)
96
96
  docs = []
97
- el.documentation.each do |doc|
98
- docs << make_quad(el.id, "documentation", doc.text)
97
+ return docs unless el.documentation && !el.documentation.empty?
98
+ el.documentation.langs.each do |lang|
99
+ docs << make_quad(el.id, "documentation", el.documentation.by_lang(lang))
99
100
  end
100
101
  docs
101
102
  end
102
103
 
103
104
  def relationships(el)
104
105
  [
105
- make_quad(el.source, predicate(el.type), el.target),
106
- make_quad(el.id, "sources", el.source),
107
- make_quad(el.id, "target", el.target)
106
+ make_quad(el.source.id, predicate(el.type), el.target.id),
107
+ make_quad(el.id, "sources", el.source.id),
108
+ make_quad(el.id, "target", el.target.id)
108
109
  ]
109
110
  end
110
111
 
@@ -112,6 +113,7 @@ module Archimate
112
113
  "AssociationRelationship" => %w(associated_with associated_with),
113
114
  "AccessRelationship" => %w(accesses accessed_by),
114
115
  "UsedByRelationship" => %w(used_by uses),
116
+ "ServingRelationship" => %w(serving served_by),
115
117
  "RealisationRelationship" => %w(realizes realized_by),
116
118
  "AssignmentRelationship" => %w(assigned_to assigned_from),
117
119
  "AggregationRelationship" => %w(aggregates aggregated_by),
@@ -120,6 +122,7 @@ module Archimate
120
122
  "TriggeringRelationship" => %w(triggers triggered_by),
121
123
  "GroupingRelationship" => %w(groups grouped_by),
122
124
  "SpecialisationRelationship" => %w(specializes specialized_by),
125
+ "SpecializationRelationship" => %w(specializes specialized_by),
123
126
  "InfluenceRelationship" => %w(influences influenced)
124
127
  }.freeze
125
128
 
@@ -18,12 +18,11 @@ module Archimate
18
18
  def self.parse(str)
19
19
  doc = Nokogiri::XML(str)
20
20
  case doc.namespaces["xmlns"]
21
- when "http://www.opengroup.org/xsd/archimate/3.0/"
22
- FileFormats::ModelExchangeFileReader30.new.parse(doc)
23
- when "http://www.opengroup.org/xsd/archimate"
24
- FileFormats::ModelExchangeFileReader21.new.parse(doc)
21
+ when "http://www.opengroup.org/xsd/archimate/3.0/",
22
+ "http://www.opengroup.org/xsd/archimate"
23
+ FileFormats::ModelExchangeFileReader.new(str).parse
25
24
  else
26
- FileFormats::ArchiFileReader.new.parse(doc)
25
+ FileFormats::ArchiFileReader.new(str).parse
27
26
  end
28
27
  end
29
28
  end
@@ -4,248 +4,15 @@ require "nokogiri"
4
4
  module Archimate
5
5
  module FileFormats
6
6
  class ArchiFileReader
7
- def initialize
8
- @progress = nil
9
- @random ||= Random.new
7
+ def initialize(doc)
8
+ @string_or_io = doc
10
9
  end
11
10
 
12
- def parse(doc)
13
- @size = 0
14
- doc.traverse { |_n| @size += 1 }
15
- @progress = ProgressIndicator.new(total: @size, title: "Parsing")
16
- @property_defs = {}
17
- tick
18
- diagrams = parse_diagrams(doc.root)
19
- DataModel::Model.new(
20
- id: doc.root["id"],
21
- name: doc.root["name"],
22
- documentation: parse_documentation(doc.root, "purpose"),
23
- properties: parse_properties(doc.root),
24
- elements: parse_elements(doc.root),
25
- organizations: parse_organizations(doc.root),
26
- relationships: parse_relationships(doc.root),
27
- diagrams: diagrams,
28
- viewpoints: [],
29
- property_definitions: @property_defs.values,
30
- namespaces: {},
31
- schema_locations: []
32
- )
33
- ensure
34
- @progress&.finish
35
- @progress = nil
36
- end
37
-
38
- def parse_documentation(node, element_name = "documentation")
39
- node.css(">#{element_name}").each_with_object([]) do |i, a|
40
- tick
41
- a << DataModel::Documentation.new(text: i.content)
42
- end
43
- end
44
-
45
- def parse_properties(node)
46
- node.css(">property").each_with_object([]) do |i, a|
47
- tick
48
- key = i["key"]
49
- next unless key
50
- if @property_defs.key?(key)
51
- prop_def = @property_defs[key]
52
- else
53
- @property_defs[key] = prop_def = DataModel::PropertyDefinition.new(
54
- id: DataModel::PropertyDefinition.identifier_for_key(key),
55
- name: key,
56
- documentation: [],
57
- value_type: "string"
58
- )
59
- end
60
- a << DataModel::Property.new(
61
- values: [
62
- DataModel::LangString.new(text: i["value"] || "en")
63
- ],
64
- property_definition: prop_def
65
- )
66
- end
67
- end
68
-
69
- def parse_elements(model)
70
- model.css(ArchiFileFormat::FOLDER_XPATHS.join(",")).css('element[id]').map do |i|
71
- tick
72
- DataModel::Element.new(
73
- id: i["id"],
74
- name: i["name"],
75
- organization_id: i.parent["id"],
76
- type: i["xsi:type"].sub("archimate:", ""),
77
- documentation: parse_documentation(i),
78
- properties: parse_properties(i)
79
- )
80
- end
81
- end
82
-
83
- def parse_organizations(node)
84
- node.css("> folder").each_with_object([]) do |i, a|
85
- tick
86
- a << DataModel::Organization.new(
87
- id: i.attr("id"),
88
- name: i.attr("name"),
89
- type: i.attr("type"),
90
- documentation: parse_documentation(i),
91
- properties: parse_properties(i),
92
- items: child_element_ids(i),
93
- organizations: parse_organizations(i)
94
- )
95
- end
96
- end
97
-
98
- def child_element_ids(node)
99
- node.css(">element[id]").each_with_object([]) do |i, a|
100
- tick
101
- a << i.attr("id")
102
- end
103
- end
104
-
105
- def parse_relationships(model)
106
- model.css(ArchiFileFormat::RELATION_XPATHS.join(",")).css("element").map do |i|
107
- tick
108
- DataModel::Relationship.new(
109
- id: i["id"],
110
- type: i.attr("xsi:type").sub("archimate:", ""),
111
- source: i.attr("source"),
112
- target: i.attr("target"),
113
- name: i["name"],
114
- access_type: parse_access_type(i["accessType"]),
115
- documentation: parse_documentation(i),
116
- properties: parse_properties(i)
117
- )
118
- end
119
- end
120
-
121
- def parse_access_type(val)
122
- return nil unless val && val.size > 0
123
- i = val.to_i
124
- return nil unless i >= 0 && i < DataModel::AccessType.size
125
- DataModel::AccessType[i]
126
- end
127
-
128
- def parse_diagrams(model)
129
- model.css(ArchiFileFormat::DIAGRAM_XPATHS.join(",")).css(
130
- 'element[xsi|type="archimate:ArchimateDiagramModel"]',
131
- 'element[xsi|type="archimate:SketchModel"]'
132
- ).map do |i|
133
- tick
134
- viewpoint_idx = i["viewpoint"]
135
- viewpoint_idx = viewpoint_idx.to_i unless viewpoint_idx.nil?
136
- viewpoint_type = viewpoint_idx.nil? ? nil : ArchiFileFormat::VIEWPOINTS[viewpoint_idx]
137
- DataModel::Diagram.new(
138
- id: i["id"],
139
- name: i["name"],
140
- viewpoint_type: viewpoint_type,
141
- viewpoint: nil,
142
- documentation: parse_documentation(i),
143
- properties: parse_properties(i),
144
- nodes: parse_nodes(i),
145
- connections: parse_all_connections(i),
146
- connection_router_type: i["connectionRouterType"],
147
- type: i.attr("xsi:type"),
148
- background: i.attr("background"),
149
- organization_id: nil
150
- )
151
- end
152
- end
153
-
154
- def parse_nodes(node)
155
- node.css("> child").each_with_object([]) do |child_node, a|
156
- tick
157
- a << DataModel::ViewNode.new(
158
- id: child_node.attr("id"),
159
- type: child_node.attr("xsi:type"),
160
- model: child_node.attr("model"),
161
- name: child_node.attr("name"),
162
- target_connections: parse_target_connections(child_node.attr("targetConnections")),
163
- archimate_element: child_node.attr("archimateElement"),
164
- bounds: parse_bounds(child_node),
165
- nodes: parse_nodes(child_node),
166
- connections: parse_connections(child_node),
167
- documentation: parse_documentation(child_node),
168
- properties: parse_properties(child_node),
169
- style: parse_style(child_node),
170
- content: child_node.at_css("> content")&.text,
171
- child_type: child_node.attr("type")
172
- )
173
- end
174
- end
175
-
176
- def parse_target_connections(str)
177
- return [] if str.nil?
178
- str.split(" ")
179
- end
180
-
181
- def parse_style(style)
182
- tick
183
- DataModel::Style.new(
184
- text_alignment: style["textAlignment"],
185
- fill_color: DataModel::Color.rgba(style["fillColor"]),
186
- line_color: DataModel::Color.rgba(style["lineColor"]),
187
- font_color: DataModel::Color.rgba(style["fontColor"]),
188
- font: DataModel::Font.archi_font_string(style["font"]),
189
- line_width: style["lineWidth"],
190
- text_position: style["textPosition"]
191
- )
192
- end
193
-
194
- def parse_bounds(node)
195
- bounds = node.at_css("> bounds")
196
- tick
197
- unless bounds.nil?
198
- DataModel::Bounds.new(
199
- x: bounds.attr("x"),
200
- y: bounds.attr("y"),
201
- width: bounds.attr("width"),
202
- height: bounds.attr("height")
203
- )
204
- end
205
- end
206
-
207
- def parse_all_connections(node)
208
- node.css("sourceConnection").each_with_object([]) do |i, a|
209
- tick
210
- a << parse_connection(i)
211
- end
212
- end
213
-
214
- def parse_connections(node)
215
- node.css("> sourceConnection").each_with_object([]) { |i, a| a << parse_connection(i) }
216
- end
217
-
218
- def parse_connection(i)
219
- DataModel::Connection.new(
220
- id: i["id"],
221
- type: i.attr("xsi:type"),
222
- source: i["source"],
223
- target: i["target"],
224
- relationship: i["relationship"] || i["archimateRelationship"],
225
- name: i["name"],
226
- style: parse_style(i),
227
- bendpoints: parse_bendpoints(i),
228
- documentation: parse_documentation(i),
229
- properties: parse_properties(i)
230
- )
231
- end
232
-
233
- # startX = location.x - source_attachment.x
234
- # startY = location.y - source_attachment.y
235
- # endX = location.x - target_attachment.x
236
- # endY = location.y - source_attachment.y
237
- def parse_bendpoints(node)
238
- node.css("bendpoint").each_with_object([]) do |i, a|
239
- tick
240
- a << DataModel::Location.new(
241
- x: i.attr("startX") || 0, y: i.attr("startY") || 0,
242
- end_x: i.attr("endX"), end_y: i.attr("endY")
243
- )
244
- end
245
- end
246
-
247
- def tick
248
- @progress&.increment
11
+ def parse()
12
+ handler_factory = Sax::Archi::ArchiHandlerFactory.new
13
+ parser = Nokogiri::XML::SAX::Parser.new(Sax::Document.new(handler_factory))
14
+ parser.parse(@string_or_io)
15
+ parser.document.model
249
16
  end
250
17
  end
251
18
  end