plantuml/src/net/sourceforge/plantuml/sdot/CucaDiagramFileMakerSmetana...

602 lines
21 KiB
Java
Raw Normal View History

2016-03-06 16:47:34 +00:00
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
2023-02-22 18:43:48 +00:00
* (C) Copyright 2009-2024, Arnaud Roques
2016-03-06 16:47:34 +00:00
*
2023-02-22 18:43:48 +00:00
* Project Info: https://plantuml.com
2022-08-17 17:34:24 +00:00
*
2017-03-15 19:13:31 +00:00
* If you like this project or if you find it useful, you can support us at:
2022-08-17 17:34:24 +00:00
*
2023-02-22 18:43:48 +00:00
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
2022-08-17 17:34:24 +00:00
*
2016-03-06 16:47:34 +00:00
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
2022-08-17 17:34:24 +00:00
*
2016-03-06 16:47:34 +00:00
*
*/
2020-12-21 19:05:24 +00:00
package net.sourceforge.plantuml.sdot;
2016-03-06 16:47:34 +00:00
import static gen.lib.cgraph.attr__c.agsafeset;
import static gen.lib.cgraph.edge__c.agedge;
import static gen.lib.cgraph.graph__c.agopen;
import static gen.lib.cgraph.node__c.agnode;
2016-04-04 19:05:10 +00:00
import static gen.lib.cgraph.subg__c.agsubg;
2016-03-06 16:47:34 +00:00
import static gen.lib.gvc.gvc__c.gvContext;
import static gen.lib.gvc.gvlayout__c.gvLayoutJobs;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
2016-04-04 19:05:10 +00:00
import java.util.LinkedHashMap;
2016-03-06 16:47:34 +00:00
import java.util.List;
import java.util.Map;
2016-04-22 20:36:08 +00:00
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
2016-03-06 16:47:34 +00:00
2020-04-19 16:04:39 +00:00
import h.ST_Agedge_s;
import h.ST_Agnode_s;
import h.ST_Agnodeinfo_t;
import h.ST_Agraph_s;
import h.ST_Agraphinfo_t;
2020-12-01 21:39:27 +00:00
import h.ST_Agrec_s;
2020-04-19 16:04:39 +00:00
import h.ST_GVC_s;
import h.ST_boxf;
2016-03-06 16:47:34 +00:00
import net.sourceforge.plantuml.FileFormatOption;
2022-12-17 11:10:05 +00:00
import net.sourceforge.plantuml.StringUtils;
2016-03-06 16:47:34 +00:00
import net.sourceforge.plantuml.UmlDiagram;
2023-02-22 18:43:48 +00:00
import net.sourceforge.plantuml.abel.Entity;
import net.sourceforge.plantuml.abel.GroupType;
import net.sourceforge.plantuml.abel.LeafType;
import net.sourceforge.plantuml.abel.Link;
2016-03-06 16:47:34 +00:00
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.core.ImageData;
2022-11-04 17:36:03 +00:00
import net.sourceforge.plantuml.cucadiagram.ICucaDiagram;
2023-02-22 18:43:48 +00:00
import net.sourceforge.plantuml.eggs.QuoteUtils;
2023-02-02 17:59:43 +00:00
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
2023-02-22 18:43:48 +00:00
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
2023-02-02 17:59:43 +00:00
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
2023-02-22 18:43:48 +00:00
import net.sourceforge.plantuml.klimt.geom.MinMaxMutable;
import net.sourceforge.plantuml.klimt.geom.XDimension2D;
import net.sourceforge.plantuml.klimt.geom.XPoint2D;
import net.sourceforge.plantuml.klimt.shape.AbstractTextBlock;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.klimt.shape.TextBlockUtils;
2022-08-17 17:34:24 +00:00
import net.sourceforge.plantuml.log.Logme;
2023-02-22 18:43:48 +00:00
import net.sourceforge.plantuml.style.ISkinParam;
2023-01-09 19:13:37 +00:00
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
2016-03-06 16:47:34 +00:00
import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Cluster;
2022-09-15 17:24:26 +00:00
import net.sourceforge.plantuml.svek.ClusterHeader;
2016-03-06 16:47:34 +00:00
import net.sourceforge.plantuml.svek.CucaDiagramFileMaker;
import net.sourceforge.plantuml.svek.DotStringFactory;
2018-10-21 19:44:14 +00:00
import net.sourceforge.plantuml.svek.GeneralImageBuilder;
2016-03-06 16:47:34 +00:00
import net.sourceforge.plantuml.svek.GraphvizCrash;
import net.sourceforge.plantuml.svek.IEntityImage;
2021-02-02 10:12:15 +00:00
import net.sourceforge.plantuml.svek.SvekNode;
2016-03-06 16:47:34 +00:00
import smetana.core.CString;
2023-02-22 18:43:48 +00:00
import smetana.core.Globals;
2016-04-04 19:05:10 +00:00
import smetana.core.JUtils;
2016-03-06 16:47:34 +00:00
import smetana.core.Macro;
2020-12-06 21:43:09 +00:00
import smetana.core.debug.SmetanaDebug;
2016-03-06 16:47:34 +00:00
2020-12-21 19:05:24 +00:00
public class CucaDiagramFileMakerSmetana implements CucaDiagramFileMaker {
2016-03-06 16:47:34 +00:00
2022-11-04 17:36:03 +00:00
private final ICucaDiagram diagram;
2016-04-04 19:05:10 +00:00
2016-08-25 20:45:37 +00:00
private final StringBounder stringBounder;
2023-02-06 21:04:53 +00:00
private final Map<Entity, ST_Agnode_s> nodes = new LinkedHashMap<Entity, ST_Agnode_s>();
2018-10-21 19:44:14 +00:00
private final Map<Link, ST_Agedge_s> edges = new LinkedHashMap<Link, ST_Agedge_s>();
2023-02-06 21:04:53 +00:00
private final Map<Entity, ST_Agraph_s> clusters = new LinkedHashMap<Entity, ST_Agraph_s>();
2016-03-06 16:47:34 +00:00
private final DotStringFactory dotStringFactory;
2023-02-22 18:43:48 +00:00
private MinMaxMutable getSmetanaMinMax() {
final MinMaxMutable result = MinMaxMutable.getEmpty(false);
for (ST_Agnode_s n : nodes.values()) {
final ST_Agnodeinfo_t data = (ST_Agnodeinfo_t) n.data;
final double width = data.width * 72;
final double height = data.height * 72;
final double x = data.coord.x;
final double y = data.coord.y;
result.addPoint(x - width / 2, y - height / 2);
result.addPoint(x + width / 2, y + height / 2);
}
for (ST_Agraph_s gr : clusters.values()) {
final ST_Agrec_s tmp1 = gr.data;
if (tmp1 instanceof ST_Agraphinfo_t == false) {
System.err.println("ERROR IN CucaDiagramFileMakerSmetana");
continue;
}
final ST_Agraphinfo_t data = (ST_Agraphinfo_t) tmp1;
final ST_boxf bb = (ST_boxf) data.bb;
final double llx = bb.LL.x;
final double lly = bb.LL.y;
final double urx = bb.UR.x;
final double ury = bb.UR.y;
result.addPoint(llx, lly);
result.addPoint(urx, ury);
}
return result;
}
2023-02-26 18:51:17 +00:00
class Drawing extends AbstractTextBlock {
2016-03-06 16:47:34 +00:00
private final YMirror ymirror;
2023-02-22 18:43:48 +00:00
private final MinMaxMutable minMax;
2016-03-06 16:47:34 +00:00
2023-02-22 18:43:48 +00:00
public Drawing() {
this.minMax = getSmetanaMinMax();
this.ymirror = new YMirror(minMax.getMaxY() + 6);
2016-03-06 16:47:34 +00:00
}
public void drawU(UGraphic ug) {
2023-02-22 18:43:48 +00:00
ug = ug.apply(new UTranslate(6, 6 - minMax.getMinY()));
2016-04-04 19:05:10 +00:00
2023-02-06 21:04:53 +00:00
for (Map.Entry<Entity, ST_Agraph_s> ent : clusters.entrySet())
2016-04-04 19:05:10 +00:00
drawGroup(ug, ymirror, ent.getKey(), ent.getValue());
2023-02-06 21:04:53 +00:00
for (Map.Entry<Entity, ST_Agnode_s> ent : nodes.entrySet()) {
final Entity leaf = ent.getKey();
2020-02-18 21:24:31 +00:00
final ST_Agnode_s agnode = ent.getValue();
2022-09-12 20:08:34 +00:00
final XPoint2D corner = getCorner(agnode);
2016-03-06 16:47:34 +00:00
2021-02-02 10:12:15 +00:00
final SvekNode node = dotStringFactory.getBibliotekon().getNode(leaf);
2020-02-18 21:24:31 +00:00
final IEntityImage image = node.getImage();
2016-03-06 16:47:34 +00:00
image.drawU(ug.apply(new UTranslate(corner)));
}
2018-10-21 19:44:14 +00:00
for (Map.Entry<Link, ST_Agedge_s> ent : edges.entrySet()) {
2016-03-06 16:47:34 +00:00
final Link link = ent.getKey();
2022-09-14 18:12:03 +00:00
if (link.isInvis())
2020-10-12 20:56:58 +00:00
continue;
2022-09-14 18:12:03 +00:00
2018-10-21 19:44:14 +00:00
final ST_Agedge_s edge = ent.getValue();
2022-10-05 20:32:57 +00:00
new SmetanaPath(link, edge, ymirror, diagram, getLabel(link), getQuantifier(link, 1),
getQuantifier(link, 2)).drawU(ug);
2016-03-06 16:47:34 +00:00
}
}
2022-09-12 20:08:34 +00:00
public XDimension2D calculateDimension(StringBounder stringBounder) {
2023-02-22 18:43:48 +00:00
return minMax.getDimension().delta(6);
2020-10-12 20:56:58 +00:00
}
2022-09-12 20:08:34 +00:00
private XPoint2D getCorner(ST_Agnode_s n) {
2023-02-22 18:43:48 +00:00
final ST_Agnodeinfo_t data = (ST_Agnodeinfo_t) n.data;
2018-11-26 18:46:22 +00:00
final double width = data.width * 72;
final double height = data.height * 72;
final double x = data.coord.x;
final double y = data.coord.y;
2016-03-06 16:47:34 +00:00
2022-09-12 20:08:34 +00:00
return ymirror.getMirrored(new XPoint2D(x - width / 2, y + height / 2));
2016-03-06 16:47:34 +00:00
}
2020-10-12 20:56:58 +00:00
public HColor getBackcolor() {
return null;
}
2016-03-06 16:47:34 +00:00
}
2022-11-04 17:36:03 +00:00
public CucaDiagramFileMakerSmetana(ICucaDiagram diagram, StringBounder stringBounder) {
2016-03-06 16:47:34 +00:00
this.diagram = diagram;
2016-08-25 20:45:37 +00:00
this.stringBounder = stringBounder;
2016-07-25 19:25:28 +00:00
this.dotStringFactory = new DotStringFactory(stringBounder, diagram);
2016-03-06 16:47:34 +00:00
2021-04-17 11:19:39 +00:00
printAllSubgroups(diagram.getRootGroup());
2016-04-04 19:05:10 +00:00
printEntities(getUnpackagedEntities());
2016-03-06 16:47:34 +00:00
}
2023-02-22 18:43:48 +00:00
private void drawGroup(UGraphic ug, YMirror ymirror, Entity group, ST_Agraph_s gr) {
2016-04-04 19:05:10 +00:00
JUtils.LOG2("drawGroup");
2020-11-21 17:33:24 +00:00
try {
2023-02-22 18:43:48 +00:00
final ST_Agrec_s tmp1 = gr.data;
2020-12-01 21:39:27 +00:00
final ST_Agraphinfo_t data = (ST_Agraphinfo_t) tmp1;
2020-11-21 17:33:24 +00:00
final ST_boxf bb = (ST_boxf) data.bb;
final double llx = bb.LL.x;
2023-02-22 18:43:48 +00:00
final double ury = ymirror.getMirrored(bb.LL.y);
final double lly = ymirror.getMirrored(bb.UR.y);
2020-11-21 17:33:24 +00:00
final double urx = bb.UR.x;
final Cluster cluster = dotStringFactory.getBibliotekon().getCluster(group);
2022-09-14 18:12:03 +00:00
cluster.setPosition(new XPoint2D(llx, lly), new XPoint2D(urx, ury));
final XDimension2D dimTitle = cluster.getTitleDimension(ug.getStringBounder());
if (dimTitle != null) {
final double x = (llx + urx) / 2 - dimTitle.getWidth() / 2;
cluster.setTitlePosition(new XPoint2D(x, lly));
}
2020-11-21 17:33:24 +00:00
JUtils.LOG2("cluster=" + cluster);
2022-02-12 17:27:51 +00:00
cluster.drawU(ug, diagram.getUmlDiagramType(), diagram.getSkinParam());
2023-02-22 18:43:48 +00:00
// ug.apply(new UTranslate(llx, lly)).apply(HColors.BLUE).draw(new
// URectangle(urx - llx, ury - lly));
2020-12-01 21:39:27 +00:00
} catch (Exception e) {
2020-11-21 17:33:24 +00:00
System.err.println("CANNOT DRAW GROUP");
}
2016-04-04 19:05:10 +00:00
}
2023-02-06 21:04:53 +00:00
private void printAllSubgroups(Entity parent) {
for (Entity g : diagram.getChildrenGroups(parent)) {
2022-09-14 18:12:03 +00:00
if (g.isRemoved())
2016-03-06 16:47:34 +00:00
continue;
2022-09-14 18:12:03 +00:00
2016-03-06 16:47:34 +00:00
if (diagram.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE) {
2023-02-06 21:04:53 +00:00
g.muteToType(LeafType.EMPTY_PACKAGE);
printEntityNew(g);
2016-03-06 16:47:34 +00:00
} else {
2021-04-17 11:19:39 +00:00
printSingleGroup(g);
2016-03-06 16:47:34 +00:00
}
}
}
2023-02-06 21:04:53 +00:00
private void printSingleGroup(Entity g) {
2022-09-14 18:12:03 +00:00
if (g.getGroupType() == GroupType.CONCURRENT_STATE)
2016-03-06 16:47:34 +00:00
return;
2022-09-14 18:12:03 +00:00
2023-02-06 21:04:53 +00:00
final ClusterHeader clusterHeader = new ClusterHeader((Entity) g, diagram.getSkinParam(), diagram,
2022-09-15 17:24:26 +00:00
stringBounder);
dotStringFactory.openCluster(g, clusterHeader);
2023-02-06 21:04:53 +00:00
this.printEntities(g.leafs());
2016-03-06 16:47:34 +00:00
2021-04-17 11:19:39 +00:00
printAllSubgroups(g);
2016-03-06 16:47:34 +00:00
dotStringFactory.closeCluster();
}
2023-02-06 21:04:53 +00:00
private void printEntities(Collection<Entity> entities) {
for (Entity ent : entities) {
2022-09-14 18:12:03 +00:00
if (ent.isRemoved())
2016-03-06 16:47:34 +00:00
continue;
2022-09-14 18:12:03 +00:00
2016-03-06 16:47:34 +00:00
printEntity(ent);
}
}
2023-02-22 18:43:48 +00:00
private void exportEntities(Globals zz, ST_Agraph_s g, Collection<Entity> entities) {
2023-02-06 21:04:53 +00:00
for (Entity ent : entities) {
2022-09-14 18:12:03 +00:00
if (ent.isRemoved())
2016-04-04 19:05:10 +00:00
continue;
2023-02-22 18:43:48 +00:00
exportEntity(zz, g, ent);
2016-04-04 19:05:10 +00:00
}
}
2023-02-22 18:43:48 +00:00
private void exportEntity(Globals zz, ST_Agraph_s g, Entity leaf) {
2021-02-02 10:12:15 +00:00
final SvekNode node = dotStringFactory.getBibliotekon().getNode(leaf);
2020-11-21 17:33:24 +00:00
if (node == null) {
System.err.println("CANNOT FIND NODE");
return;
}
2017-07-03 17:59:53 +00:00
// System.err.println("exportEntity " + leaf);
2023-02-22 18:43:48 +00:00
final ST_Agnode_s agnode = agnode(zz, g, new CString(node.getUid()), true);
agsafeset(zz, agnode, new CString("shape"), new CString("box"), new CString(""));
2020-02-18 21:24:31 +00:00
final String width = "" + (node.getWidth() / 72);
final String height = "" + (node.getHeight() / 72);
2023-02-22 18:43:48 +00:00
agsafeset(zz, agnode, new CString("width"), new CString(width), new CString(""));
agsafeset(zz, agnode, new CString("height"), new CString(height), new CString(""));
2016-04-22 20:36:08 +00:00
// System.err.println("NODE " + leaf.getUid() + " " + width + " " + height);
2020-02-18 21:24:31 +00:00
nodes.put(leaf, agnode);
2016-04-04 19:05:10 +00:00
}
2023-02-06 21:04:53 +00:00
private void printEntity(Entity ent) {
2022-09-14 18:12:03 +00:00
if (ent.isRemoved())
2016-03-06 16:47:34 +00:00
throw new IllegalStateException();
2022-09-14 18:12:03 +00:00
2016-03-06 16:47:34 +00:00
final IEntityImage image = printEntityInternal(ent);
2022-02-12 17:27:51 +00:00
final SvekNode node = getBibliotekon().createNode(ent, image, dotStringFactory.getColorSequence(),
stringBounder);
2020-02-18 21:24:31 +00:00
dotStringFactory.addNode(node);
2016-03-06 16:47:34 +00:00
}
2023-02-06 21:04:53 +00:00
private Collection<Entity> getUnpackagedEntities() {
final List<Entity> result = new ArrayList<>();
for (Entity ent : diagram.getEntityFactory().leafs())
2022-09-14 18:12:03 +00:00
if (diagram.getEntityFactory().getRootGroup() == ent.getParentContainer())
2016-03-06 16:47:34 +00:00
result.add(ent);
2022-09-14 18:12:03 +00:00
2016-03-06 16:47:34 +00:00
return result;
}
2023-02-22 18:43:48 +00:00
private void printCluster(Globals zz, ST_Agraph_s g, Cluster cluster) {
2021-02-02 10:12:15 +00:00
for (SvekNode node : cluster.getNodes()) {
2023-02-22 18:43:48 +00:00
final ST_Agnode_s agnode = agnode(zz, g, new CString(node.getUid()), true);
agsafeset(zz, agnode, new CString("shape"), new CString("box"), new CString(""));
2020-02-18 21:24:31 +00:00
final String width = "" + (node.getWidth() / 72);
final String height = "" + (node.getHeight() / 72);
2023-02-22 18:43:48 +00:00
agsafeset(zz, agnode, new CString("width"), new CString(width), new CString(""));
agsafeset(zz, agnode, new CString("height"), new CString(height), new CString(""));
2023-02-06 21:04:53 +00:00
final Entity leaf = dotStringFactory.getBibliotekon().getLeaf(node);
2020-02-18 21:24:31 +00:00
nodes.put(leaf, agnode);
2016-03-06 16:47:34 +00:00
}
}
2016-04-22 20:36:08 +00:00
private static final Lock lock = new ReentrantLock();
2016-03-06 16:47:34 +00:00
public ImageData createFile(OutputStream os, List<String> dotStrings, FileFormatOption fileFormatOption)
throws IOException {
2016-04-22 20:36:08 +00:00
lock.lock();
try {
return createFileLocked(os, dotStrings, fileFormatOption);
} finally {
lock.unlock();
}
}
@Override
2023-02-22 18:43:48 +00:00
public void createOneGraphic(UGraphic ug) {
2023-02-06 21:04:53 +00:00
for (Entity leaf : diagram.getEntityFactory().leafs())
2016-03-06 16:47:34 +00:00
printEntityNew(leaf);
2023-02-22 18:43:48 +00:00
final Globals zz = Globals.open();
2016-03-06 16:47:34 +00:00
try {
2023-02-22 18:43:48 +00:00
final TextBlock textBlock = getTextBlock(zz);
textBlock.drawU(ug);
} catch (Throwable e) {
2020-12-06 21:43:09 +00:00
SmetanaDebug.printMe();
} finally {
2023-02-22 18:43:48 +00:00
Globals.close();
}
}
2016-03-06 16:47:34 +00:00
private ImageData createFileLocked(OutputStream os, List<String> dotStrings, FileFormatOption fileFormatOption)
throws IOException {
2016-03-06 16:47:34 +00:00
2023-02-06 21:04:53 +00:00
for (Entity leaf : diagram.getEntityFactory().leafs())
printEntityNew(leaf);
2016-03-06 16:47:34 +00:00
2023-02-22 18:43:48 +00:00
final Globals zz = Globals.open();
try {
2023-02-22 18:43:48 +00:00
final TextBlock drawable = getTextBlock(zz);
2022-02-12 17:27:51 +00:00
return diagram.createImageBuilder(fileFormatOption).drawable(drawable).write(os);
2016-03-06 16:47:34 +00:00
} catch (Throwable e) {
2020-12-06 21:43:09 +00:00
SmetanaDebug.printMe();
2017-04-19 18:30:16 +00:00
UmlDiagram.exportDiagramError(os, e, fileFormatOption, diagram.seed(), diagram.getMetadata(),
diagram.getFlashData(), getFailureText3(e));
2018-05-01 17:26:04 +00:00
return ImageDataSimple.error();
2016-03-06 16:47:34 +00:00
} finally {
2023-02-22 18:43:48 +00:00
Globals.close();
2016-03-06 16:47:34 +00:00
}
}
2023-02-22 18:43:48 +00:00
private TextBlock getTextBlock(Globals zz) {
final ST_Agraph_s g = agopen(zz, new CString("g"), zz.Agdirected, null);
exportEntities(zz, g, getUnpackagedEntities());
exportGroups(zz, g, diagram.getEntityFactory().getRootGroup());
for (Link link : diagram.getLinks()) {
2023-02-22 18:43:48 +00:00
final ST_Agedge_s e = createEdge(zz, g, link);
if (e != null)
edges.put(link, e);
}
2023-02-22 18:43:48 +00:00
final ST_GVC_s gvc = gvContext(zz);
SmetanaDebug.reset();
2023-02-22 18:43:48 +00:00
gvLayoutJobs(zz, gvc, g);
SmetanaDebug.printMe();
2023-02-22 18:43:48 +00:00
final TextBlock drawable = new Drawing();
return drawable;
}
2023-02-22 18:43:48 +00:00
private void exportGroups(Globals zz, ST_Agraph_s graph, Entity parent) {
2023-02-06 21:04:53 +00:00
for (Entity g : diagram.getChildrenGroups(parent)) {
2022-09-14 18:12:03 +00:00
if (g.isRemoved())
2016-04-04 19:05:10 +00:00
continue;
2022-09-14 18:12:03 +00:00
2023-02-22 18:43:48 +00:00
if (diagram.isEmpty(g) && g.getGroupType() == GroupType.PACKAGE)
exportEntity(zz, graph, g);
else
exportGroup(zz, graph, g);
2016-04-04 19:05:10 +00:00
}
}
2023-02-22 18:43:48 +00:00
private void exportGroup(Globals zz, ST_Agraph_s graph, Entity group) {
2016-04-04 19:05:10 +00:00
final Cluster cluster = getBibliotekon().getCluster(group);
2020-10-12 20:56:58 +00:00
if (cluster == null) {
System.err.println("CucaDiagramFileMakerJDot::exportGroup issue");
return;
}
2016-04-04 19:05:10 +00:00
JUtils.LOG2("cluster = " + cluster.getClusterId());
2023-02-22 18:43:48 +00:00
final ST_Agraph_s cluster1 = agsubg(zz, graph, new CString(cluster.getClusterId()), true);
2016-04-04 19:05:10 +00:00
if (cluster.isLabel()) {
final double width = cluster.getTitleAndAttributeWidth();
final double height = cluster.getTitleAndAttributeHeight() - 5;
2023-02-22 18:43:48 +00:00
agsafeset(zz, cluster1, new CString("label"),
Macro.createHackInitDimensionFromLabel((int) width, (int) height), new CString(""));
2016-04-04 19:05:10 +00:00
}
2023-02-22 18:43:48 +00:00
this.exportEntities(zz, cluster1, group.leafs());
2016-04-04 19:05:10 +00:00
this.clusters.put(group, cluster1);
2023-02-22 18:43:48 +00:00
this.exportGroups(zz, cluster1, group);
2016-04-04 19:05:10 +00:00
}
2023-01-09 19:13:37 +00:00
private Style getStyle() {
return StyleSignatureBasic
.of(SName.root, SName.element, diagram.getUmlDiagramType().getStyleName(), SName.arrow)
.getMergedStyle(diagram.getSkinParam().getCurrentStyleBuilder());
}
2016-03-06 16:47:34 +00:00
private TextBlock getLabel(Link link) {
final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1;
ISkinParam skinParam = diagram.getSkinParam();
2023-01-09 19:13:37 +00:00
final Style style = getStyle();
final FontConfiguration labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet());
2016-07-04 19:06:50 +00:00
final TextBlock label = link.getLabel().create(labelFont,
skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam);
2022-09-14 18:12:03 +00:00
if (TextBlockUtils.isEmpty(label, stringBounder))
2016-03-06 16:47:34 +00:00
return label;
2022-09-14 18:12:03 +00:00
2016-03-06 16:47:34 +00:00
return TextBlockUtils.withMargin(label, marginLabel, marginLabel);
2018-10-21 19:44:14 +00:00
}
2016-03-06 16:47:34 +00:00
2022-10-05 20:32:57 +00:00
private TextBlock getQuantifier(Link link, int n) {
final String tmp = n == 1 ? link.getQuantifier1() : link.getQuantifier2();
2022-09-14 18:12:03 +00:00
if (tmp == null)
2018-10-21 19:44:14 +00:00
return null;
2022-09-14 18:12:03 +00:00
2018-10-21 19:44:14 +00:00
final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1;
ISkinParam skinParam = diagram.getSkinParam();
2023-01-09 19:13:37 +00:00
final Style style = getStyle();
final FontConfiguration labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet());
2018-10-21 19:44:14 +00:00
final TextBlock label = Display.getWithNewlines(tmp).create(labelFont,
skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam);
2022-09-14 18:12:03 +00:00
if (TextBlockUtils.isEmpty(label, stringBounder))
2018-10-21 19:44:14 +00:00
return label;
2022-09-14 18:12:03 +00:00
2018-10-21 19:44:14 +00:00
return TextBlockUtils.withMargin(label, marginLabel, marginLabel);
2016-03-06 16:47:34 +00:00
}
2023-02-06 21:04:53 +00:00
private ST_Agnode_s getAgnodeFromLeaf(Entity entity) {
2018-10-21 19:44:14 +00:00
final ST_Agnode_s n = nodes.get(entity);
2022-09-14 18:12:03 +00:00
if (n != null)
2016-04-04 19:05:10 +00:00
return n;
2022-09-14 18:12:03 +00:00
2020-11-21 17:33:24 +00:00
try {
2023-02-06 21:04:53 +00:00
final String id = getBibliotekon().getNodeUid((Entity) entity);
for (Map.Entry<Entity, ST_Agnode_s> ent : nodes.entrySet())
2022-09-14 18:12:03 +00:00
if (id.equals(getBibliotekon().getNodeUid(ent.getKey())))
2020-11-21 17:33:24 +00:00
return ent.getValue();
2022-09-14 18:12:03 +00:00
2020-11-21 17:33:24 +00:00
} catch (IllegalStateException e) {
System.err.println("UNKNOWN ENTITY");
2016-04-04 19:05:10 +00:00
}
return null;
}
2023-02-22 18:43:48 +00:00
private ST_Agedge_s createEdge(Globals zz, final ST_Agraph_s g, Link link) {
2018-10-21 19:44:14 +00:00
final ST_Agnode_s n = getAgnodeFromLeaf(link.getEntity1());
final ST_Agnode_s m = getAgnodeFromLeaf(link.getEntity2());
2022-09-14 18:12:03 +00:00
if (n == null)
2016-04-04 19:05:10 +00:00
return null;
2022-09-14 18:12:03 +00:00
if (m == null)
2016-03-06 16:47:34 +00:00
return null;
2022-09-14 18:12:03 +00:00
2023-02-22 18:43:48 +00:00
final ST_Agedge_s e = agedge(zz, g, n, m, null, true);
2017-07-03 17:59:53 +00:00
// System.err.println("createEdge " + link);
2023-02-22 18:43:48 +00:00
agsafeset(zz, e, new CString("arrowtail"), new CString("none"), new CString(""));
agsafeset(zz, e, new CString("arrowhead"), new CString("none"), new CString(""));
2016-03-06 16:47:34 +00:00
int length = link.getLength();
2016-04-04 19:05:10 +00:00
// System.err.println("length=" + length);
2020-02-18 21:24:31 +00:00
// if (/* pragma.horizontalLineBetweenDifferentPackageAllowed() ||
// */link.isInvis() || length != 1) {
2023-02-22 18:43:48 +00:00
agsafeset(zz, e, new CString("minlen"), new CString("" + (length - 1)), new CString(""));
2016-04-04 19:05:10 +00:00
// }
2020-02-18 21:24:31 +00:00
// System.err.print("EDGE " + link.getEntity1().getUid() + "->" +
// link.getEntity2().getUid() + " minlen="
2016-04-22 20:36:08 +00:00
// + (length - 1) + " ");
2016-03-06 16:47:34 +00:00
final TextBlock label = getLabel(link);
2016-08-25 20:45:37 +00:00
if (TextBlockUtils.isEmpty(label, stringBounder) == false) {
2022-09-12 20:08:34 +00:00
final XDimension2D dimLabel = label.calculateDimension(stringBounder);
2016-03-06 16:47:34 +00:00
// System.err.println("dimLabel = " + dimLabel);
2016-04-04 19:05:10 +00:00
final CString hackDim = Macro.createHackInitDimensionFromLabel((int) dimLabel.getWidth(),
(int) dimLabel.getHeight());
2023-02-22 18:43:48 +00:00
agsafeset(zz, e, new CString("label"), hackDim, new CString(""));
2016-04-22 20:36:08 +00:00
// System.err.print("label=" + hackDim.getContent());
2016-03-06 16:47:34 +00:00
}
2022-10-05 20:32:57 +00:00
final TextBlock q1 = getQuantifier(link, 1);
2018-10-21 19:44:14 +00:00
if (q1 != null) {
2022-09-12 20:08:34 +00:00
final XDimension2D dimLabel = q1.calculateDimension(stringBounder);
2018-10-21 19:44:14 +00:00
// System.err.println("dimLabel = " + dimLabel);
final CString hackDim = Macro.createHackInitDimensionFromLabel((int) dimLabel.getWidth(),
(int) dimLabel.getHeight());
2023-02-22 18:43:48 +00:00
agsafeset(zz, e, new CString("taillabel"), hackDim, new CString(""));
2018-10-21 19:44:14 +00:00
}
2022-10-05 20:32:57 +00:00
final TextBlock q2 = getQuantifier(link, 2);
2018-10-21 19:44:14 +00:00
if (q2 != null) {
2022-09-12 20:08:34 +00:00
final XDimension2D dimLabel = q2.calculateDimension(stringBounder);
2018-10-21 19:44:14 +00:00
// System.err.println("dimLabel = " + dimLabel);
final CString hackDim = Macro.createHackInitDimensionFromLabel((int) dimLabel.getWidth(),
(int) dimLabel.getHeight());
2023-02-22 18:43:48 +00:00
agsafeset(zz, e, new CString("headlabel"), hackDim, new CString(""));
2018-10-21 19:44:14 +00:00
}
2016-04-22 20:36:08 +00:00
// System.err.println();
2016-03-06 16:47:34 +00:00
return e;
}
static private List<String> getFailureText3(Throwable exception) {
2022-08-17 17:34:24 +00:00
Logme.error(exception);
2021-05-14 08:42:57 +00:00
final List<String> strings = new ArrayList<>();
2016-03-06 16:47:34 +00:00
strings.add("An error has occured : " + exception);
2016-12-21 22:10:29 +00:00
final String quote = StringUtils.rot(QuoteUtils.getSomeQuote());
2016-03-06 16:47:34 +00:00
strings.add("<i>" + quote);
strings.add(" ");
GraphvizCrash.addProperties(strings);
strings.add(" ");
strings.add("Sorry, the subproject Smetana is not finished yet...");
strings.add(" ");
2016-04-22 20:36:08 +00:00
strings.add("You should send this diagram and this image to <b>plantuml@gmail.com</b> or");
2023-02-22 18:43:48 +00:00
strings.add("post to <b>https://plantuml.com/qa</b> to solve this issue.");
2016-03-06 16:47:34 +00:00
strings.add(" ");
return strings;
}
2023-02-06 21:04:53 +00:00
private void printEntityNew(Entity ent) {
2016-03-06 16:47:34 +00:00
if (ent.isRemoved()) {
2020-11-21 17:33:24 +00:00
System.err.println("Jdot STRANGE: entity is removed");
return;
2016-03-06 16:47:34 +00:00
}
final IEntityImage image = printEntityInternal(ent);
2022-02-12 17:27:51 +00:00
final SvekNode shape = getBibliotekon().createNode(ent, image, dotStringFactory.getColorSequence(),
stringBounder);
2016-03-06 16:47:34 +00:00
// dotStringFactory.addShape(shape);
}
private Bibliotekon getBibliotekon() {
2016-04-04 19:05:10 +00:00
return dotStringFactory.getBibliotekon();
2016-03-06 16:47:34 +00:00
}
2023-02-06 21:04:53 +00:00
private IEntityImage printEntityInternal(Entity ent) {
2022-09-14 18:12:03 +00:00
if (ent.isRemoved())
2016-03-06 16:47:34 +00:00
throw new IllegalStateException();
2022-09-14 18:12:03 +00:00
2016-03-06 16:47:34 +00:00
if (ent.getSvekImage() == null) {
ISkinParam skinParam = diagram.getSkinParam();
if (skinParam.sameClassWidth()) {
2020-11-21 17:33:24 +00:00
System.err.println("NOT YET IMPLEMENED");
// throw new UnsupportedOperationException();
2016-03-06 16:47:34 +00:00
// final double width = getMaxWidth();
// skinParam = new SkinParamSameClassWidth(dotData.getSkinParam(), width);
}
2018-08-26 12:09:50 +00:00
return GeneralImageBuilder.createEntityImageBlock(ent, skinParam, diagram.isHideEmptyDescriptionForState(),
2017-05-10 19:51:15 +00:00
diagram, getBibliotekon(), null, diagram.getUmlDiagramType(), diagram.getLinks());
2016-03-06 16:47:34 +00:00
}
return ent.getSvekImage();
}
}