Skip to content

Added structure-based editing #181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
521e197
Relative Constraints: Migrated jep implementation.
soerendomroes Oct 17, 2022
5f964c7
Readded serialization of constraint for ElkNodes.
soerendomroes Oct 20, 2022
c4cb181
Refactored constraints.
soerendomroes Oct 20, 2022
6135a6b
Klighd.lsp: Interactive: Added NodeIdProvider.
soerendomroes Oct 21, 2022
6b43a31
Handle negative layer constraint.
soerendomroes Oct 21, 2022
8e9aaff
klighd.lsp.interactive: Use KIdentifier to get id.
soerendomroes Oct 24, 2022
0b94b34
klighd.lsp: Interactive SCCharts: Fixed documentation and license.
soerendomroes Nov 4, 2022
3d4d950
klighd.lsp: Interactive rectpacking: Still update the layout if request
soerendomroes Nov 7, 2022
b5c533e
Klighd.lsp: Enforce minimum position constraint of 0 in layer.
soerendomroes Nov 7, 2022
09e2e46
Renamed interactive type attributes.
soerendomroes Nov 7, 2022
5bec88d
klighd.lsp: Renmaing, comments and Javadoc.
soerendomroes Nov 7, 2022
6437915
klighd.lsp: Added more Javadoc.
soerendomroes Nov 7, 2022
851fa81
Initial interactive MrTree commit.
soerendomroes Nov 8, 2022
3f80be6
klighd.lsp: mrtree: Cleanup
soerendomroes Nov 11, 2022
75b9488
Fix chain empties layer after setStatic.
soerendomroes Dec 16, 2022
44e211f
interactive: layered: Setting constraints checks for empty layer.
soerendomroes Dec 16, 2022
78ebf90
Merge branch 'interactiveSCCharts' into sdo/interactiveMrTree
soerendomroes Mar 7, 2024
df751d0
Merge branch 'master' into sdo/interactiveMrTree
soerendomroes Mar 7, 2024
5c1d02b
javax-> google Singleton
soerendomroes Mar 7, 2024
2420587
Fixed order for serialize to get correct text.
soerendomroes Mar 7, 2024
a9592a9
lsp-interaction: Fixed javadoc errors.
soerendomroes Mar 8, 2024
7fd0f67
Use actionhandler service interface for interactive layout handlers.
soerendomroes Mar 12, 2024
20c1bcc
Added structure-based editing stuf (not tested).
soerendomroes Mar 12, 2024
32d21d7
Fixed LSPUtil Javadoc.
soerendomroes Mar 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions plugins/de.cau.cs.kieler.klighd.lsp/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Export-Package: de.cau.cs.kieler.klighd.lsp,
de.cau.cs.kieler.klighd.lsp.gson_utils,
de.cau.cs.kieler.klighd.lsp.interactive,
de.cau.cs.kieler.klighd.lsp.interactive.layered,
de.cau.cs.kieler.klighd.lsp.interactive.mrtree,
de.cau.cs.kieler.klighd.lsp.interactive.rectpacking,
de.cau.cs.kieler.klighd.lsp.launch,
de.cau.cs.kieler.klighd.lsp.model,
Expand All @@ -25,6 +26,7 @@ Require-Bundle: de.cau.cs.kieler.kgraph.text,
com.google.inject;bundle-version="3.0.0",
org.apache.log4j;bundle-version="1.2.15",
org.eclipse.elk.alg.layered,
org.eclipse.elk.alg.mrtree,
org.eclipse.elk.alg.rectpacking,
org.eclipse.elk.core,
org.eclipse.elk.graph,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
de.cau.cs.kieler.klighd.lsp.interactive.layered.LayeredInteractiveActionHandler
de.cau.cs.kieler.klighd.lsp.interactive.rectpacking.RectpackingInteractiveActionHandler
de.cau.cs.kieler.klighd.lsp.interactive.mrtree.MrTreeActionHandler
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
de.cau.cs.kieler.klighd.lsp.ElkGraphConstraintSerializer
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
*/
package de.cau.cs.kieler.klighd.lsp

import java.util.HashMap
import org.eclipse.xtend.lib.annotations.Accessors
import java.util.Map
import org.eclipse.sprotty.Action

/**
* Abstract class to handle Sprotty actions.
Expand All @@ -26,11 +26,17 @@ import org.eclipse.xtend.lib.annotations.Accessors
*/
abstract class AbstractActionHandler implements IActionHandler {

@Accessors(PUBLIC_GETTER, PROTECTED_SETTER)
HashMap<String, Class<?>> supportedMessages = newHashMap
Map<String, Class<? extends Action>> supportedMessages

override Map<String, Class<? extends Action>> getSupportedMessages() {
return supportedMessages
}

def setSupportedMessages(Map<String, Class<? extends Action>> messages) {
this.supportedMessages = messages
}

override canHandleAction(String kind) {
return supportedMessages.containsKey(kind)

}
return supportedMessages.containsKey(kind)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* KIELER - Kiel Integrated Environment for Layout Eclipse RichClient
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2022 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package de.cau.cs.kieler.klighd.lsp

import de.cau.cs.kieler.klighd.internal.util.KlighdInternalProperties
import de.cau.cs.kieler.klighd.lsp.interactive.ConstraintProperty
import de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer
import java.io.ByteArrayOutputStream
import java.util.List
import java.util.Map
import org.eclipse.elk.graph.ElkNode
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.TextEdit

/**
* Serializes constraint for an ELK graph by just adding the corresponding properties.
*
* @author sdo
*
*/
class ElkGraphConstraintSerializer implements IConstraintSerializer {

override canHandle(Object graph) {
return graph instanceof ElkNode
}

override serializeConstraints(List<ConstraintProperty<Object>> changedNodes,
Object graph,
String uri,
KGraphLanguageServerExtension ls,
KGraphLanguageClient client
) {
// Serialize model into given uri.
val resource = ls.getResource(uri)

// Get previous file content as String
var outputStream = new ByteArrayOutputStream
resource.save(outputStream, emptyMap)
val codeBefore = outputStream.toString
changedNodes.forEach[c|
val ElkNode elkNode = c.KNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as ElkNode
elkNode.setProperty(c.property, c.value)
]
val Map<String, List<TextEdit>> changes = newHashMap
// Get changed file as String
outputStream = new ByteArrayOutputStream
resource.save(outputStream, emptyMap)
val String codeAfter = outputStream.toString().trim

// The range is the length of the previous file.
// Just make sure the range is big enough
val Range range = new Range(new Position(0, 0), new Position(codeBefore.split("\r\n|\r|\n").length * 2, 0))
val TextEdit textEdit = new TextEdit(range, codeAfter)
changes.put(uri, #[textEdit]);
client.replaceContentInFile(uri, codeAfter, range)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@
package de.cau.cs.kieler.klighd.lsp

import org.eclipse.sprotty.Action
import java.util.Map

/**
* Service Interface for ActionHandler.
*
* @author sdo
*/
interface IActionHandler {


def Map<String, Class<? extends Action>> getSupportedMessages();

/**
* Checks and returns true if this ActionHandler can handle this action.
* @param kind String identifier of action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import java.util.HashSet
import java.util.List
import org.apache.log4j.Logger
import org.eclipse.elk.alg.layered.options.LayeredOptions
import org.eclipse.elk.alg.rectpacking.options.RectPackingOptions
import org.eclipse.elk.core.options.CoreOptions
import org.eclipse.emf.ecore.EObject
import org.eclipse.sprotty.Dimension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ import com.google.common.base.Strings
import com.google.common.base.Throwables
import com.google.common.io.ByteStreams
import com.google.inject.Inject
import com.google.inject.Injector
import de.cau.cs.kieler.klighd.IAction
import de.cau.cs.kieler.klighd.IAction.ActionContext
import de.cau.cs.kieler.klighd.Klighd
import de.cau.cs.kieler.klighd.KlighdDataManager
import de.cau.cs.kieler.klighd.ViewContext
import de.cau.cs.kieler.klighd.kgraph.KNode
import de.cau.cs.kieler.klighd.lsp.interactive.layered.LayeredInteractiveActionHandler
import de.cau.cs.kieler.klighd.lsp.interactive.rectpacking.RectpackingInteractiveActionHandler
import de.cau.cs.kieler.klighd.lsp.launch.AbstractLanguageServer
import de.cau.cs.kieler.klighd.lsp.model.CheckImagesAction
import de.cau.cs.kieler.klighd.lsp.model.CheckedImagesAction
Expand All @@ -49,8 +48,11 @@ import java.io.InputStream
import java.util.ArrayList
import java.util.Base64
import java.util.Collection
import java.util.HashMap
import java.util.List
import java.util.Map
import java.util.ServiceLoader
import java.util.Set
import java.util.concurrent.CompletableFuture
import org.apache.log4j.Logger
import org.eclipse.core.runtime.Platform
Expand Down Expand Up @@ -90,11 +92,9 @@ import org.eclipse.xtend.lib.annotations.Accessors
class KGraphDiagramServer extends LanguageAwareDiagramServer {
static val LOG = Logger.getLogger(KGraphDiagramServer)

@Inject
protected LayeredInteractiveActionHandler constraintActionHandler
@Inject protected Injector injector

@Inject
protected RectpackingInteractiveActionHandler rectpackingActionHandler
Map<String, IActionHandler> handlers = new HashMap

@Inject
protected KGraphDiagramState diagramState
Expand Down Expand Up @@ -144,6 +144,13 @@ class KGraphDiagramServer extends LanguageAwareDiagramServer {
currentRoot = new SModelRoot();
currentRoot.setType("NONE");
currentRoot.setId("ROOT");
// Create map of registered action kinds and handlers.
ServiceLoader.load(IActionHandler, KlighdDataManager.getClassLoader()).forEach[handler |
val Set<String> kindsSupported = handler.supportedMessages.keySet
for (kind : kindsSupported) {
handlers.put(kind, handler);
}
]
}

/**
Expand Down Expand Up @@ -256,12 +263,16 @@ class KGraphDiagramServer extends LanguageAwareDiagramServer {
handle(action as RefreshLayoutAction)
} else if (action.getKind === RequestDiagramPieceAction.KIND) {
handle(action as RequestDiagramPieceAction)
} else if (constraintActionHandler.canHandleAction(action.getKind)) {
constraintActionHandler.handle(action, clientId, this)
} else if (rectpackingActionHandler.canHandleAction(action.getKind)) {
rectpackingActionHandler.handle(action, clientId, this)
} else {
super.accept(message)
val handlerInstance = handlers.get(action.kind)
if (handlerInstance !== null) {
// Even though we have an instance, it is not yet populated with all injected things.
val handler = injector.getInstance(handlers.get(action.kind).class)
handler.handle(action, clientId, this)
} else {
// If no handler is registered for this message. Let the default super class handle it.
super.accept(message)
}
}
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package de.cau.cs.kieler.klighd.lsp

import com.google.common.html.HtmlEscapers
import de.cau.cs.kieler.klighd.ViewContext
import de.cau.cs.kieler.klighd.kgraph.KEdge
import de.cau.cs.kieler.klighd.kgraph.KNode

/**
Expand Down Expand Up @@ -64,6 +65,26 @@ class LSPUtil {
}
}

/**
* Get a {@code KEdge} based by id.
*
* @param diagramState The state of the diagram
* @param uri The uri of the model file
* @param edgeId The id of the edge element
* @return the {@code KEdge} of the edge described by {@code id}.
* Returns null if the {@code ViewContext} of the resource described by {@code uri} is null.
* Returns null if the element behind the id is no kEdge.
*/
static def getKEdge(KGraphDiagramState diagramState, String uri, String edgeId) {
val kGraphElement = diagramState.getIdToKGraphMap(uri).get(edgeId)

if (kGraphElement instanceof KEdge) {
return kGraphElement as KEdge
} else {
return null
}
}

/**
* Escapes the given message to be safely displayable in a client context putting this message into an HTML page
* to avoid possibilities of XSS attacks and a clearly readable message. Uses Google Guava's {@link HtmlEscapers}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2018-2021 by
* Copyright 2018-2022 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand All @@ -17,33 +17,28 @@
package de.cau.cs.kieler.klighd.lsp.gson_utils

import com.google.gson.GsonBuilder
import com.google.inject.Injector
import de.cau.cs.kieler.klighd.KlighdDataManager
import de.cau.cs.kieler.klighd.SynthesisOption
import de.cau.cs.kieler.klighd.lsp.interactive.layered.DeleteLayerConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.layered.DeletePositionConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.layered.DeleteStaticConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.layered.SetLayerConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.layered.SetPositionConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.layered.SetStaticConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.rectpacking.RectpackingDeletePositionConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.rectpacking.RectpackingSetPositionConstraintAction
import de.cau.cs.kieler.klighd.lsp.interactive.rectpacking.SetAspectRatioAction
import de.cau.cs.kieler.klighd.lsp.IActionHandler
import de.cau.cs.kieler.klighd.lsp.model.CheckedImagesAction
import de.cau.cs.kieler.klighd.lsp.model.PerformActionAction
import de.cau.cs.kieler.klighd.lsp.model.RefreshDiagramAction
import de.cau.cs.kieler.klighd.lsp.model.RefreshLayoutAction
import de.cau.cs.kieler.klighd.lsp.model.RequestDiagramPieceAction
import de.cau.cs.kieler.klighd.lsp.model.SetSynthesisAction
import java.awt.geom.Point2D
import java.util.ServiceLoader
import org.eclipse.emf.ecore.EObject
import org.eclipse.sprotty.server.json.ActionTypeAdapter

/**
* Static util class to configure needed gson type adapters for KGraph serialization.
*
* @author nre
* @author nre, sdo
*/
class KGraphTypeAdapterUtil {
def static GsonBuilder configureGson(GsonBuilder gsonBuilder) {
def static GsonBuilder configureGson(GsonBuilder gsonBuilder, Injector injector) {
gsonBuilder
.registerTypeAdapterFactory(
new ActionTypeAdapter.Factory => [
Expand All @@ -54,21 +49,18 @@ class KGraphTypeAdapterUtil {
addActionKind(RefreshDiagramAction.KIND, RefreshDiagramAction)
addActionKind(RefreshLayoutAction.KIND, RefreshLayoutAction)

// Interactive layered actions
addActionKind(SetStaticConstraintAction.KIND, SetStaticConstraintAction)
addActionKind(SetPositionConstraintAction.KIND, SetPositionConstraintAction)
addActionKind(SetLayerConstraintAction.KIND, SetLayerConstraintAction)
addActionKind(DeleteStaticConstraintAction.KIND, DeleteStaticConstraintAction)
addActionKind(DeletePositionConstraintAction.KIND, DeletePositionConstraintAction)
addActionKind(DeleteLayerConstraintAction.KIND, DeleteLayerConstraintAction)

// Interactive rectpacking actions
addActionKind(RectpackingSetPositionConstraintAction.KIND, RectpackingSetPositionConstraintAction)
addActionKind(RectpackingDeletePositionConstraintAction.KIND, RectpackingDeletePositionConstraintAction)
addActionKind(SetAspectRatioAction.KIND, SetAspectRatioAction)
// Load all registered action handlers and add their actions.
ServiceLoader.load(IActionHandler, KlighdDataManager.getClassLoader()).forEach[handler |
val handlerInstance = injector.getInstance(handler.class)
handlerInstance.supportedMessages.keySet.forEach[kind |
addActionKind(kind, handlerInstance.supportedMessages.get(kind))
]
]

// Incremental topdown actions
addActionKind(RequestDiagramPieceAction.KIND, RequestDiagramPieceAction)


]
)
.registerTypeAdapter(Point2D, new Point2DTypeAdapter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import de.cau.cs.kieler.klighd.kgraph.KNode
* @author sdo
*/
@Data
class ConstraintProperty {
class ConstraintProperty<T> {
KNode kNode
IProperty<Integer> property
IProperty<T> property
T value
}
Loading