Skip to content

Commit

Permalink
lsp.interative: Removed ls and lsClient from constraint serializer.
Browse files Browse the repository at this point in the history
  • Loading branch information
soerendomroes committed Mar 13, 2024
1 parent 2c49cff commit 0d7b948
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* KIELER - Kiel Integrated Environment for Layout Eclipse RichClient
*
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2022 by
Expand All @@ -11,63 +11,42 @@
* 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.interactive

import de.cau.cs.kieler.klighd.internal.util.KlighdInternalProperties
import de.cau.cs.kieler.klighd.lsp.KGraphLanguageClient
import de.cau.cs.kieler.klighd.lsp.KGraphLanguageServerExtension
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
import org.eclipse.emf.ecore.resource.Resource

/**
* 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,

override serializeConstraints(
List<ConstraintProperty<Object>> changedNodes,
Object graph,
String uri,
KGraphLanguageServerExtension ls,
KGraphLanguageClient client
Resource resource
) {
// 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 codeBefore = InteractiveUtil.serializeResource(resource)
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)
val codeAfter = InteractiveUtil.serializeResource(resource)

return InteractiveUtil.calculateTextEdit(codeBefore, codeAfter)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
*/
package de.cau.cs.kieler.klighd.lsp.interactive

import de.cau.cs.kieler.klighd.lsp.KGraphLanguageClient
import de.cau.cs.kieler.klighd.lsp.KGraphLanguageServerExtension
import java.util.List
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.lsp4j.TextEdit

/**
* Service interface for implementations that serialize a set constraint in the model.
Expand All @@ -40,10 +40,8 @@ interface IConstraintSerializer {
/**
* @param changedNodes The added constraints.
* @param graph The model, e.g. SCChart or ElkGraph.
* @param uri The uri of the main source file.
* @param ls The language server.
* @param client The language client.
* @param resource The resource to change
* @return The TextEdit to send to the client consisting of the new text and a range.
*/
def void serializeConstraints(List<ConstraintProperty<Object>> changedNodes, Object graph, String uri,
KGraphLanguageServerExtension ls, KGraphLanguageClient client);
def TextEdit serializeConstraints(List<ConstraintProperty<Object>> changedNodes, Object graph, Resource resource);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ import de.cau.cs.kieler.klighd.kgraph.KIdentifier
import de.cau.cs.kieler.klighd.kgraph.KNode
import de.cau.cs.kieler.klighd.lsp.KGraphLanguageClient
import de.cau.cs.kieler.klighd.lsp.KGraphLanguageServerExtension
import java.io.ByteArrayOutputStream
import java.util.ArrayList
import java.util.List
import java.util.ServiceLoader
import org.eclipse.elk.alg.layered.options.LayeredOptions
import org.eclipse.elk.graph.ElkNode
import org.eclipse.elk.graph.properties.IProperty
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.TextEdit

/**
* Provides utility methods for interactive layout.
Expand Down Expand Up @@ -186,16 +191,48 @@ class InteractiveUtil {
for (IConstraintSerializer cs : ServiceLoader.load(IConstraintSerializer,
KlighdDataManager.getClassLoader())) {
if (cs.canHandle(sourceModel)) {
cs.serializeConstraints(changedNodes, model, uri, languageServer, client)
val resource = languageServer.getResource(uri)
val textEdit = cs.serializeConstraints(changedNodes, model, resource)
// Send changes to the client.
client.replaceContentInFile(uri, textEdit.newText, textEdit.range)
// If a serializer is registered, we do not need to update the layout since the diagram will update
// since the model changes.
serializer = true
}
}
// If there is no serializer that changes the textual model (which will cause a refresh model action),
// we have to update the layout (not refresh the layout) to update based on the changed via model.
if (!serializer) {
languageServer.updateLayout(uri)
}
return
}

/**
* Creates a string of a model resource by saving the resource and returning the output string.
*
* @param resource Resource to get the string for.
*/
static def String serializeResource(Resource resource) {
var outputStream = new ByteArrayOutputStream
resource.save(outputStream, emptyMap)
return outputStream.toString
}

/**
* Creates a TextEdit based on the before and after text.
*
* @param codeBefore The whole text before
* @param codeAfter The new text
* @return A TextEdit that assumes that the whole code before will ne replaced.
*/
static def TextEdit calculateTextEdit(String codeBefore, String codeAfter) {
val lines = codeBefore.split("\r\n|\r|\n")
val lastLineLength = lines.get(lines.size - 1).length
val Range range = new Range(new Position(0, 0), new Position(lines.length, lastLineLength))
return new TextEdit(range, codeAfter)
}

/**
* Returns id of a node.
*
Expand Down

0 comments on commit 0d7b948

Please sign in to comment.