Added umlet output
This commit is contained in:
parent
9758f9aa50
commit
4b7f0e8231
@ -6,7 +6,7 @@
|
|||||||
"py_to_uxf_core": "src/py_to_uxf_core/py_to_uxf_core.json"
|
"py_to_uxf_core": "src/py_to_uxf_core/py_to_uxf_core.json"
|
||||||
},
|
},
|
||||||
"Scripts": {
|
"Scripts": {
|
||||||
"build-start": "cpl build; cd dist/py_to_uxf/build/py_to_uxf; echo \"Starting:\"; bash py_to_uxf ./",
|
"build-start": "cpl build; cd dist/py_to_uxf/build/py_to_uxf; echo \"Starting:\"; bash py_to_uxf -p ./ -o uml.uxf",
|
||||||
"bs": "cpl build-start"
|
"bs": "cpl build-start"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ from cpl_core.console import Console
|
|||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
from cpl_core.dependency_injection import ServiceProviderABC
|
||||||
|
|
||||||
from py_to_uxf_core.abc.python_parser_abc import PythonParserABC
|
from py_to_uxf_core.abc.python_parser_abc import PythonParserABC
|
||||||
|
from py_to_uxf_core.abc.umlet_creator_abc import UmletCreatorABC
|
||||||
from py_to_uxf_core.model.python_class import PythonClass
|
from py_to_uxf_core.model.python_class import PythonClass
|
||||||
|
|
||||||
|
|
||||||
@ -12,21 +13,21 @@ class Application(ApplicationABC):
|
|||||||
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
|
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||||
ApplicationABC.__init__(self, config, services)
|
ApplicationABC.__init__(self, config, services)
|
||||||
|
|
||||||
self._path = config.get_configuration('path')
|
self._path = config.get_configuration('p')
|
||||||
self._parser = services.get_service(PythonParserABC)
|
self._file = ''
|
||||||
|
try:
|
||||||
|
self._file = config.get_configuration('-pAdditionalArguments')[1]
|
||||||
|
except Exception as e:
|
||||||
|
Console.error('Expected file')
|
||||||
|
exit()
|
||||||
|
self._parser: PythonParserABC = services.get_service(PythonParserABC)
|
||||||
|
self._umlet_creator: UmletCreatorABC = services.get_service(UmletCreatorABC)
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def main(self):
|
@staticmethod
|
||||||
Console.banner('Py to UXF')
|
def _console_output(classes: list[PythonClass]):
|
||||||
if self._path is None:
|
|
||||||
Console.write_line('Expected path')
|
|
||||||
return
|
|
||||||
|
|
||||||
Console.write_line(f'Found path:', self._path)
|
|
||||||
classes: list[PythonClass] = self._parser.parse()
|
|
||||||
|
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
Console.write_line(f'Class {cls.name}')
|
Console.write_line(f'Class {cls.name}')
|
||||||
if len(cls.attributes) > 0:
|
if len(cls.attributes) > 0:
|
||||||
@ -40,3 +41,27 @@ class Application(ApplicationABC):
|
|||||||
args = ''
|
args = ''
|
||||||
Console.write_line(f'\t{func.access_modifier.value}{func.name}({args}): {func.return_type}')
|
Console.write_line(f'\t{func.access_modifier.value}{func.name}({args}): {func.return_type}')
|
||||||
Console.write_line()
|
Console.write_line()
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
Console.banner('Py to UXF')
|
||||||
|
if self._path is None:
|
||||||
|
Console.error('Expected path')
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._file is None:
|
||||||
|
Console.error(f'Expected output file')
|
||||||
|
return
|
||||||
|
|
||||||
|
Console.write_line(f'Input path:', self._path)
|
||||||
|
Console.write_line(f'Output path:', self._file)
|
||||||
|
classes: list[PythonClass] = self._parser.parse()
|
||||||
|
# self._console_output(classes)
|
||||||
|
xml = self._umlet_creator.generate_xml(classes)
|
||||||
|
|
||||||
|
if not self._file.endswith('.uxf'):
|
||||||
|
Console.error(f'Unexpected file {self._file}')
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(self._file, 'w+') as file:
|
||||||
|
file.write(xml)
|
||||||
|
file.close()
|
||||||
|
@ -7,5 +7,5 @@ cd "$path/../"
|
|||||||
|
|
||||||
export PYTHONPATH=./:$PYTHONPATH
|
export PYTHONPATH=./:$PYTHONPATH
|
||||||
|
|
||||||
python3.9 py_to_uxf/main.py --path $@
|
python3.9 py_to_uxf/main.py $@
|
||||||
echo ""
|
echo ""
|
||||||
|
@ -26,7 +26,10 @@ class Startup(StartupABC):
|
|||||||
|
|
||||||
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
|
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
|
||||||
environment.set_runtime_directory(os.path.dirname(__file__))
|
environment.set_runtime_directory(os.path.dirname(__file__))
|
||||||
configuration.add_console_argument(ConsoleArgument('--', 'path', [], ' ', is_value_token_optional=False))
|
|
||||||
|
configuration.add_console_argument(ConsoleArgument('-', 'p', [], ' ', False, [
|
||||||
|
ConsoleArgument('-', 'o', [], ' ', is_value_token_optional=False)
|
||||||
|
]))
|
||||||
configuration.add_console_arguments(error=False)
|
configuration.add_console_arguments(error=False)
|
||||||
return configuration
|
return configuration
|
||||||
|
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
from py_to_uxf_core.model.python_class import PythonClass
|
||||||
|
|
||||||
|
|
||||||
class UmletCreatorABC(ABC):
|
class UmletCreatorABC(ABC):
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __init__(self): pass
|
def __init__(self): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def generate_xml(self, classes: list[PythonClass]) -> str: pass
|
||||||
|
21
src/py_to_uxf_core/model/dimension.py
Normal file
21
src/py_to_uxf_core/model/dimension.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
class Dimension:
|
||||||
|
|
||||||
|
def __init__(self, width: int, height: int):
|
||||||
|
self._width = width
|
||||||
|
self._height = height
|
||||||
|
|
||||||
|
@property
|
||||||
|
def width(self) -> int:
|
||||||
|
return self._width
|
||||||
|
|
||||||
|
@width.setter
|
||||||
|
def width(self, value: int):
|
||||||
|
self._width = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def height(self) -> int:
|
||||||
|
return self._height
|
||||||
|
|
||||||
|
@height.setter
|
||||||
|
def height(self, value: int):
|
||||||
|
self._height = value
|
21
src/py_to_uxf_core/model/position.py
Normal file
21
src/py_to_uxf_core/model/position.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
class Position:
|
||||||
|
|
||||||
|
def __init__(self, x: int, y: int):
|
||||||
|
self._x = x
|
||||||
|
self._y = y
|
||||||
|
|
||||||
|
@property
|
||||||
|
def x(self) -> int:
|
||||||
|
return self._x
|
||||||
|
|
||||||
|
@x.setter
|
||||||
|
def x(self, value: int):
|
||||||
|
self._x = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def y(self) -> int:
|
||||||
|
return self._y
|
||||||
|
|
||||||
|
@y.setter
|
||||||
|
def y(self, value: int):
|
||||||
|
self._y = value
|
65
src/py_to_uxf_core/model/uml_class.py
Normal file
65
src/py_to_uxf_core/model/uml_class.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import textwrap
|
||||||
|
|
||||||
|
from cpl_core.console import Console
|
||||||
|
|
||||||
|
from py_to_uxf_core.model.dimension import Dimension
|
||||||
|
from py_to_uxf_core.model.position import Position
|
||||||
|
from py_to_uxf_core.model.python_class import PythonClass
|
||||||
|
|
||||||
|
|
||||||
|
class UMLClass:
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
cls: PythonClass,
|
||||||
|
pos: Position,
|
||||||
|
dim: Dimension
|
||||||
|
):
|
||||||
|
self._cls = cls
|
||||||
|
self._position = pos
|
||||||
|
self._dimension = dim
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cls(self) -> PythonClass:
|
||||||
|
return self._cls
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position(self) -> Position:
|
||||||
|
return self._position
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dimension(self) -> Dimension:
|
||||||
|
return self._dimension
|
||||||
|
|
||||||
|
def as_xml(self) -> str:
|
||||||
|
attributes = ''
|
||||||
|
functions = ''
|
||||||
|
|
||||||
|
if len(self._cls.attributes) > 0:
|
||||||
|
for atr in self._cls.attributes:
|
||||||
|
attributes += f'{atr.access_modifier.value}{atr.name}: {atr.type}\n'
|
||||||
|
|
||||||
|
if len(self._cls.functions) > 0:
|
||||||
|
for func in self._cls.functions:
|
||||||
|
args = ''
|
||||||
|
functions += f'{func.access_modifier.value}{func.name}({args}): {func.return_type}\n'
|
||||||
|
|
||||||
|
return f"""\
|
||||||
|
<element>
|
||||||
|
<id>UMLClass</id>
|
||||||
|
<coordinates>
|
||||||
|
<x>{self._position.x}</x>
|
||||||
|
<y>{self._position.y}</y>
|
||||||
|
<w>{self._dimension.width}</w>
|
||||||
|
<h>{self._dimension.height}</h>
|
||||||
|
</coordinates>
|
||||||
|
<panel_attributes>
|
||||||
|
{self._cls.name}
|
||||||
|
--
|
||||||
|
{attributes}
|
||||||
|
--
|
||||||
|
{functions}
|
||||||
|
</panel_attributes>
|
||||||
|
<additional_attributes></additional_attributes>
|
||||||
|
</element>
|
||||||
|
""".replace(' ', '').replace('\t', '')
|
@ -12,7 +12,7 @@ class FileScannerService(FileScannerABC):
|
|||||||
def __init__(self, config: ConfigurationABC):
|
def __init__(self, config: ConfigurationABC):
|
||||||
FileScannerABC.__init__(self)
|
FileScannerABC.__init__(self)
|
||||||
self._config = config
|
self._config = config
|
||||||
self._path = config.get_configuration('path')
|
self._path = config.get_configuration('p')
|
||||||
|
|
||||||
def scan_files(self) -> List[str]:
|
def scan_files(self) -> List[str]:
|
||||||
files = List(str)
|
files = List(str)
|
||||||
|
@ -53,12 +53,12 @@ class PythonParserService(PythonParserABC):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# start multi line comment
|
# start multi line comment
|
||||||
if line.startswith('"""') and not is_comment:
|
if line.startswith('"""') or line.count('"""') == 1 and not is_comment:
|
||||||
is_comment = True
|
is_comment = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# end multi line comment
|
# end multi line comment
|
||||||
if line.startswith('"""') or line.endswith('"""') and is_comment:
|
if line.startswith('"""') or line.endswith('"""') or line.count('"""') == 1 and is_comment:
|
||||||
is_comment = False
|
is_comment = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -1,7 +1,34 @@
|
|||||||
|
import textwrap
|
||||||
|
|
||||||
|
from cpl_core.console import Console
|
||||||
|
|
||||||
from py_to_uxf_core.abc.umlet_creator_abc import UmletCreatorABC
|
from py_to_uxf_core.abc.umlet_creator_abc import UmletCreatorABC
|
||||||
|
from py_to_uxf_core.model.dimension import Dimension
|
||||||
|
from py_to_uxf_core.model.position import Position
|
||||||
|
from py_to_uxf_core.model.python_class import PythonClass
|
||||||
|
from py_to_uxf_core.model.uml_class import UMLClass
|
||||||
|
|
||||||
|
|
||||||
class UmletCreatorService(UmletCreatorABC):
|
class UmletCreatorService(UmletCreatorABC):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
UmletCreatorABC.__init__(self)
|
UmletCreatorABC.__init__(self)
|
||||||
|
|
||||||
|
def generate_xml(self, classes: list[PythonClass]) -> str:
|
||||||
|
xml_cls = ''
|
||||||
|
width = 400
|
||||||
|
height = 300
|
||||||
|
next_x = 10
|
||||||
|
|
||||||
|
for cls in classes:
|
||||||
|
uml_cls = UMLClass(cls, Position(next_x, 10), Dimension(width, height))
|
||||||
|
xml_cls += uml_cls.as_xml()
|
||||||
|
next_x += width + 10
|
||||||
|
|
||||||
|
return f"""\
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<diagram program="umlet" version="14.1.1">
|
||||||
|
<zoom_level>10</zoom_level>
|
||||||
|
{xml_cls}
|
||||||
|
</diagram>
|
||||||
|
""".replace(' ', '').replace('\t', '')
|
||||||
|
Loading…
Reference in New Issue
Block a user