configurationService.ts 4.3 KB
Newer Older
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

J
Johannes Rieken 已提交
7
import { TPromise } from 'vs/base/common/winjs.base';
8
import * as objects from 'vs/base/common/objects';
9
import { getDefaultValues, toValuesTree, getConfigurationKeys } from 'vs/platform/configuration/common/model';
J
Johannes Rieken 已提交
10 11 12 13
import { ConfigWatcher } from 'vs/base/node/config';
import { Registry } from 'vs/platform/platform';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
B
Benjamin Pasero 已提交
14
import { IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, getConfigurationValue, IConfigurationKeys } from 'vs/platform/configuration/common/configuration';
J
Johannes Rieken 已提交
15 16 17
import Event, { Emitter } from 'vs/base/common/event';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
18

B
Benjamin Pasero 已提交
19
export class ConfigurationService<T> implements IConfigurationService, IDisposable {
20 21 22 23 24

	_serviceBrand: any;

	private disposables: IDisposable[];

B
Benjamin Pasero 已提交
25 26
	private rawConfig: ConfigWatcher<T>;
	private cache: T;
27 28 29

	private _onDidUpdateConfiguration: Emitter<IConfigurationServiceEvent>;

30 31
	private _telemetryService: ITelemetryService;

32 33 34 35 36 37 38 39 40 41 42
	constructor(
		@IEnvironmentService environmentService: IEnvironmentService
	) {
		this.disposables = [];

		this._onDidUpdateConfiguration = new Emitter<IConfigurationServiceEvent>();
		this.disposables.push(this._onDidUpdateConfiguration);

		this.rawConfig = new ConfigWatcher(environmentService.appSettingsPath, { changeBufferDelay: 300, defaultConfig: Object.create(null) });
		this.disposables.push(toDisposable(() => this.rawConfig.dispose()));

B
Benjamin Pasero 已提交
43
		// Listeners
44 45 46 47 48 49
		this.disposables.push(this.rawConfig.onDidUpdateConfiguration(event => {
			this.onConfigurationChange();
			if (this._telemetryService) {
				this._telemetryService.publicLog('updateUserConfiguration', { userConfigurationKeys: Object.keys(event.config) });
			}
		}));
B
Benjamin Pasero 已提交
50
		this.disposables.push(Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidRegisterConfiguration(() => this.onConfigurationChange()));
51 52 53 54 55 56 57 58 59 60 61 62
	}

	private onConfigurationChange(): void {
		this.cache = void 0; // reset our caches

		this._onDidUpdateConfiguration.fire({ config: this.getConfiguration() });
	}

	public get onDidUpdateConfiguration(): Event<IConfigurationServiceEvent> {
		return this._onDidUpdateConfiguration.event;
	}

63
	public reloadConfiguration<C>(section?: string): TPromise<C> {
B
Benjamin Pasero 已提交
64
		return new TPromise<C>(c => {
65 66 67
			this.rawConfig.reload(() => {
				this.cache = void 0; // reset our caches

B
Benjamin Pasero 已提交
68
				c(this.getConfiguration<C>(section));
69 70 71 72
			});
		});
	}

B
Benjamin Pasero 已提交
73
	public getConfiguration<C>(section?: string): C {
74 75 76 77 78 79 80 81 82
		let consolidatedConfig = this.cache;
		if (!consolidatedConfig) {
			consolidatedConfig = this.getConsolidatedConfig();
			this.cache = consolidatedConfig;
		}

		return section ? consolidatedConfig[section] : consolidatedConfig;
	}

B
Benjamin Pasero 已提交
83
	public lookup<C>(key: string): IConfigurationValue<C> {
84
		// make sure to clone the configuration so that the receiver does not tamper with the values
B
Benjamin Pasero 已提交
85
		return {
86
			default: objects.clone(getConfigurationValue<C>(getDefaultValues(), key)),
87
			user: objects.clone(getConfigurationValue<C>(toValuesTree(this.rawConfig.getConfig()), key)),
88
			value: objects.clone(getConfigurationValue<C>(this.getConfiguration(), key))
B
Benjamin Pasero 已提交
89 90 91
		};
	}

B
Benjamin Pasero 已提交
92 93 94 95 96 97 98
	public keys(): IConfigurationKeys {
		return {
			default: getConfigurationKeys(),
			user: Object.keys(this.rawConfig.getConfig())
		};
	}

B
Benjamin Pasero 已提交
99
	private getConsolidatedConfig(): T {
100
		const defaults = getDefaultValues();				// defaults coming from contributions to registries
101
		const user = toValuesTree(this.rawConfig.getConfig());	// user configured settings
102 103 104 105 106 107 108 109 110 111 112

		return objects.mixin(
			objects.clone(defaults), 	// target: default values (but dont modify!)
			user,						// source: user settings
			true						// overwrite
		);
	}

	public dispose(): void {
		this.disposables = dispose(this.disposables);
	}
113 114 115 116

	public set telemetryService(value: ITelemetryService) {
		this._telemetryService = value;
	}
117
}