lutaml 0.7.7 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.gitignore +7 -6
  4. data/.rubocop.yml +1 -0
  5. data/LUTAML.adoc +372 -0
  6. data/Makefile +2 -0
  7. data/bin/console +5 -0
  8. data/bin/folder_yaml2lutaml.sh +6 -0
  9. data/bin/plantuml2lutaml +59 -0
  10. data/bin/yaml2lutaml +144 -0
  11. data/exe/lutaml-sysml +20 -0
  12. data/exe/lutaml-wsd2uml +59 -0
  13. data/exe/lutaml-yaml2uml +144 -0
  14. data/lib/lutaml/express/README.adoc +55 -0
  15. data/lib/lutaml/express/parsers/exp.rb +21 -0
  16. data/lib/lutaml/express/version.rb +7 -0
  17. data/lib/lutaml/express.rb +9 -0
  18. data/lib/lutaml/parser.rb +7 -0
  19. data/lib/lutaml/sysml/README.md +40 -0
  20. data/lib/lutaml/sysml/allocate.rb +8 -0
  21. data/lib/lutaml/sysml/allocated.rb +7 -0
  22. data/lib/lutaml/sysml/binding_connector.rb +7 -0
  23. data/lib/lutaml/sysml/block.rb +27 -0
  24. data/lib/lutaml/sysml/constraint_block.rb +12 -0
  25. data/lib/lutaml/sysml/copy.rb +6 -0
  26. data/lib/lutaml/sysml/derive_requirement.rb +7 -0
  27. data/lib/lutaml/sysml/nested_connector_end.rb +11 -0
  28. data/lib/lutaml/sysml/refine.rb +7 -0
  29. data/lib/lutaml/sysml/requirement.rb +34 -0
  30. data/lib/lutaml/sysml/requirement_related.rb +7 -0
  31. data/lib/lutaml/sysml/satisfy.rb +7 -0
  32. data/lib/lutaml/sysml/test_case.rb +22 -0
  33. data/lib/lutaml/sysml/trace.rb +7 -0
  34. data/lib/lutaml/sysml/verify.rb +6 -0
  35. data/lib/lutaml/sysml/version.rb +5 -0
  36. data/lib/lutaml/sysml/xmi_file.rb +417 -0
  37. data/lib/lutaml/sysml.rb +10 -0
  38. data/lib/lutaml/uml/README.adoc +44 -0
  39. data/lib/lutaml/uml/abstraction.rb +11 -0
  40. data/lib/lutaml/uml/activity.rb +11 -0
  41. data/lib/lutaml/uml/actor.rb +19 -0
  42. data/lib/lutaml/uml/association.rb +43 -0
  43. data/lib/lutaml/uml/behavior.rb +11 -0
  44. data/lib/lutaml/uml/class.rb +83 -0
  45. data/lib/lutaml/uml/classifier.rb +11 -0
  46. data/lib/lutaml/uml/connector.rb +21 -0
  47. data/lib/lutaml/uml/constraint.rb +12 -0
  48. data/lib/lutaml/uml/constructor_end.rb +16 -0
  49. data/lib/lutaml/uml/data_type.rb +75 -0
  50. data/lib/lutaml/uml/dependency.rb +21 -0
  51. data/lib/lutaml/uml/diagram.rb +8 -0
  52. data/lib/lutaml/uml/document.rb +81 -0
  53. data/lib/lutaml/uml/enum.rb +45 -0
  54. data/lib/lutaml/uml/event.rb +12 -0
  55. data/lib/lutaml/uml/final_state.rb +11 -0
  56. data/lib/lutaml/uml/formatter/base.rb +67 -0
  57. data/lib/lutaml/uml/formatter/graphviz.rb +334 -0
  58. data/lib/lutaml/uml/formatter.rb +21 -0
  59. data/lib/lutaml/uml/has_attributes.rb +14 -0
  60. data/lib/lutaml/uml/has_members.rb +30 -0
  61. data/lib/lutaml/uml/instance.rb +17 -0
  62. data/lib/lutaml/uml/model.rb +13 -0
  63. data/lib/lutaml/uml/node/base.rb +21 -0
  64. data/lib/lutaml/uml/node/class_node.rb +57 -0
  65. data/lib/lutaml/uml/node/class_relationship.rb +14 -0
  66. data/lib/lutaml/uml/node/document.rb +18 -0
  67. data/lib/lutaml/uml/node/field.rb +34 -0
  68. data/lib/lutaml/uml/node/has_name.rb +15 -0
  69. data/lib/lutaml/uml/node/has_type.rb +15 -0
  70. data/lib/lutaml/uml/node/method.rb +29 -0
  71. data/lib/lutaml/uml/node/method_argument.rb +16 -0
  72. data/lib/lutaml/uml/node/relationship.rb +28 -0
  73. data/lib/lutaml/uml/opaque_behavior.rb +11 -0
  74. data/lib/lutaml/uml/operation.rb +31 -0
  75. data/lib/lutaml/uml/package.rb +53 -0
  76. data/lib/lutaml/uml/parsers/attribute.rb +70 -0
  77. data/lib/lutaml/uml/parsers/dsl.rb +413 -0
  78. data/lib/lutaml/uml/parsers/dsl_preprocessor.rb +59 -0
  79. data/lib/lutaml/uml/parsers/dsl_transform.rb +27 -0
  80. data/lib/lutaml/uml/parsers/yaml.rb +46 -0
  81. data/lib/lutaml/uml/port.rb +8 -0
  82. data/lib/lutaml/uml/primitive_type.rb +14 -0
  83. data/lib/lutaml/uml/property.rb +27 -0
  84. data/lib/lutaml/uml/pseudostate.rb +11 -0
  85. data/lib/lutaml/uml/realization.rb +11 -0
  86. data/lib/lutaml/uml/region.rb +12 -0
  87. data/lib/lutaml/uml/serializers/association.rb +58 -0
  88. data/lib/lutaml/uml/serializers/base.rb +16 -0
  89. data/lib/lutaml/uml/serializers/class.rb +29 -0
  90. data/lib/lutaml/uml/serializers/top_element_attribute.rb +14 -0
  91. data/lib/lutaml/uml/serializers/yaml_view.rb +18 -0
  92. data/lib/lutaml/uml/state.rb +12 -0
  93. data/lib/lutaml/uml/state_machine.rb +12 -0
  94. data/lib/lutaml/uml/top_element.rb +58 -0
  95. data/lib/lutaml/uml/top_element_attribute.rb +39 -0
  96. data/lib/lutaml/uml/transition.rb +12 -0
  97. data/lib/lutaml/uml/trigger.rb +12 -0
  98. data/lib/lutaml/uml/value.rb +31 -0
  99. data/lib/lutaml/uml/version.rb +7 -0
  100. data/lib/lutaml/uml/vertex.rb +11 -0
  101. data/lib/lutaml/uml.rb +13 -0
  102. data/lib/lutaml/version.rb +1 -1
  103. data/lib/lutaml/xmi/README.adoc +24 -0
  104. data/lib/lutaml/xmi/parsers/xml.rb +600 -0
  105. data/lib/lutaml/xmi/version.rb +5 -0
  106. data/lib/lutaml/xmi.rb +7 -0
  107. data/lib/lutaml/xml/lutaml_path/document_wrapper.rb +45 -0
  108. data/lib/lutaml/xml/mapper.rb +448 -0
  109. data/lib/lutaml/xml/parsers/xml.rb +57 -0
  110. data/lib/lutaml/xml.rb +9 -0
  111. data/lutaml.gemspec +8 -3
  112. metadata +192 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: baef07d33c5aa163875a731b0dcbcf9de336d0bcb6c1066a17d74210e8d26d3a
4
- data.tar.gz: b3b000fe77946b863f5ee539319ef777ea14b20de6c607091dcf84c059ccd732
3
+ metadata.gz: b0a582c930c66da4590b8f707825f61e407bbe2492c95aa6f6a61725e95e62d4
4
+ data.tar.gz: cb3045bd11c726aa0d9462f72216e783545c37e2a701c223c5dc335eb1fb8213
5
5
  SHA512:
6
- metadata.gz: 6319856a0ef1833a797e5d6aba050a83d2d145e16d508f5a9c84cfe9484b958949a5c6ca906a373bbf2786c486b7e684237c49ee907ce21caa5e58c83f0d39a9
7
- data.tar.gz: b96dedf55a1689f9213ab9d3add19ceae2c3110953721a99ddf74913b572bfff28406635a6d6b01b33431a8fbc3131971b2d6058aacabce132b7b3b8d1068913
6
+ metadata.gz: 57aecd47776c51bafead92eaa4a245639d5b38999b04b5a12343e23c0ee97141605e4b723eb0663e4b88e775d9aba6c7458a125f4d011495d26cb0e6d17e714c
7
+ data.tar.gz: 6ae62810f1212d029efbc6829a29a7fee18306e8a672c5d8ab08d6907979dfaa6db2743763400d35f3f8d4c5551ab57db53dae8c88577703ddac7869e9adfc28
@@ -11,4 +11,4 @@ jobs:
11
11
  rake:
12
12
  uses: metanorma/ci/.github/workflows/graphviz-rake.yml@main
13
13
  secrets:
14
- pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
14
+ pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }}
data/.gitignore CHANGED
@@ -1,12 +1,13 @@
1
+
1
2
  /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
3
  /coverage/
5
4
  /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
5
  Gemfile.lock
10
-
6
+ /ISO_DIS_10303-59
7
+ /pkg/
11
8
  # rspec failure tracking
12
9
  .rspec_status
10
+ /spec/reports/
11
+ /tmp/
12
+ /.yardoc
13
+ /_yardoc/
data/.rubocop.yml CHANGED
@@ -8,3 +8,4 @@ inherit_from:
8
8
 
9
9
  AllCops:
10
10
  TargetRubyVersion: 2.5
11
+ NewCops: enable
data/LUTAML.adoc ADDED
@@ -0,0 +1,372 @@
1
+ = LutaML syntax
2
+
3
+ == `diagram` syntax
4
+
5
+ `diagram` is a root element for each diagram.
6
+
7
+ [source,java]
8
+ ----
9
+ diagram MyView {
10
+ title "My diagram"
11
+ caption "My custom caption"
12
+ fontname "Helvetica"
13
+ }
14
+ ----
15
+
16
+ where:
17
+
18
+ * `fontname` - optional, configuration option to use supplied font name
19
+ * `title` - optional, set custom title for diagram
20
+ * `caption` - optional, set custom caption for diagram
21
+
22
+ == DataTypes
23
+
24
+ Lutaml supports 3 types of data_types: `data_type`, `primitive` and `enum`.
25
+
26
+ Example of data types declaration:
27
+
28
+ [source,java]
29
+ ----
30
+ diagram MyView {
31
+ enum MyEnum {}
32
+
33
+ enum AddressClassProfile {
34
+ +addressClassProfile: CharacterString
35
+ }
36
+
37
+ data_type "Banking Information" {
38
+ "art code"
39
+ "CCT Number"
40
+ }
41
+
42
+ primitive Integer
43
+
44
+ enum Profile {
45
+ imlicistAttributeProfile: CharacterString
46
+ +attributeProfile: CharacterString
47
+ -privateAttributeProfile: CharacterString
48
+ ~friendlyAttributeProfile: CharacterString
49
+ #protectedAttributeProfile: CharacterString
50
+ }
51
+ }
52
+ ----
53
+
54
+ == Associations
55
+
56
+ === Explicit declaration
57
+
58
+ Syntax:
59
+
60
+ [source,java]
61
+ ----
62
+ association name {
63
+ owned_type association|composition|aggregation|generalization|uses
64
+ member_type association|composition|aggregation|generalization|uses
65
+ owned association_name[#attribute_name] [{property_string}][cardinality]
66
+ member association_name[#attribute_name] [{property_string}][cardinality]
67
+ }
68
+ ----
69
+
70
+ where:
71
+
72
+ * `owned_type` - optional, use to define a bidirectional association (`association`|`composition`|`aggregation`|`generalization`|`uses`)
73
+ * `member_type` - association type (`association`|`composition`|`aggregation`|`generalization`|`uses`)
74
+ * `owned|member` - end of association, use `\#attribute_name` to set a role name
75
+ * `property_string` - property string for attibutes associations
76
+ * `cardinality` - examples: '1..*', '*'
77
+
78
+ Example:
79
+
80
+ [source,java]
81
+ ----
82
+ class Association {
83
+ +association:
84
+ }
85
+ class Type {
86
+ +endType:
87
+ }
88
+
89
+ association AssociatingTypeAndAssociation {
90
+ type uses
91
+ from Association#+association {subsets relationship}[*]
92
+ to Type#+/endType {readOnly, subsets relatedElement} [1..*]
93
+ }
94
+ ----
95
+
96
+ === Undirected associations
97
+
98
+ The simplest way to define relationship between two classes is to use `generalize` keyword:
99
+
100
+ [source,java]
101
+ ----
102
+ class Pet {}
103
+ class Cat {
104
+ generalize Pet
105
+ }
106
+ ----
107
+
108
+ === Attribute relationship
109
+
110
+ Derived attribute `relatedElement` can have 1 to many `Element` associated with it through `union`
111
+
112
+ [source,java]
113
+ ----
114
+ class Relationship {
115
+ +/relatedElement: Element[1..*] {union}
116
+ }
117
+ class Element {}
118
+ ----
119
+
120
+ == Class' multiline "definition" property
121
+
122
+ === Definition
123
+
124
+ Full syntax:
125
+
126
+ [source,java]
127
+ ----
128
+ definition {
129
+ inner text
130
+ }
131
+ ----
132
+
133
+
134
+ == Attributes/entries
135
+
136
+ === Definition
137
+
138
+ Full syntax:
139
+
140
+ [source,java]
141
+ ----
142
+ [visibility][/][attribute] name [:type][multiplicity][=initial value][{attribute body}]
143
+ ----
144
+
145
+ where:
146
+
147
+ * `visibility` can be equal to
148
+ ** `-`: private
149
+ ** `+`: public
150
+ ** `#`: protected
151
+ ** `~`: friendly
152
+
153
+ * `attribute` - attrbute keyword
154
+ * `/` - symbolizes a derived attribute.
155
+ * `multiplicity` - Multiplicity is in square brackets (e.g. [1..*]).
156
+ * `initial value` - Default value specifies the initial value of the attribute.
157
+ * `{attribute body}` - Body of attribute, additional properties for attribute
158
+
159
+
160
+ One can use explicit or implicit syntax for attribute definition
161
+
162
+ explicit syntax:
163
+
164
+ [source,java]
165
+ ----
166
+ class A {
167
+ attribute my_attribute
168
+ }
169
+
170
+ enum A {
171
+ entry my_val2
172
+ }
173
+ ----
174
+
175
+ implicit syntax:
176
+
177
+ [source,java]
178
+ ----
179
+ class A {
180
+ my_attribute
181
+ }
182
+
183
+ enum A {
184
+ my_val2
185
+ }
186
+ ----
187
+
188
+ [[attribute-visibility]]
189
+ === Attribute visibility
190
+
191
+ Syntax for defining visibility: `[+|-|#|~] [attribute] attribute_name`.
192
+
193
+ LutaML uses these modificators to define attribute (entry) visbility:
194
+
195
+ `+`:: public
196
+ `-`:: private
197
+ `#`:: protected
198
+ `~`:: package
199
+
200
+ example:
201
+
202
+ [source,java]
203
+ ----
204
+ class Figure {
205
+ // Public attribute `radius`
206
+ + radius
207
+ // private attribute `filled`
208
+ - filled
209
+ // protected attribute `length`
210
+ # length
211
+ }
212
+ ----
213
+
214
+ === Additional attribute' properties
215
+
216
+ example:
217
+
218
+ [source,java]
219
+ ----
220
+ class Figure {
221
+ + radius {
222
+ definition {
223
+ Radius of the Figure
224
+ }
225
+ }
226
+ }
227
+ ----
228
+
229
+ == Methods
230
+
231
+ Syntax for defining methods:
232
+
233
+ [source,java]
234
+ ----
235
+ [visbility] method-name (parameter-list): return type {property-modifier}
236
+ ----
237
+
238
+ where:
239
+
240
+ * `visibility` can be equal to
241
+ ** `-`: private
242
+ ** `+`: public
243
+ ** `#`: protected
244
+ ** `~`: friendly
245
+
246
+ * `parameter-list`: parameter list
247
+
248
+ * `property-modifier`: can be equal to
249
+ ** `redefines`
250
+ ** `query`
251
+ ** `ordered` (defaults to `unordered`)
252
+ ** `unique`(defaults to `nonunique`)
253
+
254
+ Syntax for a `parameter-list`:
255
+
256
+ [source,java]
257
+ ----
258
+ [direction] name:type [multiplicity] [=default] [{property string}]
259
+ ----
260
+
261
+ where:
262
+
263
+ * `direction` can be equal to
264
+ ** `in`
265
+ ** `out`
266
+ ** `inout`
267
+ ** `return`
268
+
269
+ == import files
270
+
271
+ Use `include` special word:
272
+
273
+ [source,java]
274
+ ----
275
+ include path/to/file
276
+ ----
277
+
278
+ == Package syntax
279
+
280
+ Namespaces
281
+
282
+ A named element is an element that can have a name and a defined visibility (public, private, protected, package):
283
+
284
+ [source,java]
285
+ ----
286
+ + => public
287
+ - => private
288
+ # => protected
289
+ ~ => package
290
+ ----
291
+
292
+ The name of the element and its visibility are optional.
293
+
294
+ [source,java]
295
+ ----
296
+ package Customers {
297
+ class Insurance {}
298
+ - class PrivateInsurance {}
299
+ # class ProtectedInsurance {}
300
+ }
301
+ ----
302
+
303
+ == Code comments
304
+
305
+ Use `//` notation for LutaML comments skipped by parser, example:
306
+
307
+ [source,java]
308
+ ----
309
+ // TODO: implement
310
+ abstract class Pet {}
311
+ ----
312
+
313
+ == Comment objects diagram
314
+
315
+ Use `\**`(one line comment) or `*| |*`(multiline comment) to create comment object for diagram entry.
316
+
317
+ If this syntax is used inside a `class`/`enum`/`association` block, it will be created for owner of this block.
318
+
319
+ [source,java]
320
+ ----
321
+ ** I am a document comment
322
+
323
+ *|
324
+ This is a
325
+ multiply
326
+ lines document comment.
327
+ *|
328
+
329
+ class A
330
+ enum B {
331
+ ** one line enum comment
332
+ foo
333
+ *|
334
+ This is a
335
+ multiply
336
+ lines class comment.
337
+ *|
338
+ bar
339
+ }
340
+ ----
341
+
342
+ == Syntax comments
343
+
344
+ Use `//` to create syntax comment, chars after `//` will be ignored during processing.
345
+
346
+ [source,java]
347
+ ----
348
+ // TODO: attributes
349
+ class A
350
+ enum B {
351
+ // Write docs
352
+ foo
353
+ bar
354
+ }
355
+ ----
356
+
357
+ == Value specification
358
+
359
+ A value specification indicates one or several values in a model. Examples for value specifications include simple, mathematical expressions, such as `4+2`, and expressions with values from the object model, `Integer::MAX_INT-1`
360
+
361
+ [source,java]
362
+ ----
363
+ class {Class name, if any} {as ref name, optional} {
364
+ {attribute name} = {attribute value}
365
+ {attribute name}:{attribute class} = {attribute value}
366
+ }
367
+
368
+ instance :{Class name, if any} {as ref name, optional} {
369
+ {attribute name} = {attribute value}
370
+ {attribute name}:{attribute class} = {attribute value}
371
+ }
372
+ ----
data/Makefile ADDED
@@ -0,0 +1,2 @@
1
+ fix-lint-staged:
2
+ git status --short | egrep '^(A|M)' | awk '{ print $$2}' | grep -v db/schema.rb | xargs bundle exec rubocop -a
data/bin/console CHANGED
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "lutaml"
6
+ require "lutaml/express"
7
+ require "lutaml/uml"
8
+ require "lutaml/xmi"
9
+ require "lutaml/sysml"
5
10
 
6
11
  # You can add fixtures and/or initialization code here to make experimenting
7
12
  # with your gem easier. You can also use a different console, if you like.
@@ -0,0 +1,6 @@
1
+ script_full_path=$(dirname "$0")
2
+
3
+ for i in $1/*.yml
4
+ do
5
+ $script_full_path/yaml2lutaml $i > "$1/$(basename -s .yml $i).lutaml"
6
+ done
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # Script to convert plantuml files into LutaML syntax
6
+ # Usage: bin/plantuml2lutaml /path/to/plantuml.wsd
7
+
8
+ file_path = ARGV[0]
9
+ FILE_NAME = File.basename(file_path, ".wsd")
10
+ wsd_file = File.new(ARGV[0])
11
+
12
+ def sync_puts(line, level = 0)
13
+ $stdout.puts("#{''.rjust(level)}#{line}")
14
+ $stdout.flush
15
+ end
16
+
17
+ SKIPPED_LINES_REGEXP = /^(@startuml|'\*{7}|note|@enduml|\!|'\/)/
18
+ COMMENT_START = /\/'/
19
+ COMMENT_END = /'\//
20
+ ASSOCIATION_MAPPINGS = {
21
+ /-\|>/ => ",inheritance",
22
+ /<\|-/ => "inheritance,",
23
+ /->/ => ",direct",
24
+ /<-/ => "direct,",
25
+ }.freeze
26
+
27
+ in_comment_block = false
28
+
29
+ def transform_line(line)
30
+ line = line.gsub(/^\s*'/, '** ').gsub(/\|[\sa-zA-Z]+$/, '')
31
+ return sync_puts(line, 2) if ASSOCIATION_MAPPINGS.keys.none? { |key| line =~ key }
32
+
33
+ owner_type, member_type = ASSOCIATION_MAPPINGS.detect { |(key, _value)| line =~ key }.last.split(",")
34
+ blocks = line.split(" ")
35
+ owner = blocks.first
36
+ member = blocks.last
37
+ sync_puts("association {", 2)
38
+ sync_puts("owner #{owner}", 4)
39
+ sync_puts("member #{member}", 4)
40
+ sync_puts("owner_type #{owner_type}", 4) if !owner_type.to_s.empty?
41
+ sync_puts("member_type #{member_type}", 4) if !member_type.to_s.empty?
42
+ sync_puts("}", 2)
43
+ end
44
+
45
+ sync_puts("diagram #{FILE_NAME} {")
46
+ wsd_file.readlines.each do |line|
47
+ if line.match?(COMMENT_START)
48
+ in_comment_block = true
49
+ end
50
+
51
+ if line.match?(COMMENT_END)
52
+ in_comment_block = false
53
+ end
54
+
55
+ next if in_comment_block || line =~ SKIPPED_LINES_REGEXP
56
+
57
+ transform_line(line)
58
+ end
59
+ sync_puts("}")
data/bin/yaml2lutaml ADDED
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # Script to convert datamodel yaml files into LutaML syntax
6
+ # Usage: bin/yaml2lutaml /path/to/datamodel/view/file.yml
7
+
8
+ require "yaml"
9
+
10
+ view_yaml = YAML.safe_load(File.read(ARGV[0]))
11
+ models_path = File.expand_path("../../models", ARGV[0])
12
+
13
+ def sync_puts(line, level = 0)
14
+ $stdout.puts("#{''.rjust(level)}#{line}")
15
+ $stdout.flush
16
+ end
17
+
18
+ encountered_relations = Hash.new { |h, key| h[key] = [] }
19
+ # relations:
20
+ # - target: AttributeProfile
21
+ # relationship:
22
+ # source:
23
+ # type: aggregation
24
+ # attribute:
25
+ # addressClassProfile:
26
+ # target:
27
+ # type: direct
28
+ # attribute:
29
+ # attributeProfile:
30
+ # cardinality:
31
+ # min: 0
32
+ # max: '*'
33
+ def process_association(owner, values, encountered_relations)
34
+ target_name = values["target"]
35
+ return if encountered_relations[owner].include?(target_name)
36
+
37
+ encountered_relations[owner].push(target_name)
38
+ sync_puts("association {", 2)
39
+
40
+ relationship_block = values["relationship"] || {}
41
+
42
+ if relationship_block["source"] && relationship_block["source"]["type"]
43
+ source = relationship_block["source"]
44
+ sync_puts("owner_type #{source['type']}", 4)
45
+ if source["attribute"]
46
+ source_attribute_name = source["attribute"].keys.first
47
+ owner += "##{source_attribute_name}"
48
+ if source["attribute"][source_attribute_name] && source["attribute"][source_attribute_name]["cardinality"]
49
+ cardinality = source["attribute"][source_attribute_name]["cardinality"]
50
+ owner += " [#{cardinality['min']}..#{cardinality['max']}]"
51
+ end
52
+ end
53
+ end
54
+ sync_puts("owner #{owner}", 4)
55
+
56
+ member = target_name
57
+ if relationship_block["target"]
58
+ target = relationship_block["target"]
59
+ type = target["type"] || "direct"
60
+ sync_puts("member_type #{type}", 4)
61
+ if target["attribute"]
62
+ target_attribute_name = target["attribute"].keys.first
63
+ member += "##{target_attribute_name}"
64
+ if target["attribute"][target_attribute_name] && target["attribute"][target_attribute_name]["cardinality"]
65
+ cardinality = target["attribute"][target_attribute_name]["cardinality"]
66
+ member += " [#{cardinality['min']}..#{cardinality['max']}]"
67
+ end
68
+ end
69
+ else
70
+ sync_puts("member_type direct", 4)
71
+ end
72
+ sync_puts("member #{member}", 4)
73
+
74
+ sync_puts("}", 2)
75
+ end
76
+ sync_puts("diagram #{File.basename(ARGV[0], 'yml')[0..-2]} {")
77
+ sync_puts("title '#{view_yaml['title']}'", 2)
78
+ sync_puts("caption '#{view_yaml['caption']}'", 2)
79
+
80
+ # Class associations notations
81
+ view_yaml["relations"]&.each do |values|
82
+ process_association(values["source"], values, encountered_relations)
83
+ end
84
+
85
+ view_yaml["imports"].keys.each do |entry|
86
+ import = YAML.safe_load(File.read(File.join(models_path, "#{entry}.yml")))
87
+ import_name = import["name"] || File.basename(entry)
88
+ # Class notation
89
+ sync_puts("#{import['modelType']} #{import_name} {", 2)
90
+ if import["definition"]
91
+ definition = <<~TEXT
92
+ definition {
93
+ #{import['definition']}
94
+ }
95
+ TEXT
96
+ sync_puts(definition, 4)
97
+ end
98
+ import["values"]&.each_pair do |key, values|
99
+ result_string = key
100
+ if values["definition"]
101
+ result_string += <<~TEXT
102
+ {
103
+ definition {
104
+ #{values['definition']}
105
+ }
106
+ }
107
+ TEXT
108
+ end
109
+ sync_puts(result_string, 4)
110
+ end
111
+ import["attributes"]&.each_pair do |key, values|
112
+ definition = values["definition"]
113
+ cardinality = if values["cardinality"]
114
+ cardinality_val = values["cardinality"]
115
+ "[#{cardinality_val['min']}..#{cardinality_val['max']}]"
116
+ else
117
+ ""
118
+ end
119
+ result_string = "+#{key}"
120
+ if values["type"]
121
+ result_string += ": #{values['type']}"
122
+ end
123
+ if cardinality
124
+ result_string += " #{cardinality}"
125
+ end
126
+ if definition
127
+ result_string += <<~TEXT
128
+ {
129
+ definition
130
+ #{definition}
131
+ end definition
132
+ }
133
+ TEXT
134
+ end
135
+ sync_puts(result_string, 4)
136
+ end
137
+ sync_puts("}", 2)
138
+
139
+ # Associations notations
140
+ import["relations"]&.each do |values|
141
+ process_association(import_name, values, encountered_relations)
142
+ end
143
+ end
144
+ sync_puts("}")
data/exe/lutaml-sysml ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # resolve bin path, ignoring symlinks
5
+ require "pathname"
6
+ bin_file = Pathname.new(__FILE__).realpath
7
+
8
+ # add self to libpath
9
+ $:.unshift File.expand_path("../../lib", bin_file)
10
+
11
+ # Fixes https://github.com/rubygems/rubygems/issues/1420
12
+ require "rubygems/specification"
13
+
14
+ class Gem::Specification
15
+ def this; self; end
16
+ end
17
+
18
+ # start up the CLI
19
+ require "reeper"
20
+ Reeper::Cli.start(ARGV)