POC finalized

This commit is contained in:
BoykoAlex
2019-08-26 18:58:56 -04:00
parent 7dfb35b335
commit c49a9f0c83
10 changed files with 21 additions and 359 deletions

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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");

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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()));
}
}
}

View File

@@ -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');