Added umlet output

This commit is contained in:
Sven Heidemann 2022-01-16 13:45:01 +01:00
parent 9758f9aa50
commit 4b7f0e8231
11 changed files with 184 additions and 17 deletions

View File

@ -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"
} }
} }

View File

@ -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()

View File

@ -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 ""

View File

@ -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

View File

@ -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

View 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

View 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

View 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', '')

View File

@ -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)

View File

@ -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

View File

@ -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', '')