lutaml-uml 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +36 -0
  3. data/.github/workflows/ubuntu.yml +38 -0
  4. data/.github/workflows/windows.yml +41 -0
  5. data/.gitignore +1 -0
  6. data/Gemfile +2 -1
  7. data/LUTAML.adoc +314 -0
  8. data/{README.md → README.adoc} +15 -16
  9. data/Rakefile +3 -1
  10. data/bin/console +1 -0
  11. data/bin/lutaml2dotpng +23 -0
  12. data/bin/yaml2lutaml +108 -0
  13. data/exe/lutaml-uml +4 -3
  14. data/lib/lutaml/layout/engine.rb +15 -0
  15. data/lib/lutaml/layout/graph_viz_engine.rb +16 -0
  16. data/lib/lutaml/uml.rb +3 -0
  17. data/lib/lutaml/uml/abstraction.rb +7 -5
  18. data/lib/lutaml/uml/activity.rb +7 -5
  19. data/lib/lutaml/uml/actor.rb +14 -12
  20. data/lib/lutaml/uml/association.rb +40 -14
  21. data/lib/lutaml/uml/behavior.rb +7 -5
  22. data/lib/lutaml/uml/class.rb +56 -16
  23. data/lib/lutaml/uml/classifier.rb +9 -6
  24. data/lib/lutaml/uml/connector.rb +16 -12
  25. data/lib/lutaml/uml/constraint.rb +8 -7
  26. data/lib/lutaml/uml/constructor_end.rb +11 -8
  27. data/lib/lutaml/uml/data_type.rb +9 -4
  28. data/lib/lutaml/uml/dependency.rb +16 -13
  29. data/lib/lutaml/uml/document.rb +71 -0
  30. data/lib/lutaml/uml/enum.rb +33 -0
  31. data/lib/lutaml/uml/event.rb +7 -5
  32. data/lib/lutaml/uml/final_state.rb +7 -5
  33. data/lib/lutaml/uml/formatter.rb +21 -0
  34. data/lib/lutaml/uml/formatter/base.rb +67 -0
  35. data/lib/lutaml/uml/formatter/graphviz.rb +335 -0
  36. data/lib/lutaml/uml/has_attributes.rb +14 -0
  37. data/lib/lutaml/uml/has_members.rb +30 -0
  38. data/lib/lutaml/uml/instance.rb +15 -10
  39. data/lib/lutaml/uml/interface/base.rb +28 -0
  40. data/lib/lutaml/uml/interface/command_line.rb +265 -0
  41. data/lib/lutaml/uml/model.rb +11 -8
  42. data/lib/lutaml/uml/node/base.rb +21 -0
  43. data/lib/lutaml/uml/node/class_node.rb +57 -0
  44. data/lib/lutaml/uml/node/class_relationship.rb +14 -0
  45. data/lib/lutaml/uml/node/document.rb +18 -0
  46. data/lib/lutaml/uml/node/field.rb +34 -0
  47. data/lib/lutaml/uml/node/has_name.rb +15 -0
  48. data/lib/lutaml/uml/node/has_type.rb +15 -0
  49. data/lib/lutaml/uml/node/method.rb +29 -0
  50. data/lib/lutaml/uml/node/method_argument.rb +16 -0
  51. data/lib/lutaml/uml/node/relationship.rb +28 -0
  52. data/lib/lutaml/uml/opaque_behavior.rb +7 -6
  53. data/lib/lutaml/uml/package.rb +16 -13
  54. data/lib/lutaml/uml/parsers/attribute.rb +70 -0
  55. data/lib/lutaml/uml/parsers/dsl.rb +375 -0
  56. data/lib/lutaml/uml/parsers/dsl_preprocessor.rb +44 -0
  57. data/lib/lutaml/uml/parsers/dsl_transform.rb +27 -0
  58. data/lib/lutaml/uml/parsers/yaml.rb +46 -0
  59. data/lib/lutaml/uml/port.rb +6 -4
  60. data/lib/lutaml/uml/primitive_type.rb +9 -4
  61. data/lib/lutaml/uml/property.rb +25 -15
  62. data/lib/lutaml/uml/pseudostate.rb +7 -6
  63. data/lib/lutaml/uml/realization.rb +7 -5
  64. data/lib/lutaml/uml/region.rb +7 -6
  65. data/lib/lutaml/uml/serializers/association.rb +58 -0
  66. data/lib/lutaml/uml/serializers/base.rb +16 -0
  67. data/lib/lutaml/uml/serializers/class.rb +29 -0
  68. data/lib/lutaml/uml/serializers/top_element_attribute.rb +14 -0
  69. data/lib/lutaml/uml/serializers/yaml_view.rb +18 -0
  70. data/lib/lutaml/uml/state.rb +8 -6
  71. data/lib/lutaml/uml/state_machine.rb +7 -5
  72. data/lib/lutaml/uml/top_element.rb +45 -35
  73. data/lib/lutaml/uml/top_element_attribute.rb +25 -0
  74. data/lib/lutaml/uml/transition.rb +8 -6
  75. data/lib/lutaml/uml/trigger.rb +8 -6
  76. data/lib/lutaml/uml/version.rb +3 -1
  77. data/lib/lutaml/uml/vertex.rb +7 -5
  78. data/lutaml-uml.gemspec +9 -2
  79. data/spec/fixtures/datamodel/models/AddressClassProfile.yml +90 -0
  80. data/spec/fixtures/datamodel/models/AddressComponentProfile.yml +63 -0
  81. data/spec/fixtures/datamodel/models/AddressComponentSpecification.yml +15 -0
  82. data/spec/fixtures/datamodel/models/AddressProfile.yml +36 -0
  83. data/spec/fixtures/datamodel/models/AttributeProfile.yml +32 -0
  84. data/spec/fixtures/datamodel/models/InterchangeAddressClassProfile.yml +79 -0
  85. data/spec/fixtures/datamodel/models/Localization copy.yml +23 -0
  86. data/spec/fixtures/datamodel/models/Localization.yml +23 -0
  87. data/spec/fixtures/datamodel/models/ProfileCompliantAddress.yml +36 -0
  88. data/spec/fixtures/datamodel/models/ProfileCompliantAddressComponent.yml +15 -0
  89. data/spec/fixtures/datamodel/models/Signature.yml +20 -0
  90. data/spec/fixtures/datamodel/models/SignatureBlankDefinition.yml +20 -0
  91. data/spec/fixtures/datamodel/models/TextDirectionCode copy.yml +16 -0
  92. data/spec/fixtures/datamodel/models/TextDirectionCode.yml +16 -0
  93. data/spec/fixtures/datamodel/models/Validity.yml +14 -0
  94. data/spec/fixtures/datamodel/models/iso19160-1/Address.yml +22 -0
  95. data/spec/fixtures/datamodel/models/iso19160-1/AddressComponent.yml +2 -0
  96. data/spec/fixtures/datamodel/style.uml.inc +37 -0
  97. data/spec/fixtures/datamodel/views/AddressClassProfile.yml +12 -0
  98. data/spec/fixtures/datamodel/views/AddressProfile.yml +3 -0
  99. data/spec/fixtures/datamodel/views/CommonModels.yml +9 -0
  100. data/spec/fixtures/datamodel/views/TopDown.yml +62 -0
  101. data/spec/fixtures/dsl/diagram.lutaml +3 -0
  102. data/spec/fixtures/dsl/diagram_attributes.lutaml +5 -0
  103. data/spec/fixtures/dsl/diagram_class_assocation.lutaml +29 -0
  104. data/spec/fixtures/dsl/diagram_class_fields.lutaml +19 -0
  105. data/spec/fixtures/dsl/diagram_comments.lutaml +28 -0
  106. data/spec/fixtures/dsl/diagram_concept_model.lutaml +132 -0
  107. data/spec/fixtures/dsl/diagram_data_types.lutaml +24 -0
  108. data/spec/fixtures/dsl/diagram_includes.lutaml +6 -0
  109. data/spec/fixtures/dsl/diagram_multiply_classes.lutaml +7 -0
  110. data/spec/fixtures/dsl/shared.lutaml +3 -0
  111. data/spec/fixtures/dsl/shared1.lutaml +4 -0
  112. data/spec/fixtures/generated_dot/AddressClassProfile.dot +170 -0
  113. data/spec/fixtures/generated_dot/AddressProfile.dot +34 -0
  114. data/spec/lutaml/uml/formatter/graphviz_spec.rb +41 -0
  115. data/spec/lutaml/uml/parsers/dsl_spec.rb +252 -0
  116. data/spec/lutaml/uml/parsers/yaml_spec.rb +18 -0
  117. data/spec/lutaml/uml/serializers/yaml_view_spec.rb +20 -0
  118. data/spec/lutaml/uml_spec.rb +2 -4
  119. data/spec/spec_helper.rb +11 -0
  120. metadata +161 -13
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lutaml
4
+ module Uml
5
+ module Parsers
6
+ # Class for preprocessing dsl ascii file special directives:
7
+ # - include
8
+ module DslPreprocessor
9
+ module_function
10
+
11
+ def call(input_file)
12
+ include_root = File.dirname(input_file.path)
13
+ input_file.read.split("\n").reduce([]) do |res, line|
14
+ res.push(*process_dsl_line(include_root, line))
15
+ end.join("\n")
16
+ end
17
+
18
+ def process_dsl_line(include_root, line)
19
+ process_include_line(include_root, process_comment_line(line))
20
+ end
21
+
22
+ def process_comment_line(line)
23
+ has_comment = line.match(Regexp.new("//.+"))
24
+ return line if has_comment.nil?
25
+
26
+ line.gsub(Regexp.new("//.+"), "")
27
+ end
28
+
29
+ def process_include_line(include_root, line)
30
+ include_path_match = line.match(/\s*include\s+(.+)/)
31
+ return line if include_path_match.nil?
32
+
33
+ path_to_file = include_path_match[1].strip
34
+ path_to_file = if path_to_file.match?(/^\//)
35
+ path_to_file
36
+ else
37
+ File.join(include_root, path_to_file)
38
+ end
39
+ File.read(path_to_file).split("\n")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+
5
+ module Lutaml
6
+ module Uml
7
+ module Parsers
8
+ # Class for additional transformations of LutaML syntax:
9
+ # visibility modifier etc
10
+ class DslTransform < Parslet::Transform
11
+ rule(visibility_modifier: simple(:visibility_value)) do
12
+ case visibility_value
13
+ when "-"
14
+ "private"
15
+ when "#"
16
+ "protected"
17
+ when "~"
18
+ "friendly"
19
+ else
20
+ "public"
21
+ end
22
+ end
23
+ rule(simple(:member)) { member.nil? ? member : member.to_s.strip }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "lutaml/uml/class"
5
+ require "lutaml/uml/document"
6
+ require "lutaml/uml/serializers/yaml_view"
7
+
8
+ module Lutaml
9
+ module Uml
10
+ module Parsers
11
+ class Yaml
12
+ def self.parse(yaml_path, options = {})
13
+ new.parse(yaml_path, options)
14
+ end
15
+
16
+ def parse(yaml_path, _options = {})
17
+ yaml_parse(yaml_path)
18
+ end
19
+
20
+ def yaml_parse(yaml_path)
21
+ yaml_content = YAML.safe_load(File.read(yaml_path))
22
+ serialized_yaml = Lutaml::Uml::Serializers::YamlView
23
+ .new(yaml_content)
24
+ result = Lutaml::Uml::Document.new(serialized_yaml)
25
+ result.classes = imports_to_classes(yaml_content, yaml_path)
26
+ result
27
+ end
28
+
29
+ private
30
+
31
+ def imports_to_classes(yaml_content, yaml_path)
32
+ models_path = File.join(File.dirname(yaml_path), "..", "models")
33
+ yaml_content["imports"].map do |(klass_name, _)|
34
+ klass_attrs = YAML.safe_load(
35
+ File.read(
36
+ File.join(models_path, "#{klass_name}.yml")
37
+ )
38
+ )
39
+ klass_attrs["name"] = klass_name if klass_attrs["name"].nil?
40
+ Lutaml::Uml::Serializers::Class.new(klass_attrs)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,6 +1,8 @@
1
- module Lutaml::Uml
2
-
3
- class Port < Property
4
- end
1
+ # frozen_string_literal: true
5
2
 
3
+ module Lutaml
4
+ module Uml
5
+ class Port < Property
6
+ end
7
+ end
6
8
  end
@@ -1,6 +1,11 @@
1
- module Lutaml::Uml
2
-
3
- class PrimitiveType < DataType
4
- end
1
+ # frozen_string_literal: true
5
2
 
3
+ module Lutaml
4
+ module Uml
5
+ class PrimitiveType < DataType
6
+ def keyword
7
+ "primitive"
8
+ end
9
+ end
10
+ end
6
11
  end
@@ -1,17 +1,27 @@
1
- module Lutaml::Uml
1
+ # frozen_string_literal: true
2
2
 
3
- class Property < TopElement
4
- attr_accessor :type, :aggregation, :association, :is_derived, :lowerValue, :upperValue
5
- def initialize
6
- @name = nil
7
- @xmi_id = nil
8
- @xmi_uuid = nil
9
- @aggregation = nil
10
- @association = nil
11
- @namespace = nil
12
- @is_derived = false
13
- @visibility = 'public'
14
- @lowerValue = '1'
15
- @upperValue = '1'
16
- end
3
+ module Lutaml
4
+ module Uml
5
+ class Property < TopElement
6
+ attr_accessor :type,
7
+ :aggregation,
8
+ :association,
9
+ :is_derived,
10
+ :lowerValue,
11
+ :upperValue
12
+
13
+ def initialize
14
+ @name = nil
15
+ @xmi_id = nil
16
+ @xmi_uuid = nil
17
+ @aggregation = nil
18
+ @association = nil
19
+ @namespace = nil
20
+ @is_derived = false
21
+ @visibility = "public"
22
+ @lowerValue = "1"
23
+ @upperValue = "1"
24
+ end
25
+ end
26
+ end
17
27
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ##
2
4
  ## Behaviour metamodel
3
5
  ##
4
- module Lutaml::Uml
5
-
6
- class Pseudostate < Vertex
7
- end
8
-
9
-
6
+ module Lutaml
7
+ module Uml
8
+ class Pseudostate < Vertex
9
+ end
10
+ end
10
11
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ##
2
4
  ## Behaviour metamodel
3
5
  ##
4
- module Lutaml::Uml
5
-
6
- class Realization < Abstraction
7
- end
8
-
6
+ module Lutaml
7
+ module Uml
8
+ class Realization < Abstraction
9
+ end
10
+ end
9
11
  end
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ##
2
4
  ## Behaviour metamodel
3
5
  ##
4
6
 
5
- module Lutaml::Uml
6
-
7
- class Region < TopElement
8
- end
9
-
10
-
7
+ module Lutaml
8
+ module Uml
9
+ class Region < TopElement
10
+ end
11
+ end
11
12
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/uml/serializers/base"
4
+ require "lutaml/uml/serializers/class"
5
+
6
+ module Lutaml
7
+ module Uml
8
+ module Serializers
9
+ class Association < Base
10
+ property :member_end, from: :target
11
+ property :member_end_attribute_name,
12
+ from: "relationship",
13
+ transform_with: (lambda do |val|
14
+ val.dig("target", "attributes")&.keys&.first ||
15
+ val.dig("target", "attribute")&.keys&.first
16
+ end)
17
+ property :member_end_cardinality,
18
+ from: "relationship",
19
+ transform_with: (lambda do |val|
20
+ res = val.dig("source", "attributes")&.values&.first ||
21
+ val.dig("source", "attribute")&.values&.first
22
+ res["cardinality"] if res
23
+ end)
24
+ property :member_end_type,
25
+ from: "relationship",
26
+ transform_with: (lambda do |val|
27
+ val.dig("target", "type")
28
+ end)
29
+ property :owner_end_attribute_name,
30
+ from: "relationship",
31
+ transform_with: (lambda do |val|
32
+ val.dig("source", "attributes")&.keys&.first ||
33
+ val.dig("source", "attribute")&.keys&.first
34
+ end)
35
+ property :owner_end_cardinality,
36
+ from: "relationship",
37
+ transform_with: (lambda do |val|
38
+ res = val.dig("source", "attributes")&.values&.first ||
39
+ val.dig("source", "attribute")&.values&.first
40
+ res["cardinality"] if res
41
+ end)
42
+ property :owner_end_type,
43
+ from: "relationship",
44
+ transform_with: (lambda do |val|
45
+ val.dig("source", "type")
46
+ end)
47
+ property :action,
48
+ transform_with: (lambda do |val|
49
+ if val["direction"] == "target"
50
+ "#{val['verb']} ▶"
51
+ else
52
+ "◀ #{val['verb']}"
53
+ end
54
+ end)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hashie"
4
+
5
+ module Lutaml
6
+ module Uml
7
+ module Serializers
8
+ class Base < Hashie::Dash
9
+ include Hashie::Extensions::Dash::PropertyTranslation
10
+ include Hashie::Extensions::Dash::IndifferentAccess
11
+ include Hashie::Extensions::Dash::Coercion
12
+ include Hashie::Extensions::IgnoreUndeclared
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/uml/serializers/base"
4
+ require "lutaml/uml/serializers/top_element_attribute"
5
+ require "lutaml/uml/serializers/association"
6
+
7
+ module Lutaml
8
+ module Uml
9
+ module Serializers
10
+ class Class < Base
11
+ property :attributes,
12
+ transform_with: (lambda do |entry|
13
+ entry
14
+ .to_a
15
+ .map do |(name, attributes)|
16
+ attributes.merge(name: name)
17
+ end
18
+ end)
19
+ property :associations,
20
+ from: :relations,
21
+ coerce: Array[::Lutaml::Uml::Serializers::Association]
22
+ property :name
23
+ # property :type, from: :modelType
24
+ # property :relations,
25
+ # coerce: Array[Relation]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/uml/serializers/base"
4
+
5
+ module Lutaml
6
+ module Uml
7
+ module Serializers
8
+ class TopElementAttribute < Base
9
+ property :cardinality
10
+ property :type
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/uml/serializers/base"
4
+ require "lutaml/uml/serializers/class"
5
+
6
+ module Lutaml
7
+ module Uml
8
+ module Serializers
9
+ class YamlView < Base
10
+ property :name
11
+ property :title
12
+ property :caption
13
+ property :groups
14
+ property :fidelity
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ##
2
4
  ## Behaviour metamodel
3
5
  ##
4
- module Lutaml::Uml
5
-
6
- class State < Vertex
7
- attr_accessor :exit, :entry, :do_activity
8
- end
9
-
6
+ module Lutaml
7
+ module Uml
8
+ class State < Vertex
9
+ attr_accessor :exit, :entry, :do_activity
10
+ end
11
+ end
10
12
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ##
2
4
  ## Behaviour metamodel
3
5
  ##
4
6
 
5
- module Lutaml::Uml
6
-
7
- class StateMachine < Behavior
8
- end
9
-
7
+ module Lutaml
8
+ module Uml
9
+ class StateMachine < Behavior
10
+ end
11
+ end
10
12
  end
@@ -1,37 +1,47 @@
1
- module Lutaml::Uml
2
-
3
- class TopElement
4
- attr_accessor :name, :xmi_id, :xmi_uuid, :namespace, :stereotype, :href, :visibility
5
-
6
- def initialize
7
- @name = nil
8
- @xmi_id = nil
9
- @xmi_uuid = nil
10
- @namespace = nil
11
- @href = nil
12
- @visibility = 'public'
13
- end
14
-
15
- def full_name
16
- if self.name == nil
17
- return nil
18
- end
19
-
20
- the_name = self.name
21
- next_namespace = self.namespace
22
-
23
- while next_namespace != nil
24
- if next_namespace.name != nil
25
- the_name = next_namespace.name + '::' + the_name
26
- else
27
- the_name = '::' + the_name
28
- end
29
- next_namespace = next_namespace.namespace
30
- end
31
-
32
- the_name
33
-
34
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Lutaml
4
+ module Uml
5
+ class TopElement
6
+ include HasAttributes
7
+
8
+ attr_accessor :name,
9
+ :xmi_id,
10
+ :xmi_uuid,
11
+ :namespace,
12
+ :keyword,
13
+ :stereotype,
14
+ :href,
15
+ :visibility,
16
+ :comments
17
+
18
+ # rubocop:disable Rails/ActiveRecordAliases
19
+ def initialize(attributes = {})
20
+ @visibility = "public"
21
+ @name = attributes["name"]
22
+ update_attributes(attributes)
23
+ end
24
+ # rubocop:enable Rails/ActiveRecordAliases
25
+
26
+ def full_name
27
+ if name == nil
28
+ return nil
29
+ end
30
+
31
+ the_name = name
32
+ next_namespace = namespace
33
+
34
+ while !next_namespace.nil?
35
+ the_name = if !next_namespace.name.nil?
36
+ next_namespace.name + "::" + the_name
37
+ else
38
+ "::" + the_name
39
+ end
40
+ next_namespace = next_namespace.namespace
41
+ end
42
+
43
+ the_name
44
+ end
45
+ end
35
46
  end
36
-
37
47
  end