Skip to content

Commit 9d6e84f

Browse files
committed
Improved drawio diagram generation
1 parent bb4b451 commit 9d6e84f

2 files changed

Lines changed: 86 additions & 12 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ FROST-Server.HTTP/keycloak.json
2222
FROST-Server.MQTT/FrostMqtt.properties
2323
logs
2424
Tools/ModelExtractor/examples
25+

Plugins/OData/src/main/java/de/fraunhofer/iosb/ilt/frostserver/plugin/odata/metadata/MxGraphGenerator.java

Lines changed: 85 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@
3636
import de.fraunhofer.iosb.ilt.frostserver.property.type.TypeComplex;
3737
import java.io.IOException;
3838
import java.io.Writer;
39+
import java.nio.charset.StandardCharsets;
40+
import java.security.MessageDigest;
41+
import java.security.NoSuchAlgorithmException;
3942
import java.util.ArrayList;
4043
import java.util.Collection;
4144
import java.util.HashMap;
45+
import java.util.HexFormat;
4246
import java.util.List;
4347
import java.util.Map;
4448
import java.util.Set;
@@ -52,18 +56,18 @@
5256
*/
5357
public class MxGraphGenerator {
5458

55-
private static final String STYLE_LIST = "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#98D095;strokeColor=#82b366;swimlaneFillColor=#E3F7E2;";
56-
private static final String STYLE_LIST_ITEM = "text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=visible;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;html=1;";
59+
private static final String STYLE_LIST = "swimlane;fontStyle=1;childLayout=stackLayout;horizontal=1;startSize=32;fontSize=16;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#98D095;strokeColor=#82b366;swimlaneFillColor=#E3F7E2;";
60+
private static final String STYLE_LIST_ITEM = "text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=visible;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;html=1;fontSize=14;";
5761
private static final String STYLE_CONNECTOR = "endArrow=classic;startArrow=classic;html=1;rounded=0;";
58-
private static final String STYLE_LABEL = "edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];labelBackgroundColor=none;fontSize=10;spacingLeft=1;spacing=3;spacingRight=2;";
62+
private static final String STYLE_LABEL = "edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];labelBackgroundColor=none;fontSize=12;spacingLeft=1;spacing=3;spacingRight=2;";
5963

6064
private static final String AS_SOURCEPOINT = "sourcePoint";
6165
private static final String AS_TARGETPOINT = "targetPoint";
6266
private static final String AS_OFFSET = "offset";
6367
private static final String AS_GEOMETRY = "geometry";
64-
private static final int BOX_WIDTH = 140;
65-
private static final int BOX_HEIGHT_BASE = 30;
66-
private static final int BOX_HEIGHT_ITEM = 16;
68+
private static final int BOX_WIDTH = 160;
69+
private static final int BOX_HEIGHT_BASE = 32;
70+
private static final int BOX_HEIGHT_ITEM = 18;
6771
private static final int DISTANCE = 100;
6872

6973
private final Map<EntityType, MxCell> typeCells = new HashMap<>();
@@ -136,6 +140,7 @@ private void addEntityType(EntityType et, MxCell cellOne, Root root, Set<String>
136140
.setX(globalX * (BOX_WIDTH + DISTANCE))
137141
.setY(globalY);
138142
MxCell typeCell = new MxCell()
143+
.setId(genIdFor(et))
139144
.setValue(et.entityName)
140145
.setStyle(STYLE_LIST)
141146
.setParent(cellOne.getId())
@@ -145,7 +150,7 @@ private void addEntityType(EntityType et, MxCell cellOne, Root root, Set<String>
145150
typeCells.put(et, typeCell);
146151
int listItemY = BOX_HEIGHT_BASE;
147152
for (EntityPropertyMain ep : entityProperties) {
148-
addEntityProperty(listItemY, typeCell, ep, root);
153+
addEntityProperty(listItemY, typeCell, et, ep, root);
149154
listItemY += BOX_HEIGHT_ITEM;
150155
if (ep.getType() instanceof TypeComplex) {
151156
complexTypes.add(ep.getType().getName());
@@ -178,6 +183,7 @@ private void addComplexPropertyType(TypeComplex tc, MxCell cellOne, Root root) {
178183
.setX(globalX * (BOX_WIDTH + DISTANCE))
179184
.setY(globalY);
180185
MxCell typeCell = new MxCell()
186+
.setId(genIdFor(tc))
181187
.setValue(tc.getName())
182188
.setStyle(STYLE_LIST)
183189
.setParent(cellOne.getId())
@@ -189,17 +195,18 @@ private void addComplexPropertyType(TypeComplex tc, MxCell cellOne, Root root) {
189195
for (Map.Entry<String, PropertyType> prop : properties.entrySet()) {
190196
final String name = prop.getKey();
191197
final PropertyType type = prop.getValue();
192-
addPropertyType(listItemY, typeCell, name, type, tc.isRequired(name), root);
198+
addTypeProperty(listItemY, typeCell, tc, name, type, tc.isRequired(name), root);
193199
listItemY += BOX_HEIGHT_ITEM;
194200
}
195201
}
196202

197-
private void addPropertyType(int listItemY, MxCell typeCell, String name, PropertyType pt, boolean required, Root root) {
203+
private void addTypeProperty(int listItemY, MxCell typeCell, TypeComplex tc, String name, PropertyType pt, boolean required, Root root) {
198204
MxGeometry propGeom = new MxGeometry()
199205
.setWidth(BOX_WIDTH)
200206
.setHeight(BOX_HEIGHT_ITEM)
201207
.setY(listItemY);
202208
MxCell propCell = new MxCell()
209+
.setId(genIdForTypeProperty(tc, name))
203210
.setParent(typeCell.getId())
204211
.setValue(createText(name, pt.getName(), required))
205212
.setStyle(STYLE_LIST_ITEM)
@@ -209,12 +216,13 @@ private void addPropertyType(int listItemY, MxCell typeCell, String name, Proper
209216
root.addMxCell(propCell);
210217
}
211218

212-
private void addEntityProperty(int listItemY, MxCell typeCell, EntityPropertyMain ep, Root root) {
219+
private void addEntityProperty(int listItemY, MxCell typeCell, EntityType et, EntityPropertyMain ep, Root root) {
213220
MxGeometry propGeom = new MxGeometry()
214221
.setWidth(BOX_WIDTH)
215222
.setHeight(BOX_HEIGHT_ITEM)
216223
.setY(listItemY);
217224
MxCell propCell = new MxCell()
225+
.setId(genIdFor(et, ep))
218226
.setParent(typeCell.getId())
219227
.setValue(createTextForEp(ep))
220228
.setStyle(STYLE_LIST_ITEM)
@@ -277,6 +285,7 @@ private void createLink(MxCell sourceCell, MxCell targetCell, MxCell cellOne, Ro
277285
.setY(targetCell.getMxGeometry().getY())
278286
.setAs(AS_TARGETPOINT));
279287
MxCell linkCell = new MxCell()
288+
.setId(genIdFor(np))
280289
.setStyle(STYLE_CONNECTOR)
281290
.setParent(cellOne.getId())
282291
.setSource(sourceCell.getId())
@@ -292,6 +301,7 @@ private void createLink(MxCell sourceCell, MxCell targetCell, MxCell cellOne, Ro
292301

293302
private MxCell createLabelCell(NavigationProperty np, MxCell linkCell, boolean target) {
294303
return new MxCell()
304+
.setId(genIdForNpLabel(np))
295305
.setValue(textForNp(np))
296306
.setStyle(STYLE_LABEL)
297307
.setParent(linkCell.getId())
@@ -323,6 +333,66 @@ public String textForNp(NavigationProperty np) {
323333
return result.toString();
324334
}
325335

336+
private static String genIdFor(EntityType et) {
337+
String data = "ET-" + et.entityName;
338+
return createHash(data);
339+
}
340+
341+
private static String genIdFor(TypeComplex tc) {
342+
String data = "TC-" + tc.getName();
343+
return createHash(data);
344+
}
345+
346+
private static String genIdFor(NavigationProperty np) {
347+
String data = genNpString(np);
348+
return createHash(data);
349+
}
350+
351+
private static String genIdForNpLabel(NavigationProperty np) {
352+
String data = genNpString(np) + ":" + np.getEntityType().entityName + ":" + np.getName();
353+
return createHash(data);
354+
}
355+
356+
private static String genNpString(NavigationProperty np) {
357+
String etName1;
358+
String etName2;
359+
String npName1;
360+
String npName2;
361+
if (np.getEntityType().entityName.compareTo(np.getInverse().getEntityType().entityName) > 0) {
362+
etName1 = np.getEntityType().entityName;
363+
etName2 = np.getInverse().getEntityType().entityName;
364+
npName1 = np.getName();
365+
npName2 = np.getInverse().getName();
366+
} else {
367+
etName1 = np.getInverse().getEntityType().entityName;
368+
etName2 = np.getEntityType().entityName;
369+
npName1 = np.getInverse().getName();
370+
npName2 = np.getName();
371+
}
372+
String data = "ET-" + etName1 + "-" + npName1 + "-" + npName2 + "-" + etName2;
373+
return data;
374+
}
375+
376+
private static String genIdFor(EntityType et, EntityPropertyMain ep) {
377+
String data = "ET-" + et.entityName + "-EP-" + ep.getName();
378+
return createHash(data);
379+
}
380+
381+
private static String genIdForTypeProperty(TypeComplex tc, String name) {
382+
String data = "TC-" + tc.getName() + "-P-" + name;
383+
return createHash(data);
384+
}
385+
386+
private static String createHash(String data) {
387+
try {
388+
MessageDigest md = MessageDigest.getInstance("SHA-256");
389+
byte[] byteHash = md.digest(data.getBytes(StandardCharsets.UTF_8));
390+
return HexFormat.of().formatHex(byteHash);
391+
} catch (NoSuchAlgorithmException ex) {
392+
return UUID.randomUUID().toString();
393+
}
394+
}
395+
326396
@JsonRootName("mxfile")
327397
private static class MxFile {
328398

@@ -642,7 +712,7 @@ public Root addMxCell(MxCell cell) {
642712

643713
private static class MxCell {
644714

645-
private String id = UUID.randomUUID().toString();
715+
private String id;
646716
private String value;
647717
private String style;
648718
private String parent;
@@ -655,6 +725,9 @@ private static class MxCell {
655725

656726
@JacksonXmlProperty(isAttribute = true)
657727
public String getId() {
728+
if (id == null) {
729+
id = UUID.randomUUID().toString();
730+
}
658731
return id;
659732
}
660733

@@ -756,12 +829,12 @@ public MxCell setMxGeometry(MxGeometry mxGeometry) {
756829

757830
private static class MxGeometry {
758831

759-
private final String as = AS_GEOMETRY;
760832
private Integer x;
761833
private Integer y;
762834
private Integer width;
763835
private Integer height;
764836
private Integer relative;
837+
private final String as = AS_GEOMETRY;
765838

766839
private final List<MxPoint> mxPoint = new ArrayList<>();
767840
private Array array;

0 commit comments

Comments
 (0)