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

Add Preference API #30

Merged
merged 4 commits into from
Jun 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK it was me that added it with a wrong name :o

$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);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is update method?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getConfiguration returns an object with WorkspaceConfiguration interface. There is method update implemented.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

};

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