xuml-populate 0.1.3__tar.gz
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.
- xuml_populate-0.1.3/LICENSE +21 -0
- xuml_populate-0.1.3/MANIFEST.in +2 -0
- xuml_populate-0.1.3/PKG-INFO +142 -0
- xuml_populate-0.1.3/README.md +91 -0
- xuml_populate-0.1.3/pyproject.toml +30 -0
- xuml_populate-0.1.3/setup.cfg +4 -0
- xuml_populate-0.1.3/src/xuml_populate/__init__.py +1 -0
- xuml_populate-0.1.3/src/xuml_populate/__main__.py +74 -0
- xuml_populate-0.1.3/src/xuml_populate/config.py +5 -0
- xuml_populate-0.1.3/src/xuml_populate/exceptions/__init__.py +0 -0
- xuml_populate-0.1.3/src/xuml_populate/exceptions/action_exceptions.py +232 -0
- xuml_populate-0.1.3/src/xuml_populate/exceptions/class_exceptions.py +22 -0
- xuml_populate-0.1.3/src/xuml_populate/exceptions/mp_exceptions.py +94 -0
- xuml_populate-0.1.3/src/xuml_populate/log.conf +42 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/__init__.py +0 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/__init__.py +0 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/action.py +49 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/aparse_types.py +28 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/expressions/__init__.py +0 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/expressions/class_accessor.py +52 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/expressions/instance_set.py +97 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/expressions/restriction_condition.py +354 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/expressions/scalar_expr.py +139 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/expressions/table_expr.py +194 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/extract_action.py +63 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/instance_assignment.py +109 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/project_action.py +81 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/read_action.py +79 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/rename_action.py +64 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/restrict_action.py +77 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/scalar_assignment.py +91 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/select_action.py +184 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/set_action.py +99 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/switch_action.py +76 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/switch_statement.py +166 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/table.py +70 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/table_assignment.py +83 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/table_attribute.py +35 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/traverse_action.py +527 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/validation/__init__.py +0 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/actions/validation/parameter_validation.py +47 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/activity.py +202 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/attribute.py +156 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/binary_association.py +220 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/domain.py +117 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/ee.py +51 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/element.py +95 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/flow.py +450 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/generalization.py +100 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/lineage.py +204 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/method.py +104 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/mm_class.py +113 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/mm_type.py +117 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/mmclass_nt.py +225 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/mmdb.ral +1 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/ns_flow.py +105 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/operation.py +104 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/ordinal.py +47 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/reference.py +33 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/relationship.py +58 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/signature.py +33 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/state_model.py +248 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/statement.py +73 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/subsystem.py +36 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/synch_output.py +59 -0
- xuml_populate-0.1.3/src/xuml_populate/populate/xunit.py +105 -0
- xuml_populate-0.1.3/src/xuml_populate/system.py +167 -0
- xuml_populate-0.1.3/src/xuml_populate/tree/__init__.py +0 -0
- xuml_populate-0.1.3/src/xuml_populate/tree/tree.py +57 -0
- xuml_populate-0.1.3/src/xuml_populate.egg-info/PKG-INFO +142 -0
- xuml_populate-0.1.3/src/xuml_populate.egg-info/SOURCES.txt +74 -0
- xuml_populate-0.1.3/src/xuml_populate.egg-info/dependency_links.txt +1 -0
- xuml_populate-0.1.3/src/xuml_populate.egg-info/entry_points.txt +2 -0
- xuml_populate-0.1.3/src/xuml_populate.egg-info/requires.txt +17 -0
- xuml_populate-0.1.3/src/xuml_populate.egg-info/top_level.txt +1 -0
- xuml_populate-0.1.3/tests/test_parse.py +17 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Leon Starr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xuml-populate
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Populates the SM Metamodel schema with a user model and outputs this as a TclRAL *.ral database
|
|
5
|
+
Author-email: Leon Starr <leon_starr@modelint.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) Leon Starr
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: repository, https://github.com/modelint/xuml-populate
|
|
29
|
+
Project-URL: documentation, https://github.com/modelint/xuml-populate/wiki
|
|
30
|
+
Keywords: shlaer-mellor,metamodel,executable uml,mbse,xuml,xtuml,platform independent,sysml
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Programming Language :: Python
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Requires-Python: >=3.11
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
Requires-Dist: xcm-parser
|
|
38
|
+
Requires-Dist: xsm-parser
|
|
39
|
+
Requires-Dist: op-parser
|
|
40
|
+
Requires-Dist: mtd-parser
|
|
41
|
+
Requires-Dist: mi-pyral
|
|
42
|
+
Requires-Dist: scrall
|
|
43
|
+
Requires-Dist: tomli; python_version < "3.11"
|
|
44
|
+
Provides-Extra: build
|
|
45
|
+
Requires-Dist: build; extra == "build"
|
|
46
|
+
Requires-Dist: twine; extra == "build"
|
|
47
|
+
Provides-Extra: dev
|
|
48
|
+
Requires-Dist: bump2version; extra == "dev"
|
|
49
|
+
Requires-Dist: pytest; extra == "dev"
|
|
50
|
+
Dynamic: license-file
|
|
51
|
+
|
|
52
|
+
# Blueprint MBSE Repository Populator
|
|
53
|
+
|
|
54
|
+
This package transforms human readable text files describing an Executable UML model of a system into
|
|
55
|
+
a populated metamodel database. With your models loaded into this database it is now possible to produce
|
|
56
|
+
a variety of useful artifacts to support model execution and verification, code generation and anything else
|
|
57
|
+
that performs detailed analyis on the model components and their relationships.
|
|
58
|
+
|
|
59
|
+
The text files are expressed in an easy to read markdown format so you can browse through the classes, relationships,
|
|
60
|
+
states and transitions, actions and all other model components.
|
|
61
|
+
|
|
62
|
+
Here we support the Shlaer-Mellor variant of Executable UML exclusively.
|
|
63
|
+
|
|
64
|
+
## Command usage
|
|
65
|
+
|
|
66
|
+
`% modeldb -s elevator`
|
|
67
|
+
|
|
68
|
+
Assuming your system is named 'elevator' and is in the current working directory with the internal structure defined below, will output a file named `mmdb_elevator.ral`. This *.ral file is a text file serialization of a TclRAL database.
|
|
69
|
+
|
|
70
|
+
Your user model is loaded into the Shlaer-Mellor Metamodel and, if there are no errors, you know you have a Shlaer-Mellor Executable Model that doesn't break any of the rules defined by the metamodel.
|
|
71
|
+
|
|
72
|
+
You can load and view it using TclRAL or PyRAL or feed it to other downstream Blueprint tools such as the
|
|
73
|
+
Model Executor which among its tasks will generate a user model database.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## Input to the populator
|
|
77
|
+
|
|
78
|
+
Each system is defined in a single package broken down into standard hierarchy of folders like so:
|
|
79
|
+
|
|
80
|
+
system
|
|
81
|
+
domain
|
|
82
|
+
subsystem
|
|
83
|
+
classmodel.xcm
|
|
84
|
+
types.yaml
|
|
85
|
+
methods
|
|
86
|
+
m1.mtd
|
|
87
|
+
m2.mtd
|
|
88
|
+
...
|
|
89
|
+
state-machines
|
|
90
|
+
s1.xsm
|
|
91
|
+
...
|
|
92
|
+
external
|
|
93
|
+
EE
|
|
94
|
+
op1.op
|
|
95
|
+
...
|
|
96
|
+
subsystem2
|
|
97
|
+
...
|
|
98
|
+
domain2
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
Here is a partial layout for The Elevator Case Study as an example:
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
elevator-case-study // system
|
|
105
|
+
elevator-management // application domain
|
|
106
|
+
elevator // All defined in one subsystem
|
|
107
|
+
elevator.xcm // the class model
|
|
108
|
+
methods // methods for all classes in subsystem
|
|
109
|
+
cabin // methods on 'cabin' class
|
|
110
|
+
ping.mtd // the ping method
|
|
111
|
+
...
|
|
112
|
+
...
|
|
113
|
+
state-machines // lifecycles and assigners for this subsystem
|
|
114
|
+
cabin.xsm // lifecycles named by class, assigners by association
|
|
115
|
+
transfer.xsm
|
|
116
|
+
R53.xsm // assigner state machine on association R53
|
|
117
|
+
...
|
|
118
|
+
external // external entities, each a proxy for some class
|
|
119
|
+
CABIN // proxy for 'cabin' class
|
|
120
|
+
arrived-at-floor.op // two ee operations
|
|
121
|
+
goto-floor.op
|
|
122
|
+
types.yaml // data types for all subsystems in domain
|
|
123
|
+
transport // two more domains (not broken down yet)
|
|
124
|
+
signal io
|
|
125
|
+
|
|
126
|
+
Each modeled domain has its own folder. Above we just see one for the Elevator Managment domain.
|
|
127
|
+
|
|
128
|
+
Each domain requires at least one subsystem folder. Here we see only one and that is the Elevator domain.
|
|
129
|
+
|
|
130
|
+
Within a subsystem folder there is one class model expressed as an .xcm (executable class model) file.
|
|
131
|
+
|
|
132
|
+
The folders are optional and are:
|
|
133
|
+
|
|
134
|
+
* external – external entities and their operations, one subfolder per external entity
|
|
135
|
+
* methods – class methods each in a folder matching the class name with each method in a separate .mtd file
|
|
136
|
+
* state-machines – each state machine, assigner or lifecycle, in its own .xsm (executable state machine) file
|
|
137
|
+
|
|
138
|
+
Also within a domain you have a types.yaml file which specifies each domain specific type (Pressure, Speed, etc) and selects
|
|
139
|
+
a corresponding system (database) type. This is a stop gap measure as we have not yet provided a more robust typing
|
|
140
|
+
domain, so, for now we settle with what our database has to offer (int, string, float, etc). Unltimately, though,
|
|
141
|
+
a full featured typing facility will support a variety of types and operations on those types as well as a type
|
|
142
|
+
definition system. Note that the typing facility can be, but need not necessarily be a modeled domain.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Blueprint MBSE Repository Populator
|
|
2
|
+
|
|
3
|
+
This package transforms human readable text files describing an Executable UML model of a system into
|
|
4
|
+
a populated metamodel database. With your models loaded into this database it is now possible to produce
|
|
5
|
+
a variety of useful artifacts to support model execution and verification, code generation and anything else
|
|
6
|
+
that performs detailed analyis on the model components and their relationships.
|
|
7
|
+
|
|
8
|
+
The text files are expressed in an easy to read markdown format so you can browse through the classes, relationships,
|
|
9
|
+
states and transitions, actions and all other model components.
|
|
10
|
+
|
|
11
|
+
Here we support the Shlaer-Mellor variant of Executable UML exclusively.
|
|
12
|
+
|
|
13
|
+
## Command usage
|
|
14
|
+
|
|
15
|
+
`% modeldb -s elevator`
|
|
16
|
+
|
|
17
|
+
Assuming your system is named 'elevator' and is in the current working directory with the internal structure defined below, will output a file named `mmdb_elevator.ral`. This *.ral file is a text file serialization of a TclRAL database.
|
|
18
|
+
|
|
19
|
+
Your user model is loaded into the Shlaer-Mellor Metamodel and, if there are no errors, you know you have a Shlaer-Mellor Executable Model that doesn't break any of the rules defined by the metamodel.
|
|
20
|
+
|
|
21
|
+
You can load and view it using TclRAL or PyRAL or feed it to other downstream Blueprint tools such as the
|
|
22
|
+
Model Executor which among its tasks will generate a user model database.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Input to the populator
|
|
26
|
+
|
|
27
|
+
Each system is defined in a single package broken down into standard hierarchy of folders like so:
|
|
28
|
+
|
|
29
|
+
system
|
|
30
|
+
domain
|
|
31
|
+
subsystem
|
|
32
|
+
classmodel.xcm
|
|
33
|
+
types.yaml
|
|
34
|
+
methods
|
|
35
|
+
m1.mtd
|
|
36
|
+
m2.mtd
|
|
37
|
+
...
|
|
38
|
+
state-machines
|
|
39
|
+
s1.xsm
|
|
40
|
+
...
|
|
41
|
+
external
|
|
42
|
+
EE
|
|
43
|
+
op1.op
|
|
44
|
+
...
|
|
45
|
+
subsystem2
|
|
46
|
+
...
|
|
47
|
+
domain2
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
Here is a partial layout for The Elevator Case Study as an example:
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
elevator-case-study // system
|
|
54
|
+
elevator-management // application domain
|
|
55
|
+
elevator // All defined in one subsystem
|
|
56
|
+
elevator.xcm // the class model
|
|
57
|
+
methods // methods for all classes in subsystem
|
|
58
|
+
cabin // methods on 'cabin' class
|
|
59
|
+
ping.mtd // the ping method
|
|
60
|
+
...
|
|
61
|
+
...
|
|
62
|
+
state-machines // lifecycles and assigners for this subsystem
|
|
63
|
+
cabin.xsm // lifecycles named by class, assigners by association
|
|
64
|
+
transfer.xsm
|
|
65
|
+
R53.xsm // assigner state machine on association R53
|
|
66
|
+
...
|
|
67
|
+
external // external entities, each a proxy for some class
|
|
68
|
+
CABIN // proxy for 'cabin' class
|
|
69
|
+
arrived-at-floor.op // two ee operations
|
|
70
|
+
goto-floor.op
|
|
71
|
+
types.yaml // data types for all subsystems in domain
|
|
72
|
+
transport // two more domains (not broken down yet)
|
|
73
|
+
signal io
|
|
74
|
+
|
|
75
|
+
Each modeled domain has its own folder. Above we just see one for the Elevator Managment domain.
|
|
76
|
+
|
|
77
|
+
Each domain requires at least one subsystem folder. Here we see only one and that is the Elevator domain.
|
|
78
|
+
|
|
79
|
+
Within a subsystem folder there is one class model expressed as an .xcm (executable class model) file.
|
|
80
|
+
|
|
81
|
+
The folders are optional and are:
|
|
82
|
+
|
|
83
|
+
* external – external entities and their operations, one subfolder per external entity
|
|
84
|
+
* methods – class methods each in a folder matching the class name with each method in a separate .mtd file
|
|
85
|
+
* state-machines – each state machine, assigner or lifecycle, in its own .xsm (executable state machine) file
|
|
86
|
+
|
|
87
|
+
Also within a domain you have a types.yaml file which specifies each domain specific type (Pressure, Speed, etc) and selects
|
|
88
|
+
a corresponding system (database) type. This is a stop gap measure as we have not yet provided a more robust typing
|
|
89
|
+
domain, so, for now we settle with what our database has to offer (int, string, float, etc). Unltimately, though,
|
|
90
|
+
a full featured typing facility will support a variety of types and operations on those types as well as a type
|
|
91
|
+
definition system. Note that the typing facility can be, but need not necessarily be a modeled domain.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "xuml-populate"
|
|
7
|
+
version = "0.1.3"
|
|
8
|
+
description = "Populates the SM Metamodel schema with a user model and outputs this as a TclRAL *.ral database"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [{ name = "Leon Starr", email = "leon_starr@modelint.com" }]
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
classifiers = [
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
]
|
|
17
|
+
keywords = ["shlaer-mellor", "metamodel", "executable uml", "mbse", "xuml", "xtuml", "platform independent", "sysml"]
|
|
18
|
+
dependencies = ["xcm-parser", "xsm-parser", "op-parser", "mtd-parser", "mi-pyral", "scrall", 'tomli; python_version < "3.11"']
|
|
19
|
+
requires-python = ">=3.11"
|
|
20
|
+
|
|
21
|
+
[project.optional-dependencies]
|
|
22
|
+
build = ["build", "twine"]
|
|
23
|
+
dev = ["bump2version", "pytest"]
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
modeldb = "xuml_populate.__main__:main"
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
repository = "https://github.com/modelint/xuml-populate"
|
|
30
|
+
documentation = "https://github.com/modelint/xuml-populate/wiki"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.1.3"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Blueprint Model Repository Populator
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
import logging
|
|
6
|
+
import logging.config
|
|
7
|
+
import sys
|
|
8
|
+
import argparse
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from xuml_populate.system import System
|
|
11
|
+
from xuml_populate import version
|
|
12
|
+
import atexit
|
|
13
|
+
|
|
14
|
+
_logpath = Path("repo_pop.log")
|
|
15
|
+
_progname = 'Blueprint model repository populator'
|
|
16
|
+
|
|
17
|
+
def clean_up():
|
|
18
|
+
"""Normal and exception exit activities"""
|
|
19
|
+
_logpath.unlink(missing_ok=True)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_logger():
|
|
23
|
+
"""Initiate the logger"""
|
|
24
|
+
log_conf_path = Path(__file__).parent / 'log.conf' # Logging configuration is in this file
|
|
25
|
+
logging.config.fileConfig(fname=log_conf_path, disable_existing_loggers=False)
|
|
26
|
+
return logging.getLogger(__name__) # Create a logger for this module
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Configure the expected parameters and actions for the argparse module
|
|
30
|
+
def parse(cl_input):
|
|
31
|
+
parser = argparse.ArgumentParser(description=_progname)
|
|
32
|
+
parser.add_argument('-s', '--system', action='store',
|
|
33
|
+
help='Name of the system package')
|
|
34
|
+
parser.add_argument('-D', '--debug', action='store_true',
|
|
35
|
+
help='Debug mode'),
|
|
36
|
+
parser.add_argument('-d', '--display', action='store_true',
|
|
37
|
+
help='Display the populated database on the console')
|
|
38
|
+
parser.add_argument('-L', '--log', action='store_true',
|
|
39
|
+
help='Generate a diagnostic log file')
|
|
40
|
+
parser.add_argument('-A', '--actions', action='store_true',
|
|
41
|
+
help='Parse actions'),
|
|
42
|
+
parser.add_argument('-V', '--version', action='store_true',
|
|
43
|
+
help='Print the current version of the repo populator')
|
|
44
|
+
return parser.parse_args(cl_input)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def main():
|
|
48
|
+
# Start logging
|
|
49
|
+
logger = get_logger()
|
|
50
|
+
logger.info(f'{_progname} version: {version}')
|
|
51
|
+
|
|
52
|
+
# Parse the command line args
|
|
53
|
+
args = parse(sys.argv[1:])
|
|
54
|
+
|
|
55
|
+
if not args.log:
|
|
56
|
+
# If no log file is requested, remove the log file before termination
|
|
57
|
+
atexit.register(clean_up)
|
|
58
|
+
|
|
59
|
+
if args.version:
|
|
60
|
+
# Just print the version and quit
|
|
61
|
+
print(f'{_progname} version: {version}')
|
|
62
|
+
sys.exit(0)
|
|
63
|
+
|
|
64
|
+
# System package specified
|
|
65
|
+
if args.system:
|
|
66
|
+
system_pkg_path = Path(args.system).resolve()
|
|
67
|
+
s = System(name=system_pkg_path.stem, system_path=system_pkg_path, parse_actions=args.actions, display=args.display)
|
|
68
|
+
|
|
69
|
+
logger.info("No problemo") # We didn't die on an exception, basically
|
|
70
|
+
print("\nNo problemo")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""
|
|
2
|
+
action_exceptions.py – Errors that occur while populating actions
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Every error should have the same format
|
|
6
|
+
# with a standard prefix and postfix defined here
|
|
7
|
+
pre = "\nScrall populator: -- "
|
|
8
|
+
post = " --"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ActionException(Exception):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
class UndefinedMethod(ActionException):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
class UndefinedAttribute(ActionException):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
class UndefinedParameter(ActionException):
|
|
21
|
+
pass
|
|
22
|
+
class UndefinedTableAttribute(ActionException):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
class SwitchException(ActionException):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
class BadScalarSwitchInput(SwitchException):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
class FlowException(ActionException):
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
class ControlFlowHasNoTargetActions(FlowException):
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
class NonScalarFlowRequired(FlowException):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
class TableExpressionException(ActionException):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
class ScalarExpressionException(ActionException):
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
class ScalarOperationOrExpressionExpected(ScalarExpressionException):
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
class ScalarAssignmentfromMultipleTuples(ScalarExpressionException):
|
|
50
|
+
pass
|
|
51
|
+
class ScalarAssignmentFlowMismatch(ScalarExpressionException):
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
class UndefinedHeaderExpressionOp(TableExpressionException):
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
class ProductForbidsCommonAttributes(TableExpressionException):
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
class SetOpRequiresSameHeaders(TableExpressionException):
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
class UnjoinableHeaders(TableExpressionException):
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
class TraversalActionException(ActionException):
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
class SelectActionException(ActionException):
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
class NoInputInstanceFlow(SelectActionException):
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
class ProjectedAttributeNotDefined(TableExpressionException):
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
class TableOperationOrExpressionExpected(TableExpressionException):
|
|
79
|
+
pass
|
|
80
|
+
|
|
81
|
+
class SelectionOnScalarFlow(ActionException):
|
|
82
|
+
def __init__(self, path, text, x):
|
|
83
|
+
self.path = path
|
|
84
|
+
self.text = text[slice(*x)]
|
|
85
|
+
|
|
86
|
+
def __str__(self):
|
|
87
|
+
return f'{pre}Cannot select/restrict on a scalar flow. Verify input to selection phrase' \
|
|
88
|
+
f'{post}\n\t[{self.path}] >> {self.text}'
|
|
89
|
+
|
|
90
|
+
class AssignZeroOneInstanceHasMultiple(ActionException):
|
|
91
|
+
def __init__(self, path, text, x):
|
|
92
|
+
self.path = path
|
|
93
|
+
self.text = text[slice(*x)]
|
|
94
|
+
|
|
95
|
+
def __str__(self):
|
|
96
|
+
return f'{pre}Single instance assignment operator may recieve multiple instances, try ..= operator or ' \
|
|
97
|
+
f'modify RHS to yield at most one instance{post}\n\t[{self.path}] >> {self.text}'
|
|
98
|
+
|
|
99
|
+
class NoClassOrInstanceFlowForInstanceSetName(ActionException):
|
|
100
|
+
def __init__(self, path, text, x):
|
|
101
|
+
self.path = path
|
|
102
|
+
self.text = text[slice(*x)]
|
|
103
|
+
|
|
104
|
+
def __str__(self):
|
|
105
|
+
return f'{pre}Name in instance set is neither a class or an instance flow source' \
|
|
106
|
+
f'{post}\n\t[{self.path}] >> {self.text}'
|
|
107
|
+
|
|
108
|
+
class ComparingNonAttributeInSelection(SelectActionException):
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
class NoDestinationInPath(ActionException):
|
|
112
|
+
def __init__(self, path):
|
|
113
|
+
self.path = path
|
|
114
|
+
|
|
115
|
+
def __str__(self):
|
|
116
|
+
return f'{pre}No destination class at end of path: [{self.path}].{post}'
|
|
117
|
+
|
|
118
|
+
class UndefinedClass(ActionException):
|
|
119
|
+
def __init__(self, cname):
|
|
120
|
+
self.cname = cname
|
|
121
|
+
|
|
122
|
+
def __str__(self):
|
|
123
|
+
return f'{pre}Class [{self.cname}] not defined.{post}'
|
|
124
|
+
|
|
125
|
+
class IncompletePath(ActionException):
|
|
126
|
+
def __init__(self, path):
|
|
127
|
+
self.path = path
|
|
128
|
+
|
|
129
|
+
def __str__(self):
|
|
130
|
+
return f'{pre}Path requires at least one hop: [{self.path}].{post}'
|
|
131
|
+
|
|
132
|
+
class NoPathFromClass(ActionException):
|
|
133
|
+
def __init__(self, rnum, domain):
|
|
134
|
+
self.rnum = rnum
|
|
135
|
+
self.domain = domain
|
|
136
|
+
|
|
137
|
+
def __str__(self):
|
|
138
|
+
return f'{pre}Undefined relationship [{self.rnum}] in domain [{self.domain}].{post}'
|
|
139
|
+
|
|
140
|
+
class UndefinedRelationship(ActionException):
|
|
141
|
+
def __init__(self, rnum, domain):
|
|
142
|
+
self.rnum = rnum
|
|
143
|
+
self.domain = domain
|
|
144
|
+
|
|
145
|
+
def __str__(self):
|
|
146
|
+
return f'{pre}Undefined relationship [{self.rnum}] in domain [{self.domain}].{post}'
|
|
147
|
+
|
|
148
|
+
class UndefinedAssociation(ActionException):
|
|
149
|
+
def __init__(self, rnum, domain):
|
|
150
|
+
self.rnum = rnum
|
|
151
|
+
self.domain = domain
|
|
152
|
+
|
|
153
|
+
def __str__(self):
|
|
154
|
+
return f'{pre}Undefined association [{self.rnum}] in domain [{self.domain}].{post}'
|
|
155
|
+
|
|
156
|
+
class PerspectiveNotDefined(TraversalActionException):
|
|
157
|
+
def __init__(self, phrase,domain):
|
|
158
|
+
self.phrase = phrase
|
|
159
|
+
self.domain = domain
|
|
160
|
+
|
|
161
|
+
def __str__(self):
|
|
162
|
+
return f'{pre}Perspective [{self.phrase}] not defined in domain [{self.domain}].{post}'
|
|
163
|
+
|
|
164
|
+
class RelationshipUnreachableFromClass(TraversalActionException):
|
|
165
|
+
def __init__(self, rnum, cname, domain):
|
|
166
|
+
self.cname = cname
|
|
167
|
+
self.rnum = rnum
|
|
168
|
+
self.domain = domain
|
|
169
|
+
|
|
170
|
+
def __str__(self):
|
|
171
|
+
return f'{pre}Unreachable relationship [{self.rnum}] from [{self.cname}] in domain [{self.domain}].{post}'
|
|
172
|
+
|
|
173
|
+
class NeedPerspectiveToHop(TraversalActionException):
|
|
174
|
+
def __init__(self, rnum, domain):
|
|
175
|
+
self.rnum = rnum
|
|
176
|
+
self.domain = domain
|
|
177
|
+
|
|
178
|
+
def __str__(self):
|
|
179
|
+
return f'{pre}Reflexive association [{self.rnum}] in domain [{self.domain}] cannot be resolved' \
|
|
180
|
+
f'without perspective.{post}'
|
|
181
|
+
class NeedPerspectiveOrClassToHop(TraversalActionException):
|
|
182
|
+
def __init__(self, rnum, domain):
|
|
183
|
+
self.rnum = rnum
|
|
184
|
+
self.domain = domain
|
|
185
|
+
|
|
186
|
+
def __str__(self):
|
|
187
|
+
return f'{pre}Association [{self.rnum}] in domain [{self.domain}] cannot be resolved' \
|
|
188
|
+
f'without perspective or class.{post}'
|
|
189
|
+
|
|
190
|
+
class HopToUnreachableClass(TraversalActionException):
|
|
191
|
+
def __init__(self, cname, rnum, domain):
|
|
192
|
+
self.cname = cname
|
|
193
|
+
self.rnum = rnum
|
|
194
|
+
self.domain = domain
|
|
195
|
+
|
|
196
|
+
def __str__(self):
|
|
197
|
+
return f'{pre}Relationship [{self.rnum}] does not reach class [{self.cname}] in domain [{self.domain}].{post}'
|
|
198
|
+
|
|
199
|
+
class SubclassNotInGeneralization(TraversalActionException):
|
|
200
|
+
def __init__(self, subclass, rnum, domain):
|
|
201
|
+
self.subclass = subclass
|
|
202
|
+
self.rnum = rnum
|
|
203
|
+
self.domain = domain
|
|
204
|
+
|
|
205
|
+
def __str__(self):
|
|
206
|
+
return f'{pre}Generalization [{self.rnum}] does not include subclass [{self.subclass}] in domain' \
|
|
207
|
+
f'[{self.domain}].{post}'
|
|
208
|
+
class NoSubclassInHop(TraversalActionException):
|
|
209
|
+
def __init__(self, superclass, rnum, domain):
|
|
210
|
+
self.superclass = superclass
|
|
211
|
+
self.rnum = rnum
|
|
212
|
+
self.domain = domain
|
|
213
|
+
|
|
214
|
+
def __str__(self):
|
|
215
|
+
return f'{pre}Generalization [{self.rnum}] from [{self.superclass}] does not reach a subclass in domain' \
|
|
216
|
+
f'[{self.domain}].{post}'
|
|
217
|
+
class MissingTorPrefInAssociativeRel(TraversalActionException):
|
|
218
|
+
def __init__(self, rnum, domain):
|
|
219
|
+
self.rnum = rnum
|
|
220
|
+
self.domain = domain
|
|
221
|
+
|
|
222
|
+
def __str__(self):
|
|
223
|
+
return f'{pre}P or T ref not found for associative relationship [{self.rnum}] in domain [{self.domain}].{post}'
|
|
224
|
+
|
|
225
|
+
class UnexpectedClassOrPerspectiveInPath(TraversalActionException):
|
|
226
|
+
def __init__(self, name, path):
|
|
227
|
+
self.name = name
|
|
228
|
+
self.path = path
|
|
229
|
+
|
|
230
|
+
def __str__(self):
|
|
231
|
+
return f'{pre}Name [{self.name}] not expected in path [{self.path}].{post}'
|
|
232
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
class_exceptions.py – Exceptions encountered when loading a model
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Every error should have the same format
|
|
6
|
+
# with a standard prefix and postfix defined here
|
|
7
|
+
pre = "\nModel loader -- "
|
|
8
|
+
post = " --"
|
|
9
|
+
|
|
10
|
+
# ---
|
|
11
|
+
# ---
|
|
12
|
+
|
|
13
|
+
class UserModel(Exception):
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
class ReferenceToNonIdentifier(UserModel):
|
|
17
|
+
def __str__(self):
|
|
18
|
+
return f"{pre}Attribute does not reference an identifier in target"
|
|
19
|
+
|
|
20
|
+
class MixedTargetID(UserModel):
|
|
21
|
+
def __str__(self):
|
|
22
|
+
return f"{pre}Attributes from more than one ID in target reference"
|