/* tslint:disable */ import { injectable, inject } from 'inversify'; import { IWorkspaceFolder, IWorkspaceData, IConfigurationService, WorkbenchState, IConfigurationChangeEvent, IWorkspaceFoldersChangeEvent, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, IConfigurationData, IConfigurationOverrides, IWorkspaceContextService, ConfigurationTarget, IConfigurationModel, IClientWorkspaceContextService, } from '../../interfaces'; import { basenameOrAuthority, dirname, isEqual, relativePath } from '@vscode-alt/monaco-editor/esm/vs/base/common/resources'; import { Workspace, WorkspaceFolder, ConfigurationModel, isConfigurationOverrides, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, ConfigurationChangeEvent } from '../../core'; import { WorkspaceConfiguration as Configuration } from '../../core/workspace/configuration'; import { URI } from '@vscode-alt/monaco-editor/esm/vs/base/common/uri'; import { Event, Emitter } from '@vscode-alt/monaco-editor/esm/vs/base/common/event'; import { ResourceMap } from '@vscode-alt/monaco-editor/esm/vs/base/common/map'; import { Disposable } from '@vscode-alt/monaco-editor/esm/vs/base/common/lifecycle'; import { Queue, Barrier } from '@vscode-alt/monaco-editor/esm/vs/base/common/async'; // import * as ILogger from 'bunyan'; import { CommonType } from '@common-stack/core'; import { CdmLogger } from '@cdm-logger/core'; type ILogger = CdmLogger.ILogger; @injectable() export abstract class AbstractWorkspaceService extends Disposable implements IConfigurationService, IClientWorkspaceContextService { protected workspace: Workspace; protected completeWorkspaceBarrier: Barrier; protected updateWorkspaceBarrier: Barrier; private _configuration: Configuration; protected logger: ILogger; protected readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); public readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; protected readonly _onDidChangeWorkspaceFolders: Emitter = this._register(new Emitter()); public readonly onDidChangeWorkspaceFolders: Event = this._onDidChangeWorkspaceFolders.event; protected readonly _onDidChangeWorkspaceName: Emitter = this._register(new Emitter()); public readonly onDidChangeWorkspaceName: Event = this._onDidChangeWorkspaceName.event; protected readonly _onDidChangeWorkbenchState: Emitter = this._register(new Emitter()); public readonly onDidChangeWorkbenchState: Event = this._onDidChangeWorkbenchState.event; constructor( @inject(CommonType.LOGGER) logger: ILogger, ) { super(); this.logger = logger.child({ className: 'AbstractWorkspaceService' }) this.completeWorkspaceBarrier = new Barrier(); } public abstract extInitialize(); public abstract initialize(args); public getCompleteWorkspace(): Promise { return this.completeWorkspaceBarrier.wait().then(() => this.getWorkspace()); } public getWorkspace(): Workspace { return this.workspace; } public getWorkbenchState(): WorkbenchState { // Workspace has configuration file if (this.workspace.configuration) { return WorkbenchState.WORKSPACE; } // Folder has single root if (this.workspace.folders.length === 1) { return WorkbenchState.FOLDER; } // Empty return WorkbenchState.EMPTY; } get configuration() { return this._configuration; } set configuration(configuration: Configuration) { this._configuration = configuration; } public getWorkspaceFolder(resource: URI): IWorkspaceFolder | null { return this.workspace.getFolder(resource); } abstract addFolders(foldersToAdd: IWorkspaceFolderCreationData[], index?: number): Promise; abstract removeFolders(foldersToRemove: URI[]): Promise; abstract updateFolders(foldersToAdd: IWorkspaceFolderCreationData[], foldersToRemove: URI[], index?: number): Promise; public isInsideWorkspace(resource: URI): boolean { return !!this.getWorkspaceFolder(resource); } public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean { switch (this.getWorkbenchState()) { case WorkbenchState.FOLDER: return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && isEqual(workspaceIdentifier, this.workspace.folders[0].uri); case WorkbenchState.WORKSPACE: return isWorkspaceIdentifier(workspaceIdentifier) && this.workspace.id === workspaceIdentifier.id; } return false; } public getConfigurationData(): IConfigurationData { return this.configuration.toData(); } public extAcceptConfigurationChanged(data: IConfigurationData, event: IConfigurationChangeEvent) { this._configuration = AbstractWorkspaceService.parse(data); // this._confugrationScopes = data.configurationScopes; this._onDidChangeConfiguration.fire(event); } public extAcceptChangedWorkbenchState(workspace: IWorkspaceData, event: WorkbenchState) { this.workspace = this.reviveWorkspaceUris(workspace); this._onDidChangeWorkbenchState.fire(event); this.releaseUpdateWorkspaceBarrier(); } public extAcceptChangedWorkspaceFolders(workspace: IWorkspaceData, event: IWorkspaceFoldersChangeEvent) { this.workspace = this.reviveWorkspaceUris(workspace); this._onDidChangeWorkspaceFolders.fire(event); this.releaseUpdateWorkspaceBarrier(); } public extAcceptChangedWorkspaceName(workspace: IWorkspaceData) { this.workspace = this.reviveWorkspaceUris(workspace); this._onDidChangeWorkspaceName.fire(); this.releaseUpdateWorkspaceBarrier(); } public getValue(): T; public getValue(section: string): T; public getValue(overrides: IConfigurationOverrides): T; public getValue(section: string, overrides: IConfigurationOverrides): T; public getValue(arg1?: any, arg2?: any): any { const section = typeof arg1 === 'string' ? arg1 : undefined; const overrides = isConfigurationOverrides(arg1) ? arg1 : isConfigurationOverrides(arg2) ? arg2 : {}; return this.configuration.getValue(section, overrides); } public abstract updateValue(key: string, value: any): Promise; public abstract updateValue(key: string, value: any, overrides: IConfigurationOverrides): Promise; public abstract updateValue(key: string, value: any, target: ConfigurationTarget): Promise; public abstract updateValue(key: string, value: any, overrides: IConfigurationOverrides, target: ConfigurationTarget): Promise; public abstract updateValue(key: string, value: any, overrides: IConfigurationOverrides, target: ConfigurationTarget, donotNotifyError: boolean): Promise; public abstract updateValue(key: string, value: any, arg3?: any, arg4?: any, donotNotifyError?: any): Promise public abstract reloadConfiguration(folder?: IWorkspaceFolder): Promise; inspect(key: string, overrides?: IConfigurationOverrides): { default: T, user: T, userLocal?: T, userRemote?: T, workspace?: T, workspaceFolder?: T, memory?: T, value: T } { return this._configuration.inspect(key, overrides); } keys(): { default: string[]; user: string[]; workspace: string[]; workspaceFolder: string[]; } { return this._configuration.keys(); } triggerConfigurationChange(arg0: any, WORKSPACE: any) { throw new Error("Method not implemented."); } public static parse(data: IConfigurationData): Configuration { const defaultConfiguration = AbstractWorkspaceService.parseConfigurationModel(data.defaults); const userConfiguration = AbstractWorkspaceService.parseConfigurationModel(data.user); const workspaceConfiguration = AbstractWorkspaceService.parseConfigurationModel(data.workspace); const folders: ResourceMap = Object.keys(data.folders).reduce((result, key) => { result.set(URI.parse(key), AbstractWorkspaceService.parseConfigurationModel(data.folders[key])); return result; }, new ResourceMap()); return new Configuration(defaultConfiguration, userConfiguration, new ConfigurationModel(), workspaceConfiguration, folders, new ConfigurationModel(), new ResourceMap()); } protected releaseWorkspaceBarrier(): void { if (!this.completeWorkspaceBarrier.isOpen()) { this.completeWorkspaceBarrier.open(); } } protected releaseUpdateWorkspaceBarrier(): void { if (this.updateWorkspaceBarrier && !this.updateWorkspaceBarrier.isOpen()) { this.updateWorkspaceBarrier.open(); } } protected static parseConfigurationModel(model: IConfigurationModel): ConfigurationModel { return new ConfigurationModel(model.contents, model.keys, model.overrides).freeze(); } protected reviveWorkspaceUris(workspaceData: IWorkspaceData) { let workspaceConfig, workspaceFolders; if (workspaceData.folders) { workspaceFolders = workspaceData.folders.map(({ index, uri: uriComponent, name }) => ( new WorkspaceFolder({ index, uri: URI.revive(uriComponent), name }) )); } if (workspaceData.configuration) { workspaceConfig = URI.revive(workspaceData.configuration); } return new Workspace(workspaceData.id, workspaceFolders, workspaceConfig); } }