added ecore deserialization command

This commit is contained in:
JanikNex 2023-12-28 21:39:09 +01:00
parent 8b7b91ea36
commit 398148894d
4 changed files with 127 additions and 1 deletions

View file

@ -89,6 +89,11 @@
"command": "model-modeling-language.serializeToEMF",
"title": "Generate Ecore/XMI in workspace",
"category": "Model Modeling Language"
},
{
"command": "model-modeling-language.deserializeEcoreToMML",
"title": "Translate Ecore Model to MML",
"category": "Model Modeling Language"
}
],
"menus": {
@ -100,6 +105,10 @@
{
"command": "model-modeling-language.serializeToEMF",
"when": "false"
},
{
"command": "model-modeling-language.deserializeEcoreToMML",
"when": "false"
}
],
"explorer/context": [
@ -112,6 +121,11 @@
"when": "resourceExtname == .mml",
"command": "model-modeling-language.serializeToEMF",
"group": "navigation"
},
{
"when": "resourceExtname == .ecore",
"command": "model-modeling-language.deserializeEcoreToMML",
"group": "navigation"
}
],
"editor/context": [
@ -124,6 +138,11 @@
"when": "resourceLangId == model-modeling-language",
"command": "model-modeling-language.serializeToEMF",
"group": "navigation"
},
{
"when": "resourceExtname == .ecore && resourceScheme == file",
"command": "model-modeling-language.deserializeEcoreToMML",
"group": "navigation"
}
]
}

View file

@ -67,13 +67,28 @@ export function getSerializedWorkspace(client: LanguageClient, ...args: any[]):
});
}
export function writeToFile(enhancedSerializedWorkspace: EnhancedSerializedWorkspace): void {
export function writeSerializedWorkspaceToFile(enhancedSerializedWorkspace: EnhancedSerializedWorkspace): void {
const content: string = JSON.stringify(enhancedSerializedWorkspace.documents);
if (writeToFile(enhancedSerializedWorkspace.wsBasePath, `${enhancedSerializedWorkspace.wsName}.json`, content)) {
showUIMessage(MessageType.INFO, `Stored serialized workspace in ${enhancedSerializedWorkspace.wsName}.json`);
}
}
export function writeGeneratedMmlFile(sourceEcoreFile: vscode.Uri, fileName: string, content: string): void {
const workspace = vscode.workspace.getWorkspaceFolder(sourceEcoreFile);
if (workspace == undefined) {
showUIMessage(MessageType.ERROR, "Could not determine workspace!");
return;
}
const workspacePath = workspace.uri.fsPath;
const targetPath: fs.PathLike = path.join(workspacePath, "generated",);
if (writeToFile(targetPath, `${fileName}.mml`, content)) {
showUIMessage(MessageType.INFO, `Translated Ecore file to MML (${targetPath})`);
}
}
function writeToFile(targetParentDir: string, targetFileName: string, content: string): boolean {
let fd;
try {

View file

@ -0,0 +1,90 @@
import {ExtensionCommand, writeGeneratedMmlFile} from "./command-utils.js";
import {LanguageClient} from "vscode-languageclient/node.js";
import * as vscode from "vscode";
import {showUIMessage} from "../../shared/NotificationUtil.js";
import {MessageType} from "../../shared/MmlNotificationTypes.js";
import {spawn} from "node:child_process";
import {deserializeSerializedCLIDoc} from "../../language/deserializer/mml-deserializer.js";
export class DeserializeEcoreToMmlCommand extends ExtensionCommand {
constructor(client: LanguageClient, logger: vscode.OutputChannel) {
super("model-modeling-language.deserializeEcoreToMML", client, logger);
}
execute(...args: any[]): any {
if (args.length == 0 || args.length > 2 || (args.length == 2 && !Array.isArray(args.at(1)))) {
showUIMessage(MessageType.ERROR, `Unexpected file selection Please try again or report a bug!`);
showUIMessage(MessageType.INFO, JSON.stringify(args));
return;
} else if (args.length == 2 && args.at(1).length != 1) {
showUIMessage(MessageType.ERROR, `You must select a single Ecore file! (You selected ${args.at(1).length})`);
return;
}
const selection: vscode.Uri = args.at(0);
if (selection.scheme != "file") {
showUIMessage(MessageType.ERROR, `Invalid selection scheme: ${selection.scheme}`);
return;
}
showUIMessage(MessageType.INFO, `Got command! Selection: ${selection.fsPath}`);
const workspaceConfiguration = vscode.workspace.getConfiguration('model-modeling-language');
const connectorPath: string | undefined = workspaceConfiguration.get('cli.path');
const connectorCommand = `java -jar ${connectorPath} serialize ${selection.fsPath}`;
let serializedEcore: string = "";
let recordData: boolean = false;
this.logger.appendLine("[INFO] " + "======== Model Modeling Language CLI ========");
this.logger.appendLine("[INFO] " + connectorCommand);
this.logger.appendLine("[INFO] ");
const proc = spawn(connectorCommand, {shell: true});
proc.stdin.setDefaultEncoding('utf8');
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', (data) => {
this.logger.appendLine("[INFO] " + data);
if (typeof data === 'string') {
if (recordData) {
serializedEcore += data;
} else if (data.trim() == "=$MML-CONTENT-START$=") {
recordData = true;
}
}
});
proc.stderr.on('data', (data) => {
this.logger.appendLine("[ERROR] " + data);
showUIMessage(MessageType.ERROR, data);
});
proc.on('close', (code) => {
if (code == 0) {
this.logger.appendLine(`[COMPLETED] Received data!`);
const trimmed: string = serializedEcore.trim();
if (trimmed.startsWith("[{") && trimmed.endsWith("}]")) {
this.logger.appendLine(`[COMPLETED] Start deserializing...`);
const deserialized: {
modelName: string,
modelCode: string
} = deserializeSerializedCLIDoc(trimmed);
this.logger.appendLine(`[COMPLETED] ${deserialized.modelName}`);
this.logger.appendLine(`[COMPLETED] ${deserialized.modelCode}`);
writeGeneratedMmlFile(selection, deserialized.modelName, deserialized.modelCode);
} else {
this.logger.appendLine("=== RECEIVED ===");
this.logger.appendLine(trimmed);
showUIMessage(MessageType.ERROR, "Failed to parse CLI output!")
}
} else if (code == 1) {
showUIMessage(MessageType.ERROR, `Translation failed!`);
} else if (code == 2) {
showUIMessage(MessageType.ERROR, `Input failed!`);
}
});
}
}

View file

@ -4,6 +4,7 @@ import * as vscode from 'vscode';
import * as path from 'node:path';
import {SerializeToFileCommand} from "./commands/serialize-to-file-command.js";
import {SerializeToEmfCommand} from "./commands/serialize-to-emf-command.js";
import {DeserializeEcoreToMmlCommand} from "./commands/deserialize-ecore-to-mml-command.js";
let client: LanguageClient;
let logger: vscode.OutputChannel;
@ -66,4 +67,5 @@ function startLanguageClient(context: vscode.ExtensionContext): LanguageClient {
function registerCommands(context: vscode.ExtensionContext) {
new SerializeToFileCommand(client, logger).register(context);
new SerializeToEmfCommand(client, logger).register(context);
new DeserializeEcoreToMmlCommand(client, logger).register(context);
}