POC finalized
This commit is contained in:
@@ -30,16 +30,15 @@
|
||||
<artifactId>org.eclipse.sprotty.server</artifactId>
|
||||
<version>${sprotty-version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.eclipse.elk/org.eclipse.elk.core -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.elk</groupId>
|
||||
<artifactId>org.eclipse.elk.core</artifactId>
|
||||
<version>${elk-version}</version>
|
||||
<groupId>org.eclipse.sprotty</groupId>
|
||||
<artifactId>org.eclipse.sprotty.layout</artifactId>
|
||||
<version>${sprotty-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.elk</groupId>
|
||||
<artifactId>org.eclipse.elk.alg.layered</artifactId>
|
||||
<version>${elk-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.springframework.ide.vscode.commons.sprotty.elk;
|
||||
|
||||
import org.eclipse.elk.core.RecursiveGraphLayoutEngine;
|
||||
import org.eclipse.elk.core.util.BasicProgressMonitor;
|
||||
import org.eclipse.elk.graph.ElkNode;
|
||||
import org.eclipse.sprotty.ILayoutEngine;
|
||||
import org.eclipse.sprotty.SModelRoot;
|
||||
|
||||
public class ElkLayoutEngine implements ILayoutEngine {
|
||||
|
||||
@Override
|
||||
public void layout(SModelRoot root) {
|
||||
ElkUtils utils = new ElkUtils(root);
|
||||
ElkNode graph = utils.graph;
|
||||
new RecursiveGraphLayoutEngine().layout(graph, new BasicProgressMonitor());
|
||||
utils.applyLayout();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package org.springframework.ide.vscode.commons.sprotty.elk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.elk.alg.layered.options.ContentAlignment;
|
||||
import org.eclipse.elk.alg.layered.options.FixedAlignment;
|
||||
import org.eclipse.elk.alg.layered.options.LayeredOptions;
|
||||
import org.eclipse.elk.alg.layered.options.NodePlacementStrategy;
|
||||
import org.eclipse.elk.core.options.Alignment;
|
||||
import org.eclipse.elk.core.options.Direction;
|
||||
import org.eclipse.elk.graph.ElkBendPoint;
|
||||
import org.eclipse.elk.graph.ElkEdge;
|
||||
import org.eclipse.elk.graph.ElkEdgeSection;
|
||||
import org.eclipse.elk.graph.ElkNode;
|
||||
import org.eclipse.elk.graph.properties.IProperty;
|
||||
import org.eclipse.elk.graph.properties.Property;
|
||||
import org.eclipse.elk.graph.util.ElkGraphUtil;
|
||||
import org.eclipse.sprotty.Point;
|
||||
import org.eclipse.sprotty.SEdge;
|
||||
import org.eclipse.sprotty.SModelElement;
|
||||
import org.eclipse.sprotty.SModelRoot;
|
||||
import org.eclipse.sprotty.SNode;
|
||||
import org.eclipse.sprotty.SShapeElement;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class ElkUtils {
|
||||
|
||||
private static final IProperty<SModelElement> SPROTTY_ELEMENT = new Property<>("sprotty-element");
|
||||
public final ElkNode graph;
|
||||
private Map<String, ElkNode> nodes = new HashMap<>();;
|
||||
|
||||
public ElkUtils(SModelRoot root) {
|
||||
graph = ElkGraphUtil.createGraph();
|
||||
|
||||
// graph.setProperty(LayeredOptions.DIRECTION, Direction.DOWN);
|
||||
// graph.setProperty(LayeredOptions.CONTENT_ALIGNMENT, EnumSet.of(ContentAlignment.H_CENTER));
|
||||
// graph.setProperty(LayeredOptions.ALIGNMENT, Alignment.RIGHT);
|
||||
|
||||
// graph.setProperty(LayeredOptions.NODE_PLACEMENT_STRATEGY, NodePlacementStrategy.SIMPLE);
|
||||
graph.setProperty(LayeredOptions.NODE_PLACEMENT_BK_FIXED_ALIGNMENT, FixedAlignment.BALANCED);
|
||||
|
||||
List<SEdge> edges = new ArrayList<>();
|
||||
for (SModelElement child : root.getChildren()) {
|
||||
System.out.println(child.getClass());
|
||||
if (child instanceof SNode) {
|
||||
nodes.put(child.getId(), toElk((SNode)child, graph));
|
||||
} else if (child instanceof SEdge) {
|
||||
edges.add((SEdge)child);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported graph layout element");
|
||||
}
|
||||
}
|
||||
|
||||
for (SEdge edge : edges) {
|
||||
toElk(edge);
|
||||
}
|
||||
}
|
||||
|
||||
private ElkEdge toElk(SEdge child) {
|
||||
ElkNode source = nodes.get(child.getSourceId());
|
||||
ElkNode target = nodes.get(child.getTargetId());
|
||||
Assert.isTrue(source != null);
|
||||
Assert.isTrue(target != null);
|
||||
ElkEdge edge = ElkGraphUtil.createSimpleEdge(source, target);
|
||||
edge.setProperty(SPROTTY_ELEMENT, child);
|
||||
return edge;
|
||||
}
|
||||
|
||||
private ElkNode toElk(SNode child, ElkNode parent) {
|
||||
ElkNode node = ElkGraphUtil.createNode(parent);
|
||||
node.setX(child.getPosition().getX());
|
||||
node.setY(child.getPosition().getY());
|
||||
node.setWidth(child.getSize().getWidth());
|
||||
node.setHeight(child.getSize().getHeight());
|
||||
node.setIdentifier(child.getId());
|
||||
node.setProperty(SPROTTY_ELEMENT, child);
|
||||
// node.setProperty(LayeredOptions.ALIGNMENT, Alignment.CENTER);
|
||||
return node;
|
||||
}
|
||||
|
||||
public void applyLayout() {
|
||||
for (Entry<String, ElkNode> entry : nodes.entrySet()) {
|
||||
ElkNode elkNode = entry.getValue();
|
||||
SModelElement element = elkNode.getProperty(SPROTTY_ELEMENT);
|
||||
if (element instanceof SShapeElement) {
|
||||
SShapeElement shape = (SShapeElement) element;
|
||||
shape.setPosition(new Point(elkNode.getX(), elkNode.getY()));
|
||||
}
|
||||
}
|
||||
|
||||
for (ElkEdge elkEdge : graph.getContainedEdges()) {
|
||||
SModelElement element = elkEdge.getProperty(SPROTTY_ELEMENT);
|
||||
if (element instanceof SEdge) {
|
||||
SEdge edge = (SEdge) element;
|
||||
List<Point> bendpoints = new ArrayList<>();
|
||||
for (ElkEdgeSection section : elkEdge.getSections()) {
|
||||
bendpoints.add(new Point(section.getStartX(), section.getStartY()));
|
||||
for (ElkBendPoint elkBend : section.getBendPoints()) {
|
||||
Point bendpoint = new Point(elkBend.getX(), elkBend.getY());
|
||||
bendpoints.add(bendpoint);
|
||||
}
|
||||
bendpoints.add(new Point(section.getEndX(), section.getEndY()));
|
||||
}
|
||||
edge.setRoutingPoints(bendpoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +1,18 @@
|
||||
package org.springframework.ide.vscode.commons.sprotty.scan;
|
||||
|
||||
import org.eclipse.elk.alg.layered.options.LayeredMetaDataProvider;
|
||||
import org.eclipse.elk.core.data.LayoutMetaDataService;
|
||||
import org.eclipse.sprotty.IDiagramExpansionListener;
|
||||
import org.eclipse.sprotty.IDiagramOpenListener;
|
||||
import org.eclipse.sprotty.IDiagramSelectionListener;
|
||||
import org.eclipse.sprotty.ILayoutEngine;
|
||||
import org.eclipse.sprotty.IModelUpdateListener;
|
||||
import org.eclipse.sprotty.SModelCloner;
|
||||
import org.eclipse.sprotty.layout.ElkLayoutEngine;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ide.vscode.commons.sprotty.elk.ElkLayoutEngine;
|
||||
|
||||
@Configuration
|
||||
public class DiagramServerConfiguration {
|
||||
|
||||
@Bean public IModelUpdateListener modelUpdateListener() {
|
||||
return new IModelUpdateListener.NullImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ILayoutEngine layoutEngine() {
|
||||
LayoutMetaDataService.getInstance().registerLayoutMetaDataProviders(new LayeredMetaDataProvider());
|
||||
ElkLayoutEngine.initialize(new LayeredMetaDataProvider());
|
||||
return new ElkLayoutEngine();
|
||||
}
|
||||
|
||||
@Bean public IDiagramSelectionListener diagramSelectionListener() {
|
||||
return new IDiagramSelectionListener.NullImpl();
|
||||
}
|
||||
|
||||
@Bean public IDiagramExpansionListener diagramExpansionListener() {
|
||||
return new IDiagramExpansionListener.NullImpl();
|
||||
}
|
||||
|
||||
@Bean public IDiagramOpenListener diagramOpenListener() {
|
||||
return new IDiagramOpenListener.NullImpl();
|
||||
}
|
||||
|
||||
@Bean public SModelCloner modelCloner() {
|
||||
return new SModelCloner();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,9 +3,8 @@ package org.springframework.ide.vscode.commons.sprotty.scan;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.sprotty.ActionMessage;
|
||||
import org.eclipse.sprotty.IDiagramServer;
|
||||
|
||||
public interface DiagramServerManager /*extends IDiagramServer.Provider*/ {
|
||||
public interface DiagramServerManager {
|
||||
|
||||
void setRemoteEndpoint(Consumer<ActionMessage> remoteEndpoint);
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ import org.eclipse.sprotty.SEdge;
|
||||
import org.eclipse.sprotty.SGraph;
|
||||
import org.eclipse.sprotty.SLabel;
|
||||
import org.eclipse.sprotty.SModelElement;
|
||||
import org.eclipse.sprotty.SModelRoot;
|
||||
import org.eclipse.sprotty.SNode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBean;
|
||||
@@ -37,6 +37,11 @@ import com.google.common.cache.CacheBuilder;
|
||||
@Component
|
||||
public class LiveBeansDiagramServerManager implements DiagramServerManager {
|
||||
|
||||
public static final SGraph EMPTY_GRAPH = new SGraph(((Consumer<SGraph>) (SGraph it) -> {
|
||||
it.setType("NONE");
|
||||
it.setId("EMPTY");
|
||||
}));
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LiveBeansDiagramServerManager.class);
|
||||
|
||||
private Cache<String, IDiagramServer> servers = CacheBuilder.newBuilder().build();
|
||||
@@ -47,9 +52,11 @@ public class LiveBeansDiagramServerManager implements DiagramServerManager {
|
||||
@Autowired
|
||||
private ILayoutEngine layoutEngine;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext appContext;
|
||||
|
||||
private Consumer<ActionMessage> remoteEndpoint;
|
||||
|
||||
// @Override
|
||||
private IDiagramServer getDiagramServer(String clientId) {
|
||||
try {
|
||||
return servers.get(clientId, () -> {
|
||||
@@ -82,7 +89,7 @@ public class LiveBeansDiagramServerManager implements DiagramServerManager {
|
||||
}
|
||||
}
|
||||
|
||||
private SModelRoot generateModel(String clientId) {
|
||||
private SGraph generateModel(String clientId) {
|
||||
try {
|
||||
Collection<SpringBootApp> apps = runningAppProvider.getAllRunningSpringApps();
|
||||
if (!apps.isEmpty()) {
|
||||
@@ -97,11 +104,11 @@ public class LiveBeansDiagramServerManager implements DiagramServerManager {
|
||||
} catch (Exception e) {
|
||||
log.error("{}", e);
|
||||
}
|
||||
return SGraph.EMPTY_ROOT;
|
||||
return EMPTY_GRAPH;
|
||||
}
|
||||
|
||||
private SModelRoot toSprottyGraph(SpringBootApp app) throws Exception {
|
||||
SModelRoot graph = new SModelRoot();
|
||||
private SGraph toSprottyGraph(SpringBootApp app) throws Exception {
|
||||
SGraph graph = new SGraph();
|
||||
graph.setId(app.getProcessName());
|
||||
graph.setType("graph");
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package org.springframework.ide.vscode.boot.app.diagram;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.sprotty.Dimension;
|
||||
import org.eclipse.sprotty.IDiagramServer;
|
||||
import org.eclipse.sprotty.Point;
|
||||
import org.eclipse.sprotty.SCompartment;
|
||||
import org.eclipse.sprotty.SEdge;
|
||||
import org.eclipse.sprotty.SLabel;
|
||||
import org.eclipse.sprotty.SModelRoot;
|
||||
import org.eclipse.sprotty.SNode;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import net.bytebuddy.utility.RandomString;
|
||||
|
||||
|
||||
//@Component
|
||||
public class MockDiagramServerModel implements InitializingBean {
|
||||
|
||||
@Autowired
|
||||
IDiagramServer diagramServer;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("taskScheduler")
|
||||
private TaskScheduler taskScheduler;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// taskScheduler.scheduleAtFixedRate(() -> diagramServer.setModel(generateModel()), Duration.ofSeconds(5));
|
||||
diagramServer.setModel(generateModel(10));
|
||||
}
|
||||
|
||||
public static SModelRoot generateModel(int nodesNum) {
|
||||
SModelRoot graph = new SModelRoot();
|
||||
graph.setId("graph");
|
||||
graph.setType("graph");
|
||||
|
||||
SNode node0 = createBean("node0", "main", new Point(100, 100), new Dimension(120, 40));
|
||||
|
||||
graph.setChildren(new ArrayList<>());
|
||||
graph.getChildren().add(node0);
|
||||
|
||||
for (int i = 1; i < nodesNum; i++) {
|
||||
SNode node = createBean("node" + i, RandomString.make(((int) Math.round(Math.random()* 10 + 1))), new Point(Math.random() * 1024, Math.random() * 768), new Dimension(120, 40));
|
||||
SEdge edge = createEdge("edge-" + i, node0.getId(), node.getId());
|
||||
graph.getChildren().add(edge);
|
||||
graph.getChildren().add(node);
|
||||
|
||||
}
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
private static SNode createBean(String id, String labelText, Point location, Dimension size) {
|
||||
SNode node = new SNode();
|
||||
node.setId(id);
|
||||
node.setType("node:bean");
|
||||
node.setLayout("vbox");
|
||||
node.setPosition(new Point(Math.random() * 1024, Math.random() * 768));
|
||||
node.setSize(new Dimension(80, 80));
|
||||
node.setChildren(new ArrayList<>());
|
||||
|
||||
SCompartment compartment = new SCompartment();
|
||||
compartment.setId(id + "-comp");
|
||||
compartment.setType("compartment");
|
||||
compartment.setLayout("hbox");
|
||||
compartment.setChildren(new ArrayList<>());
|
||||
|
||||
SLabel label = new SLabel();
|
||||
label.setId(id + "-lanbel");
|
||||
label.setType("node:label");
|
||||
label.setText(labelText);
|
||||
|
||||
compartment.getChildren().add(label);
|
||||
node.getChildren().add(compartment);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private static SEdge createEdge(String id, String sourceId, String targetId) {
|
||||
SEdge edge = new SEdge();
|
||||
edge.setId(id);
|
||||
edge.setType("edge:straight");
|
||||
edge.setSourceId(sourceId);
|
||||
edge.setTargetId(targetId);
|
||||
return edge;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.springframework.ide.vscode.boot.app.diagram;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.sprotty.IDiagramServer;
|
||||
import org.eclipse.sprotty.IPopupModelFactory;
|
||||
import org.eclipse.sprotty.RequestPopupModelAction;
|
||||
import org.eclipse.sprotty.SGraph;
|
||||
import org.eclipse.sprotty.SLabel;
|
||||
import org.eclipse.sprotty.SModelElement;
|
||||
import org.eclipse.sprotty.SModelRoot;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PopupModelFactory implements IPopupModelFactory {
|
||||
|
||||
@Override
|
||||
public SModelRoot createPopupModel(SModelElement element, RequestPopupModelAction request, IDiagramServer server) {
|
||||
|
||||
// SGraph graph = new SGraph();
|
||||
// graph.setId("popup");
|
||||
// List<SModelElement> children = new ArrayList<>();
|
||||
//
|
||||
// SLabel label = new SLabel();
|
||||
// label.setType("node:label");
|
||||
// label.setText("I'm a tooltip!");
|
||||
// children.add(label);
|
||||
//
|
||||
// graph.setChildren(children);
|
||||
//
|
||||
// return graph;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package org.springframework.ide.vscode.boot.test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.elk.alg.layered.options.LayeredMetaDataProvider;
|
||||
import org.eclipse.elk.core.RecursiveGraphLayoutEngine;
|
||||
import org.eclipse.elk.core.data.LayoutMetaDataService;
|
||||
import org.eclipse.elk.core.util.BasicProgressMonitor;
|
||||
import org.eclipse.elk.graph.ElkNode;
|
||||
import org.eclipse.sprotty.Point;
|
||||
import org.eclipse.sprotty.SModelRoot;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.app.diagram.MockDiagramServerModel;
|
||||
import org.springframework.ide.vscode.commons.sprotty.elk.ElkUtils;
|
||||
|
||||
|
||||
public class LayoutTest {
|
||||
|
||||
@Test
|
||||
public void testCreateGraph() throws Exception {
|
||||
SModelRoot modelRoot = MockDiagramServerModel.generateModel(10);
|
||||
ElkNode graph = new ElkUtils(modelRoot).graph;
|
||||
assertNotNull(graph);
|
||||
assertEquals(10, graph.getChildren().size());
|
||||
assertEquals(9, graph.getContainedEdges().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLayout() throws Exception {
|
||||
LayoutMetaDataService.getInstance().registerLayoutMetaDataProviders(new LayeredMetaDataProvider());
|
||||
|
||||
SModelRoot modelRoot = MockDiagramServerModel.generateModel(10);
|
||||
ElkNode graph = new ElkUtils(modelRoot).graph;
|
||||
|
||||
Map<String, Point> locations = new HashMap<>();
|
||||
|
||||
for (ElkNode child : graph.getChildren()) {
|
||||
locations.put(child.getIdentifier(), new Point(child.getX(), child.getY()));
|
||||
}
|
||||
|
||||
new RecursiveGraphLayoutEngine().layout(graph, new BasicProgressMonitor());
|
||||
|
||||
for (ElkNode child : graph.getChildren()) {
|
||||
assertNotEquals(locations.get(child.getIdentifier()), new Point(child.getX(), child.getY()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -108,6 +108,7 @@ export default function runStandalone(clientId: string) {
|
||||
if (modelSource instanceof VSCodeWebViewDiagramServer) {
|
||||
console.log('Listen and acquire VSCode API with client-id = ' + clientId);
|
||||
modelSource.listen(acquireVsCodeApi());
|
||||
dispatcher.dispatch(new RequestModelAction());
|
||||
}
|
||||
|
||||
console.log('Before requesting model');
|
||||
|
||||
Reference in New Issue
Block a user