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.
- 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
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
module ModelExchangeFile
|
|
7
|
+
module V30
|
|
8
|
+
module OrganizationBody
|
|
9
|
+
def serialize_organization_body(xml, organization)
|
|
10
|
+
if organization.items.empty? &&
|
|
11
|
+
(!organization.documentation || organization.documentation.empty?) &&
|
|
12
|
+
organization.organizations.empty?
|
|
13
|
+
return
|
|
14
|
+
end
|
|
15
|
+
serialize_label(xml, organization.name, :label)
|
|
16
|
+
serialize(xml, organization.documentation)
|
|
17
|
+
serialize(xml, organization.organizations)
|
|
18
|
+
organization.items.each { |i| serialize_item(xml, i) }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
module ModelExchangeFile
|
|
7
|
+
module V30
|
|
8
|
+
module Property
|
|
9
|
+
def serialize_property(xml, property)
|
|
10
|
+
xml.property("propertyDefinitionRef" => property.property_definition.id) do
|
|
11
|
+
XmlLangString.new(property.value, :value).serialize(xml)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
module ModelExchangeFile
|
|
7
|
+
module V30
|
|
8
|
+
# Property Definitions as defined in ArchiMate 3.0 Model Exchange XSDs
|
|
9
|
+
class PropertyDefinitions
|
|
10
|
+
def initialize(property_defs)
|
|
11
|
+
@property_definitions = property_defs
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serialize(xml)
|
|
15
|
+
return if @property_definitions.empty?
|
|
16
|
+
xml.propertyDefinitions do
|
|
17
|
+
@property_definitions.each { |property_def| serialize_property_definition(xml, property_def) }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def serialize_property_definition(xml, property_def)
|
|
22
|
+
xml.propertyDefinition(
|
|
23
|
+
"identifier" => property_def.id,
|
|
24
|
+
"type" => property_def.type
|
|
25
|
+
) do
|
|
26
|
+
XmlLangString.new(property_def.name, :name).serialize(xml)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
module ModelExchangeFile
|
|
7
|
+
module V30
|
|
8
|
+
module ViewNode
|
|
9
|
+
def serialize_view_node(xml, view_node, x_offset = 0, y_offset = 0)
|
|
10
|
+
attrs = view_node_attrs(view_node, x_offset, y_offset)
|
|
11
|
+
xml.node(attrs) do
|
|
12
|
+
serialize_label(xml, view_node.name, :label)
|
|
13
|
+
serialize(xml, view_node.style) if view_node.style
|
|
14
|
+
view_node.nodes.each do |c|
|
|
15
|
+
serialize_view_node(xml, c) # , view_node_attrs[:x].to_f, view_node_attrs[:y].to_f)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def view_node_attrs(view_node, x_offset = 0, y_offset = 0)
|
|
21
|
+
attrs = {
|
|
22
|
+
identifier: identifier(view_node.id),
|
|
23
|
+
elementRef: nil,
|
|
24
|
+
"xsi:type" => view_node.type,
|
|
25
|
+
"x" => view_node.bounds ? (view_node.bounds&.x + x_offset).round : nil,
|
|
26
|
+
"y" => view_node.bounds ? (view_node.bounds&.y + y_offset).round : nil,
|
|
27
|
+
"w" => view_node.bounds&.width&.round,
|
|
28
|
+
"h" => view_node.bounds&.height&.round
|
|
29
|
+
}
|
|
30
|
+
if view_node.element
|
|
31
|
+
attrs[:elementRef] = identifier(view_node.element.id)
|
|
32
|
+
elsif view_node.view_refs
|
|
33
|
+
# Since it doesn't seem to be forbidden, we just assume we can use
|
|
34
|
+
# the elementref for views in views
|
|
35
|
+
attrs[:elementRef] = view_node.view_refs
|
|
36
|
+
attrs[:type] = "model"
|
|
37
|
+
end
|
|
38
|
+
remove_nil_values(attrs)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
class NamedCollection
|
|
7
|
+
def initialize(name, collection)
|
|
8
|
+
@name = name
|
|
9
|
+
@collection = collection
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def serialize(xml, &block)
|
|
13
|
+
return unless @collection&.size&.positive?
|
|
14
|
+
xml.send(@name) do
|
|
15
|
+
block.call(xml, @collection)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
class Writer
|
|
7
|
+
attr_reader :model
|
|
8
|
+
|
|
9
|
+
def self.write(model, output_io)
|
|
10
|
+
writer = new(model)
|
|
11
|
+
writer.write(output_io)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(model)
|
|
15
|
+
@model = model
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def serialize(xml, collection)
|
|
19
|
+
Array(collection).each do |item|
|
|
20
|
+
case item
|
|
21
|
+
when DataModel::Element
|
|
22
|
+
serialize_element(xml, item)
|
|
23
|
+
when DataModel::Relationship
|
|
24
|
+
serialize_relationship(xml, item)
|
|
25
|
+
when DataModel::Organization
|
|
26
|
+
serialize_organization(xml, item)
|
|
27
|
+
when DataModel::Diagram
|
|
28
|
+
serialize_diagram(xml, item)
|
|
29
|
+
when DataModel::Location
|
|
30
|
+
serialize_location(xml, item)
|
|
31
|
+
when DataModel::Bounds
|
|
32
|
+
serialize_bounds(xml, item)
|
|
33
|
+
when DataModel::ViewNode
|
|
34
|
+
serialize_view_node(xml, item)
|
|
35
|
+
when DataModel::PreservedLangString
|
|
36
|
+
Serializer::XmlLangString.new(item, :documentation).serialize(xml)
|
|
37
|
+
when DataModel::Property
|
|
38
|
+
serialize_property(xml, item)
|
|
39
|
+
when DataModel::Connection
|
|
40
|
+
serialize_connection(xml, item)
|
|
41
|
+
when DataModel::Style
|
|
42
|
+
serialize_style(xml, item)
|
|
43
|
+
else
|
|
44
|
+
raise TypeError, "Unexpected item type #{item.class}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def remove_nil_values(h)
|
|
50
|
+
h.delete_if { |_k, v| v.nil? }
|
|
51
|
+
h
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
class XmlLangString
|
|
7
|
+
def initialize(lang_str, tag_name)
|
|
8
|
+
@tag_name = tag_name
|
|
9
|
+
@lang_str = lang_str
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def serialize(xml)
|
|
13
|
+
return unless @lang_str && !@lang_str.empty?
|
|
14
|
+
|
|
15
|
+
@lang_str.langs.each do |lang|
|
|
16
|
+
attrs = lang && !lang.empty? ? { "xml:lang" => lang } : {}
|
|
17
|
+
xml.send(@tag_name, attrs) { xml.text text_proc(@lang_str.by_lang(lang)) }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Processes text for text elements
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def text_proc(str)
|
|
25
|
+
str.strip.tr("\r", "\n")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Archimate
|
|
4
|
+
module FileFormats
|
|
5
|
+
module Serializer
|
|
6
|
+
class XmlMetadata
|
|
7
|
+
def initialize(metadata)
|
|
8
|
+
@metadata = metadata
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def serialize(xml)
|
|
12
|
+
return unless @metadata && !@metadata.schema_infos.empty?
|
|
13
|
+
xml.metadata do
|
|
14
|
+
if @metadata.schema_infos.size == 1
|
|
15
|
+
serialize_schema_info_body(xml, @metadata.schema_infos.first)
|
|
16
|
+
else
|
|
17
|
+
@metadata.schema_infos.each do |schema_info|
|
|
18
|
+
serialize_schema_info(xml, schema_info)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def serialize_schema_info(xml, schema_info)
|
|
27
|
+
xml.schemaInfo do
|
|
28
|
+
serialize_schema_info_body(xml, schema_info)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def serialize_schema_info_body(xml, schema_info)
|
|
33
|
+
xml.schema { xml.text schema_info.schema } if schema_info.schema
|
|
34
|
+
xml.schemaversion { xml.text schema_info.schemaversion } if schema_info.schemaversion
|
|
35
|
+
schema_info.elements.each do |el|
|
|
36
|
+
serialize_any_element(xml, el)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def serialize_any_element(xml, el)
|
|
41
|
+
xml_prefix(xml, el).send(el.element.to_sym, serialize_any_attributes(el.attributes)) do
|
|
42
|
+
xml.text(el.content) if el.content&.size&.positive?
|
|
43
|
+
el.children.each { |child| serialize_any_element(xml, child) }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def xml_prefix(xml, el)
|
|
48
|
+
if el.prefix && !el.prefix.empty?
|
|
49
|
+
xml[el.prefix]
|
|
50
|
+
else
|
|
51
|
+
xml
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def serialize_any_attributes(attrs)
|
|
56
|
+
attrs.each_with_object({}) do |attr, hash|
|
|
57
|
+
key = attr.prefix&.size&.positive? ? [attr.prefix, attr.attribute].join(":") : attr.attribute
|
|
58
|
+
hash[key] = attr.value
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Archimate
|
|
4
4
|
module FileFormats
|
|
5
|
-
module
|
|
5
|
+
module Serializer
|
|
6
6
|
# Property Definitions as defined in ArchiMate 2.1 Model Exchange XSDs
|
|
7
7
|
class XmlPropertyDefs
|
|
8
8
|
def initialize(property_defs)
|
|
@@ -16,7 +16,7 @@ module Archimate
|
|
|
16
16
|
xml.propertydef(
|
|
17
17
|
"identifier" => property_def.id,
|
|
18
18
|
"name" => property_def.name,
|
|
19
|
-
"type" => property_def.
|
|
19
|
+
"type" => property_def.type
|
|
20
20
|
)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -86,8 +86,8 @@ module Archimate
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def entity_hash_name(entity)
|
|
89
|
-
layer = DataModel::
|
|
90
|
-
layer_sort_order = layer ? DataModel::
|
|
89
|
+
layer = DataModel::Layers.for_element(entity.type)
|
|
90
|
+
layer_sort_order = layer ? DataModel::Layers.find_index(layer) : 9
|
|
91
91
|
[
|
|
92
92
|
entity.class.name, # Taking advantage of Element being before Relationship
|
|
93
93
|
layer_sort_order.to_s,
|
|
@@ -104,7 +104,7 @@ module Archimate
|
|
|
104
104
|
# 4. names differ only in punctuation
|
|
105
105
|
# 5. names differ only by stop-words (list of words such as "the", "api", etc.)
|
|
106
106
|
def simplify(entity)
|
|
107
|
-
name = entity.name&.dup || ""
|
|
107
|
+
name = entity.name&.dup.to_s || ""
|
|
108
108
|
name.sub!("(copy)", "") # (copy) is a special case inserted by the Archi tool
|
|
109
109
|
name.downcase!
|
|
110
110
|
name.gsub!(/[[:punct:]]/, "") unless entity.is_a?(DataModel::Relationship)
|
|
@@ -13,8 +13,6 @@ module Archimate
|
|
|
13
13
|
# [x] warn about names with (copy)
|
|
14
14
|
# [x] blank element names
|
|
15
15
|
class Linter
|
|
16
|
-
include FileFormats::ArchimateV2
|
|
17
|
-
|
|
18
16
|
attr_reader :model
|
|
19
17
|
|
|
20
18
|
def initialize(model)
|
|
@@ -50,18 +48,18 @@ module Archimate
|
|
|
50
48
|
def report_subsection(issues, output_io)
|
|
51
49
|
issues.each do |sub_issues|
|
|
52
50
|
output_io.puts(sub_issues)
|
|
53
|
-
output_io.puts("Sub Total: #{sub_issues.size}")
|
|
51
|
+
output_io.puts("Sub Total: #{sub_issues.size}") unless sub_issues.empty?
|
|
54
52
|
end
|
|
55
53
|
end
|
|
56
54
|
|
|
57
55
|
def unused_elements
|
|
58
|
-
referenced_elements =
|
|
59
|
-
model.elements.reject { |el| referenced_elements.include?(el
|
|
56
|
+
referenced_elements = model.diagrams.inject([]) { |memo, dia| memo.concat(dia.elements) }.uniq
|
|
57
|
+
model.elements.reject { |el| referenced_elements.include?(el) }
|
|
60
58
|
end
|
|
61
59
|
|
|
62
60
|
def unused_relationships
|
|
63
|
-
|
|
64
|
-
model.relationships.reject { |el|
|
|
61
|
+
referenced_relationships = model.diagrams.inject([]) { |memo, dia| memo.concat(dia.relationships) }.uniq
|
|
62
|
+
model.relationships.reject { |el| referenced_relationships.include?(el) }
|
|
65
63
|
end
|
|
66
64
|
|
|
67
65
|
def empty_views
|
|
@@ -88,15 +86,11 @@ module Archimate
|
|
|
88
86
|
end
|
|
89
87
|
end
|
|
90
88
|
|
|
91
|
-
def diagram_referenced_ids
|
|
92
|
-
@ref_ids ||= model.diagrams.inject([]) { |memo, dia| memo.concat(dia.referenced_identified_nodes) }.uniq
|
|
93
|
-
end
|
|
94
|
-
|
|
95
89
|
def invalid_for_viewpoint
|
|
96
90
|
model.diagrams.each_with_object([]) do |diagram, errors|
|
|
97
91
|
next if diagram.total_viewpoint?
|
|
98
|
-
valid_entity_types = VIEWPOINTS[diagram.
|
|
99
|
-
valid_relation_types = VIEWPOINTS[diagram.
|
|
92
|
+
valid_entity_types = DataModel::ViewpointType::VIEWPOINTS[diagram.viewpoint_type][:entities]
|
|
93
|
+
valid_relation_types = DataModel::ViewpointType::VIEWPOINTS[diagram.viewpoint_type][:relations]
|
|
100
94
|
invalid_elements = diagram.all_nodes.reject do |child|
|
|
101
95
|
child.element&.type.nil? || valid_entity_types.include?(child.element&.type)
|
|
102
96
|
end
|
|
@@ -113,21 +107,22 @@ module Archimate
|
|
|
113
107
|
end
|
|
114
108
|
end
|
|
115
109
|
|
|
116
|
-
# Nesting is valid for relations:
|
|
117
|
-
# * CompositionRelationship
|
|
118
|
-
# * AggregationRelationship
|
|
119
|
-
# * AssignmentRelationship
|
|
120
110
|
def nesting_without_relation
|
|
121
|
-
model
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
111
|
+
model
|
|
112
|
+
.diagrams
|
|
113
|
+
.flat_map(&:all_nodes) # These are top level view nodes
|
|
114
|
+
.reject { |view_node| !view_node.element || view_node.nodes.empty? } # reject the ones with no child view nodes
|
|
115
|
+
.flat_map { |parent|
|
|
116
|
+
parent
|
|
117
|
+
.nodes
|
|
118
|
+
.select(&:element)
|
|
119
|
+
.map { |child| [parent, child] } } # map into parent-child pairs for children that are elements
|
|
120
|
+
.select { |pair|
|
|
121
|
+
model.relationships.none? { |rel|
|
|
122
|
+
(rel.source.equal?(pair[0]) && rel.target.equal?(pair[1]))
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
.map { |pair| "#{pair[1].element} should not nest in #{pair[0].element} without valid relationship"}
|
|
131
126
|
end
|
|
132
127
|
|
|
133
128
|
def entity_naming_rules
|
|
@@ -135,9 +130,9 @@ module Archimate
|
|
|
135
130
|
if entity.name.nil? || entity.name.empty?
|
|
136
131
|
errors << "#{entity} name is empty"
|
|
137
132
|
elsif entity.name.size < 2
|
|
138
|
-
errors << "#{entity} name #{entity.name
|
|
133
|
+
errors << "#{entity} name #{entity.name} is too short"
|
|
139
134
|
elsif entity.name.include?("(copy)")
|
|
140
|
-
errors << "#{entity} name #{entity.name
|
|
135
|
+
errors << "#{entity} name #{entity.name} contains '(copy)'"
|
|
141
136
|
end
|
|
142
137
|
end
|
|
143
138
|
end
|
|
@@ -8,6 +8,7 @@ module Archimate
|
|
|
8
8
|
|
|
9
9
|
def initialize(connection)
|
|
10
10
|
@connection = connection
|
|
11
|
+
@path = Path.new(@connection)
|
|
11
12
|
@css_style = CssStyle.new(connection.style)
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -19,22 +20,22 @@ module Archimate
|
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def to_svg(xml)
|
|
22
|
-
return if connection.
|
|
23
|
+
return if connection.source.nodes.include?(connection.target)
|
|
23
24
|
xml.path(path_attrs) do
|
|
24
25
|
xml.title @connection.description
|
|
25
26
|
end
|
|
26
27
|
|
|
27
|
-
name = connection&.
|
|
28
|
+
name = connection&.relationship&.name&.strip
|
|
28
29
|
return if name.nil? || name.empty?
|
|
30
|
+
pt = @path.point(text_position)
|
|
29
31
|
xml.text_(
|
|
30
32
|
class: "archimate-relationship-name",
|
|
31
|
-
|
|
33
|
+
x: pt.x,
|
|
34
|
+
y: pt.y,
|
|
32
35
|
"text-anchor" => "middle",
|
|
33
36
|
style: css_style.text
|
|
34
37
|
) do
|
|
35
|
-
xml.
|
|
36
|
-
xml.text name
|
|
37
|
-
end
|
|
38
|
+
xml.text name
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
41
|
|
|
@@ -52,11 +53,11 @@ module Archimate
|
|
|
52
53
|
def text_position
|
|
53
54
|
case connection.style
|
|
54
55
|
when 0
|
|
55
|
-
"10%"
|
|
56
|
+
0.1 # "10%"
|
|
56
57
|
when 1
|
|
57
|
-
"90%"
|
|
58
|
+
0.9 # "90%"
|
|
58
59
|
else
|
|
59
|
-
"50%"
|
|
60
|
+
0.5 # "50%"
|
|
60
61
|
end
|
|
61
62
|
end
|
|
62
63
|
|
|
@@ -64,20 +65,20 @@ module Archimate
|
|
|
64
65
|
{
|
|
65
66
|
id: id,
|
|
66
67
|
class: path_class,
|
|
67
|
-
d:
|
|
68
|
+
d: @path.d,
|
|
68
69
|
style: line_style
|
|
69
70
|
}
|
|
70
71
|
end
|
|
71
72
|
|
|
72
73
|
def id
|
|
73
|
-
connection.
|
|
74
|
+
connection.relationship&.id || connection.id
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
# Look at the type (if any of the path and set the class appropriately)
|
|
77
78
|
def path_class
|
|
78
79
|
[
|
|
79
80
|
"archimate",
|
|
80
|
-
css_classify(connection&.
|
|
81
|
+
css_classify(connection&.relationship&.type || "default")
|
|
81
82
|
].join("-") + " archimate-relationship"
|
|
82
83
|
end
|
|
83
84
|
|
|
@@ -88,97 +89,6 @@ module Archimate
|
|
|
88
89
|
.gsub(/([a-z\d])([A-Z])/, '\1-\2')
|
|
89
90
|
.downcase
|
|
90
91
|
end
|
|
91
|
-
|
|
92
|
-
def ranges_overlap(r1, r2)
|
|
93
|
-
begin_max = [r1, r2].map(&:begin).max
|
|
94
|
-
end_min = [r1, r2].map(&:end).min
|
|
95
|
-
return nil if begin_max > end_min
|
|
96
|
-
(begin_max + end_min) / 2.0
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# builds the line coordinates for the path
|
|
100
|
-
# rough drawing is the point at center of first element, point of each bendpoint, and center of end element
|
|
101
|
-
# First naive implementation
|
|
102
|
-
# if left/right range of both overlap, use centerpoint of overlap range as x val
|
|
103
|
-
# if top/bottom range of both overlap, use centerpoint of overlap range as y val
|
|
104
|
-
def path_d
|
|
105
|
-
source_bounds = connection.source_element&.absolute_position || DataModel::Bounds.zero
|
|
106
|
-
target_bounds = connection.target_element&.absolute_position || DataModel::Bounds.zero
|
|
107
|
-
|
|
108
|
-
start_point = DataModel::Bounds.new(
|
|
109
|
-
x: source_bounds.left + source_bounds.width / 2.0,
|
|
110
|
-
y: source_bounds.top + source_bounds.height / 2.0,
|
|
111
|
-
width: 0,
|
|
112
|
-
height: 0
|
|
113
|
-
)
|
|
114
|
-
bp_bounds = connection.bendpoints.map do |bp|
|
|
115
|
-
DataModel::Bounds.new(
|
|
116
|
-
x: start_point.x + (bp.x || 0),
|
|
117
|
-
y: start_point.y + (bp.y || 0),
|
|
118
|
-
width: 0,
|
|
119
|
-
height: 0
|
|
120
|
-
)
|
|
121
|
-
end
|
|
122
|
-
bp_bounds = bp_bounds.reject do |bounds|
|
|
123
|
-
bounds.inside?(source_bounds) || bounds.inside?(target_bounds)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
bounds = [source_bounds].concat(bp_bounds) << target_bounds
|
|
127
|
-
|
|
128
|
-
points = []
|
|
129
|
-
a = bounds.shift
|
|
130
|
-
until bounds.empty?
|
|
131
|
-
b = bounds.shift
|
|
132
|
-
points.concat(calc_points(a, b))
|
|
133
|
-
a = b
|
|
134
|
-
end
|
|
135
|
-
points.uniq!
|
|
136
|
-
[move_to(points.shift)].concat(points.map { |pt| line_to(pt) }).join(" ")
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# a: Bounds
|
|
140
|
-
# b: Bounds
|
|
141
|
-
def calc_points(a, b)
|
|
142
|
-
ax_range = a.x_range
|
|
143
|
-
bx_range = b.x_range
|
|
144
|
-
|
|
145
|
-
overlap_x_center = ranges_overlap(ax_range, bx_range)
|
|
146
|
-
|
|
147
|
-
if overlap_x_center
|
|
148
|
-
ax = bx = overlap_x_center
|
|
149
|
-
elsif b.is_right_of?(a)
|
|
150
|
-
ax = a.right
|
|
151
|
-
bx = b.left
|
|
152
|
-
else
|
|
153
|
-
ax = a.left
|
|
154
|
-
bx = b.right
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
ay_range = a.y_range
|
|
158
|
-
by_range = b.y_range
|
|
159
|
-
|
|
160
|
-
overlap_y_center = ranges_overlap(ay_range, by_range)
|
|
161
|
-
|
|
162
|
-
if overlap_y_center
|
|
163
|
-
ay = by = overlap_y_center
|
|
164
|
-
elsif b.is_above?(a)
|
|
165
|
-
ay = a.top
|
|
166
|
-
by = b.bottom
|
|
167
|
-
else
|
|
168
|
-
ay = a.bottom
|
|
169
|
-
by = b.top
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
[Point.new(ax, ay), Point.new(bx, by)]
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def move_to(point)
|
|
176
|
-
"M #{point.x} #{point.y}"
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def line_to(point)
|
|
180
|
-
"L #{point.x} #{point.y}"
|
|
181
|
-
end
|
|
182
92
|
end
|
|
183
93
|
end
|
|
184
94
|
end
|