3636import de .fraunhofer .iosb .ilt .frostserver .property .type .TypeComplex ;
3737import java .io .IOException ;
3838import java .io .Writer ;
39+ import java .nio .charset .StandardCharsets ;
40+ import java .security .MessageDigest ;
41+ import java .security .NoSuchAlgorithmException ;
3942import java .util .ArrayList ;
4043import java .util .Collection ;
4144import java .util .HashMap ;
45+ import java .util .HexFormat ;
4246import java .util .List ;
4347import java .util .Map ;
4448import java .util .Set ;
5256 */
5357public 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