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.
- checksums.yaml +4 -4
- data/.gitignore +7 -6
- data/.rubocop.yml +1 -0
- data/LUTAML.adoc +372 -0
- data/Makefile +2 -0
- data/bin/console +5 -0
- data/bin/folder_yaml2lutaml.sh +6 -0
- data/bin/plantuml2lutaml +59 -0
- data/bin/yaml2lutaml +144 -0
- data/exe/lutaml-sysml +20 -0
- data/exe/lutaml-wsd2uml +59 -0
- data/exe/lutaml-yaml2uml +144 -0
- data/lib/lutaml/express/README.adoc +55 -0
- data/lib/lutaml/express/parsers/exp.rb +21 -0
- data/lib/lutaml/express/version.rb +7 -0
- data/lib/lutaml/express.rb +9 -0
- data/lib/lutaml/parser.rb +7 -0
- data/lib/lutaml/sysml/README.md +40 -0
- data/lib/lutaml/sysml/allocate.rb +8 -0
- data/lib/lutaml/sysml/allocated.rb +7 -0
- data/lib/lutaml/sysml/binding_connector.rb +7 -0
- data/lib/lutaml/sysml/block.rb +27 -0
- data/lib/lutaml/sysml/constraint_block.rb +12 -0
- data/lib/lutaml/sysml/copy.rb +6 -0
- data/lib/lutaml/sysml/derive_requirement.rb +7 -0
- data/lib/lutaml/sysml/nested_connector_end.rb +11 -0
- data/lib/lutaml/sysml/refine.rb +7 -0
- data/lib/lutaml/sysml/requirement.rb +34 -0
- data/lib/lutaml/sysml/requirement_related.rb +7 -0
- data/lib/lutaml/sysml/satisfy.rb +7 -0
- data/lib/lutaml/sysml/test_case.rb +22 -0
- data/lib/lutaml/sysml/trace.rb +7 -0
- data/lib/lutaml/sysml/verify.rb +6 -0
- data/lib/lutaml/sysml/version.rb +5 -0
- data/lib/lutaml/sysml/xmi_file.rb +417 -0
- data/lib/lutaml/sysml.rb +10 -0
- data/lib/lutaml/uml/README.adoc +44 -0
- data/lib/lutaml/uml/abstraction.rb +11 -0
- data/lib/lutaml/uml/activity.rb +11 -0
- data/lib/lutaml/uml/actor.rb +19 -0
- data/lib/lutaml/uml/association.rb +43 -0
- data/lib/lutaml/uml/behavior.rb +11 -0
- data/lib/lutaml/uml/class.rb +83 -0
- data/lib/lutaml/uml/classifier.rb +11 -0
- data/lib/lutaml/uml/connector.rb +21 -0
- data/lib/lutaml/uml/constraint.rb +12 -0
- data/lib/lutaml/uml/constructor_end.rb +16 -0
- data/lib/lutaml/uml/data_type.rb +75 -0
- data/lib/lutaml/uml/dependency.rb +21 -0
- data/lib/lutaml/uml/diagram.rb +8 -0
- data/lib/lutaml/uml/document.rb +81 -0
- data/lib/lutaml/uml/enum.rb +45 -0
- data/lib/lutaml/uml/event.rb +12 -0
- data/lib/lutaml/uml/final_state.rb +11 -0
- data/lib/lutaml/uml/formatter/base.rb +67 -0
- data/lib/lutaml/uml/formatter/graphviz.rb +334 -0
- data/lib/lutaml/uml/formatter.rb +21 -0
- data/lib/lutaml/uml/has_attributes.rb +14 -0
- data/lib/lutaml/uml/has_members.rb +30 -0
- data/lib/lutaml/uml/instance.rb +17 -0
- data/lib/lutaml/uml/model.rb +13 -0
- data/lib/lutaml/uml/node/base.rb +21 -0
- data/lib/lutaml/uml/node/class_node.rb +57 -0
- data/lib/lutaml/uml/node/class_relationship.rb +14 -0
- data/lib/lutaml/uml/node/document.rb +18 -0
- data/lib/lutaml/uml/node/field.rb +34 -0
- data/lib/lutaml/uml/node/has_name.rb +15 -0
- data/lib/lutaml/uml/node/has_type.rb +15 -0
- data/lib/lutaml/uml/node/method.rb +29 -0
- data/lib/lutaml/uml/node/method_argument.rb +16 -0
- data/lib/lutaml/uml/node/relationship.rb +28 -0
- data/lib/lutaml/uml/opaque_behavior.rb +11 -0
- data/lib/lutaml/uml/operation.rb +31 -0
- data/lib/lutaml/uml/package.rb +53 -0
- data/lib/lutaml/uml/parsers/attribute.rb +70 -0
- data/lib/lutaml/uml/parsers/dsl.rb +413 -0
- data/lib/lutaml/uml/parsers/dsl_preprocessor.rb +59 -0
- data/lib/lutaml/uml/parsers/dsl_transform.rb +27 -0
- data/lib/lutaml/uml/parsers/yaml.rb +46 -0
- data/lib/lutaml/uml/port.rb +8 -0
- data/lib/lutaml/uml/primitive_type.rb +14 -0
- data/lib/lutaml/uml/property.rb +27 -0
- data/lib/lutaml/uml/pseudostate.rb +11 -0
- data/lib/lutaml/uml/realization.rb +11 -0
- data/lib/lutaml/uml/region.rb +12 -0
- data/lib/lutaml/uml/serializers/association.rb +58 -0
- data/lib/lutaml/uml/serializers/base.rb +16 -0
- data/lib/lutaml/uml/serializers/class.rb +29 -0
- data/lib/lutaml/uml/serializers/top_element_attribute.rb +14 -0
- data/lib/lutaml/uml/serializers/yaml_view.rb +18 -0
- data/lib/lutaml/uml/state.rb +12 -0
- data/lib/lutaml/uml/state_machine.rb +12 -0
- data/lib/lutaml/uml/top_element.rb +58 -0
- data/lib/lutaml/uml/top_element_attribute.rb +39 -0
- data/lib/lutaml/uml/transition.rb +12 -0
- data/lib/lutaml/uml/trigger.rb +12 -0
- data/lib/lutaml/uml/value.rb +31 -0
- data/lib/lutaml/uml/version.rb +7 -0
- data/lib/lutaml/uml/vertex.rb +11 -0
- data/lib/lutaml/uml.rb +13 -0
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/README.adoc +24 -0
- data/lib/lutaml/xmi/parsers/xml.rb +600 -0
- data/lib/lutaml/xmi/version.rb +5 -0
- data/lib/lutaml/xmi.rb +7 -0
- data/lib/lutaml/xml/lutaml_path/document_wrapper.rb +45 -0
- data/lib/lutaml/xml/mapper.rb +448 -0
- data/lib/lutaml/xml/parsers/xml.rb +57 -0
- data/lib/lutaml/xml.rb +9 -0
- data/lutaml.gemspec +8 -3
- metadata +192 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d6709956ec738c3ca16661750783447cc48fadcb00206ab24bbe78ea6109c716
|
|
4
|
+
data.tar.gz: 5c956576b76701da6bb95e29904bb817604c41f5efcf8210399ea6b2edd3f8cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0bf7f57aedbc5d46efda3413fb3c92137a445ef4e3666e81f440470e299144e91ba57ac714b79e2d2d2920eb525a3b6d562f70b61c687973a2288659e56d4783
|
|
7
|
+
data.tar.gz: a9faa2d0b5eb4e72f4b1bc0585542da8e47c557cfc51cee66dedf2f1bfc2c0e3ae3b762e0d5fe35fd28dfc5a691d6794243b2ad08576115ea255081873bf93e4
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
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
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.
|
data/bin/plantuml2lutaml
ADDED
|
@@ -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)
|