archimate 1.2.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +47 -0
- data/TODOs.org +219 -0
- data/archimate.gemspec +2 -1
- data/exe/archidiff +7 -0
- data/exe/archidiff-summary +7 -0
- data/exe/archimerge +7 -0
- data/exe/fmtxml +7 -0
- data/lib/archimate.rb +10 -21
- data/lib/archimate/cli/archi.rb +2 -1
- data/lib/archimate/cli/cleanup.rb +8 -9
- data/lib/archimate/cli/convert.rb +3 -1
- data/lib/archimate/cli/mapper.rb +1 -1
- data/lib/archimate/cli/stats.rb +1 -1
- data/lib/archimate/config.rb +4 -1
- data/lib/archimate/data_model.rb +11 -24
- data/lib/archimate/data_model/any_attribute.rb +18 -5
- data/lib/archimate/data_model/any_element.rb +30 -7
- data/lib/archimate/data_model/bounds.rb +34 -7
- data/lib/archimate/data_model/color.rb +32 -7
- data/lib/archimate/data_model/comparison.rb +87 -0
- data/lib/archimate/data_model/concern.rb +20 -7
- data/lib/archimate/data_model/connection.rb +71 -51
- data/lib/archimate/data_model/connector_type.rb +23 -0
- data/lib/archimate/data_model/diagram.rb +72 -10
- data/lib/archimate/data_model/diagram_type.rb +17 -0
- data/lib/archimate/data_model/differentiable.rb +142 -0
- data/lib/archimate/data_model/element.rb +39 -45
- data/lib/archimate/data_model/element_type.rb +89 -0
- data/lib/archimate/data_model/font.rb +30 -12
- data/lib/archimate/data_model/lang_string.rb +89 -16
- data/lib/archimate/data_model/layer.rb +55 -0
- data/lib/archimate/data_model/layers.rb +62 -0
- data/lib/archimate/data_model/location.rb +27 -11
- data/lib/archimate/data_model/metadata.rb +10 -3
- data/lib/archimate/data_model/model.rb +188 -121
- data/lib/archimate/data_model/modeling_note.rb +14 -3
- data/lib/archimate/data_model/organization.rb +44 -13
- data/lib/archimate/data_model/{documentation.rb → preserved_lang_string.rb} +1 -5
- data/lib/archimate/data_model/property.rb +17 -11
- data/lib/archimate/data_model/property_definition.rb +34 -4
- data/lib/archimate/data_model/referenceable.rb +0 -9
- data/lib/archimate/data_model/referenceable_collection.rb +201 -0
- data/lib/archimate/data_model/relationship.rb +52 -33
- data/lib/archimate/data_model/relationship_type.rb +43 -0
- data/lib/archimate/data_model/schema_info.rb +17 -6
- data/lib/archimate/data_model/style.rb +41 -11
- data/lib/archimate/data_model/view_node.rb +153 -59
- data/lib/archimate/data_model/viewpoint.rb +56 -80
- data/lib/archimate/data_model/viewpoint_type.rb +429 -0
- data/lib/archimate/export/csv_export.rb +2 -2
- data/lib/archimate/export/cypher.rb +2 -2
- data/lib/archimate/export/graph_ml.rb +7 -5
- data/lib/archimate/export/jsonl.rb +166 -0
- data/lib/archimate/export/n_quads.rb +8 -5
- data/lib/archimate/file_format.rb +4 -5
- data/lib/archimate/file_formats/archi_file_reader.rb +7 -240
- data/lib/archimate/file_formats/archi_file_writer.rb +16 -188
- data/lib/archimate/file_formats/model_exchange_file_reader.rb +7 -225
- data/lib/archimate/file_formats/model_exchange_file_writer_21.rb +22 -114
- data/lib/archimate/file_formats/model_exchange_file_writer_30.rb +22 -122
- data/lib/archimate/file_formats/sax.rb +55 -0
- data/lib/archimate/file_formats/sax/any_element.rb +64 -0
- data/lib/archimate/file_formats/sax/archi/archi_handler_factory.rb +48 -0
- data/lib/archimate/file_formats/sax/archi/bounds.rb +25 -0
- data/lib/archimate/file_formats/sax/archi/connection.rb +47 -0
- data/lib/archimate/file_formats/sax/archi/content.rb +28 -0
- data/lib/archimate/file_formats/sax/archi/diagram.rb +66 -0
- data/lib/archimate/file_formats/sax/archi/element.rb +36 -0
- data/lib/archimate/file_formats/sax/archi/location.rb +25 -0
- data/lib/archimate/file_formats/sax/archi/model.rb +109 -0
- data/lib/archimate/file_formats/sax/archi/organization.rb +60 -0
- data/lib/archimate/file_formats/sax/archi/property.rb +54 -0
- data/lib/archimate/file_formats/sax/archi/relationship.rb +50 -0
- data/lib/archimate/file_formats/sax/archi/style.rb +35 -0
- data/lib/archimate/file_formats/sax/archi/view_node.rb +76 -0
- data/lib/archimate/file_formats/sax/capture_content.rb +20 -0
- data/lib/archimate/file_formats/sax/capture_documentation.rb +19 -0
- data/lib/archimate/file_formats/sax/capture_properties.rb +20 -0
- data/lib/archimate/file_formats/sax/content_element.rb +19 -0
- data/lib/archimate/file_formats/sax/document.rb +80 -0
- data/lib/archimate/file_formats/sax/handler.rb +54 -0
- data/lib/archimate/file_formats/sax/lang_string.rb +28 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/color.rb +36 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/connection.rb +67 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/diagram.rb +60 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/element.rb +43 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/font.rb +44 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/item.rb +64 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/location.rb +23 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/metadata.rb +66 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/model.rb +124 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/model_exchange_handler_factory.rb +53 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/property.rb +32 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/property_definition.rb +36 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/relationship.rb +49 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/schema_info.rb +47 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/style.rb +66 -0
- data/lib/archimate/file_formats/sax/model_exchange_file/view_node.rb +86 -0
- data/lib/archimate/file_formats/sax/no_op.rb +17 -0
- data/lib/archimate/file_formats/sax/preserved_lang_string.rb +28 -0
- data/lib/archimate/file_formats/serializer.rb +57 -0
- data/lib/archimate/file_formats/serializer/archi/bounds.rb +23 -0
- data/lib/archimate/file_formats/serializer/archi/connection.rb +33 -0
- data/lib/archimate/file_formats/serializer/archi/diagram.rb +28 -0
- data/lib/archimate/file_formats/serializer/archi/documentation.rb +16 -0
- data/lib/archimate/file_formats/serializer/archi/element.rb +24 -0
- data/lib/archimate/file_formats/serializer/archi/location.rb +26 -0
- data/lib/archimate/file_formats/serializer/archi/model.rb +25 -0
- data/lib/archimate/file_formats/serializer/archi/organization.rb +21 -0
- data/lib/archimate/file_formats/serializer/archi/property.rb +15 -0
- data/lib/archimate/file_formats/serializer/archi/relationship.rb +36 -0
- data/lib/archimate/file_formats/serializer/archi/view_node.rb +52 -0
- data/lib/archimate/file_formats/serializer/archi/viewpoint_type.rb +45 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/element.rb +25 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/location.rb +15 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/model_exchange_file_writer.rb +32 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/organization.rb +23 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/properties.rb +15 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/relationship.rb +19 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/style.rb +48 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/connection.rb +25 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/diagram.rb +27 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/item.rb +17 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/label.rb +17 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/model.rb +36 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/organization_body.rb +25 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/property.rb +19 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v21/view_node.rb +44 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/connection.rb +26 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/diagram.rb +27 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/item.rb +17 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/label.rb +17 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/model.rb +41 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/organization_body.rb +25 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/property.rb +19 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/property_definitions.rb +34 -0
- data/lib/archimate/file_formats/serializer/model_exchange_file/v30/view_node.rb +45 -0
- data/lib/archimate/file_formats/serializer/named_collection.rb +21 -0
- data/lib/archimate/file_formats/serializer/writer.rb +56 -0
- data/lib/archimate/file_formats/serializer/xml_lang_string.rb +30 -0
- data/lib/archimate/file_formats/serializer/xml_metadata.rb +64 -0
- data/lib/archimate/file_formats/{model_exchange_file → serializer}/xml_property_defs.rb +2 -2
- data/lib/archimate/lint/duplicate_entities.rb +3 -3
- data/lib/archimate/lint/linter.rb +24 -29
- data/lib/archimate/svg/connection.rb +13 -103
- data/lib/archimate/svg/diagram.rb +1 -1
- data/lib/archimate/svg/entity/base_entity.rb +12 -8
- data/lib/archimate/svg/entity/data_entity.rb +2 -2
- data/lib/archimate/svg/entity/diagram_model_reference.rb +1 -1
- data/lib/archimate/svg/entity/event_entity.rb +2 -2
- data/lib/archimate/svg/entity/gap.rb +1 -1
- data/lib/archimate/svg/entity/group.rb +1 -1
- data/lib/archimate/svg/entity/motivation_entity.rb +1 -1
- data/lib/archimate/svg/entity/node.rb +1 -1
- data/lib/archimate/svg/entity/rect_entity.rb +1 -1
- data/lib/archimate/svg/entity/rounded_rect_entity.rb +1 -1
- data/lib/archimate/svg/entity/service_entity.rb +2 -2
- data/lib/archimate/svg/entity/value.rb +2 -2
- data/lib/archimate/svg/path.rb +153 -0
- data/lib/archimate/svg/point.rb +8 -1
- data/lib/archimate/version.rb +1 -1
- metadata +118 -36
- data/lib/archimate/data_model/archimate_node.rb +0 -181
- data/lib/archimate/data_model/concept.rb +0 -14
- data/lib/archimate/data_model/constants.rb +0 -82
- data/lib/archimate/data_model/container.rb +0 -17
- data/lib/archimate/data_model/diffable_array.rb +0 -213
- data/lib/archimate/data_model/diffable_primitive.rb +0 -83
- data/lib/archimate/data_model/label.rb +0 -19
- data/lib/archimate/data_model/named_referenceable.rb +0 -14
- data/lib/archimate/data_model/view.rb +0 -12
- data/lib/archimate/data_model/view_concept.rb +0 -18
- data/lib/archimate/file_formats/archi_file_format.rb +0 -151
- data/lib/archimate/file_formats/archimate_v2.rb +0 -461
- data/lib/archimate/file_formats/model_exchange_file/xml_lang_string.rb +0 -35
- data/lib/archimate/file_formats/model_exchange_file/xml_metadata.rb +0 -115
- data/lib/archimate/file_formats/model_exchange_file/xml_property_definitions.rb +0 -28
- data/lib/archimate/file_formats/model_exchange_file_reader_21.rb +0 -73
- data/lib/archimate/file_formats/model_exchange_file_reader_30.rb +0 -134
- data/lib/archimate/file_formats/model_exchange_file_writer.rb +0 -157
- 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
|
-
|
85
|
-
|
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,
|
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 =
|
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
|
98
|
-
|
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
|
-
|
23
|
-
|
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
|
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
|
-
@
|
9
|
-
@random ||= Random.new
|
7
|
+
def initialize(doc)
|
8
|
+
@string_or_io = doc
|
10
9
|
end
|
11
10
|
|
12
|
-
def parse(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|