1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 10:59:01 +00:00

Improve ELK support

This commit is contained in:
Arnaud Roques 2021-04-20 22:19:49 +02:00
parent bc1074a775
commit e1e6bcc5c8
30 changed files with 934 additions and 136 deletions

View File

@ -56,6 +56,7 @@ import net.sourceforge.plantuml.ugraphic.ImageBuilder;
public abstract class TitledDiagram extends AbstractPSystem implements Diagram, Annotated {
public static boolean FORCE_SMETANA = false;
public static boolean FORCE_ELK = false;
private DisplayPositionned title = DisplayPositionned.none(HorizontalAlignment.CENTER, VerticalAlignment.TOP);
@ -213,6 +214,8 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram,
}
public boolean isUseElk() {
if (FORCE_ELK)
return true;
return this.useElk;
}

View File

@ -46,7 +46,7 @@ import java.util.Set;
import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Line;
import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UPolygon;
@ -68,7 +68,7 @@ public class Neighborhood {
public void drawU(UGraphic ug, double minX, double minY, Bibliotekon bibliotekon, Dimension2D shapeDim) {
final Set<Point2D> contactPoints = new HashSet<Point2D>();
for (Link link : sametailLinks) {
final Line line = bibliotekon.getLine(link);
final SvekLine line = bibliotekon.getLine(link);
final Point2D contact = line.getStartContactPoint();
contactPoints.add(contact);
}
@ -90,7 +90,7 @@ public class Neighborhood {
}
for (Link link : allButSametails) {
final Line line = bibliotekon.getLine(link);
final SvekLine line = bibliotekon.getLine(link);
final Point2D contact = link.getEntity1() == leaf ? line.getStartContactPoint() : line.getEndContactPoint();
if (contact == null) {
assert false;

View File

@ -47,34 +47,61 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.elk.core.RecursiveGraphLayoutEngine;
import org.eclipse.elk.core.options.CoreOptions;
import org.eclipse.elk.core.options.Direction;
import org.eclipse.elk.core.options.EdgeLabelPlacement;
import org.eclipse.elk.core.options.EdgeType;
import org.eclipse.elk.core.options.NodeLabelPlacement;
import org.eclipse.elk.core.options.SizeConstraint;
import org.eclipse.elk.core.options.SizeOptions;
import org.eclipse.elk.core.util.NullElkProgressMonitor;
import org.eclipse.elk.graph.ElkEdge;
import org.eclipse.elk.graph.ElkLabel;
import org.eclipse.elk.graph.ElkNode;
import org.eclipse.elk.graph.util.ElkGraphUtil;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.UseStyle;
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.GroupType;
import net.sourceforge.plantuml.cucadiagram.IEntity;
import net.sourceforge.plantuml.cucadiagram.IGroup;
import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory;
/*
* You can choose between real "org.eclipse.elk..." classes or proxied "net.sourceforge.plantuml.elk.proxy..."
*
* Using proxied classes allows to compile PlantUML without having ELK available on the classpath.
* Since GraphViz is the default layout engine up to now, we do not want to enforce the use of ELK just for compilation.
* (for people not using maven)
*
* If you are debugging, you should probably switch to "org.eclipse.elk..." classes
*
*/
/*
import org.eclipse.elk.core.RecursiveGraphLayoutEngine;
import org.eclipse.elk.core.options.CoreOptions;
import org.eclipse.elk.core.options.Direction;
import org.eclipse.elk.core.options.EdgeLabelPlacement;
import org.eclipse.elk.core.options.HierarchyHandling;
import org.eclipse.elk.core.options.NodeLabelPlacement;
import org.eclipse.elk.core.util.NullElkProgressMonitor;
import org.eclipse.elk.graph.ElkEdge;
import org.eclipse.elk.graph.ElkLabel;
import org.eclipse.elk.graph.ElkNode;
import org.eclipse.elk.graph.util.ElkGraphUtil;
*/
import net.sourceforge.plantuml.elk.proxy.core.RecursiveGraphLayoutEngine;
import net.sourceforge.plantuml.elk.proxy.core.options.CoreOptions;
import net.sourceforge.plantuml.elk.proxy.core.options.Direction;
import net.sourceforge.plantuml.elk.proxy.core.options.EdgeLabelPlacement;
import net.sourceforge.plantuml.elk.proxy.core.options.HierarchyHandling;
import net.sourceforge.plantuml.elk.proxy.core.options.NodeLabelPlacement;
import net.sourceforge.plantuml.elk.proxy.core.util.NullElkProgressMonitor;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdge;
import net.sourceforge.plantuml.elk.proxy.graph.ElkLabel;
import net.sourceforge.plantuml.elk.proxy.graph.ElkNode;
import net.sourceforge.plantuml.elk.proxy.graph.util.ElkGraphUtil;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
@ -82,12 +109,19 @@ import net.sourceforge.plantuml.graphic.QuoteUtils;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Cluster;
import net.sourceforge.plantuml.svek.ClusterDecoration;
import net.sourceforge.plantuml.svek.CucaDiagramFileMaker;
import net.sourceforge.plantuml.svek.DotStringFactory;
import net.sourceforge.plantuml.svek.GeneralImageBuilder;
import net.sourceforge.plantuml.svek.GraphvizCrash;
import net.sourceforge.plantuml.svek.IEntityImage;
import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -183,27 +217,100 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
}
public void drawU(UGraphic ug) {
// Draw all clusters
for (Entry<IGroup, ElkNode> ent : clusters.entrySet()) {
final IGroup group = ent.getKey();
final ElkNode elkNode = ent.getValue();
final Point2D corner = getPosition(elkNode);
final URectangle rect = new URectangle(elkNode.getWidth(), elkNode.getHeight());
// Print a simple rectangle right now
ug.apply(HColorUtils.BLACK).apply(new UStroke(1.5)).apply(new UTranslate(corner)).draw(rect);
drawAllClusters(ug);
drawAllNodes(ug);
drawAllEdges(ug);
}
// Draw all nodes
private void drawAllClusters(UGraphic ug) {
for (Entry<IGroup, ElkNode> ent : clusters.entrySet()) {
drawSingleCluster(ug, ent.getKey(), ent.getValue());
}
}
private void drawAllNodes(UGraphic ug) {
for (Entry<ILeaf, ElkNode> ent : nodes.entrySet()) {
final ILeaf leaf = ent.getKey();
final ElkNode elkNode = ent.getValue();
drawSingleNode(ug, ent.getKey(), ent.getValue());
}
}
private void drawAllEdges(UGraphic ug) {
for (Entry<Link, ElkEdge> ent : edges.entrySet()) {
final Link link = ent.getKey();
if (link.isInvis()) {
continue;
}
drawSingleEdge(ug, link, ent.getValue());
}
}
private void drawSingleCluster(UGraphic ug, IGroup group, ElkNode elkNode) {
final Point2D corner = getPosition(elkNode);
final URectangle rect = new URectangle(elkNode.getWidth(), elkNode.getHeight());
PackageStyle packageStyle = group.getPackageStyle();
final ISkinParam skinParam = diagram.getSkinParam();
if (packageStyle == null) {
packageStyle = skinParam.packageStyle();
}
final UmlDiagramType umlDiagramType = diagram.getUmlDiagramType();
final double shadowing;
final UStroke stroke;
if (UseStyle.useBetaStyle()) {
final Style style = Cluster.getDefaultStyleDefinition(umlDiagramType.getStyleName())
.getMergedStyle(skinParam.getCurrentStyleBuilder());
shadowing = style.value(PName.Shadowing).asDouble();
stroke = style.getStroke();
} else {
if (group.getUSymbol() == null) {
shadowing = skinParam.shadowing2(group.getStereotype(), USymbol.PACKAGE.getSkinParameter()) ? 3 : 0;
} else {
shadowing = skinParam.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()) ? 3
: 0;
}
stroke = Cluster.getStrokeInternal(group, skinParam);
}
HColor backColor = getBackColor(umlDiagramType);
backColor = Cluster.getBackColor(backColor, skinParam, group.getStereotype(),
umlDiagramType.getStyleName());
final double roundCorner = group.getUSymbol() == null ? 0
: group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, group.getStereotype());
final TextBlock ztitle = getTitleBlock(group);
final TextBlock zstereo = TextBlockUtils.empty(0, 0);
final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
zstereo, 0, 0, elkNode.getWidth(), elkNode.getHeight(), stroke);
final HColor borderColor = HColorUtils.BLACK;
decoration.drawU(ug.apply(new UTranslate(corner)), backColor, borderColor, shadowing, roundCorner,
skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false),
skinParam.getStereotypeAlignment());
// // Print a simple rectangle right now
// ug.apply(HColorUtils.BLACK).apply(new UStroke(1.5)).apply(new UTranslate(corner)).draw(rect);
}
private TextBlock getTitleBlock(IGroup g) {
final Display label = g.getDisplay();
if (label == null) {
return TextBlockUtils.empty(0, 0);
}
final ISkinParam skinParam = diagram.getSkinParam();
final FontConfiguration fontConfiguration = g.getFontConfigurationForTitle(skinParam);
return label.create(fontConfiguration, HorizontalAlignment.CENTER, skinParam);
}
private HColor getBackColor(UmlDiagramType umlDiagramType) {
return null;
}
private void drawSingleNode(UGraphic ug, ILeaf leaf, ElkNode elkNode) {
final IEntityImage image = printEntityInternal(leaf);
// Retrieve coord from ELK
final Point2D corner = getPosition(elkNode);
@ -211,23 +318,13 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
image.drawU(ug.apply(new UTranslate(corner)));
}
// Draw all edges
for (Entry<Link, ElkEdge> ent : edges.entrySet()) {
final Link link = ent.getKey();
if (link.isInvis()) {
continue;
}
final ElkEdge edge = ent.getValue();
// Unfortunately, we have to translate "edge" in its own "cluster" coordonate
private void drawSingleEdge(UGraphic ug, Link link, ElkEdge edge) {
// Unfortunately, we have to translate "edge" in its own "cluster" coordinate
final Point2D translate = getPosition(edge.getContainingNode());
final UGraphic ugTranslated = ug.apply(new UTranslate(translate));
new ElkPath(link, edge, diagram, getLabel(link), getQualifier(link, 1), getQualifier(link, 2))
.drawU(ugTranslated);
}
final ElkPath elkPath = new ElkPath(diagram, SName.classDiagram, link, edge, getLabel(link),
getQualifier(link, 1), getQualifier(link, 2));
elkPath.drawU(ug.apply(new UTranslate(translate)));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
@ -253,6 +350,14 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
return result;
}
private ElkNode getElkNode(final IEntity entity) {
ElkNode node = nodes.get(entity);
if (node == null) {
node = clusters.get(entity);
}
return node;
}
@Override
public ImageData createFile(OutputStream os, List<String> dotStrings, FileFormatOption fileFormatOption)
throws IOException {
@ -261,6 +366,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
try {
final ElkNode root = ElkGraphUtil.createGraph();
root.setProperty(CoreOptions.DIRECTION, Direction.DOWN);
root.setProperty(CoreOptions.HIERARCHY_HANDLING, HierarchyHandling.INCLUDE_CHILDREN);
printAllSubgroups(root, diagram.getRootGroup());
printEntities(root, getUnpackagedEntities());
@ -360,20 +466,26 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
// No idea of what we are doing here :-)
label.setProperty(CoreOptions.NODE_LABELS_PLACEMENT,
EnumSet.of(NodeLabelPlacement.INSIDE, NodeLabelPlacement.H_CENTER, NodeLabelPlacement.V_CENTER));
// This padding setting have no impact ?
// label.setProperty(CoreOptions.NODE_LABELS_PADDING, new ElkPadding(100.0));
node.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.NODE_LABELS));
node.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.noneOf(SizeOptions.class));
// final EnumSet<SizeConstraint> constraints =
// EnumSet.of(SizeConstraint.NODE_LABELS);
// node.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, constraints);
// node.setProperty(CoreOptions.NODE_SIZE_OPTIONS,
// EnumSet.noneOf(SizeOptions.class));
// Let's store this
nodes.put(leaf, node);
}
private void manageSingleEdge(final Link link) {
final ElkNode node1 = nodes.get(link.getEntity1());
final ElkNode node2 = nodes.get(link.getEntity2());
final ElkNode node1 = getElkNode(link.getEntity1());
final ElkNode node2 = getElkNode(link.getEntity2());
final ElkEdge edge = ElkGraphUtil.createEdge(node1.getParent());
final ElkEdge edge = ElkGraphUtil.createSimpleEdge(node1, node2);
final TextBlock labelLink = getLabel(link);
if (labelLink != null) {
@ -383,7 +495,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
edgeLabel.setDimensions(dim.getWidth(), dim.getHeight());
// Duplicated, with qualifier, but who cares?
edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true);
edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
// edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
}
if (link.getQualifier1() != null) {
final ElkLabel edgeLabel = ElkGraphUtil.createLabel(edge);
@ -394,7 +506,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
edgeLabel.setProperty(CoreOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.TAIL);
// Duplicated, with main label, but who cares?
edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true);
edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
// edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
}
if (link.getQualifier2() != null) {
final ElkLabel edgeLabel = ElkGraphUtil.createLabel(edge);
@ -405,10 +517,9 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
edgeLabel.setProperty(CoreOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.HEAD);
// Duplicated, with main label, but who cares?
edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true);
edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
// edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
}
edge.getSources().add(node1);
edge.getTargets().add(node2);
edges.put(link, edge);
}

View File

@ -35,27 +35,53 @@
*/
package net.sourceforge.plantuml.elk;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.List;
/*
* You can choose between real "org.eclipse.elk..." classes or proxied "net.sourceforge.plantuml.elk.proxy..."
*
* Using proxied classes allows to compile PlantUML without having ELK available on the classpath.
* Since GraphViz is the default layout engine up to now, we do not want to enforce the use of ELK just for compilation.
* (for people not using maven)
*
* If you are debugging, you should probably switch to "org.eclipse.elk..." classes
*
*/
/*
import org.eclipse.elk.graph.ElkBendPoint;
import org.eclipse.elk.graph.ElkEdge;
import org.eclipse.elk.graph.ElkEdgeSection;
import org.eclipse.elk.graph.ElkLabel;
import org.eclipse.emf.common.util.EList;
*/
import net.sourceforge.plantuml.elk.proxy.graph.ElkBendPoint;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdge;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdgeSection;
import net.sourceforge.plantuml.elk.proxy.graph.ElkLabel;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.LinkDecor;
import net.sourceforge.plantuml.cucadiagram.LinkType;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactory;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryExtends;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class ElkPath implements UDrawable {
@ -67,9 +93,10 @@ public class ElkPath implements UDrawable {
private final TextBlock headLabel;
private final TextBlock tailLabel;
private final Rose rose = new Rose();
private final SName styleName;
public ElkPath(Link link, ElkEdge edge, CucaDiagram diagram, TextBlock centerLabel, TextBlock tailLabel,
TextBlock headLabel) {
public ElkPath(CucaDiagram diagram, SName styleName, Link link, ElkEdge edge, TextBlock centerLabel,
TextBlock tailLabel, TextBlock headLabel) {
this.link = link;
this.edge = edge;
@ -77,6 +104,8 @@ public class ElkPath implements UDrawable {
this.centerLabel = centerLabel;
this.tailLabel = tailLabel;
this.headLabel = headLabel;
this.styleName = styleName;
}
private ColorParam getArrowColorParam() {
@ -119,18 +148,46 @@ public class ElkPath implements UDrawable {
}
ug = ug.apply(stroke).apply(color);
final EList<ElkEdgeSection> sections = edge.getSections();
final List<ElkEdgeSection> sections = edge.getSections();
if (sections.size() == 0) {
System.err.println("Strange: no section?");
System.err.println("Maybe a 'Long hierarchical edge' " + edge.isHierarchical());
return;
} else {
drawSections(ug, sections);
}
final UDrawable extremityFactory1 = getDecors(link.getType().getDecor1(), Math.PI / 2, HColorUtils.WHITE);
final UDrawable extremityFactory2 = getDecors(link.getType().getDecor2(), -Math.PI / 2, HColorUtils.WHITE);
if (extremityFactory1 != null) {
final double x = sections.get(0).getEndX();
final double y = sections.get(0).getEndY();
extremityFactory1.drawU(ug.apply(new UTranslate(x, y)));
}
if (extremityFactory2 != null) {
final double x = sections.get(0).getStartX();
final double y = sections.get(0).getStartY();
extremityFactory2.drawU(ug.apply(new UTranslate(x, y)));
}
drawLabels(ug);
}
private UDrawable getDecors(LinkDecor decors, double angle, HColor backColor) {
// For legacy reason, extends are treated differently
if (decors == LinkDecor.EXTENDS) {
return new ExtremityFactoryExtends(backColor).createUDrawable(new Point2D.Double(), angle, null);
}
final ExtremityFactory extremityFactory = decors.getExtremityFactory(backColor);
if (extremityFactory == null) {
return null;
}
return extremityFactory.createUDrawable(new Point2D.Double(), angle, null);
}
private void drawLabels(UGraphic ug) {
for (ElkLabel label : edge.getLabels()) {
final double x = label.getX();
@ -151,9 +208,9 @@ public class ElkPath implements UDrawable {
}
}
private void drawSections(UGraphic ug, final EList<ElkEdgeSection> sections) {
private void drawSections(UGraphic ug, final Collection<ElkEdgeSection> sections) {
for (ElkEdgeSection section : sections) {
final EList<ElkBendPoint> points = section.getBendPoints();
final Collection<ElkBendPoint> points = section.getBendPoints();
double x1 = section.getStartX();
double y1 = section.getStartY();

View File

@ -0,0 +1,7 @@
package net.sourceforge.plantuml.elk.proxy;
public interface EnumProxy {
public Enum getTrueObject();
}

View File

@ -0,0 +1,227 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* 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
*
*
*/
package net.sourceforge.plantuml.elk.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/*
* Various methods to do Java introspection
*/
public class Reflect {
public static Class clazz(String className) {
try {
return Class.forName(className);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Enum getEnum(String clazz, String name) {
try {
final Class cl = clazz(clazz);
for (Object en : cl.getEnumConstants()) {
if (en.toString().equals(name)) {
return (Enum) en;
}
}
throw new UnsupportedOperationException(name);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object opt(String className, String fieldname) {
try {
final Class<?> cl = Class.forName(className);
final Field field = cl.getField(fieldname);
return field.get(null);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object newInstance(String className) {
try {
final Class<?> cl = Class.forName(className);
return cl.newInstance();
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object newInstance(String className, Object arg1) {
try {
final Class<?> cl = Class.forName(className);
final Constructor<?> m = cl.getConstructor(arg1.getClass());
return m.newInstance(arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object field(String className, String fieldName) {
try {
final Class<?> cl = Class.forName(className);
final Field f = cl.getField(fieldName);
return f.get(null);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic(String className, String method) {
try {
final Class<?> cl = Class.forName(className);
final Method m = cl.getMethod(method);
return m.invoke(null);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic(String className, String method, Object arg1) {
try {
final Class<?> cl = Class.forName(className);
final Method m = cl.getMethod(method, arg1.getClass());
return m.invoke(null, arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic(String className, String method, Object arg1, Object arg2) {
try {
final Class<?> cl = Class.forName(className);
final Method m = cl.getMethod(method, arg1.getClass(), arg2.getClass());
return m.invoke(null, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic2(String className, String method, Object arg1) {
try {
final Class<?> cl = Class.forName(className);
final Method m = getStaticMethod(cl, method, 1);
return m.invoke(null, arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic2(String className, String method, Object arg1, Object arg2) {
try {
final Class<?> cl = Class.forName(className);
final Method m = getStaticMethod(cl, method, 2);
return m.invoke(null, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Method getStaticMethod(Class<?> cl, String method, int nbArgs) {
for (Method m : cl.getMethods()) {
if (m.getName().equals(method) && m.getParameters().length == nbArgs) {
return m;
}
}
throw new IllegalArgumentException();
}
public static Object call(Object instance, String method) {
try {
final Method m = instance.getClass().getMethod(method);
return m.invoke(instance);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object call(Object instance, String method, Object arg1) {
try {
final Method m = instance.getClass().getMethod(method, arg1.getClass());
return m.invoke(instance, arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object call(Object instance, String method, Object arg1, Object arg2) {
try {
final Method m = instance.getClass().getMethod(method, arg1.getClass(), arg2.getClass());
return m.invoke(instance, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object call2(Object instance, String method, Object arg1, Object arg2) {
try {
final Method m = getMethod(instance, method, 2);
return m.invoke(instance, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Method getMethod(Object instance, String method, int nbArgs) {
for (Method m : instance.getClass().getMethods()) {
if (m.getName().equals(method) && m.getParameters().length == nbArgs) {
return m;
}
}
throw new IllegalArgumentException();
}
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core;
import net.sourceforge.plantuml.elk.proxy.Reflect;
import net.sourceforge.plantuml.elk.proxy.core.util.NullElkProgressMonitor;
import net.sourceforge.plantuml.elk.proxy.graph.ElkNode;
public class RecursiveGraphLayoutEngine {
private final Object obj = Reflect.newInstance("org.eclipse.elk.core.RecursiveGraphLayoutEngine");
public void layout(ElkNode root, NullElkProgressMonitor monitor) {
Reflect.call2(obj, "layout", root.obj, monitor.obj);
}
}

View File

@ -0,0 +1,16 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class CoreOptions {
public static final Object DIRECTION = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "DIRECTION");
public static final Object EDGE_LABELS_INLINE = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "EDGE_LABELS_INLINE");
public static final Object NODE_SIZE_CONSTRAINTS = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "NODE_SIZE_CONSTRAINTS");
public static final Object HIERARCHY_HANDLING = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "HIERARCHY_HANDLING");
public static final Object EDGE_LABELS_PLACEMENT = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "EDGE_LABELS_PLACEMENT");
public static final Object EDGE_TYPE = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "EDGE_TYPE");
public static final Object NODE_LABELS_PLACEMENT = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "NODE_LABELS_PLACEMENT");
public static final Object NODE_SIZE_OPTIONS = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "NODE_SIZE_OPTIONS");
}

View File

@ -0,0 +1,9 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class Direction {
public static final Object DOWN = Reflect.field("org.eclipse.elk.core.options.Direction", "DOWN");
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public enum EdgeLabelPlacement implements EnumProxy {
TAIL, HEAD;
@Override
public Enum getTrueObject() {
return Reflect.getEnum("org.eclipse.elk.core.options.EdgeLabelPlacement", name());
}
}

View File

@ -0,0 +1,9 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class HierarchyHandling {
public static final Object INCLUDE_CHILDREN = Reflect.field("org.eclipse.elk.core.options.HierarchyHandling", "INCLUDE_CHILDREN");
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public enum NodeLabelPlacement implements EnumProxy {
INSIDE, V_CENTER, H_CENTER;
@Override
public Enum getTrueObject() {
return Reflect.getEnum("org.eclipse.elk.core.options.NodeLabelPlacement", name());
}
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public enum SizeConstraint implements EnumProxy {
NODE_LABELS;
@Override
public Enum getTrueObject() {
return Reflect.getEnum("org.eclipse.elk.core.options.SizeConstraint", name());
}
}

View File

@ -0,0 +1,10 @@
package net.sourceforge.plantuml.elk.proxy.core.util;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class NullElkProgressMonitor {
public final Object obj = Reflect.newInstance("org.eclipse.elk.core.util.NullElkProgressMonitor");
}

View File

@ -0,0 +1,34 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkBendPoint {
public final Object obj;
public ElkBendPoint(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
}
@Override
public int hashCode() {
return this.obj.hashCode();
}
@Override
public boolean equals(Object other) {
return this.obj.equals(((ElkBendPoint) other).obj);
}
public double getX() {
return (Double) Reflect.call(obj, "getX");
}
public double getY() {
return (Double) Reflect.call(obj, "getY");
}
}

View File

@ -0,0 +1,41 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkEdge extends ElkWithProperty {
public ElkEdge(Object obj) {
super(obj);
}
public ElkNode getContainingNode() {
return new ElkNode(Reflect.call(obj, "getContainingNode"));
}
public Collection<ElkLabel> getLabels() {
final List<ElkLabel> result = new ArrayList<ElkLabel>();
Collection internal = (Collection) Reflect.call(obj, "getLabels");
for (Object element : internal) {
result.add(new ElkLabel(element));
}
return result;
}
public List<ElkEdgeSection> getSections() {
final List<ElkEdgeSection> result = new ArrayList<ElkEdgeSection>();
Collection internal = (Collection) Reflect.call(obj, "getSections");
for (Object element : internal) {
result.add(new ElkEdgeSection(element));
}
return result;
}
public boolean isHierarchical() {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,55 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkEdgeSection {
public final Object obj;
public ElkEdgeSection(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
}
@Override
public int hashCode() {
return this.obj.hashCode();
}
@Override
public boolean equals(Object other) {
return this.obj.equals(((ElkEdgeSection) other).obj);
}
public double getStartX() {
return (Double) Reflect.call(obj, "getStartX");
}
public double getStartY() {
return (Double) Reflect.call(obj, "getStartY");
}
public double getEndX() {
return (Double) Reflect.call(obj, "getEndX");
}
public double getEndY() {
return (Double) Reflect.call(obj, "getEndY");
}
public Collection<ElkBendPoint> getBendPoints() {
final List<ElkBendPoint> result = new ArrayList<ElkBendPoint>();
Collection internal = (Collection) Reflect.call(obj, "getBendPoints");
for (Object element : internal) {
result.add(new ElkBendPoint(element));
}
return result;
}
}

View File

@ -0,0 +1,31 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkLabel extends ElkWithProperty {
public ElkLabel(Object obj) {
super(obj);
}
public void setText(String text) {
Reflect.call(obj, "setText", text);
}
public void setDimensions(double width, double height) {
Reflect.call2(obj, "setDimensions", width, height);
}
public String getText() {
return (String) Reflect.call(obj, "getText");
}
public double getX() {
return (Double) Reflect.call(obj, "getX");
}
public double getY() {
return (Double) Reflect.call(obj, "getY");
}
}

View File

@ -0,0 +1,51 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.ArrayList;
import java.util.Collection;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkNode extends ElkWithProperty {
public ElkNode(Object obj) {
super(obj);
}
public ElkNode getParent() {
final Object tmp = Reflect.call(obj, "getParent");
if (tmp == null) {
return null;
}
return new ElkNode(tmp);
}
public double getX() {
return (Double) Reflect.call(obj, "getX");
}
public double getY() {
return (Double) Reflect.call(obj, "getY");
}
public Collection<ElkLabel> getLabels() {
final Collection<ElkLabel> result = new ArrayList<ElkLabel>();
final Collection internal = (Collection) Reflect.call(obj, "getLabels");
for (Object element : internal) {
result.add(new ElkLabel(element));
}
return result;
}
public double getWidth() {
return (Double) Reflect.call(obj, "getWidth");
}
public double getHeight() {
return (Double) Reflect.call(obj, "getHeight");
}
public void setDimensions(double width, double height) {
Reflect.call2(obj, "setDimensions", width, height);
}
}

View File

@ -0,0 +1,49 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.Collection;
import java.util.EnumSet;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkWithProperty {
public final Object obj;
public ElkWithProperty(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
}
@Override
final public int hashCode() {
return this.obj.hashCode();
}
@Override
final public boolean equals(Object other) {
return this.obj.equals(((ElkWithProperty) other).obj);
}
final public void setProperty(Object key, Object value) {
if (value instanceof EnumSet) {
EnumSet result = null;
for (Object foo : (Collection) value) {
final EnumProxy elk = (EnumProxy) foo;
if (result == null) {
result = EnumSet.noneOf((Class<Enum>) elk.getClass());
}
result.add(elk);
}
Reflect.call2(obj, "setProperty", key, result);
} else if (value instanceof EnumProxy) {
final Enum elk = ((EnumProxy) value).getTrueObject();
Reflect.call2(obj, "setProperty", key, elk);
} else {
Reflect.call2(obj, "setProperty", key, value);
}
}
}

View File

@ -0,0 +1,31 @@
package net.sourceforge.plantuml.elk.proxy.graph.util;
import net.sourceforge.plantuml.elk.proxy.Reflect;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdge;
import net.sourceforge.plantuml.elk.proxy.graph.ElkLabel;
import net.sourceforge.plantuml.elk.proxy.graph.ElkNode;
public class ElkGraphUtil {
public static ElkLabel createLabel(ElkEdge edge) {
return new ElkLabel(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createLabel", edge.obj));
}
public static ElkLabel createLabel(ElkNode node) {
return new ElkLabel(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createLabel", node.obj));
}
public static ElkNode createNode(ElkNode root) {
return new ElkNode(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createNode", root.obj));
}
public static ElkEdge createSimpleEdge(ElkNode node1, ElkNode node2) {
return new ElkEdge(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createSimpleEdge", node1.obj,
node2.obj));
}
public static ElkNode createGraph() {
return new ElkNode(Reflect.callStatic("org.eclipse.elk.graph.util.ElkGraphUtil", "createGraph"));
}
}

View File

@ -55,9 +55,9 @@ public class Bibliotekon {
private final Map<ILeaf, SvekNode> nodeMap = new LinkedHashMap<ILeaf, SvekNode>();;
private final List<Line> lines0 = new ArrayList<Line>();
private final List<Line> lines1 = new ArrayList<Line>();
private final List<Line> allLines = new ArrayList<Line>();
private final List<SvekLine> lines0 = new ArrayList<SvekLine>();
private final List<SvekLine> lines1 = new ArrayList<SvekLine>();
private final List<SvekLine> allLines = new ArrayList<SvekLine>();
public SvekNode createNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) {
final SvekNode node = new SvekNode(ent, image, colorSequence, stringBounder);
@ -74,13 +74,13 @@ public class Bibliotekon {
return null;
}
public void addLine(Line line) {
public void addLine(SvekLine line) {
allLines.add(line);
if (first(line)) {
if (line.hasNoteLabelText()) {
// lines0.add(0, line);
for (int i = 0; i < lines0.size(); i++) {
final Line other = lines0.get(i);
final SvekLine other = lines0.get(i);
if (other.hasNoteLabelText() == false && line.sameConnections(other)) {
lines0.add(i, line);
return;
@ -95,7 +95,7 @@ public class Bibliotekon {
}
}
private static boolean first(Line line) {
private static boolean first(SvekLine line) {
final int length = line.getLength();
if (length == 1) {
return true;
@ -158,15 +158,15 @@ public class Bibliotekon {
return Collections.unmodifiableMap(result);
}
public List<Line> allLines() {
public List<SvekLine> allLines() {
return Collections.unmodifiableList(allLines);
}
public List<Line> lines0() {
public List<SvekLine> lines0() {
return Collections.unmodifiableList(lines0);
}
public List<Line> lines1() {
public List<SvekLine> lines1() {
return Collections.unmodifiableList(lines1);
}
@ -178,9 +178,9 @@ public class Bibliotekon {
return Collections.unmodifiableCollection(nodeMap.values());
}
public List<Line> getAllLineConnectedTo(IEntity leaf) {
final List<Line> result = new ArrayList<Line>();
for (Line line : allLines) {
public List<SvekLine> getAllLineConnectedTo(IEntity leaf) {
final List<SvekLine> result = new ArrayList<SvekLine>();
for (SvekLine line : allLines) {
if (line.isLinkFromOrTo(leaf)) {
result.add(line);
}
@ -188,8 +188,8 @@ public class Bibliotekon {
return Collections.unmodifiableList(result);
}
public Line getLine(Link link) {
for (Line line : allLines) {
public SvekLine getLine(Link link) {
for (SvekLine line : allLines) {
if (line.isLink(link)) {
return line;
}
@ -198,7 +198,7 @@ public class Bibliotekon {
}
public IEntity getOnlyOther(IEntity entity) {
for (Line line : allLines) {
for (SvekLine line : allLines) {
final IEntity other = line.getOther(entity);
if (other != null) {
return other;

View File

@ -178,7 +178,7 @@ public class Cluster implements Moveable {
return Collections.unmodifiableList(nodes);
}
private List<SvekNode> getNodesOrderedTop(Collection<Line> lines) {
private List<SvekNode> getNodesOrderedTop(Collection<SvekLine> lines) {
final List<SvekNode> firsts = new ArrayList<SvekNode>();
final Set<String> tops = new HashSet<String>();
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
@ -192,7 +192,7 @@ public class Cluster implements Moveable {
}
}
for (Line l : lines) {
for (SvekLine l : lines) {
if (tops.contains(l.getStartUidPrefix())) {
final SvekNode sh = shs.get(l.getEndUidPrefix());
if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL) {
@ -211,7 +211,7 @@ public class Cluster implements Moveable {
return firsts;
}
private List<SvekNode> getNodesOrderedWithoutTop(Collection<Line> lines) {
private List<SvekNode> getNodesOrderedWithoutTop(Collection<SvekLine> lines) {
final List<SvekNode> all = new ArrayList<SvekNode>(nodes);
final Set<String> tops = new HashSet<String>();
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
@ -229,7 +229,7 @@ public class Cluster implements Moveable {
}
}
for (Line l : lines) {
for (SvekLine l : lines) {
if (tops.contains(l.getStartUidPrefix())) {
final SvekNode sh = shs.get(l.getEndUidPrefix());
if (sh != null) {
@ -308,7 +308,6 @@ public class Cluster implements Moveable {
if (fullName.startsWith("##") == false) {
ug.draw(new UComment("cluster " + fullName));
}
final Stereotype stereotype = group.getStereotype();
HColor borderColor;
if (UseStyle.useBetaStyle()) {
final Style style = getDefaultStyleDefinition(umlDiagramType.getStyleName())
@ -317,11 +316,11 @@ public class Cluster implements Moveable {
} else {
if (umlDiagramType == UmlDiagramType.STATE) {
borderColor = getColor(ColorParam.stateBorder, skinParam, stereotype);
borderColor = getColor(ColorParam.stateBorder, skinParam, group.getStereotype());
} else if (umlDiagramType == UmlDiagramType.ACTIVITY) {
borderColor = getColor(ColorParam.packageBorder, skinParam, stereotype);
borderColor = getColor(ColorParam.packageBorder, skinParam, group.getStereotype());
} else {
borderColor = getColor(ColorParam.packageBorder, skinParam, stereotype);
borderColor = getColor(ColorParam.packageBorder, skinParam, group.getStereotype());
}
}
@ -374,13 +373,13 @@ public class Cluster implements Moveable {
shadowing = skinParam2.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()) ? 3
: 0;
}
stroke = getStrokeInternal(skinParam2);
stroke = getStrokeInternal(group, skinParam2);
}
HColor backColor = getBackColor(umlDiagramType);
backColor = getBackColor(backColor, skinParam2, group.getStereotype(), umlDiagramType.getStyleName());
if (ztitle != null || zstereo != null) {
final double roundCorner = group.getUSymbol() == null ? 0
: group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, stereotype);
: group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, group.getStereotype());
final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
zstereo, minX, minY, maxX, maxY, stroke);
@ -402,7 +401,7 @@ public class Cluster implements Moveable {
}
private UStroke getStrokeInternal(ISkinParam skinParam) {
static public UStroke getStrokeInternal(IGroup group, ISkinParam skinParam) {
final Colors colors = group.getColors(skinParam);
if (colors.getSpecificLineStroke() != null) {
return colors.getSpecificLineStroke();
@ -517,8 +516,8 @@ public class Cluster implements Moveable {
return fontParam.getStyleDefinition(SName.stateDiagram).getMergedStyle(skinParam.getCurrentStyleBuilder());
}
private boolean isThereALinkFromOrToGroup(Collection<Line> lines) {
for (Line line : lines) {
private boolean isThereALinkFromOrToGroup(Collection<SvekLine> lines) {
for (SvekLine line : lines) {
if (line.isLinkFromOrTo(group)) {
return true;
}
@ -526,7 +525,7 @@ public class Cluster implements Moveable {
return false;
}
public void printCluster1(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder) {
public void printCluster1(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder) {
for (SvekNode node : getNodesOrderedTop(lines)) {
node.appendShape(sb, stringBounder);
}
@ -618,8 +617,8 @@ public class Cluster implements Moveable {
printRanks(RANK_SINK, withPositionProtected(stringBounder, EntityPosition.getOutputs()), sb, stringBounder);
}
public SvekNode printCluster2(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder, DotMode dotMode,
GraphvizVersion graphvizVersion, UmlDiagramType type) {
public SvekNode printCluster2(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
SvekNode added = null;
for (SvekNode node : getNodesOrderedWithoutTop(lines)) {
@ -639,16 +638,16 @@ public class Cluster implements Moveable {
return added;
}
private void appendRankSame(StringBuilder sb, Collection<Line> lines) {
private void appendRankSame(StringBuilder sb, Collection<SvekLine> lines) {
for (String same : getRankSame(lines)) {
sb.append(same);
SvekUtils.println(sb);
}
}
private Set<String> getRankSame(Collection<Line> lines) {
private Set<String> getRankSame(Collection<SvekLine> lines) {
final Set<String> rankSame = new HashSet<String>();
for (Line l : lines) {
for (SvekLine l : lines) {
if (l.hasEntryPoint()) {
continue;
}
@ -738,8 +737,8 @@ public class Cluster implements Moveable {
return null;
}
private void printInternal(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder, DotMode dotMode,
GraphvizVersion graphvizVersion, UmlDiagramType type) {
private void printInternal(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
final boolean thereALinkFromOrToGroup2 = isThereALinkFromOrToGroup(lines);
boolean thereALinkFromOrToGroup1 = thereALinkFromOrToGroup2;
final boolean useProtectionWhenThereALinkFromOrToGroup = graphvizVersion
@ -753,7 +752,7 @@ public class Cluster implements Moveable {
}
final Set<EntityPosition> entityPositionsExceptNormal = entityPositionsExceptNormal();
if (entityPositionsExceptNormal.size() > 0) {
for (Line line : lines) {
for (SvekLine line : lines) {
if (line.isLinkFromOrTo(group)) {
line.setProjectionCluster(this);
}
@ -779,7 +778,7 @@ public class Cluster implements Moveable {
final String label;
if (isLabel()) {
final StringBuilder sblabel = new StringBuilder("<");
Line.appendTable(sblabel, getTitleAndAttributeWidth(), getTitleAndAttributeHeight() - 5, colorTitle);
SvekLine.appendTable(sblabel, getTitleAndAttributeWidth(), getTitleAndAttributeHeight() - 5, colorTitle);
sblabel.append(">");
label = sblabel.toString();
final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment,

View File

@ -76,13 +76,6 @@ public class ClusterDecoration {
return style.toUSymbol();
}
public final static int marginTitleX1 = 3;
public final static int marginTitleX2 = 3;
public final static int marginTitleX3 = 7;
public final static int marginTitleY0 = 0;
public final static int marginTitleY1 = 3;
public final static int marginTitleY2 = 3;
public void drawU(UGraphic ug, HColor backColor, HColor borderColor, double shadowing, double roundCorner,
HorizontalAlignment titleAlignment, HorizontalAlignment stereoAlignment) {
final SymbolContext biColor = new SymbolContext(backColor, borderColor);
@ -91,8 +84,8 @@ public class ClusterDecoration {
}
final SymbolContext symbolContext = biColor.withShadow(shadowing).withStroke(defaultStroke)
.withCorner(roundCorner, 0);
symbol.asBig(title, titleAlignment, stereo, maxX - minX, maxY - minY, symbolContext, stereoAlignment).drawU(
ug.apply(new UTranslate(minX, minY)));
symbol.asBig(title, titleAlignment, stereo, maxX - minX, maxY - minY, symbolContext, stereoAlignment)
.drawU(ug.apply(new UTranslate(minX, minY)));
}
}

View File

@ -125,7 +125,7 @@ public class DotStringFactory implements Moveable {
private double getHorizontalDzeta() {
double max = 0;
for (Line l : bibliotekon.allLines()) {
for (SvekLine l : bibliotekon.allLines()) {
final double c = l.getHorizontalDzeta(stringBounder);
if (c > max) {
max = c;
@ -136,7 +136,7 @@ public class DotStringFactory implements Moveable {
private double getVerticalDzeta() {
double max = 0;
for (Line l : bibliotekon.allLines()) {
for (SvekLine l : bibliotekon.allLines()) {
final double c = l.getVerticalDzeta(stringBounder);
if (c > max) {
max = c;
@ -207,14 +207,14 @@ public class DotStringFactory implements Moveable {
manageMinMaxCluster(sb);
root.printCluster1(sb, bibliotekon.allLines(), stringBounder);
for (Line line : bibliotekon.lines0()) {
for (SvekLine line : bibliotekon.lines0()) {
line.appendLine(getGraphvizVersion(), sb, dotMode);
}
root.fillRankMin(rankMin);
root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType);
printMinRanking(sb);
for (Line line : bibliotekon.lines1()) {
for (SvekLine line : bibliotekon.lines1()) {
line.appendLine(getGraphvizVersion(), sb, dotMode);
}
SvekUtils.println(sb);
@ -442,11 +442,11 @@ public class DotStringFactory implements Moveable {
cluster.setTitlePosition(minXtitle, minYtitle);
}
for (Line line : bibliotekon.allLines()) {
for (SvekLine line : bibliotekon.allLines()) {
line.solveLine(svgResult);
}
for (Line line : bibliotekon.allLines()) {
for (SvekLine line : bibliotekon.allLines()) {
line.manageCollision(bibliotekon.allNodes());
}
// corner1.manage(0, 0);
@ -493,7 +493,7 @@ public class DotStringFactory implements Moveable {
for (SvekNode sh : bibliotekon.allNodes()) {
sh.moveSvek(deltaX, deltaY);
}
for (Line line : bibliotekon.allLines()) {
for (SvekLine line : bibliotekon.allLines()) {
line.moveSvek(deltaX, deltaY);
}
for (Cluster cl : bibliotekon.allCluster()) {

View File

@ -424,17 +424,10 @@ public final class GeneralImageBuilder {
}
try {
final ISkinParam skinParam = dotData.getSkinParam();
final FontConfiguration labelFont;
if (UseStyle.useBetaStyle()) {
final Style style = getDefaultStyleDefinitionArrow(link.getStereotype())
.getMergedStyle(link.getStyleBuilder());
labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet());
} else {
labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
}
final FontConfiguration labelFont = getFontForLink(link, skinParam);
final Line line = new Line(link, dotStringFactory.getColorSequence(), skinParam, stringBounder,
labelFont, dotStringFactory.getBibliotekon(), dotData.getPragma());
final SvekLine line = new SvekLine(link, dotStringFactory.getColorSequence(), skinParam, stringBounder,
labelFont, dotStringFactory.getBibliotekon(), pragma);
dotStringFactory.getBibliotekon().addLine(line);
@ -489,6 +482,18 @@ public final class GeneralImageBuilder {
}
private FontConfiguration getFontForLink(Link link, final ISkinParam skinParam) {
final FontConfiguration labelFont;
if (UseStyle.useBetaStyle()) {
final Style style = getDefaultStyleDefinitionArrow(link.getStereotype())
.getMergedStyle(link.getStyleBuilder());
labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet());
} else {
labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
}
return labelFont;
}
private boolean isSvekTrace() {
final String value = pragma.getValue("svek_trace");
return "true".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value);

View File

@ -101,7 +101,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorNone;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class Line implements Moveable, Hideable, GuideLine {
public class SvekLine implements Moveable, Hideable, GuideLine {
private static final Dimension2DDouble CONSTRAINT_SPOT = new Dimension2DDouble(10, 10);
@ -205,7 +205,7 @@ public class Line implements Moveable, Hideable, GuideLine {
throw new IllegalArgumentException();
}
public Line(Link link, ColorSequence colorSequence, ISkinParam skinParam, StringBounder stringBounder,
public SvekLine(Link link, ColorSequence colorSequence, ISkinParam skinParam, StringBounder stringBounder,
FontConfiguration font, Bibliotekon bibliotekon, Pragma pragma) {
if (link == null) {
@ -985,7 +985,7 @@ public class Line implements Moveable, Hideable, GuideLine {
return link.isHidden();
}
public boolean sameConnections(Line other) {
public boolean sameConnections(SvekLine other) {
return link.sameConnections(other.link);
}

View File

@ -98,7 +98,7 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage
final Set<String> ids = new HashSet<String>();
for (Line line : dotStringFactory.getBibliotekon().allLines()) {
for (SvekLine line : dotStringFactory.getBibliotekon().allLines()) {
final UGraphic ug2 = line.isHidden() ? ug.apply(UHidden.HIDDEN) : ug;
if (UseStyle.useBetaStyle()) {

View File

@ -53,7 +53,7 @@ import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Line;
import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -100,10 +100,10 @@ public class EntityImageLollipopInterfaceEye1 extends AbstractEntityImage {
Point2D pos = bibliotekon.getNode(getEntity()).getPosition();
final List<Line> lines = bibliotekon.getAllLineConnectedTo(getEntity());
final List<SvekLine> lines = bibliotekon.getAllLineConnectedTo(getEntity());
final UTranslate reverse = new UTranslate(pos).reverse();
final ConnectedCircle connectedCircle = new ConnectedCircle(SIZE / 2);
for (Line line : lines) {
for (SvekLine line : lines) {
Point2D pt = line.getMyPoint(getEntity());
pt = reverse.getTranslated(pt);
connectedCircle.addSecondaryConnection(pt);

View File

@ -71,7 +71,7 @@ import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.Line;
import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.svek.SvekNode;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -300,11 +300,11 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
return ShapeType.RECTANGLE;
}
private Line opaleLine;
private SvekLine opaleLine;
private SvekNode node;
private SvekNode other;
public void setOpaleLine(Line line, SvekNode node, SvekNode other) {
public void setOpaleLine(SvekLine line, SvekNode node, SvekNode other) {
if (other == null) {
throw new IllegalArgumentException();
}