diff --git a/eclipse-distribution/pom.xml b/eclipse-distribution/pom.xml
index 207e8961a..8c25bfeeb 100644
--- a/eclipse-distribution/pom.xml
+++ b/eclipse-distribution/pom.xml
@@ -225,7 +225,7 @@
orbit
p2
- http://download.eclipse.org/tools/orbit/downloads/drops/S20180302171354/repository/
+ http://download.eclipse.org/tools/orbit/downloads/drops/S20180504181223/repository/
+
maven-extras-mirror
p2
diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springsource/ide/eclipse/commons/frameworks/test/util/ACondition.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springsource/ide/eclipse/commons/frameworks/test/util/ACondition.java
index 69a7f96e6..a7da3ccb3 100644
--- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springsource/ide/eclipse/commons/frameworks/test/util/ACondition.java
+++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springsource/ide/eclipse/commons/frameworks/test/util/ACondition.java
@@ -238,9 +238,14 @@ public abstract class ACondition {
}
}
}
-
+
public static boolean inUIThread() {
- return Display.getDefault().getThread() == Thread.currentThread();
+ try {
+ return Display.getDefault().getThread() == Thread.currentThread();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
}
public static StringBuffer getStackDumps() {
diff --git a/theia-extensions/theia-cf-manifest-yaml/README.md b/theia-extensions/theia-cf-manifest-yaml/README.md
index 2ade37e3a..ea10ce590 100644
--- a/theia-extensions/theia-cf-manifest-yaml/README.md
+++ b/theia-extensions/theia-cf-manifest-yaml/README.md
@@ -14,6 +14,14 @@ Install npm and node.
Install yarn.
npm install -g yarn
+
+## Install dependencies
+
+Install dependencies and compile the code.
+
+ yarn
+
+Note: it is also running `yarn rebuild:browser` and `yarn rebuild:electron`, thus one could navigate to the proper folder and launch it
## Running the browser example
diff --git a/theia-extensions/theia-cf-manifest-yaml/cf-manifest-yaml/src/browser/cf-manifest-yaml-contribution.ts b/theia-extensions/theia-cf-manifest-yaml/cf-manifest-yaml/src/browser/cf-manifest-yaml-contribution.ts
deleted file mode 100644
index 5f1e97bbf..000000000
--- a/theia-extensions/theia-cf-manifest-yaml/cf-manifest-yaml/src/browser/cf-manifest-yaml-contribution.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { injectable, inject } from "inversify";
-import { CommandContribution, CommandRegistry, MenuContribution, MenuModelRegistry, MessageService } from "@theia/core/lib/common";
-import { CommonMenus } from "@theia/core/lib/browser";
-
-export const CfManifestYamlCommand = {
- id: 'CfManifestYaml.command',
- label: "Shows a message"
-};
-
-@injectable()
-export class CfManifestYamlCommandContribution implements CommandContribution {
-
- constructor(
- @inject(MessageService) private readonly messageService: MessageService,
- ) { }
-
- registerCommands(registry: CommandRegistry): void {
- registry.registerCommand(CfManifestYamlCommand, {
- execute: () => this.messageService.info('Hello World!')
- });
- }
-}
-
-@injectable()
-export class CfManifestYamlMenuContribution implements MenuContribution {
-
- registerMenus(menus: MenuModelRegistry): void {
- menus.registerMenuAction(CommonMenus.EDIT_FIND, {
- commandId: CfManifestYamlCommand.id,
- label: 'Say Hello'
- });
- }
-}
\ No newline at end of file
diff --git a/theia-extensions/theia-cf-manifest-yaml/cf-manifest-yaml/src/node/cf-manifest-yaml-contribution.ts b/theia-extensions/theia-cf-manifest-yaml/cf-manifest-yaml/src/node/cf-manifest-yaml-contribution.ts
index f1b13ae33..d21302eae 100644
--- a/theia-extensions/theia-cf-manifest-yaml/cf-manifest-yaml/src/node/cf-manifest-yaml-contribution.ts
+++ b/theia-extensions/theia-cf-manifest-yaml/cf-manifest-yaml/src/node/cf-manifest-yaml-contribution.ts
@@ -33,6 +33,7 @@ export class CfManifestYamlContribution extends BaseLanguageServerContribution {
'-Dsts.lsp.client=theia',
'-Dlsp.completions.indentation.enable=true',
'-Dlsp.yaml.completions.errors.disable=true',
+ '-Dorg.slf4j.simpleLogger.logFile=cf-manifest-yaml.log'
];
}
diff --git a/theia-extensions/theia-concourse/.gitignore b/theia-extensions/theia-concourse/.gitignore
new file mode 100644
index 000000000..efbb05f07
--- /dev/null
+++ b/theia-extensions/theia-concourse/.gitignore
@@ -0,0 +1,8 @@
+node_modules
+.browser_modules
+lib
+*.log
+*-app/*
+!*-app/package.json
+/**/server
+
diff --git a/theia-extensions/theia-concourse/.vscode/launch.json b/theia-extensions/theia-concourse/.vscode/launch.json
new file mode 100644
index 000000000..63be10364
--- /dev/null
+++ b/theia-extensions/theia-concourse/.vscode/launch.json
@@ -0,0 +1,60 @@
+{
+ // Use IntelliSense to learn about possible Node.js debug attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Start Browser Backend",
+ "program": "${workspaceRoot}/browser-app/src-gen/backend/main.js",
+ "args": [
+ "--loglevel=debug",
+ "--port=3000",
+ "--no-cluster"
+ ],
+ "env": {
+ "NODE_ENV": "development"
+ },
+ "sourceMaps": true,
+ "outFiles": [
+ "${workspaceRoot}/node_modules/@theia/*/lib/**/*.js",
+ "${workspaceRoot}/browser-app/lib/**/*.js",
+ "${workspaceRoot}/browser-app/src-gen/**/*.js"
+ ],
+ "smartStep": true,
+ "internalConsoleOptions": "openOnSessionStart",
+ "outputCapture": "std"
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Start Electron Backend",
+ "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
+ "windows": {
+ "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
+ },
+ "program": "${workspaceRoot}/electron-app/src-gen/frontend/electron-main.js",
+ "protocol": "inspector",
+ "args": [
+ "--loglevel=debug",
+ "--hostname=localhost",
+ "--no-cluster"
+ ],
+ "env": {
+ "NODE_ENV": "development"
+ },
+ "sourceMaps": true,
+ "outFiles": [
+ "${workspaceRoot}/electron-app/src-gen/frontend/electron-main.js",
+ "${workspaceRoot}/electron-app/src-gen/backend/main.js",
+ "${workspaceRoot}/electron-app/lib/**/*.js",
+ "${workspaceRoot}/node_modules/@theia/*/lib/**/*.js"
+ ],
+ "smartStep": true,
+ "internalConsoleOptions": "openOnSessionStart",
+ "outputCapture": "std"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/README.md b/theia-extensions/theia-concourse/README.md
new file mode 100644
index 000000000..99ad843ba
--- /dev/null
+++ b/theia-extensions/theia-concourse/README.md
@@ -0,0 +1,81 @@
+# Concourse Extension for Theia IDE
+The example of how to build the Theia-based applications with the concourse-extension.
+
+## Getting started
+
+Install [nvm](https://github.com/creationix/nvm#install-script).
+
+ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash
+
+Install npm and node.
+
+ nvm install 8
+ nvm use 8
+
+Install yarn.
+
+ npm install -g yarn
+
+## Install dependencies
+
+Install dependencies and compile the code.
+
+ yarn
+
+Note: it is also running `yarn rebuild:browser` and `yarn rebuild:electron`, thus one could navigate to the proper folder and launch it
+
+## Running the browser example
+
+ yarn rebuild:browser
+ cd browser-app
+ yarn start
+
+Open http://localhost:3000 in the browser.
+
+## Running the Electron example
+
+ yarn rebuild:electron
+ cd electron-app
+ yarn start
+
+## Developing with the browser example
+
+Start watching of the hello world extension.
+
+ cd concourse-extension
+ yarn watch
+
+Start watching of the browser example.
+
+ yarn rebuild:browser
+ cd browser-app
+ yarn watch
+
+Launch `Start Browser Backend` configuration from VS code.
+
+Open http://localhost:3000 in the browser.
+
+## Developing with the Electron example
+
+Start watching of the hello world extension.
+
+ cd concourse-extension
+ yarn watch
+
+Start watching of the electron example.
+
+ yarn rebuild:electron
+ cd electron-app
+ yarn watch
+
+Launch `Start Electron Backend` configuration from VS code.
+
+## Publishing concourse-extension
+
+Create a npm user and login to the npm registry, [more on npm publishing](https://docs.npmjs.com/getting-started/publishing-npm-packages).
+
+ npm login
+
+Publish packages with lerna to update versions properly across local packages, [more on publishing with lerna](https://github.com/lerna/lerna#publish).
+
+ npx lerna publish
diff --git a/theia-extensions/theia-concourse/browser-app/package.json b/theia-extensions/theia-concourse/browser-app/package.json
new file mode 100644
index 000000000..e29365f8f
--- /dev/null
+++ b/theia-extensions/theia-concourse/browser-app/package.json
@@ -0,0 +1,32 @@
+{
+ "private": true,
+ "name": "browser-app",
+ "version": "0.0.0",
+ "dependencies": {
+ "@theia/core": "latest",
+ "@theia/filesystem": "latest",
+ "@theia/workspace": "latest",
+ "@theia/preferences": "latest",
+ "@theia/navigator": "latest",
+ "@theia/process": "latest",
+ "@theia/terminal": "latest",
+ "@theia/editor": "latest",
+ "@theia/languages": "latest",
+ "@theia/markers": "latest",
+ "@theia/monaco": "latest",
+ "@theia/typescript": "latest",
+ "@theia/messages": "latest",
+ "@theia/concourse": "0.0.0"
+ },
+ "devDependencies": {
+ "@theia/cli": "latest"
+ },
+ "scripts": {
+ "prepare": "theia build",
+ "start": "theia start",
+ "watch": "theia build --watch"
+ },
+ "theia": {
+ "target": "browser"
+ }
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/concourse/package.json b/theia-extensions/theia-concourse/concourse/package.json
new file mode 100644
index 000000000..9c7a5148c
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "@theia/concourse",
+ "keywords": [
+ "theia-extension"
+ ],
+ "version": "0.0.0",
+ "files": [
+ "lib",
+ "src"
+ ],
+ "dependencies": {
+ "@theia/core": "latest",
+ "@theia/languages": "latest",
+ "@pivotal-tools/jvm-launch-utils": "0.0.11",
+ "@types/glob": "^5.0.30",
+ "glob": "^7.1.2"
+ },
+ "devDependencies": {
+ "rimraf": "latest",
+ "typescript": "latest",
+ "download": "^6.2.5"
+ },
+ "scripts": {
+ "prepare": "yarn run clean && yarn run download && yarn run build",
+ "download": "node script.js",
+ "clean": "rimraf lib",
+ "build": "tsc",
+ "watch": "tsc -w"
+ },
+ "theiaExtensions": [
+ {
+ "frontend": "lib/browser/concourse-frontend-module",
+ "backend": "lib/node/concourse-backend-module"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/concourse/properties.json b/theia-extensions/theia-concourse/concourse/properties.json
new file mode 100644
index 000000000..5ba610250
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/properties.json
@@ -0,0 +1,3 @@
+{
+ "jarUrl": "https://s3.amazonaws.com/dist.springsource.com/release/STS4/fatjars/concourse-language-server-0.2.1-201805111942.jar"
+}
diff --git a/theia-extensions/theia-concourse/concourse/script.js b/theia-extensions/theia-concourse/concourse/script.js
new file mode 100644
index 000000000..08321c90c
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/script.js
@@ -0,0 +1,34 @@
+const fs = require('fs');
+const path = require('path');
+const url = require('url');
+const glob = require('glob');
+const download = require('download');
+const PROPERTIES = require('./properties.json');
+
+let fileExists = function(path) {
+ return new Promise((resolve, reject) => {
+ fs.access(path, fs.R_OK, error => {
+ resolve(!error || error.code !== 'ENOENT');
+ })
+ });
+};
+
+const serverHome = path.join(__dirname, 'server');
+const filePaths = glob.sync('concourse-language-server*.jar', { cwd: serverHome });
+
+if (filePaths.length === 0) {
+ const serverDownloadUrl = PROPERTIES.jarUrl;
+ const fileName = path.basename(url.parse(serverDownloadUrl).pathname);
+ const localFileName = path.join(serverHome, fileName.startsWith('concourse-language-server') ? fileName : 'concourse-language-server.jar');
+ console.log(`Downloading ${serverDownloadUrl} to ${localFileName}`);
+ fileExists(serverHome)
+ .then(doesExist => { if (!doesExist) fs.mkdir(serverHome) })
+ .then(() => download(serverDownloadUrl))
+ .then(data => fs.writeFileSync(localFileName, data))
+ .then(() => fileExists(localFileName))
+ .then(doesExist => { if (!doesExist) throw Error(`Failed to install the ${this.getServerName()} language server`); })
+ .then(() => console.log(`Successfully downloaded ${serverDownloadUrl}`));
+}
+
+
+
diff --git a/theia-extensions/theia-concourse/concourse/src/browser/concourse-frontend-module.ts b/theia-extensions/theia-concourse/concourse/src/browser/concourse-frontend-module.ts
new file mode 100644
index 000000000..f93cc62f0
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/src/browser/concourse-frontend-module.ts
@@ -0,0 +1,16 @@
+/**
+ * Generated using theia-extension-generator
+ */
+
+import { ContainerModule } from "inversify";
+import { ConcourseClientContribution } from './language-client-contribution';
+import { LanguageClientContribution } from '@theia/languages/lib/browser';
+
+// Contribute monaco-editor languages for pipeline and task yaml
+import './pipeline-yaml-monaco-contribution';
+import './task-yaml-monaco-contribution';
+
+export default new ContainerModule(bind => {
+ // add your contribution bindings here
+ bind(LanguageClientContribution).to(ConcourseClientContribution).inSingletonScope();
+});
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/concourse/src/browser/language-client-contribution.ts b/theia-extensions/theia-concourse/concourse/src/browser/language-client-contribution.ts
new file mode 100644
index 000000000..dde18880c
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/src/browser/language-client-contribution.ts
@@ -0,0 +1,33 @@
+import { injectable, inject } from 'inversify';
+import { BaseLanguageClientContribution, Workspace, Languages, LanguageClientFactory } from '@theia/languages/lib/browser';
+import {
+ CONCOURSE_PIPELINE_YAML_LANGUAGE_ID, CONCOURSE_SERVER_ID, CONCOURSE_SERVER_NAME,
+ CONCOURSE_TASK_YAML_LANGUAGE_ID
+} from '../common';
+
+@injectable()
+export class ConcourseClientContribution extends BaseLanguageClientContribution {
+
+ readonly id = CONCOURSE_SERVER_ID;
+ readonly name = CONCOURSE_SERVER_NAME;
+
+ constructor(
+ @inject(Workspace) protected readonly workspace: Workspace,
+ @inject(Languages) protected readonly languages: Languages,
+ @inject(LanguageClientFactory) protected readonly languageClientFactory: LanguageClientFactory,
+ ) {
+ super(workspace, languages, languageClientFactory);
+ }
+
+ protected get documentSelector() {
+ return [CONCOURSE_PIPELINE_YAML_LANGUAGE_ID, CONCOURSE_TASK_YAML_LANGUAGE_ID];
+ }
+
+ protected get globPatterns() {
+ return [
+ '*pipeline*.yml',
+ '*task.yml',
+ '**/tasks/*.yml'
+ ];
+ }
+}
diff --git a/theia-extensions/theia-concourse/concourse/src/browser/pipeline-yaml-monaco-contribution.ts b/theia-extensions/theia-concourse/concourse/src/browser/pipeline-yaml-monaco-contribution.ts
new file mode 100644
index 000000000..642d7e0e2
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/src/browser/pipeline-yaml-monaco-contribution.ts
@@ -0,0 +1,26 @@
+///
+import {
+ CONCOURSE_PIPELINE_YAML_LANGUAGE_ID,
+ CONCOURSE_PIPELINE_YAML_LANGUAGE_NAME
+} from '../common';
+
+// Pipeline .yml file language registration
+
+let YAML_LANG_MODULE_PROMISE: monaco.Promise;
+
+monaco.languages.register({
+ id: CONCOURSE_PIPELINE_YAML_LANGUAGE_ID,
+ filenamePatterns: ['*pipeline*.yml'],
+ aliases: [CONCOURSE_PIPELINE_YAML_LANGUAGE_NAME, CONCOURSE_PIPELINE_YAML_LANGUAGE_ID],
+ firstLine: '^#(\\s)*pipeline(\\s)*',
+});
+
+monaco.languages.onLanguage(CONCOURSE_PIPELINE_YAML_LANGUAGE_ID, () => {
+ if (!YAML_LANG_MODULE_PROMISE) {
+ YAML_LANG_MODULE_PROMISE = (monaco.languages.getLanguages().find(ext => ext.id === 'yaml')).loader();
+ }
+ return YAML_LANG_MODULE_PROMISE.then(mod => {
+ monaco.languages.setLanguageConfiguration(CONCOURSE_PIPELINE_YAML_LANGUAGE_ID, mod.conf);
+ monaco.languages.setMonarchTokensProvider(CONCOURSE_PIPELINE_YAML_LANGUAGE_ID, mod.language);
+ })
+});
diff --git a/theia-extensions/theia-concourse/concourse/src/browser/task-yaml-monaco-contribution.ts b/theia-extensions/theia-concourse/concourse/src/browser/task-yaml-monaco-contribution.ts
new file mode 100644
index 000000000..16bfb30d0
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/src/browser/task-yaml-monaco-contribution.ts
@@ -0,0 +1,26 @@
+///
+import {
+ CONCOURSE_TASK_YAML_LANGUAGE_ID,
+ CONCOURSE_TASK_YAML_LANGUAGE_NAME
+} from '../common';
+
+// Task .yml file language registration
+
+let YAML_LANG_MODULE_PROMISE: monaco.Promise;
+
+monaco.languages.register({
+ id: CONCOURSE_TASK_YAML_LANGUAGE_ID,
+ filenamePatterns: ['*task.yml', '**/tasks/*.yml'],
+ aliases: [CONCOURSE_TASK_YAML_LANGUAGE_NAME, CONCOURSE_TASK_YAML_LANGUAGE_ID],
+ firstLine: '^#(\\\\s)*task(\\\\s)*',
+});
+
+monaco.languages.onLanguage(CONCOURSE_TASK_YAML_LANGUAGE_ID, () => {
+ if (!YAML_LANG_MODULE_PROMISE) {
+ YAML_LANG_MODULE_PROMISE = (monaco.languages.getLanguages().find(ext => ext.id === 'yaml')).loader();
+ }
+ return YAML_LANG_MODULE_PROMISE.then(mod => {
+ monaco.languages.setLanguageConfiguration(CONCOURSE_TASK_YAML_LANGUAGE_ID, mod.conf);
+ monaco.languages.setMonarchTokensProvider(CONCOURSE_TASK_YAML_LANGUAGE_ID, mod.language);
+ })
+});
diff --git a/theia-extensions/theia-concourse/concourse/src/common/index.ts b/theia-extensions/theia-concourse/concourse/src/common/index.ts
new file mode 100644
index 000000000..9863f022d
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/src/common/index.ts
@@ -0,0 +1,8 @@
+export const CONCOURSE_SERVER_ID = 'concourse-yaml';
+export const CONCOURSE_SERVER_NAME = 'Concourse YAML';
+
+export const CONCOURSE_PIPELINE_YAML_LANGUAGE_ID = 'concourse-pipeline-yaml';
+export const CONCOURSE_PIPELINE_YAML_LANGUAGE_NAME = 'Concourse Pipeline';
+
+export const CONCOURSE_TASK_YAML_LANGUAGE_ID = 'concourse-task-yaml';
+export const CONCOURSE_TASK_YAML_LANGUAGE_NAME = 'Concourse Task';
diff --git a/theia-extensions/theia-concourse/concourse/src/node/concourse-backend-module.ts b/theia-extensions/theia-concourse/concourse/src/node/concourse-backend-module.ts
new file mode 100644
index 000000000..2f7cc3800
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/src/node/concourse-backend-module.ts
@@ -0,0 +1,7 @@
+import { ContainerModule } from "inversify";
+import { LanguageServerContribution } from "@theia/languages/lib/node";
+import { ConcourseLanguageContribution } from './concourse-language-contribution';
+
+export default new ContainerModule(bind => {
+ bind(LanguageServerContribution).to(ConcourseLanguageContribution).inSingletonScope();
+});
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/concourse/src/node/concourse-language-contribution.ts b/theia-extensions/theia-concourse/concourse/src/node/concourse-language-contribution.ts
new file mode 100644
index 000000000..3fa3cbf0c
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/src/node/concourse-language-contribution.ts
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 TypeFox and others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+import * as path from 'path';
+import * as glob from 'glob';
+import { injectable } from 'inversify';
+// import { DEBUG_MODE } from '@theia/core/lib/node';
+import { IConnection, BaseLanguageServerContribution } from '@theia/languages/lib/node';
+import { CONCOURSE_SERVER_ID, CONCOURSE_SERVER_NAME } from '../common';
+import { findJvm } from '@pivotal-tools/jvm-launch-utils';
+
+
+@injectable()
+export class ConcourseLanguageContribution extends BaseLanguageServerContribution {
+
+ readonly id = CONCOURSE_SERVER_ID;
+ readonly name = CONCOURSE_SERVER_NAME;
+
+ start(clientConnection: IConnection): void {
+ const serverPath = path.resolve(__dirname, '../../server');
+ const jarPaths = glob.sync('concourse-language-server*.jar', { cwd: serverPath });
+ if (jarPaths.length === 0) {
+ throw new Error('The Concourse YAML server launcher is not found.');
+ }
+
+ const jarPath = path.resolve(serverPath, jarPaths[0]);
+ findJvm()
+ .catch(error => {
+ throw new Error('Error trying to find JVM');
+ })
+ .then(jvm => {
+ if (!jvm) {
+ throw new Error("Couldn't locate java in $JAVA_HOME or $PATH");
+ }
+
+ this.startSocketServer().then(server => {
+ const socket = this.accept(server);
+
+ // this.logInfo('logs at ' + path.resolve(workspacePath, '.metadata', '.log'));
+ const env = Object.create(process.env);
+ const addressInfo = server.address();
+ if (typeof addressInfo === 'string') {
+ throw new Error(`Address info was string ${addressInfo}`);
+ }
+ env.CLIENT_HOST = addressInfo.address;
+ env.CLIENT_PORT = addressInfo.port;
+ const command = jvm.getJavaExecutable();
+ const args = [
+ '-Dsts.lsp.client=theia',
+ '-Dlsp.completions.indentation.enable=true',
+ '-Dlsp.yaml.completions.errors.disable=true',
+ '-Dorg.slf4j.simpleLogger.logFile=concourse-yaml.log',
+ `-Dserver.port=${env.CLIENT_PORT}`
+ ];
+
+ // if (DEBUG_MODE) {
+ args.push(
+ '-Xdebug',
+ '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=7999',
+ '-Dlog.level=ALL'
+ );
+ // }
+
+ args.push(
+ '-jar', jarPath,
+ );
+
+ this.createProcessSocketConnection(socket, socket, command, args, { env })
+ .then(serverConnection => this.forward(clientConnection, serverConnection));
+ });
+
+ });
+
+ }
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/concourse/tsconfig.json b/theia-extensions/theia-concourse/concourse/tsconfig.json
new file mode 100644
index 000000000..7362f7bed
--- /dev/null
+++ b/theia-extensions/theia-concourse/concourse/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "strict": true,
+ "experimentalDecorators": true,
+ "noUnusedLocals": true,
+ "emitDecoratorMetadata": true,
+ "downlevelIteration": true,
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "target": "es5",
+ "lib": [
+ "es6",
+ "dom"
+ ],
+ "sourceMap": true,
+ "rootDir": "src",
+ "outDir": "lib"
+ },
+ "include": [
+ "src"
+ ]
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/electron-app/package.json b/theia-extensions/theia-concourse/electron-app/package.json
new file mode 100644
index 000000000..49dc6a5bb
--- /dev/null
+++ b/theia-extensions/theia-concourse/electron-app/package.json
@@ -0,0 +1,32 @@
+{
+ "private": true,
+ "name": "electron-app",
+ "version": "0.0.0",
+ "dependencies": {
+ "@theia/core": "latest",
+ "@theia/filesystem": "latest",
+ "@theia/workspace": "latest",
+ "@theia/preferences": "latest",
+ "@theia/navigator": "latest",
+ "@theia/process": "latest",
+ "@theia/terminal": "latest",
+ "@theia/editor": "latest",
+ "@theia/languages": "latest",
+ "@theia/markers": "latest",
+ "@theia/monaco": "latest",
+ "@theia/typescript": "latest",
+ "@theia/messages": "latest",
+ "@theia/concourse": "0.0.0"
+ },
+ "devDependencies": {
+ "@theia/cli": "latest"
+ },
+ "scripts": {
+ "prepare": "theia build",
+ "start": "theia start",
+ "watch": "theia build --watch"
+ },
+ "theia": {
+ "target": "electron"
+ }
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/lerna.json b/theia-extensions/theia-concourse/lerna.json
new file mode 100644
index 000000000..10fe79d90
--- /dev/null
+++ b/theia-extensions/theia-concourse/lerna.json
@@ -0,0 +1,11 @@
+{
+ "lerna": "2.4.0",
+ "version": "0.0.0",
+ "useWorkspaces": true,
+ "npmClient": "yarn",
+ "command": {
+ "run": {
+ "stream": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-concourse/package.json b/theia-extensions/theia-concourse/package.json
new file mode 100644
index 000000000..f41e91087
--- /dev/null
+++ b/theia-extensions/theia-concourse/package.json
@@ -0,0 +1,14 @@
+{
+ "private": true,
+ "scripts": {
+ "prepare": "lerna run prepare",
+ "rebuild:browser": "theia rebuild:browser",
+ "rebuild:electron": "theia rebuild:electron"
+ },
+ "devDependencies": {
+ "lerna": "2.4.0"
+ },
+ "workspaces": [
+ "concourse", "browser-app", "electron-app"
+ ]
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-spring-boot/README.md b/theia-extensions/theia-spring-boot/README.md
index eb4299772..021c7578d 100644
--- a/theia-extensions/theia-spring-boot/README.md
+++ b/theia-extensions/theia-spring-boot/README.md
@@ -16,6 +16,14 @@ Install yarn.
npm install -g yarn
+## Install dependencies
+
+Install dependencies and compile the code.
+
+ yarn
+
+Note: it is also running `yarn rebuild:browser` and `yarn rebuild:electron`, thus one could navigate to the proper folder and launch it
+
## Running the browser example
yarn rebuild:browser
@@ -32,7 +40,7 @@ Open http://localhost:3000 in the browser.
## Developing with the browser example
-Start watching of the hello world extension.
+Start watching of the extension.
cd spring-boot
yarn watch
@@ -49,7 +57,7 @@ Open http://localhost:3000 in the browser.
## Developing with the Electron example
-Start watching of the hello world extension.
+Start watching of extension.
cd spring-boot
yarn watch
diff --git a/theia-extensions/theia-spring-boot/spring-boot/package.json b/theia-extensions/theia-spring-boot/spring-boot/package.json
index 32258949d..ba4320b63 100644
--- a/theia-extensions/theia-spring-boot/spring-boot/package.json
+++ b/theia-extensions/theia-spring-boot/spring-boot/package.json
@@ -12,6 +12,7 @@
"dependencies": {
"@theia/core": "latest",
"@theia/languages": "latest",
+ "@theia/preferences": "latest",
"@theia/editor": "latest",
"@theia/monaco": "latest",
"@theia/java": "latest",
diff --git a/theia-extensions/theia-spring-boot/spring-boot/src/browser/boot-preferences.ts b/theia-extensions/theia-spring-boot/spring-boot/src/browser/boot-preferences.ts
new file mode 100644
index 000000000..7edd56671
--- /dev/null
+++ b/theia-extensions/theia-spring-boot/spring-boot/src/browser/boot-preferences.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 TypeFox and others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License'); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+import { interfaces } from 'inversify';
+import { createPreferenceProxy, PreferenceProxy, PreferenceService, PreferenceContribution, PreferenceSchema } from '@theia/core/lib/browser';
+
+// tslint:disable:max-line-length
+
+export const BootConfigSchema: PreferenceSchema = {
+ 'type': 'object',
+ 'title': 'Spring Boot Java Configuration',
+ properties: {
+ 'boot-java.boot-hints.on': {
+ type: 'boolean',
+ description: 'Enable/Disable Spring running Boot application live hints decorators in Java source code.',
+ default: true
+ },
+ 'spring-boot.ls.java.home': {
+ type: 'string',
+ description: `Override JAVA_HOME used for launching the spring-boot-language-server JVM process.`,
+ default: null
+ },
+ 'spring-boot.ls.java.heap': {
+ type: 'string',
+ description: `Max JVM heap value, passed via -Xmx argument when launching spring-boot-language-server JVM process.`,
+ default: null
+ }
+ }
+};
+
+export interface BootConfiguration {
+ 'boot-java.boot-hints.on': boolean;
+ 'spring-boot.ls.java.home': string | null;
+ 'spring-boot.ls.java.heap': string | null;
+}
+
+export const BootPreferences = Symbol('BootJavaPreferences');
+export type BootPreferences = PreferenceProxy;
+
+export function createBootPreferences(preferences: PreferenceService): BootPreferences {
+ return createPreferenceProxy(preferences, BootConfigSchema);
+}
+
+export function bindBootPreferences(bind: interfaces.Bind): void {
+ bind(BootPreferences).toDynamicValue(ctx => {
+ const preferences = ctx.container.get(PreferenceService);
+ return createBootPreferences(preferences);
+ });
+ bind(PreferenceContribution).toConstantValue({ schema: BootConfigSchema });
+}
diff --git a/theia-extensions/theia-spring-boot/spring-boot/src/browser/language-client-contribution.ts b/theia-extensions/theia-spring-boot/spring-boot/src/browser/language-client-contribution.ts
index 99d690890..d6d621802 100644
--- a/theia-extensions/theia-spring-boot/spring-boot/src/browser/language-client-contribution.ts
+++ b/theia-extensions/theia-spring-boot/spring-boot/src/browser/language-client-contribution.ts
@@ -1,4 +1,4 @@
-import { injectable, inject } from 'inversify';
+import { injectable, inject, postConstruct } from 'inversify';
import { BaseLanguageClientContribution, Workspace, Languages, LanguageClientFactory } from '@theia/languages/lib/browser';
import {
SPRING_BOOT_SERVER_ID,
@@ -10,6 +10,13 @@ import { DocumentSelector } from '@theia/languages/lib/common';
import { JAVA_LANGUAGE_ID } from '@theia/java/lib/common';
import { HighlightService} from './highlight-service';
import { ClasspathService } from './classpath-service';
+import { BootPreferences } from './boot-preferences';
+import { NotificationType } from 'vscode-jsonrpc';
+import { DidChangeConfigurationParams } from 'vscode-base-languageclient/lib/base';
+import { Utils } from './utils';
+
+const CONFIG_CHANGED_NOTIFICATION_TYPE = new NotificationType('workspace/didChangeConfiguration');
+
@injectable()
export class SpringBootClientContribution extends BaseLanguageClientContribution {
@@ -22,15 +29,35 @@ export class SpringBootClientContribution extends BaseLanguageClientContribution
@inject(Languages) protected readonly languages: Languages,
@inject(LanguageClientFactory) protected readonly languageClientFactory: LanguageClientFactory,
@inject(HighlightService) protected readonly highlightService: HighlightService,
- @inject(ClasspathService) protected readonly classpathService: ClasspathService
+ @inject(ClasspathService) protected readonly classpathService: ClasspathService,
+ @inject(BootPreferences) protected readonly preferences: BootPreferences
) {
super(workspace, languages, languageClientFactory);
+ }
+
+ @postConstruct()
+ protected async init() {
+ await this.preferences.ready;
+
+ // Send settings to LS
+ this.sendConfig();
+ this.preferences.onPreferenceChanged(() => this.sendConfig());
+
this.languageClient.then(client => {
this.highlightService.attach(client);
// this.classpathService.attach(client);
});
}
+ private sendConfig() {
+ return this.languageClient.then(client => {
+ const params = Utils.convertDotToNested(Object.assign({}, this.preferences));
+ return client.sendNotification(CONFIG_CHANGED_NOTIFICATION_TYPE, {
+ settings: params
+ });
+ })
+ }
+
protected get documentSelector(): DocumentSelector | undefined {
return [JAVA_LANGUAGE_ID, BOOT_PROPERTIES_YAML_LANGUAGE_ID, BOOT_PROPERTIES_LANGUAGE_ID];
}
diff --git a/theia-extensions/theia-spring-boot/spring-boot/src/browser/spring-boot-frontend-module.ts b/theia-extensions/theia-spring-boot/spring-boot/src/browser/spring-boot-frontend-module.ts
index c07f97fb2..82b85ea11 100644
--- a/theia-extensions/theia-spring-boot/spring-boot/src/browser/spring-boot-frontend-module.ts
+++ b/theia-extensions/theia-spring-boot/spring-boot/src/browser/spring-boot-frontend-module.ts
@@ -6,9 +6,11 @@ import './monaco-yaml-contribution';
import './monaco-properties-contribution';
import { HighlightService } from './highlight-service';
import { ClasspathService } from './classpath-service';
+import { bindBootPreferences } from './boot-preferences';
export default new ContainerModule(bind => {
// add your contribution bindings here
+ bindBootPreferences(bind);
bind(LanguageClientContribution).to(SpringBootClientContribution).inSingletonScope();
bind(HighlightService).toSelf().inSingletonScope();
bind(ClasspathService).toSelf().inSingletonScope();
diff --git a/theia-extensions/theia-spring-boot/spring-boot/src/browser/utils.ts b/theia-extensions/theia-spring-boot/spring-boot/src/browser/utils.ts
new file mode 100644
index 000000000..5b5f929c2
--- /dev/null
+++ b/theia-extensions/theia-spring-boot/spring-boot/src/browser/utils.ts
@@ -0,0 +1,27 @@
+export class Utils {
+
+ private static setNestedValue(properties: string[], value: any, obj: any){
+ if (properties.length > 1) {
+ // The property doesn't exists OR is not an object (and so we overwritte it) so we create it
+ if (!obj.hasOwnProperty(properties[0]) || typeof obj[properties[0]] !== 'object') {
+ obj[properties[0]] = {};
+ }
+ Utils.setNestedValue(properties.slice(1), value, obj[properties[0]]);
+ } else {
+ obj[properties[0]] = value;
+ }
+ }
+
+ public static convertDotToNested(source: any): any {
+ const result = {};
+ Object.keys(source).forEach(property => {
+ const properties = property.split('.');
+ if (source[property] && typeof source[property] === 'object') {
+ Utils.setNestedValue(properties, Utils.convertDotToNested(source[property]), result);
+ } else {
+ Utils.setNestedValue(properties, source[property], result);
+ }
+ });
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/theia-extensions/theia-spring-boot/spring-boot/src/node/spring-boot-ls-contribution.ts b/theia-extensions/theia-spring-boot/spring-boot/src/node/spring-boot-ls-contribution.ts
index 058158653..2a95f3ee7 100644
--- a/theia-extensions/theia-spring-boot/spring-boot/src/node/spring-boot-ls-contribution.ts
+++ b/theia-extensions/theia-spring-boot/spring-boot/src/node/spring-boot-ls-contribution.ts
@@ -56,8 +56,7 @@ export class SpringBootLsContribution extends BaseLanguageServerContribution {
'-Dsts.lsp.client=theia',
'-Dlsp.completions.indentation.enable=true',
'-Dlsp.yaml.completions.errors.disable=true',
- '-Dorg.slf4j.simpleLogger.logFile=boot-java.log',
- '-Dorg.slf4j.simpleLogger.defaultLogLevel=debug'
+ '-Dorg.slf4j.simpleLogger.logFile=boot-java.log'
];
args.push(`-Dserver.port=${env.CLIENT_PORT}`);