Skip to content
This repository has been archived by the owner on Jun 20, 2018. It is now read-only.

Commit

Permalink
Add Preference API (#30)
Browse files Browse the repository at this point in the history
* implement Preference API

Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
  • Loading branch information
akurinnoy authored and benoitf committed Jun 19, 2018
1 parent bdc0080 commit f29cc7b
Show file tree
Hide file tree
Showing 12 changed files with 567 additions and 46 deletions.
4 changes: 4 additions & 0 deletions packages/core/src/browser/preferences/preference-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ export class PreferenceServiceImpl implements PreferenceService, FrontendApplica
}
}

getPreferences(): { [key: string]: any } {
return this.preferences;
}

has(preferenceName: string): boolean {
return this.preferences[preferenceName] !== undefined;
}
Expand Down
8 changes: 5 additions & 3 deletions packages/plugin-ext/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
"dependencies": {
"@theia/core": "^0.3.11",
"@theia/filesystem": "^0.3.11",
"@theia/workspace": "^0.3.11",
"@theia/plugin": "^0.3.11",
"@theia/monaco": "^0.3.11",
"@theia/plugin": "^0.3.11",
"@theia/workspace": "^0.3.11",
"decompress": "^4.2.0",
"lodash.clonedeep": "^4.5.0",
"ps-tree": "1.1.0",
"vscode-uri": "^1.0.1"
},
Expand Down Expand Up @@ -50,7 +51,8 @@
},
"devDependencies": {
"@theia/ext-scripts": "^0.3.11",
"@types/decompress": "^4.2.2"
"@types/decompress": "^4.2.2",
"@types/lodash.clonedeep": "^4.5.3"
},
"nyc": {
"extends": "../../configs/nyc.json"
Expand Down
27 changes: 24 additions & 3 deletions packages/plugin-ext/src/api/plugin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import { QueryParameters } from '../common/env';
import { TextEditorCursorStyle } from '../common/editor-options';
import { TextEditorLineNumbersStyle, EndOfLine, OverviewRulerLane } from '../plugin/types-impl';
import { UriComponents } from '../common/uri-components';
import { PreferenceChange } from '@theia/core/lib/browser';
import { ConfigurationTarget } from '../plugin/types-impl';

export interface HostedPluginManagerExt {
$initialize(contextPath: string, pluginMedata: PluginMetadata): void;
$initialize(contextPath: string, pluginMetadata: PluginMetadata): void;
$loadPlugin(contextPath: string, plugin: Plugin): void;
$stopPlugin(contextPath: string): PromiseLike<void>;
}
Expand Down Expand Up @@ -379,14 +381,32 @@ export interface EnvExt {
$setQueryParameters(queryParams: QueryParameters): void;
}

export interface PreferenceRegistryMain {
$updateConfigurationOption(
target: boolean | ConfigurationTarget | undefined,
key: string,
value: any,
resource: any | undefined
): PromiseLike<void>;
$removeConfigurationOption(
target: boolean | ConfigurationTarget | undefined,
key: string,
resource: any | undefined
): PromiseLike<void>;
}
export interface PreferenceRegistryExt {
$acceptConfigurationChanged(data: { [key: string]: any }, eventData: PreferenceChange): void;
}

export const PLUGIN_RPC_CONTEXT = {
COMMAND_REGISTRY_MAIN: <ProxyIdentifier<CommandRegistryMain>>createProxyIdentifier<CommandRegistryMain>('CommandRegistryMain'),
QUICK_OPEN_MAIN: createProxyIdentifier<QuickOpenMain>('QuickOpenMain'),
MESSAGE_REGISTRY_MAIN: <ProxyIdentifier<MessageRegistryMain>>createProxyIdentifier<MessageRegistryMain>('MessageRegistryMain'),
TEXT_EDITORS_MAIN: createProxyIdentifier<TextEditorsMain>('TextEditorsMain'),
DOCUMENTS_MAIN: createProxyIdentifier<DocumentsMain>('DocumentsMain'),
STATUS_BAR_MESSAGE_REGISTRY_MAIN: <ProxyIdentifier<StatusBarMessageRegistryMain>>createProxyIdentifier<StatusBarMessageRegistryMain>('StatusBarMessageRegistryMain'),
ENV_MAIN: createProxyIdentifier<EnvMain>('EnvMain')
ENV_MAIN: createProxyIdentifier<EnvMain>('EnvMain'),
PREFERENCE_REGISTRY_MAIN: createProxyIdentifier<PreferenceRegistryMain>('PreferenceRegistryMain')
};

export const MAIN_RPC_CONTEXT = {
Expand All @@ -397,5 +417,6 @@ export const MAIN_RPC_CONTEXT = {
TEXT_EDITORS_EXT: createProxyIdentifier<TextEditorsExt>('TextEditorsExt'),
EDITORS_AND_DOCUMENTS_EXT: createProxyIdentifier<EditorsAndDocumentsExt>('EditorsAndDocumentsExt'),
DOCUMENTS_EXT: createProxyIdentifier<DocumentsExt>('DocumentsExt'),
ENV_EXT: createProxyIdentifier<EnvExt>('EnvExt')
ENV_EXT: createProxyIdentifier<EnvExt>('EnvExt'),
PREFERENCE_REGISTRY_EXT: createProxyIdentifier<PreferenceRegistryExt>('PreferenceRegistryExt')
};
17 changes: 17 additions & 0 deletions packages/plugin-ext/src/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (C) 2018 Red Hat, Inc. 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
*/

/**
* Returns `true` if the parameter has type "object" and not null, an array, a regexp, a date.
*/
export function isObject(obj: any): boolean {
return typeof obj === 'object'
&& obj !== null
&& !Array.isArray(obj)
&& !(obj instanceof RegExp)
&& !(obj instanceof Date);
}
89 changes: 52 additions & 37 deletions packages/plugin-ext/src/hosted/browser/hosted-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { MAIN_RPC_CONTEXT, Plugin } from '../../api/plugin-api';
import { setUpPluginApi } from '../../main/browser/main-context';
import { RPCProtocol, RPCProtocolImpl } from '../../api/rpc-protocol';
import { ILogger } from '@theia/core';
import { PreferenceServiceImpl } from '@theia/core/lib/browser';
@injectable()
export class HostedPluginSupport {
container: interfaces.Container;
Expand All @@ -26,69 +27,83 @@ export class HostedPluginSupport {
@inject(HostedPluginWatcher)
private readonly watcher: HostedPluginWatcher;

private theiaReadyPromise: Promise<any>;

constructor(
@inject(PreferenceServiceImpl) private readonly preferenceServiceImpl: PreferenceServiceImpl
) {
this.theiaReadyPromise = Promise.all([this.preferenceServiceImpl.ready]);
}

checkAndLoadPlugin(container: interfaces.Container): void {
this.container = container;
this.initPlugins();
}

public initPlugins(): void {
this.server.getHostedPlugin().then((pluginMedata: any) => {
if (pluginMedata) {
this.loadPlugin(pluginMedata, this.container);
this.server.getHostedPlugin().then((pluginMetadata: any) => {
if (pluginMetadata) {
this.loadPlugin(pluginMetadata, this.container);
}
});

const backendMetadatas = this.server.getDeployedBackendMetadata();
const backendMetadata = this.server.getDeployedBackendMetadata();

backendMetadatas.then((pluginMetadatas: PluginMetadata[]) => {
pluginMetadatas.forEach(pluginMetadata => this.loadPlugin(pluginMetadata, this.container));
backendMetadata.then((pluginMetadata: PluginMetadata[]) => {
pluginMetadata.forEach(metadata => this.loadPlugin(metadata, this.container));
});

this.server.getDeployedFrontendMetadata().then((pluginMetadatas: PluginMetadata[]) => {
pluginMetadatas.forEach(pluginMetadata => this.loadPlugin(pluginMetadata, this.container));
this.server.getDeployedFrontendMetadata().then((pluginMetadata: PluginMetadata[]) => {
pluginMetadata.forEach(metadata => this.loadPlugin(metadata, this.container));
});

}

public loadPlugin(pluginMedata: PluginMetadata, container: interfaces.Container): void {
const pluginModel = pluginMedata.model;
const pluginLifecycle = pluginMedata.lifecycle;
public loadPlugin(pluginMetadata: PluginMetadata, container: interfaces.Container): void {
const pluginModel = pluginMetadata.model;
const pluginLifecycle = pluginMetadata.lifecycle;
this.logger.info('Ask to load the plugin with model ', pluginModel, ' and lifecycle', pluginLifecycle);
if (pluginModel.entryPoint!.frontend) {
this.logger.info(`Loading frontend hosted plugin: ${pluginModel.name}`);
this.worker = new PluginWorker();
setUpPluginApi(this.worker.rpc, container);
const hostedExtManager = this.worker.rpc.getProxy(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT);
const plugin: Plugin = {
pluginPath: pluginModel.entryPoint.frontend!,
model: pluginModel,
lifecycle: pluginLifecycle
};
const frontendInitPath = pluginLifecycle.frontendInitPath;
if (frontendInitPath) {
hostedExtManager.$initialize(frontendInitPath, pluginMedata);
hostedExtManager.$loadPlugin(frontendInitPath, plugin);
} else {
hostedExtManager.$loadPlugin('', plugin);
}

this.theiaReadyPromise.then(() => {
const hostedExtManager = this.worker.rpc.getProxy(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT);
const plugin: Plugin = {
pluginPath: pluginModel.entryPoint.frontend!,
model: pluginModel,
lifecycle: pluginLifecycle
};
const frontendInitPath = pluginLifecycle.frontendInitPath;
if (frontendInitPath) {
hostedExtManager.$initialize(frontendInitPath, pluginMetadata);
hostedExtManager.$loadPlugin(frontendInitPath, plugin);
} else {
hostedExtManager.$loadPlugin('', plugin);
}
});
}
if (pluginModel.entryPoint!.backend) {
this.logger.info(`Loading backend hosted plugin: ${pluginModel.name}`);
const rpc = this.createServerRpc();
setUpPluginApi(rpc, container);
const hostedExtManager = rpc.getProxy(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT);
const plugin: Plugin = {
pluginPath: pluginModel.entryPoint.backend!,
model: pluginModel,
lifecycle: pluginLifecycle
};
const backendInitPath = pluginLifecycle.backendInitPath;
if (backendInitPath) {
hostedExtManager.$initialize(backendInitPath, pluginMedata);
hostedExtManager.$loadPlugin(backendInitPath, plugin);
} else {
hostedExtManager.$loadPlugin('', plugin);
}

this.theiaReadyPromise.then(() => {
const hostedExtManager = rpc.getProxy(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT);
const plugin: Plugin = {
pluginPath: pluginModel.entryPoint.backend!,
model: pluginModel,
lifecycle: pluginLifecycle
};
const backendInitPath = pluginLifecycle.backendInitPath;
if (backendInitPath) {
hostedExtManager.$initialize(backendInitPath, pluginMetadata);
hostedExtManager.$loadPlugin(backendInitPath, plugin);
} else {
hostedExtManager.$loadPlugin('', plugin);
}
});
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/plugin-ext/src/main/browser/main-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { interfaces } from 'inversify';
import { CommandRegistryMainImpl } from './command-registry-main';
import { PreferenceRegistryMainImpl } from './preference-registry-main';
import { QuickOpenMainImpl } from './quick-open-main';
import { RPCProtocol } from '../../api/rpc-protocol';
import { PLUGIN_RPC_CONTEXT } from '../../api/plugin-api';
Expand All @@ -26,6 +27,9 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
const messageRegistryMain = new MessageRegistryMainImpl(container);
rpc.set(PLUGIN_RPC_CONTEXT.MESSAGE_REGISTRY_MAIN, messageRegistryMain);

const preferenceRegistryMain = new PreferenceRegistryMainImpl(rpc, container);
rpc.set(PLUGIN_RPC_CONTEXT.PREFERENCE_REGISTRY_MAIN, preferenceRegistryMain);

// tslint:disable-next-line:no-unused-variable
// @ts-ignore
const windowStateMain = new WindowStateMain(rpc);
Expand Down
61 changes: 61 additions & 0 deletions packages/plugin-ext/src/main/browser/preference-registry-main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2018 Red Hat, Inc. 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 {
PreferenceService,
PreferenceServiceImpl,
PreferenceScope
} from '@theia/core/lib/browser/preferences';
import { interfaces } from 'inversify';
import {
MAIN_RPC_CONTEXT,
PreferenceRegistryExt,
PreferenceRegistryMain,
} from '../../api/plugin-api';
import { RPCProtocol } from '../../api/rpc-protocol';
import { ConfigurationTarget } from '../../plugin/types-impl';

export class PreferenceRegistryMainImpl implements PreferenceRegistryMain {
private proxy: PreferenceRegistryExt;
private preferenceService: PreferenceService;

constructor(prc: RPCProtocol, container: interfaces.Container) {
this.proxy = prc.getProxy(MAIN_RPC_CONTEXT.PREFERENCE_REGISTRY_EXT);
this.preferenceService = container.get(PreferenceService);
const preferenceServiceImpl = container.get(PreferenceServiceImpl);

preferenceServiceImpl.onPreferenceChanged(e => {
this.proxy.$acceptConfigurationChanged(preferenceServiceImpl.getPreferences(), e);
});
}

$updateConfigurationOption(target: boolean | ConfigurationTarget | undefined, key: string, value: any): PromiseLike<void> {
const scope = this.parseConfigurationTarget(target);
return this.preferenceService.set(key, value, scope);
}

$removeConfigurationOption(target: boolean | ConfigurationTarget | undefined, key: string): PromiseLike<void> {
const scope = this.parseConfigurationTarget(target);
return this.preferenceService.set(key, undefined, scope);
}

private parseConfigurationTarget(arg?: boolean | ConfigurationTarget): PreferenceScope {
if (arg === void 0 || arg === null) {
return PreferenceScope.Workspace;
}
if (typeof arg === 'boolean') {
return arg ? PreferenceScope.User : PreferenceScope.Workspace;
}

if (arg === ConfigurationTarget.User) {
return PreferenceScope.User;
} else {
return PreferenceScope.Workspace;
}
}

}
10 changes: 10 additions & 0 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { WindowStateExtImpl } from './window-state';
import { EnvExtImpl } from './env';
import { QueryParameters } from '../common/env';
import {
ConfigurationTarget,
Disposable,
Position,
Range,
Expand All @@ -39,6 +40,7 @@ import { TextEditorsExtImpl } from './text-editors';
import { DocumentsExtImpl } from './documents';
import Uri from 'vscode-uri';
import { TextEditorCursorStyle } from '../common/editor-options';
import { PreferenceRegistryExtImpl } from './preference-registry';

export function createAPI(rpc: RPCProtocol): typeof theia {
const commandRegistryExt = rpc.set(MAIN_RPC_CONTEXT.COMMAND_REGISTRY_EXT, new CommandRegistryImpl(rpc));
Expand All @@ -50,6 +52,7 @@ export function createAPI(rpc: RPCProtocol): typeof theia {
const documents = rpc.set(MAIN_RPC_CONTEXT.DOCUMENTS_EXT, new DocumentsExtImpl(rpc, editorsAndDocuments));
const statusBarMessageRegistryExt = new StatusBarMessageRegistryExt(rpc);
const envExt = rpc.set(MAIN_RPC_CONTEXT.ENV_EXT, new EnvExtImpl(rpc));
const preferenceRegistryExt = rpc.set(MAIN_RPC_CONTEXT.PREFERENCE_REGISTRY_EXT, new PreferenceRegistryExtImpl(rpc));

const commands: typeof theia.commands = {
// tslint:disable-next-line:no-any
Expand Down Expand Up @@ -155,6 +158,12 @@ export function createAPI(rpc: RPCProtocol): typeof theia {
onDidOpenTextDocument(listener, thisArg?, disposables?) {
return documents.onDidAddDocument(listener, thisArg, disposables);
},
getConfiguration(section?, resource?): theia.WorkspaceConfiguration {
return preferenceRegistryExt.getConfiguration(section, resource);
},
onDidChangeConfiguration(listener, thisArgs?, disposables?): theia.Disposable {
return preferenceRegistryExt.onDidChangeConfiguration(listener, thisArgs, disposables);
}
};

const env: typeof theia.env = {
Expand Down Expand Up @@ -194,6 +203,7 @@ export function createAPI(rpc: RPCProtocol): typeof theia {
SnippetString,
DecorationRangeBehavior,
OverviewRulerLane,
ConfigurationTarget,
};

}
Expand Down
Loading

0 comments on commit f29cc7b

Please sign in to comment.