lutaml 0.7.7 → 0.8.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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -6
  3. data/.rubocop.yml +1 -0
  4. data/LUTAML.adoc +372 -0
  5. data/Makefile +2 -0
  6. data/bin/console +5 -0
  7. data/bin/folder_yaml2lutaml.sh +6 -0
  8. data/bin/plantuml2lutaml +59 -0
  9. data/bin/yaml2lutaml +144 -0
  10. data/exe/lutaml-sysml +20 -0
  11. data/exe/lutaml-wsd2uml +59 -0
  12. data/exe/lutaml-yaml2uml +144 -0
  13. data/lib/lutaml/express/README.adoc +55 -0
  14. data/lib/lutaml/express/parsers/exp.rb +21 -0
  15. data/lib/lutaml/express/version.rb +7 -0
  16. data/lib/lutaml/express.rb +9 -0
  17. data/lib/lutaml/parser.rb +7 -0
  18. data/lib/lutaml/sysml/README.md +40 -0
  19. data/lib/lutaml/sysml/allocate.rb +8 -0
  20. data/lib/lutaml/sysml/allocated.rb +7 -0
  21. data/lib/lutaml/sysml/binding_connector.rb +7 -0
  22. data/lib/lutaml/sysml/block.rb +27 -0
  23. data/lib/lutaml/sysml/constraint_block.rb +12 -0
  24. data/lib/lutaml/sysml/copy.rb +6 -0
  25. data/lib/lutaml/sysml/derive_requirement.rb +7 -0
  26. data/lib/lutaml/sysml/nested_connector_end.rb +11 -0
  27. data/lib/lutaml/sysml/refine.rb +7 -0
  28. data/lib/lutaml/sysml/requirement.rb +34 -0
  29. data/lib/lutaml/sysml/requirement_related.rb +7 -0
  30. data/lib/lutaml/sysml/satisfy.rb +7 -0
  31. data/lib/lutaml/sysml/test_case.rb +22 -0
  32. data/lib/lutaml/sysml/trace.rb +7 -0
  33. data/lib/lutaml/sysml/verify.rb +6 -0
  34. data/lib/lutaml/sysml/version.rb +5 -0
  35. data/lib/lutaml/sysml/xmi_file.rb +417 -0
  36. data/lib/lutaml/sysml.rb +10 -0
  37. data/lib/lutaml/uml/README.adoc +44 -0
  38. data/lib/lutaml/uml/abstraction.rb +11 -0
  39. data/lib/lutaml/uml/activity.rb +11 -0
  40. data/lib/lutaml/uml/actor.rb +19 -0
  41. data/lib/lutaml/uml/association.rb +43 -0
  42. data/lib/lutaml/uml/behavior.rb +11 -0
  43. data/lib/lutaml/uml/class.rb +83 -0
  44. data/lib/lutaml/uml/classifier.rb +11 -0
  45. data/lib/lutaml/uml/connector.rb +21 -0
  46. data/lib/lutaml/uml/constraint.rb +12 -0
  47. data/lib/lutaml/uml/constructor_end.rb +16 -0
  48. data/lib/lutaml/uml/data_type.rb +75 -0
  49. data/lib/lutaml/uml/dependency.rb +21 -0
  50. data/lib/lutaml/uml/diagram.rb +8 -0
  51. data/lib/lutaml/uml/document.rb +81 -0
  52. data/lib/lutaml/uml/enum.rb +45 -0
  53. data/lib/lutaml/uml/event.rb +12 -0
  54. data/lib/lutaml/uml/final_state.rb +11 -0
  55. data/lib/lutaml/uml/formatter/base.rb +67 -0
  56. data/lib/lutaml/uml/formatter/graphviz.rb +334 -0
  57. data/lib/lutaml/uml/formatter.rb +21 -0
  58. data/lib/lutaml/uml/has_attributes.rb +14 -0
  59. data/lib/lutaml/uml/has_members.rb +30 -0
  60. data/lib/lutaml/uml/instance.rb +17 -0
  61. data/lib/lutaml/uml/model.rb +13 -0
  62. data/lib/lutaml/uml/node/base.rb +21 -0
  63. data/lib/lutaml/uml/node/class_node.rb +57 -0
  64. data/lib/lutaml/uml/node/class_relationship.rb +14 -0
  65. data/lib/lutaml/uml/node/document.rb +18 -0
  66. data/lib/lutaml/uml/node/field.rb +34 -0
  67. data/lib/lutaml/uml/node/has_name.rb +15 -0
  68. data/lib/lutaml/uml/node/has_type.rb +15 -0
  69. data/lib/lutaml/uml/node/method.rb +29 -0
  70. data/lib/lutaml/uml/node/method_argument.rb +16 -0
  71. data/lib/lutaml/uml/node/relationship.rb +28 -0
  72. data/lib/lutaml/uml/opaque_behavior.rb +11 -0
  73. data/lib/lutaml/uml/operation.rb +31 -0
  74. data/lib/lutaml/uml/package.rb +53 -0
  75. data/lib/lutaml/uml/parsers/attribute.rb +70 -0
  76. data/lib/lutaml/uml/parsers/dsl.rb +413 -0
  77. data/lib/lutaml/uml/parsers/dsl_preprocessor.rb +59 -0
  78. data/lib/lutaml/uml/parsers/dsl_transform.rb +27 -0
  79. data/lib/lutaml/uml/parsers/yaml.rb +46 -0
  80. data/lib/lutaml/uml/port.rb +8 -0
  81. data/lib/lutaml/uml/primitive_type.rb +14 -0
  82. data/lib/lutaml/uml/property.rb +27 -0
  83. data/lib/lutaml/uml/pseudostate.rb +11 -0
  84. data/lib/lutaml/uml/realization.rb +11 -0
  85. data/lib/lutaml/uml/region.rb +12 -0
  86. data/lib/lutaml/uml/serializers/association.rb +58 -0
  87. data/lib/lutaml/uml/serializers/base.rb +16 -0
  88. data/lib/lutaml/uml/serializers/class.rb +29 -0
  89. data/lib/lutaml/uml/serializers/top_element_attribute.rb +14 -0
  90. data/lib/lutaml/uml/serializers/yaml_view.rb +18 -0
  91. data/lib/lutaml/uml/state.rb +12 -0
  92. data/lib/lutaml/uml/state_machine.rb +12 -0
  93. data/lib/lutaml/uml/top_element.rb +58 -0
  94. data/lib/lutaml/uml/top_element_attribute.rb +39 -0
  95. data/lib/lutaml/uml/transition.rb +12 -0
  96. data/lib/lutaml/uml/trigger.rb +12 -0
  97. data/lib/lutaml/uml/value.rb +31 -0
  98. data/lib/lutaml/uml/version.rb +7 -0
  99. data/lib/lutaml/uml/vertex.rb +11 -0
  100. data/lib/lutaml/uml.rb +13 -0
  101. data/lib/lutaml/version.rb +1 -1
  102. data/lib/lutaml/xmi/README.adoc +24 -0
  103. data/lib/lutaml/xmi/parsers/xml.rb +600 -0
  104. data/lib/lutaml/xmi/version.rb +5 -0
  105. data/lib/lutaml/xmi.rb +7 -0
  106. data/lib/lutaml/xml/lutaml_path/document_wrapper.rb +45 -0
  107. data/lib/lutaml/xml/mapper.rb +448 -0
  108. data/lib/lutaml/xml/parsers/xml.rb +57 -0
  109. data/lib/lutaml/xml.rb +9 -0
  110. data/lutaml.gemspec +8 -3
  111. 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: d6709956ec738c3ca16661750783447cc48fadcb00206ab24bbe78ea6109c716
4
+ data.tar.gz: 5c956576b76701da6bb95e29904bb817604c41f5efcf8210399ea6b2edd3f8cd
5
5
  SHA512:
6
- metadata.gz: 6319856a0ef1833a797e5d6aba050a83d2d145e16d508f5a9c84cfe9484b958949a5c6ca906a373bbf2786c486b7e684237c49ee907ce21caa5e58c83f0d39a9
7
- data.tar.gz: b96dedf55a1689f9213ab9d3add19ceae2c3110953721a99ddf74913b572bfff28406635a6d6b01b33431a8fbc3131971b2d6058aacabce132b7b3b8d1068913
6
+ metadata.gz: 0bf7f57aedbc5d46efda3413fb3c92137a445ef4e3666e81f440470e299144e91ba57ac714b79e2d2d2920eb525a3b6d562f70b61c687973a2288659e56d4783
7
+ data.tar.gz: a9faa2d0b5eb4e72f4b1bc0585542da8e47c557cfc51cee66dedf2f1bfc2c0e3ae3b762e0d5fe35fd28dfc5a691d6794243b2ad08576115ea255081873bf93e4
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)