umlio 0.1.0__py3-none-any.whl

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.
umlio/BaseUmlToXml.py ADDED
@@ -0,0 +1,43 @@
1
+
2
+ from umlshapes.types.Common import UmlShape
3
+ from umlshapes.types.UmlDimensions import UmlDimensions
4
+ from umlshapes.types.UmlPosition import UmlPosition
5
+
6
+ from umlio.IOTypes import ElementAttributes
7
+ from umlio.XMLConstants import XmlConstants
8
+
9
+
10
+ class BaseUmlToXml:
11
+ def __init__(self):
12
+ pass
13
+
14
+ def _umlBaseAttributes(self, umlShape: UmlShape) -> ElementAttributes:
15
+ """
16
+ Create the common OglObject attributes
17
+
18
+ Args:
19
+ umlShape: OGL Object
20
+
21
+ Returns:
22
+ The updated originalElement
23
+ """
24
+ umlClassId: str = str(umlShape.id)
25
+ size: UmlDimensions = umlShape.size
26
+ position: UmlPosition = umlShape.position
27
+
28
+ w: int = size.width
29
+ h: int = size.height
30
+ x: int = position.x
31
+ y: int = position.y
32
+
33
+ attributes: ElementAttributes = ElementAttributes(
34
+ {
35
+ XmlConstants.ATTRIBUTE_ID: umlClassId,
36
+ XmlConstants.ATTRIBUTE_WIDTH: str(w),
37
+ XmlConstants.ATTRIBUTE_HEIGHT: str(h),
38
+ XmlConstants.ATTRIBUTE_X: str(x),
39
+ XmlConstants.ATTRIBUTE_Y: str(y),
40
+ }
41
+ )
42
+
43
+ return attributes
umlio/IOTypes.py ADDED
@@ -0,0 +1,98 @@
1
+
2
+ from typing import Dict
3
+ from typing import List
4
+ from typing import NewType
5
+
6
+ from enum import Enum
7
+
8
+ from dataclasses import dataclass
9
+ from dataclasses import field
10
+
11
+ from pathlib import Path
12
+
13
+ from umlshapes.shapes.UmlActor import UmlActor
14
+ from umlshapes.shapes.UmlClass import UmlClass
15
+ from umlshapes.shapes.UmlNote import UmlNote
16
+ from umlshapes.shapes.UmlText import UmlText
17
+ from umlshapes.shapes.UmlUseCase import UmlUseCase
18
+
19
+ from umlshapes.links.UmlLink import UmlLink
20
+
21
+ UML_VERSION: str = '12.0'
22
+
23
+ UmlDiagramTitle = NewType('UmlDiagramTitle', str)
24
+ UmlClasses = NewType('UmlClasses', List[UmlClass])
25
+ UmlUseCases = NewType('UmlUseCases', List[UmlUseCase])
26
+ UmlActors = NewType('UmlActors', List[UmlActor])
27
+ UmlNotes = NewType('UmlNotes', List[UmlNote])
28
+ UmlTexts = NewType('UmlTexts', List[UmlText])
29
+ UmlLinks = NewType('UmlLinks', List[UmlLink])
30
+
31
+ ElementAttributes = NewType('ElementAttributes', Dict[str, str])
32
+
33
+
34
+ class UmlDiagramType(Enum):
35
+ CLASS_DIAGRAM = 'Class Diagram'
36
+ USE_CASE_DIAGRAM = 'Use Case Diagram'
37
+ SEQUENCE_DIAGRAM = 'Sequence Diagram'
38
+ NOT_SET = 'Not Set'
39
+
40
+
41
+ def umlClassesFactory() -> UmlClasses:
42
+ """
43
+ Factory method to create the UmlClasses data structure;
44
+
45
+ Returns: A new data structure
46
+ """
47
+ return UmlClasses([])
48
+
49
+
50
+ def umlUseCasesFactory() -> UmlUseCases:
51
+ return UmlUseCases([])
52
+
53
+
54
+ def umlActorsFactory() -> UmlActors:
55
+ return UmlActors([])
56
+
57
+
58
+ def umlNotesFactory() -> UmlNotes:
59
+ return UmlNotes([])
60
+
61
+
62
+ def umlTextsFactory() -> UmlTexts:
63
+ return UmlTexts([])
64
+
65
+
66
+ def umlLinksFactory() -> UmlLinks:
67
+ return UmlLinks([])
68
+
69
+
70
+ @dataclass
71
+ class UmlDiagram:
72
+ diagramType: UmlDiagramType = UmlDiagramType.NOT_SET
73
+ diagramTitle: UmlDiagramTitle = UmlDiagramTitle('')
74
+ scrollPositionX: int = 1
75
+ scrollPositionY: int = 1
76
+ pixelsPerUnitX: int = 1
77
+ pixelsPerUnitY: int = 1
78
+ umlClasses: UmlClasses = field(default_factory=umlClassesFactory)
79
+ umlUseCases: UmlUseCases = field(default_factory=umlUseCasesFactory)
80
+ umlActors: UmlActors = field(default_factory=umlActorsFactory)
81
+ umlNotes: UmlNotes = field(default_factory=umlNotesFactory)
82
+ umlTexts: UmlTexts = field(default_factory=umlTextsFactory)
83
+ umlLinks: UmlLinks = field(default_factory=umlLinksFactory)
84
+
85
+
86
+ UmlDiagrams = NewType('UmlDiagrams', Dict[UmlDiagramTitle, UmlDiagram])
87
+
88
+
89
+ def createUmlDiagramsFactory() -> UmlDiagrams:
90
+ return UmlDiagrams({})
91
+
92
+
93
+ @dataclass
94
+ class UmlProject:
95
+ fileName: str = ''
96
+ version: str = UML_VERSION
97
+ codePath: Path = Path('')
98
+ umlDiagrams: UmlDiagrams = field(default_factory=createUmlDiagramsFactory)
umlio/PyutToXml.py ADDED
@@ -0,0 +1,349 @@
1
+
2
+ from logging import Logger
3
+ from logging import getLogger
4
+
5
+ from os import linesep as osLineSep
6
+
7
+ from xml.etree.ElementTree import Element
8
+ from xml.etree.ElementTree import SubElement
9
+
10
+ from codeallybasic.Common import XML_END_OF_LINE_MARKER
11
+
12
+ from umlio.IOTypes import ElementAttributes
13
+
14
+ from pyutmodelv2.PyutLink import LinkDestination
15
+ from pyutmodelv2.PyutLink import LinkSource
16
+ from pyutmodelv2.PyutLink import PyutLink
17
+
18
+ from pyutmodelv2.PyutModelTypes import ClassName
19
+ from pyutmodelv2.PyutActor import PyutActor
20
+ from pyutmodelv2.PyutClass import PyutClass
21
+ from pyutmodelv2.PyutClassCommon import PyutClassCommon
22
+ from pyutmodelv2.PyutField import PyutField
23
+ from pyutmodelv2.PyutInterface import PyutInterface
24
+ from pyutmodelv2.PyutMethod import PyutMethod
25
+ from pyutmodelv2.PyutMethod import SourceCode
26
+ from pyutmodelv2.PyutNote import PyutNote
27
+ from pyutmodelv2.PyutParameter import PyutParameter
28
+ from pyutmodelv2.PyutSDInstance import PyutSDInstance
29
+ from pyutmodelv2.PyutSDMessage import PyutSDMessage
30
+ from pyutmodelv2.PyutText import PyutText
31
+ from pyutmodelv2.PyutUseCase import PyutUseCase
32
+
33
+ from umlio.XMLConstants import XmlConstants
34
+
35
+
36
+ class PyutToXml:
37
+ """
38
+ Serializes Pyut Model classes to DOM
39
+ """
40
+
41
+ def __init__(self):
42
+ super().__init__()
43
+ self.logger: Logger = getLogger(__name__)
44
+
45
+ def pyutClassToXml(self, pyutClass: PyutClass, graphicElement: Element) -> Element:
46
+ """
47
+ Exporting a PyutClass to a miniDom Element.
48
+
49
+ Args:
50
+ pyutClass: The pyut class to serialize
51
+ graphicElement: The xml element to update
52
+
53
+ Returns:
54
+ A new updated element
55
+ """
56
+
57
+ commonAttributes = self._pyutClassCommonAttributes(pyutClass)
58
+ attributes = {
59
+ XmlConstants.ATTRIBUTE_ID: str(pyutClass.id),
60
+ XmlConstants.ATTRIBUTE_NAME: pyutClass.name,
61
+ XmlConstants.ATTRIBUTE_DISPLAY_METHODS: str(pyutClass.showMethods),
62
+ XmlConstants.ATTRIBUTE_DISPLAY_PARAMETERS: pyutClass.displayParameters.value,
63
+ XmlConstants.ATTRIBUTE_DISPLAY_CONSTRUCTOR: pyutClass.displayConstructor.value,
64
+ XmlConstants.ATTRIBUTE_DISPLAY_DUNDER_METHODS: pyutClass.displayDunderMethods.value,
65
+ XmlConstants.ATTRIBUTE_DISPLAY_FIELDS: str(pyutClass.showFields),
66
+ XmlConstants.ATTRIBUTE_DISPLAY_STEREOTYPE: str(pyutClass.displayStereoType),
67
+ XmlConstants.ATTRIBUTE_FILENAME: pyutClass.fileName,
68
+ }
69
+
70
+ attributes = attributes | commonAttributes
71
+
72
+ pyutClassElement: Element = SubElement(graphicElement, XmlConstants.ELEMENT_MODEL_CLASS, attrib=attributes)
73
+
74
+ for method in pyutClass.methods:
75
+ self._pyutMethodToXml(pyutMethod=method, pyutClassElement=pyutClassElement)
76
+
77
+ for pyutField in pyutClass.fields:
78
+ self._pyutFieldToXml(pyutField=pyutField, pyutClassElement=pyutClassElement)
79
+ return pyutClassElement
80
+
81
+ def pyutLinkToXml(self, pyutLink: PyutLink, oglLinkElement: Element) -> Element:
82
+ """
83
+ Exporting a PyutLink to an Element.
84
+
85
+ Args:
86
+ pyutLink: Link to save
87
+ oglLinkElement: xml document
88
+
89
+ Returns:
90
+ A new minidom element
91
+ """
92
+ src: LinkSource = pyutLink.source
93
+ dst: LinkDestination = pyutLink.destination
94
+
95
+ srcLinkId: int = src.id
96
+ destLinkId: int = dst.id
97
+
98
+ attributes: ElementAttributes = ElementAttributes({
99
+ XmlConstants.ATTRIBUTE_NAME: pyutLink.name,
100
+ XmlConstants.ATTRIBUTE_TYPE: pyutLink.linkType.name,
101
+ XmlConstants.ATTRIBUTE_SOURCE_ID: str(srcLinkId),
102
+ XmlConstants.ATTRIBUTE_DESTINATION_ID: str(destLinkId),
103
+ XmlConstants.ATTRIBUTE_BIDIRECTIONAL: str(pyutLink.bidirectional),
104
+ XmlConstants.ATTRIBUTE_SOURCE_CARDINALITY_VALUE: pyutLink.sourceCardinality,
105
+ XmlConstants.ATTRIBUTE_DESTINATION_CARDINALITY_VALUE: pyutLink.destinationCardinality,
106
+ })
107
+ pyutLinkElement: Element = SubElement(oglLinkElement, XmlConstants.ELEMENT_MODEL_LINK, attrib=attributes)
108
+
109
+ return pyutLinkElement
110
+
111
+ def pyutInterfaceToXml(self, pyutInterface: PyutInterface, interface2Element: Element) -> Element:
112
+
113
+ classId: int = pyutInterface.id
114
+
115
+ attributes: ElementAttributes = ElementAttributes({
116
+ XmlConstants.ATTRIBUTE_ID: str(classId),
117
+ XmlConstants.ATTRIBUTE_NAME: pyutInterface.name,
118
+ XmlConstants.ATTRIBUTE_DESCRIPTION: pyutInterface.description
119
+ })
120
+ pyutInterfaceElement: Element = SubElement(interface2Element, XmlConstants.ELEMENT_MODEL_INTERFACE, attrib=attributes)
121
+
122
+ for method in pyutInterface.methods:
123
+ self._pyutMethodToXml(pyutMethod=method, pyutClassElement=pyutInterfaceElement)
124
+
125
+ for className in pyutInterface.implementors:
126
+ self.logger.debug(f'implementing className: {className}')
127
+ self._pyutImplementorToXml(className, pyutInterfaceElement)
128
+
129
+ return pyutInterfaceElement
130
+
131
+ def pyutNoteToXml(self, pyutNote: PyutNote, oglNoteElement: Element) -> Element:
132
+
133
+ noteId: int = pyutNote.id
134
+ content: str = pyutNote.content
135
+ fixedContent: str = content.replace(osLineSep, XML_END_OF_LINE_MARKER)
136
+ if pyutNote.fileName is None:
137
+ pyutNote.fileName = ''
138
+
139
+ attributes: ElementAttributes = ElementAttributes({
140
+ XmlConstants.ATTRIBUTE_ID: str(noteId),
141
+ XmlConstants.ATTRIBUTE_CONTENT: fixedContent,
142
+ XmlConstants.ATTRIBUTE_FILENAME: pyutNote.fileName,
143
+ })
144
+ pyutNoteElement: Element = SubElement(oglNoteElement, XmlConstants.ELEMENT_MODEL_NOTE, attrib=attributes)
145
+
146
+ return pyutNoteElement
147
+
148
+ def pyutTextToXml(self, pyutText: PyutText, oglTextElement: Element) -> Element:
149
+
150
+ textId: int = pyutText.id
151
+ content: str = pyutText.content
152
+ fixedContent: str = content.replace(osLineSep, XML_END_OF_LINE_MARKER)
153
+
154
+ attributes: ElementAttributes = ElementAttributes({
155
+ XmlConstants.ATTRIBUTE_ID: str(textId),
156
+ XmlConstants.ATTRIBUTE_CONTENT: fixedContent,
157
+ })
158
+ pyutTextElement: Element = SubElement(oglTextElement, XmlConstants.ELEMENT_MODEL_TEXT, attrib=attributes)
159
+
160
+ return pyutTextElement
161
+
162
+ def pyutActorToXml(self, pyutActor: PyutActor, oglActorElement: Element) -> Element:
163
+
164
+ actorId: int = pyutActor.id
165
+ fileName: str = pyutActor.fileName
166
+ if fileName is None:
167
+ fileName = ''
168
+
169
+ attributes: ElementAttributes = ElementAttributes({
170
+ XmlConstants.ATTRIBUTE_ID: str(actorId),
171
+ XmlConstants.ATTRIBUTE_NAME: pyutActor.name,
172
+ XmlConstants.ATTRIBUTE_FILE_NAME: fileName,
173
+ })
174
+ pyutActorElement: Element = SubElement(oglActorElement, XmlConstants.ELEMENT_MODEL_ACTOR, attributes)
175
+
176
+ return pyutActorElement
177
+
178
+ def pyutUseCaseToXml(self, pyutUseCase: PyutUseCase, oglUseCaseElement: Element) -> Element:
179
+
180
+ useCaseId: int = pyutUseCase.id
181
+ fileName: str = pyutUseCase.fileName
182
+ if fileName is None:
183
+ fileName = ''
184
+
185
+ attributes: ElementAttributes = ElementAttributes({
186
+ XmlConstants.ATTRIBUTE_ID: str(useCaseId),
187
+ XmlConstants.ATTRIBUTE_NAME: pyutUseCase.name,
188
+ XmlConstants.ATTRIBUTE_FILE_NAME: fileName
189
+ })
190
+ pyutUseCaseElement: Element = SubElement(oglUseCaseElement, XmlConstants.ELEMENT_MODEL_USE_CASE, attributes)
191
+
192
+ return pyutUseCaseElement
193
+
194
+ def pyutSDInstanceToXml(self, pyutSDInstance: PyutSDInstance, oglSDInstanceElement: Element) -> Element:
195
+
196
+ sdInstanceId: int = pyutSDInstance.id
197
+
198
+ attributes: ElementAttributes = ElementAttributes({
199
+ XmlConstants.ATTRIBUTE_ID: str(sdInstanceId),
200
+ XmlConstants.ATTRIBUTE_INSTANCE_NAME: pyutSDInstance.instanceName,
201
+ XmlConstants.ATTRIBUTE_LIFE_LINE_LENGTH: str(pyutSDInstance.instanceLifeLineLength),
202
+ })
203
+
204
+ pyutSDInstanceElement: Element = SubElement(oglSDInstanceElement, XmlConstants.ELEMENT_MODEL_SD_INSTANCE, attrib=attributes)
205
+
206
+ return pyutSDInstanceElement
207
+
208
+ def pyutSDMessageToXml(self, pyutSDMessage: PyutSDMessage, oglSDMessageElement: Element) -> Element:
209
+
210
+ sdMessageId: int = pyutSDMessage.id
211
+
212
+ # srcInstance: PyutSDInstance = pyutSDMessage.getSource()
213
+ # dstInstance: PyutSDInstance = pyutSDMessage.getDestination()
214
+ srcInstance: LinkSource = pyutSDMessage.source
215
+ dstInstance: LinkDestination = pyutSDMessage.destination
216
+
217
+ idSrc: int = srcInstance.id
218
+ idDst: int = dstInstance.id
219
+
220
+ attributes: ElementAttributes = ElementAttributes({
221
+ XmlConstants.ATTRIBUTE_ID: str(sdMessageId),
222
+ XmlConstants.ATTRIBUTE_MESSAGE: pyutSDMessage.message,
223
+ XmlConstants.ATTRIBUTE_SOURCE_TIME: str(pyutSDMessage.sourceY),
224
+ XmlConstants.ATTRIBUTE_DESTINATION_TIME: str(pyutSDMessage.destinationY),
225
+ XmlConstants.ATTRIBUTE_SD_MESSAGE_SOURCE_ID: str(idSrc),
226
+ XmlConstants.ATTRIBUTE_SD_MESSAGE_DESTINATION_ID: str(idDst),
227
+ })
228
+
229
+ pyutSDMessageElement: Element = SubElement(oglSDMessageElement, XmlConstants.ELEMENT_MODEL_SD_MESSAGE, attrib=attributes)
230
+
231
+ return pyutSDMessageElement
232
+
233
+ def _pyutMethodToXml(self, pyutMethod: PyutMethod, pyutClassElement: Element) -> Element:
234
+ """
235
+ Exporting a PyutMethod to an Element
236
+
237
+ Args:
238
+ pyutMethod: Method to serialize
239
+ pyutClassElement: xml document
240
+
241
+ Returns:
242
+ The new updated element
243
+ """
244
+ attributes = {
245
+ XmlConstants.ATTRIBUTE_NAME: pyutMethod.name,
246
+ XmlConstants.ATTRIBUTE_VISIBILITY: pyutMethod.visibility.name,
247
+ XmlConstants.ATTRIBUTE_METHOD_RETURN_TYPE: pyutMethod.returnType.value,
248
+ }
249
+ pyutMethodElement: Element = SubElement(pyutClassElement, XmlConstants.ELEMENT_MODEL_METHOD, attrib=attributes)
250
+ for modifier in pyutMethod.modifiers:
251
+ attributes = {
252
+ XmlConstants.ATTRIBUTE_NAME: modifier.name,
253
+ }
254
+ SubElement(pyutMethodElement, XmlConstants.ELEMENT_MODEL_MODIFIER, attrib=attributes)
255
+ self._pyutSourceCodeToXml(pyutMethod.sourceCode, pyutMethodElement)
256
+
257
+ for pyutParameter in pyutMethod.parameters:
258
+ self._pyutParameterToXml(pyutParameter, pyutMethodElement)
259
+ # pyutMethodElement: Element = xmlDoc.createElement(XmlConstants.ELEMENT_MODEL_METHOD)
260
+ #
261
+ # pyutMethodElement.setAttribute(XmlConstants.ATTR_NAME, pyutMethod.name)
262
+ #
263
+ # visibility: PyutVisibilityEnum = pyutMethod.getVisibility()
264
+ # visName: str = self.__safeVisibilityToName(visibility)
265
+ #
266
+ # if visibility is not None:
267
+ # pyutMethodElement.setAttribute(XmlConstants.ATTR_VISIBILITY, visName)
268
+ #
269
+ # for modifier in pyutMethod.modifiers:
270
+ # xmlModifier: Element = xmlDoc.createElement(XmlConstants.ELEMENT_MODEL_MODIFIER)
271
+ # xmlModifier.setAttribute(XmlConstants.ATTR_NAME, modifier.name)
272
+ # pyutMethodElement.appendChild(xmlModifier)
273
+ #
274
+ # if pyutMethod.returnType is not None:
275
+ # xmlReturnType: Element = xmlDoc.createElement(XmlConstants.ELEMENT_MODEL_RETURN)
276
+ # xmlReturnType.setAttribute(XmlConstants.ATTR_TYPE, str(pyutMethod.returnType))
277
+ # pyutMethodElement.appendChild(xmlReturnType)
278
+ #
279
+ # for param in pyutMethod.parameters:
280
+ # pyutMethodElement.appendChild(self._pyutParamToDom(param, xmlDoc))
281
+ #
282
+ # codeRoot: Element = self._pyutSourceCodeToDom(pyutMethod.sourceCode, xmlDoc)
283
+ # pyutMethodElement.appendChild(codeRoot)
284
+ # return pyutMethodElement
285
+ return pyutMethodElement
286
+
287
+ def _pyutClassCommonAttributes(self, classCommon: PyutClassCommon):
288
+
289
+ attributes = {
290
+ XmlConstants.ATTRIBUTE_DESCRIPTION: classCommon.description
291
+ }
292
+ return attributes
293
+
294
+ def _pyutSourceCodeToXml(self, sourceCode: SourceCode, pyutMethodElement: Element):
295
+
296
+ codeRoot: Element = SubElement(pyutMethodElement, XmlConstants.ELEMENT_MODEL_SOURCE_CODE)
297
+
298
+ for code in sourceCode:
299
+ codeElement: Element = SubElement(codeRoot, XmlConstants.ELEMENT_MODEL_CODE)
300
+ codeElement.text = code
301
+
302
+ return codeRoot
303
+
304
+ def _pyutParameterToXml(self, pyutParameter: PyutParameter, pyutMethodElement: Element) -> Element:
305
+
306
+ attributes = {
307
+ XmlConstants.ATTRIBUTE_NAME: pyutParameter.name,
308
+ XmlConstants.ATTRIBUTE_TYPE: pyutParameter.type.value,
309
+ # XmlConstants.ATTR_DEFAULT_VALUE: pyutParameter.defaultValue,
310
+ }
311
+
312
+ defaultValue = pyutParameter.defaultValue
313
+ if defaultValue is not None:
314
+ attributes[XmlConstants.ATTRIBUTE_DEFAULT_VALUE] = pyutParameter.defaultValue
315
+
316
+ pyutParameterElement: Element = SubElement(pyutMethodElement, XmlConstants.ELEMENT_MODEL_PARAMETER, attrib=attributes)
317
+
318
+ return pyutParameterElement
319
+
320
+ def _pyutFieldToXml(self, pyutField: PyutField, pyutClassElement: Element) -> Element:
321
+ """
322
+ Serialize a PyutField to an Element
323
+
324
+ Args:
325
+ pyutField: The PyutField to serialize
326
+ pyutClassElement: The Pyut Class element to update
327
+
328
+ Returns:
329
+ The new updated element
330
+ """
331
+ attributes = {
332
+ XmlConstants.ATTRIBUTE_NAME: pyutField.name,
333
+ XmlConstants.ATTRIBUTE_VISIBILITY: pyutField.visibility.name,
334
+ XmlConstants.ATTRIBUTE_TYPE: pyutField.type.value,
335
+ XmlConstants.ATTRIBUTE_DEFAULT_VALUE: pyutField.defaultValue,
336
+ }
337
+ pyutFieldElement: Element = SubElement(pyutClassElement, XmlConstants.ELEMENT_MODEL_FIELD, attrib=attributes)
338
+
339
+ return pyutFieldElement
340
+
341
+ def _pyutImplementorToXml(self, className: ClassName, xmlDoc: Element) -> Element:
342
+
343
+ # root: Element = xmlDoc.createElement(XmlConstants.ELEMENT_IMPLEMENTOR)
344
+ # root.setAttribute()
345
+ attributes: ElementAttributes = ElementAttributes({
346
+ XmlConstants.ATTRIBUTE_IMPLEMENTING_CLASS_NAME: className,
347
+ })
348
+ implementorElement: Element = SubElement(xmlDoc, XmlConstants.ELEMENT_MODEL_IMPLEMENTOR, attrib=attributes)
349
+ return implementorElement
umlio/UmlClassToXml.py ADDED
@@ -0,0 +1,47 @@
1
+
2
+ from logging import Logger
3
+ from logging import getLogger
4
+
5
+ from xml.etree.ElementTree import Element
6
+ from xml.etree.ElementTree import SubElement
7
+
8
+ from umlshapes.shapes.UmlClass import UmlClass
9
+
10
+ from umlio.BaseUmlToXml import BaseUmlToXml
11
+ from umlio.IOTypes import UmlClasses
12
+ from umlio.PyutToXml import PyutToXml
13
+ from umlio.XMLConstants import XmlConstants
14
+
15
+
16
+ class UmlClassToXml(BaseUmlToXml):
17
+ def __init__(self):
18
+
19
+ super().__init__()
20
+
21
+ self.logger: Logger = getLogger(__name__)
22
+ self._pyutToXml: PyutToXml = PyutToXml()
23
+
24
+ def serialize(self, documentTop: Element, umlClasses: UmlClasses) -> Element:
25
+
26
+ for umlClass in umlClasses:
27
+ self._oglClassToXml(documentTop=documentTop, umlClass=umlClass)
28
+
29
+ return documentTop
30
+
31
+ def _oglClassToXml(self, documentTop: Element, umlClass: UmlClass) -> Element:
32
+ """
33
+ Exports an UmlClass to a minidom Element.
34
+
35
+ Args:
36
+ documentTop: The document to append to
37
+ umlClass: UML Class to serialize
38
+
39
+ Returns:
40
+ The newly created `UmlClass` Element
41
+ """
42
+ attributes = self._umlBaseAttributes(umlShape=umlClass)
43
+ oglClassSubElement: Element = SubElement(documentTop, XmlConstants.ELEMENT_UML_CLASS, attrib=attributes)
44
+
45
+ self._pyutToXml.pyutClassToXml(graphicElement=oglClassSubElement, pyutClass=umlClass.pyutClass)
46
+
47
+ return oglClassSubElement
umlio/UmlLinksToXml.py ADDED
@@ -0,0 +1,153 @@
1
+
2
+ from typing import cast
3
+
4
+ from logging import Logger
5
+ from logging import getLogger
6
+
7
+ from wx import Point
8
+
9
+ from xml.etree.ElementTree import Element
10
+ from xml.etree.ElementTree import SubElement
11
+
12
+ from umlshapes.links.DeltaXY import DeltaXY
13
+ from umlshapes.links.UmlAssociation import UmlAssociation
14
+ from umlshapes.links.UmlAssociationLabel import UmlAssociationLabel
15
+ from umlshapes.links.UmlLink import UmlLink
16
+ from umlshapes.links.eventhandlers.UmlLinkEventHandler import LineControlPoints
17
+
18
+ from umlshapes.types.Common import EndPoints
19
+ from umlshapes.types.UmlPosition import UmlPosition
20
+
21
+ from umlio.BaseUmlToXml import BaseUmlToXml
22
+
23
+ from umlio.IOTypes import ElementAttributes
24
+ from umlio.IOTypes import UmlLinks
25
+ from umlio.PyutToXml import PyutToXml
26
+
27
+ from umlio.XMLConstants import XmlConstants
28
+
29
+
30
+ class UmlLinksToXml(BaseUmlToXml):
31
+ def __init__(self):
32
+ super().__init__()
33
+ self.logger: Logger = getLogger(__name__)
34
+
35
+ self._pyutToXml: PyutToXml = PyutToXml()
36
+
37
+ def serialize(self, documentTop: Element, umlLinks: UmlLinks) -> Element:
38
+
39
+ for umlLink in umlLinks:
40
+ # if isinstance(oglLink, OglInterface2):
41
+ # self._oglInterface2ToXml(documentElement=documentTop, oglInterface=oglLink)
42
+ # else:
43
+ self._oglLinkToXml(documentElement=documentTop, umlLink=umlLink)
44
+
45
+ return documentTop
46
+
47
+ def _oglLinkToXml(self, documentElement: Element, umlLink: UmlLink) -> Element:
48
+
49
+ attributes: ElementAttributes = self._umlLinkAttributes(umlLink=umlLink)
50
+ oglLinkSubElement: Element = SubElement(documentElement, XmlConstants.ELEMENT_UML_LINK, attrib=attributes)
51
+
52
+ if isinstance(umlLink, UmlAssociation):
53
+
54
+ associationName: UmlAssociationLabel = umlLink.associationName
55
+ src: UmlAssociationLabel = umlLink.sourceCardinality
56
+ dst: UmlAssociationLabel = umlLink.destinationCardinality
57
+ associationLabels = {
58
+ XmlConstants.ELEMENT_ASSOCIATION_LABEL: associationName,
59
+ XmlConstants.ELEMENT_ASSOCIATION_SOURCE_LABEL: src,
60
+ XmlConstants.ELEMENT_ASSOCIATION_DESTINATION_LABEL: dst
61
+ }
62
+ for eltName in associationLabels:
63
+ umlAssociationLabel: UmlAssociationLabel = associationLabels[eltName]
64
+
65
+ linkDelta: DeltaXY = umlAssociationLabel.linkDelta
66
+
67
+ labelAttributes: ElementAttributes = ElementAttributes({
68
+ XmlConstants.ATTRIBUTE_DELTA_X: str(linkDelta.deltaX),
69
+ XmlConstants.ATTRIBUTE_DELTA_Y: str(linkDelta.deltaY),
70
+ })
71
+ # noinspection PyUnusedLocal
72
+ labelElement: Element = SubElement(oglLinkSubElement, eltName, attrib=labelAttributes)
73
+
74
+ lineControlPoints: LineControlPoints = umlLink.GetLineControlPoints()
75
+ realControlPoints: LineControlPoints = self._removeEndPoints(umlLink=umlLink, lineControlPoints=lineControlPoints)
76
+ for pt in realControlPoints:
77
+ wxPoint: Point = cast(Point, pt)
78
+ controlPointAttributes: ElementAttributes = ElementAttributes({
79
+ XmlConstants.ATTRIBUTE_X: str(wxPoint.x),
80
+ XmlConstants.ATTRIBUTE_Y: str(wxPoint.y),
81
+ })
82
+ SubElement(oglLinkSubElement, XmlConstants.ELEMENT_MODEL_LINE_CONTROL_POINT, attrib=controlPointAttributes)
83
+
84
+ self._pyutToXml.pyutLinkToXml(pyutLink=umlLink.pyutLink, oglLinkElement=oglLinkSubElement)
85
+
86
+ return oglLinkSubElement
87
+
88
+ # def _oglInterface2ToXml(self, documentElement: Element, oglInterface: OglInterface2) -> Element:
89
+ # """
90
+ #
91
+ # Args:
92
+ # documentElement: untangler element for document
93
+ # oglInterface: Lollipop to serialize
94
+ # Returns:
95
+ # New untangle element
96
+ # """
97
+ # destAnchor: SelectAnchorPoint = oglInterface.destinationAnchor
98
+ # attachmentPoint: AttachmentSide = destAnchor.attachmentPoint
99
+ # x, y = destAnchor.GetPosition()
100
+ #
101
+ # attributes: ElementAttributes = ElementAttributes({
102
+ # XmlConstants.ATTR_LOLLIPOP_ATTACHMENT_POINT: attachmentPoint.__str__(),
103
+ # XmlConstants.ATTR_X: str(x),
104
+ # XmlConstants.ATTR_Y: str(y),
105
+ # })
106
+ # oglInterface2: Element = SubElement(documentElement, XmlConstants.ELEMENT_OGL_INTERFACE2, attrib=attributes)
107
+ #
108
+ # self._pyutToXml.pyutInterfaceToXml(oglInterface.pyutInterface, oglInterface2)
109
+ # return oglInterface2
110
+ #
111
+ def _umlLinkAttributes(self, umlLink: UmlLink) -> ElementAttributes:
112
+
113
+ # srcX, srcY = umlLink.sourceAnchor.model.GetPosition()
114
+ # destX, destY = umlLink.destinationAnchor.model.GetPosition()
115
+
116
+ umlLinkId: str = str(umlLink.id)
117
+ endPoints: EndPoints = umlLink.endPoints
118
+ fromPosition: UmlPosition = endPoints.fromPosition
119
+ toPosition: UmlPosition = endPoints.toPosition
120
+
121
+ attributes: ElementAttributes = ElementAttributes({
122
+ XmlConstants.ATTRIBUTE_ID: umlLinkId,
123
+ XmlConstants.ATTRIBUTE_LINK_FROM_X: str(fromPosition.x),
124
+ XmlConstants.ATTRIBUTE_LINK_FROM_Y: str(fromPosition.y),
125
+ XmlConstants.ATTRIBUTE_LINK_TO_X: str(toPosition.x),
126
+ XmlConstants.ATTRIBUTE_LINK_TO_Y: str(toPosition.y),
127
+ XmlConstants.ATTRIBUTE_SPLINE: str(umlLink.spline) # piecewise polynomial function
128
+ })
129
+
130
+ return attributes
131
+
132
+ def _removeEndPoints(self, umlLink: 'UmlLink', lineControlPoints: LineControlPoints) -> LineControlPoints:
133
+ """
134
+ Do not consider the end points
135
+
136
+ Args:
137
+ umlLink:
138
+ lineControlPoints:
139
+
140
+ Returns: The control points less the 2 end points
141
+ """
142
+
143
+ realControlPoints: LineControlPoints = LineControlPoints(lineControlPoints[:])
144
+
145
+ x1, y1, x2, y2 = umlLink.FindLineEndPoints()
146
+
147
+ pt1: Point = Point(x1, y1)
148
+ pt2: Point = Point(x2, y2)
149
+
150
+ realControlPoints.remove(pt1)
151
+ realControlPoints.remove(pt2)
152
+
153
+ return realControlPoints