Skip to content

Commit

Permalink
Merge pull request #36 from eclipse-emfcloud/codegen
Browse files Browse the repository at this point in the history
#10 Finalize the integration of Code Generation
  • Loading branch information
CamilleLetavernier authored Sep 18, 2020
2 parents 779510e + 854875d commit c8667d7
Show file tree
Hide file tree
Showing 48 changed files with 1,036 additions and 314 deletions.
3 changes: 2 additions & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ pipeline {
container('ci'){
timeout(30){
dir('server'){
sh 'mvn clean verify --batch-mode package'
sh 'mvn --version'
sh 'mvn clean verify --batch-mode -Dmaven.repo.local=/home/jenkins/.m2/repository'
}
}
}
Expand Down
Binary file not shown.
81 changes: 81 additions & 0 deletions client/theia-ecore/src/browser/EcoreCommandContribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ export const NEW_ECORE_FILE: Command = {
label: "New Ecore-File"
};

export const GENERATE_GENMODEL_DEFAULT: Command = {
id: "file.generateGenModelDefault",
category: "File",
label: "Generate GenModel (with default Values)"
};

export const GENERATE_GENMODEL: Command = {
id: "file.generateGenModel",
category: "File",
label: "Generate GenModel"
};

export const GENERATE_CODE: Command = {
id: "file.generateCode",
category: "File",
label: "Generate Code"
};

@injectable()
export class EcoreCommandContribution implements CommandContribution {

Expand Down Expand Up @@ -101,6 +119,69 @@ export class EcoreCommandContribution implements CommandContribution {
}
})
}));
registry.registerCommand(GENERATE_GENMODEL_DEFAULT, this.newWorkspaceRootUriAwareCommandHandler({
execute: uri => this.getDirectory(uri).then(parent => {
if (parent) {
const parentUri = new URI(parent.uri);

this.fileGenServer.generateGenModel(parentUri.path.toString() ,uri.path.toString(), "", "").then(() => {
const extensionStart = uri.displayName.lastIndexOf(".");
const genmodelPath = parentUri.toString() + "/" + uri.displayName.substring(0, extensionStart) + ".genmodel";
const fileUri = new URI(genmodelPath);
open(this.openerService, fileUri);
});
}
})
}));
registry.registerCommand(GENERATE_GENMODEL, this.newWorkspaceRootUriAwareCommandHandler({
execute: uri => this.getDirectory(uri).then(parent => {
if (parent) {
const parentUri = new URI(parent.uri);

const showInput = (hint: string, prefix: string, onEnter: (result: string) => void): void => {
const quickOpenModel: QuickOpenModel = {
onType(lookFor: string, acceptor: (items: QuickOpenItem[]) => void): void {
const dynamicItems: QuickOpenItem[] = [];
const suffix = "Press 'Enter' to confirm or 'Escape' to cancel.";

dynamicItems.push(new SingleStringInputOpenItem(
`${prefix}: ${lookFor}. ${suffix}`,
() => onEnter(lookFor),
(mode: QuickOpenMode) => mode === QuickOpenMode.OPEN,
() => false
));

acceptor(dynamicItems);
}
};
this.quickOpenService.open(quickOpenModel, this.getOptions(hint, false));
};

showInput("Name", "Custom RootPackage Name", customPackageName => {
showInput("Output folder name (relative from project root)", "folder name", folderName => {
this.fileGenServer.generateGenModel(parentUri.path.toString() ,uri.path.toString(), customPackageName, folderName).then(() => {
const extensionStart = uri.displayName.lastIndexOf(".");
const genmodelPath = parentUri.toString() + "/" + uri.displayName.substring(0, extensionStart) + ".genmodel";
const fileUri = new URI(genmodelPath);
open(this.openerService, fileUri);
});
});
});
}
})
}));
registry.registerCommand(GENERATE_CODE, this.newWorkspaceRootUriAwareCommandHandler({
execute: uri => this.getDirectory(uri).then(parent => {
if (parent) {
const parentUri = new URI(parent.uri);
if(parentUri.parent){
this.fileGenServer.generateCode(uri.path.toString(), parentUri.parent.path.toString()).then(() => {
open(this.openerService, uri);
});
}
}
})
}));
}

protected withProgress<T>(task: () => Promise<T>): Promise<T> {
Expand Down
2 changes: 2 additions & 0 deletions client/theia-ecore/src/common/generate-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ export const FILEGEN_SERVICE_PATH = "/services/codegen";

export interface FileGenServer extends JsonRpcServer<undefined> {
generateEcore(name: string, prefix: string, uri: string, path: string): Promise<string>;
generateCode(genmodelPath: string, workspacePath: string): Promise<string>;
generateGenModel(workspacePath: string, ecorePath: string, customPackageName: string, folderName: string): Promise<string>;
}
106 changes: 89 additions & 17 deletions client/theia-ecore/src/node/ecore-file-generation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,19 @@ export class EcoreFileGenServer implements FileGenServer, BackendApplicationCont
@inject(ILogger) private readonly logger: ILogger) { }

generateEcore(name: string, prefix: string, uri: string, workspacePath: string): Promise<string> {
const jarPath = path.resolve(__dirname, "..", "..",
"server", "ecore-backend-server-1.0-SNAPSHOT-jar-with-dependencies.jar");
if (jarPath.length === 0) {
throw new Error("The EcoreGeneration.jar is not found. ");
}
const jarPath = this.getEclipseProductJar();

const command = "java";
const args: string[] = [];
let platformWorkspacePath = workspacePath;
if (os.platform() === "win32") {
platformWorkspacePath = workspacePath.substr(1);
}

args.push(
"-jar", jarPath,
"-name", name,
"-prefix", prefix,
"-uri", uri,
"-workspacePath", platformWorkspacePath
"-cp", jarPath,
"org.eclipse.equinox.launcher.Main",
"-application", "org.eclipse.emfcloud.ecore.backend.app.create-ecore",
name, prefix, uri, platformWorkspacePath
);

return new Promise(resolve => {
Expand All @@ -58,18 +52,84 @@ export class EcoreFileGenServer implements FileGenServer, BackendApplicationCont
process.process.on("exit", (code: any) => {
switch (code) {
case 0: resolve("OK"); break;
case -10: resolve("Name Parameter missing"); break;
case -11: resolve("NsPrefix Parameter missing"); break;
case -12: resolve("NsURI Parameter missing"); break;
case -13: resolve("Workspace Path Parameter missing"); break;
case -20: resolve("Encoding not found, check Server Log!"); break;
case -30: resolve("IO Exception occurred, check Server Log!"); break;
case -10: resolve("Name is missing"); break;
case -11: resolve("Prefix is missing"); break;
case -12: resolve("Uri is missing"); break;
case -13: resolve("Workspace Path is missing"); break;
default: resolve("UNKNOWN ERROR"); break;
}
});
});
}

generateGenModel(workspacePath: string,ecorePath: string, customPackageName: string, folderName: string): Promise<string> {
const jarPath = this.getEclipseProductJar();

const command = "java";
const args: string[] = [];
args.push(
"-cp", jarPath,
"org.eclipse.equinox.launcher.Main",
"-application", "org.eclipse.emfcloud.ecore.backend.app.create-genmodel",
ecorePath, customPackageName, folderName
);

return new Promise(resolve => {
const process = this.spawnProcess(command, args);
// eslint-disable-next-line no-null/no-null
if (process === undefined || process.process === undefined || process === null || process.process === null) {
resolve("Process not spawned");
return;
} else {
if (process.process.stdout){
process.process.stdout.on("data", function (data) {
console.log("stdout: " + data.toString());
});
}
}

process.process.on("exit", (code: any) => {
switch (code) {
case 0: resolve("OK"); break;
case -10: resolve("Ecore File Path is missing"); break;
case -11: resolve("Custom Root Package is missing"); break;
case -12: resolve("Outputfolder is missing"); break;
default: resolve("UNKNOWN ERROR " + code); break;
}
});
});
}

generateCode(genmodelPath: string, workspacePath: string): Promise<string> {
const jarPath = this.getEclipseProductJar();

const command = "java";
const args: string[] = [];
args.push(
"-cp", jarPath,
"org.eclipse.equinox.launcher.Main",
"-data", workspacePath,
"-application", "org.eclipse.emfcloud.ecore.backend.app.codegen",
genmodelPath
);

return new Promise(resolve => {
const process = this.spawnProcess(command, args);
// eslint-disable-next-line no-null/no-null
if (process === undefined || process.process === undefined || process === null || process.process === null) {
resolve("Process not spawned");
return;
}

process.process.on("exit", (code: any) => {
switch (code) {
case 0: resolve("OK"); break;
default: resolve("UNKNOWN ERROR " + code); break;
}
});
});
}

onStop(app?: Application): void {
this.dispose();
}
Expand All @@ -82,6 +142,18 @@ export class EcoreFileGenServer implements FileGenServer, BackendApplicationCont
// do nothing
}

private getEclipseProductJar(): string{
const jarPath = path.resolve(__dirname, "..", "..", "..", "..",
"server", "org.eclipse.emfcloud.ecore.backend-app", "org.eclipse.emfcloud.ecore.codegen.product",
"target", "products", "org.eclipse.emfcloud.ecore.codegen.product", "linux", "gtk", "x86_64", "plugins",
"org.eclipse.equinox.launcher_1.5.600.v20191014-2022.jar");
if (jarPath.length === 0) {
throw new Error("The eclipse.equinox.launcher is not found. ");
}

return jarPath;
}

private spawnProcess(command: string, args?: string[]): RawProcess | undefined {
const rawProcess = this.processFactory({ command, args });
if (rawProcess.process === undefined) {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions server/.project
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,15 @@
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
<filteredResources>
<filter>
<id>1599121354274</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
34 changes: 34 additions & 0 deletions server/org.eclipse.emfcloud.ecore.backend-app/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>backend-app</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
<filteredResources>
<filter>
<id>1599121354242</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
3 changes: 3 additions & 0 deletions server/org.eclipse.emfcloud.ecore.backend-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ecore GLSP Backend App

This folder contains the Eclipse Plug-ins for the Ecore GLSP Backend product. It provides an entry point for all Eclipse Applications involved in the Ecore GLSP Backend (GenModel creation, Code generation...)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.emfcloud.ecore.backend.app</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<filteredResources>
<filter>
<id>0</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ecore GLSP Backend
Bundle-SymbolicName: org.eclipse.emfcloud.ecore.backend.app;singleton:=true
Bundle-Version: 1.0.0.qualifier
Automatic-Module-Name: ecore.glsp.backend.app
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.equinox.app,
org.eclipse.emf.codegen.ecore;bundle-version="2.20.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml
source.. = src/
Loading

0 comments on commit c8667d7

Please sign in to comment.