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
@@ -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