diff --git a/build.gradle b/build.gradle index 6266c8e..918ded5 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,9 @@ group 'org.contextmapper' repositories { mavenCentral() + maven { + url "https://oss.sonatype.org/content/repositories/snapshots/" + } } configurations { diff --git a/cml.configuration.json b/cml.configuration.json index aa25710..d43e282 100644 --- a/cml.configuration.json +++ b/cml.configuration.json @@ -1,17 +1,13 @@ { "comments": { - // symbol used for single line comment. Remove this entry if your language does not support line comments "lineComment": "//", - // symbols used for start and end a block comment. Remove this entry if your language does not support block comments "blockComment": [ "/*", "*/" ] }, - // symbols used as brackets "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ], - // symbols that are auto closed when typing "autoClosingPairs": [ ["{", "}"], ["[", "]"], @@ -19,7 +15,6 @@ ["\"", "\""], ["'", "'"] ], - // symbols that that can be used to surround a selection "surroundingPairs": [ ["{", "}"], ["[", "]"], diff --git a/gradle.properties b/gradle.properties index de9fc64..e5e40d9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -cmlVersion=5.13.0 +cmlVersion=5.13.1-SNAPSHOT gradleNodePluginVersion=2.2.4 nodeVersion=10.16.0 npmVersion=6.10.2 diff --git a/package.json b/package.json index 98e3f64..e2f969d 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "Domain Modeling" ], "activationEvents": [ - "onLanguage:cml" + "onLanguage:cml", + "onLanguage:scl" ], "main": "out/extension", "contributes": { @@ -46,6 +47,18 @@ ".cml" ], "configuration": "./cml.configuration.json" + }, + { + "id": "scl", + "aliases": [ + "Service Cutter DSL", + "SCL", + "scl" + ], + "extensions": [ + ".scl" + ], + "configuration": "./scl.configuration.json" } ], "grammars": [ @@ -53,6 +66,11 @@ "language": "cml", "scopeName": "source.cml", "path": "./syntaxes/cml.tmLanguage.json" + }, + { + "language": "scl", + "scopeName": "source.scl", + "path": "./syntaxes/scl.tmLanguage.json" } ], "commands": [ @@ -75,6 +93,31 @@ "command": "cml.generate.contextmap.proxy", "title": "Generate Graphical Context Map", "when": "editorLangId == cml" + }, + { + "command": "cml.generate.new.service.cut.proxy", + "title": "Generate New Service Cut", + "when": "editorLangId == cml" + }, + { + "command": "cml.generate.servicecutter.input.proxy", + "title": "Generate Service Cutter Input (ERD as JSON)", + "when": "editorLangId == cml" + }, + { + "command": "cml.generate.servicecutter.user.representations.proxy", + "title": "Generate Service Cutter User Representations (SCL)", + "when": "editorLangId == cml" + }, + { + "command": "cml.generate.servicecutter.user.representation.example.file.proxy", + "title": "Generate Service Cutter User Representation Example File (SCL)", + "when": "editorLangId == cml" + }, + { + "command": "scl.generate.user.representations.json.file.proxy", + "title": "Generate Service Cutter User Representation JSON File", + "when": "editorLangId == scl" } ], "menus": { @@ -98,6 +141,31 @@ "when": "resourceLangId == cml", "command": "cml.generate.mdsl.proxy", "group": "cmlGenerators@4" + }, + { + "when": "resourceLangId == cml", + "command": "cml.generate.new.service.cut.proxy", + "group": "cmlGenerators@5" + }, + { + "when": "resourceLangId == cml", + "command": "cml.generate.servicecutter.input.proxy", + "group": "cmlGenerators@6" + }, + { + "when": "resourceLangId == cml", + "command": "cml.generate.servicecutter.user.representations.proxy", + "group": "cmlGenerators@7" + }, + { + "when": "resourceLangId == cml", + "command": "cml.generate.servicecutter.user.representation.example.file.proxy", + "group": "cmlGenerators@8" + }, + { + "when": "resourceLangId == scl", + "command": "scl.generate.user.representations.json.file.proxy", + "group": "sclGenerators@1" } ] }, diff --git a/scl.configuration.json b/scl.configuration.json new file mode 100644 index 0000000..d43e282 --- /dev/null +++ b/scl.configuration.json @@ -0,0 +1,25 @@ +{ + "comments": { + "lineComment": "//", + "blockComment": [ "/*", "*/" ] + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ] +} \ No newline at end of file diff --git a/src/commands/generators.ts b/src/commands/generators.ts index 8e4c60a..0de9514 100644 --- a/src/commands/generators.ts +++ b/src/commands/generators.ts @@ -3,10 +3,9 @@ */ import { commands, window, workspace, Uri, OpenDialogOptions, InputBoxOptions, TextDocumentShowOptions, ViewColumn } from "vscode"; -import * as editor from "../cml-editor/cml-editor"; +import * as editor from "../editors/cml-editor"; import { CommandType } from "./command" import * as fs from 'fs'; -import * as path from 'path'; export function generatePlantUML(): CommandType { return generate('cml.generate.puml', 'The PlantUML diagrams have been generated into the src-gen folder.'); @@ -77,6 +76,22 @@ export function generateContextMap(): CommandType { }; } +export function generateNewServiceCut(): CommandType { + return generate('cml.generate.new.service.cut', 'The new CML model (new service cut) has been created.'); +} + +export function generateServiceCutterInput(): CommandType { + return generate('cml.generate.servicecutter.input', 'The Service Cutter input file (JSON) has been generated into the src-gen folder.'); +} + +export function generateServiceCutterUserRepresentations(): CommandType { + return generate('cml.generate.servicecutter.user.representations', 'The Service Cutter user representations file (SCL) has been generated.'); +} + +export function generateServiceCutterUserRepresentationExampleFile(): CommandType { + return generate('cml.generate.servicecutter.user.representation.example.file', 'The Service Cutter user representation example file file (SCL) has been generated.'); +} + function generate(command: string, successMessage: string, ...additionalParameters: any[]): CommandType { return async () => { if (editor.isNotCMLEditor()) diff --git a/src/commands/sclGenerators.ts b/src/commands/sclGenerators.ts new file mode 100644 index 0000000..fb0b765 --- /dev/null +++ b/src/commands/sclGenerators.ts @@ -0,0 +1,28 @@ +/** + * SCL generator commands + */ + +import { commands, window, workspace, Uri, OpenDialogOptions, InputBoxOptions, TextDocumentShowOptions, ViewColumn } from "vscode"; +import * as editor from "../editors/scl-editor"; +import { CommandType } from "./command" + +export function generateServiceCutterUserRepresentationJSONFile(): CommandType { + return generate('scl.generate.user.representations.json.file', 'The JSON file has been generated into the src-gen folder.'); +} + +function generate(command: string, successMessage: string, ...additionalParameters: any[]): CommandType { + return async () => { + if (editor.isNotSCLEditor()) + return; + + if (editor.documentHasURI()) { + console.log(`Send command ${command} to SCL language server.`); + const returnVal: string = await commands.executeCommand(command, window.activeTextEditor.document.uri.toString(), additionalParameters); + if (returnVal.startsWith('Error occurred:')) { + window.showErrorMessage(returnVal); + } else { + window.showInformationMessage(successMessage); + } + } + }; +} diff --git a/src/commands/transformations.ts b/src/commands/transformations.ts index 01ecaa5..ac95ce4 100644 --- a/src/commands/transformations.ts +++ b/src/commands/transformations.ts @@ -3,7 +3,7 @@ */ import { commands, window, workspace, Uri, OpenDialogOptions, InputBoxOptions, TextDocumentShowOptions, ViewColumn } from "vscode"; -import * as editor from "../cml-editor/cml-editor"; +import * as editor from "../editors/cml-editor"; import { CommandType } from "./command" import * as input from "./userinput"; diff --git a/src/cml-editor/cml-editor.ts b/src/editors/cml-editor.ts similarity index 100% rename from src/cml-editor/cml-editor.ts rename to src/editors/cml-editor.ts diff --git a/src/editors/scl-editor.ts b/src/editors/scl-editor.ts new file mode 100644 index 0000000..452e010 --- /dev/null +++ b/src/editors/scl-editor.ts @@ -0,0 +1,14 @@ +/** + * Helper functions for SCL editor + */ + +import { window, Uri } from "vscode"; + +export function isNotSCLEditor(): boolean { + let activeEditor = window.activeTextEditor; + return !activeEditor || !activeEditor.document || activeEditor.document.languageId !== 'scl'; +} + +export function documentHasURI(): boolean { + return window.activeTextEditor.document.uri instanceof Uri; +} diff --git a/src/extension.ts b/src/extension.ts index 30a0ea3..1585bc3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,6 +7,7 @@ import { Trace } from 'vscode-jsonrpc'; import { commands, workspace, ExtensionContext, Uri, InputBoxOptions } from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions, VersionedTextDocumentIdentifier } from 'vscode-languageclient'; import * as generators from "./commands/generators"; +import * as sclGenerators from "./commands/sclGenerators"; import * as transformations from "./commands/transformations"; export function activate(context: ExtensionContext) { @@ -19,7 +20,7 @@ export function activate(context: ExtensionContext) { }; let clientOptions: LanguageClientOptions = { - documentSelector: ['cml'], + documentSelector: ['cml', 'scl'], synchronize: { fileEvents: workspace.createFileSystemWatcher('**/*.*') } @@ -30,10 +31,18 @@ export function activate(context: ExtensionContext) { // Register generator commands context.subscriptions.push( + // CML commands.registerCommand("cml.generate.puml.proxy", generators.generatePlantUML()), commands.registerCommand("cml.generate.mdsl.proxy", generators.generateMDSL()), commands.registerCommand("cml.generate.generic.text.file.proxy", generators.generateGenericTextFile()), - commands.registerCommand("cml.generate.contextmap.proxy", generators.generateContextMap()) + commands.registerCommand("cml.generate.contextmap.proxy", generators.generateContextMap()), + commands.registerCommand("cml.generate.new.service.cut.proxy", generators.generateNewServiceCut()), + commands.registerCommand("cml.generate.servicecutter.input.proxy", generators.generateServiceCutterInput()), + commands.registerCommand("cml.generate.servicecutter.user.representations.proxy", generators.generateServiceCutterUserRepresentations()), + commands.registerCommand("cml.generate.servicecutter.user.representation.example.file.proxy", generators.generateServiceCutterUserRepresentationExampleFile()), + + // SCL + commands.registerCommand("scl.generate.user.representations.json.file.proxy", sclGenerators.generateServiceCutterUserRepresentationJSONFile()) ); // Register OOAD transformation commands diff --git a/syntaxes/scl.tmLanguage.json b/syntaxes/scl.tmLanguage.json new file mode 100644 index 0000000..7f163d2 --- /dev/null +++ b/syntaxes/scl.tmLanguage.json @@ -0,0 +1,71 @@ +{ + "name": "Service Cutter DSL", + "scopeName": "source.scl", + "fileTypes": [ + "scl" + ], + "repository": { + "general": { + "patterns": [ + { + "include": "#linecomment" + }, + { + "include": "#blockcomment" + }, + { + "include": "#useCaseKeywords" + }, + { + "include": "#compatibilitiesKeywords" + }, + { + "include": "#commonSCLKeywords" + }, + { + "include": "#stringsSingle" + }, + { + "include": "#stringsDouble" + } + ] + }, + "linecomment": { + "name": "comment.line.double-dash.scl", + "begin": "(^[ \\t]+)?(?=//)", + "end": "(?=$)" + }, + "blockcomment": { + "name": "comment.block.scl", + "begin": "/\\*(\\*)?(?!/)", + "end": "\\*/" + }, + "useCaseKeywords": { + "name": "keyword.control.scl", + "match": "\\b(UseCase|isLatencyCritical|true|reads|writes)\\b" + }, + "compatibilitiesKeywords": { + "name": "keyword.control.scl", + "match": "\\b(Compatibilities|AvailabilityCriticality|characteristic|ConsistencyCriticality|ContentVolatility|SecurityCriticality|StorageSimilarity|StructuralVolatility)\\b" + }, + "commonSCLKeywords": { + "name": "keyword.control.scl", + "match": "\\b(Aggregate|Entity|PredefinedService|SecurityAccessGroup|SeparatedSecurityZone|SharedOwnerGroup)\\b" + }, + "stringsSingle": { + "name": "string.quoted.single.scl", + "begin": "'", + "end": "'" + }, + "stringsDouble": { + "name": "string.quoted.double.scl", + "begin": "\"", + "end": "\"" + } + }, + "patterns": [ + { + "include": "#general" + } + ] +} \ No newline at end of file