Skip to content

Commit

Permalink
Ensure resolving of relative paths in JSON schema settings
Browse files Browse the repository at this point in the history
Signed-off-by: Nina Doschek <ndoschek@eclipsesource.com>
  • Loading branch information
ndoschek committed Apr 29, 2020
1 parent d0ab89a commit f134faf
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 69 deletions.
94 changes: 26 additions & 68 deletions packages/json/src/browser/json-client-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ export class JsonClientContribution extends BaseLanguageClientContribution {
this.initializeJsonSchemaStoreAssociations();
}

protected async updateSchemas(client: ILanguageClient): Promise<void> {
protected updateSchemas(client: ILanguageClient): void {
this.schemaRegistry = {};
this.updateJsonSchemaStoreSchemas();
this.initializeJsonPreferencesAssociations().then(() => client.sendNotification('json/schemaAssociations', this.schemaRegistry));
this.updateJsonSchemaStoreAssociations();
this.initializeJsonPreferencesAssociations();
client.sendNotification('json/schemaAssociations', this.schemaRegistry);
}

protected updateJsonSchemaStoreSchemas(client?: ILanguageClient): void {
protected updateJsonSchemaStoreAssociations(): void {
const schemaStoreConfigs = [...this.jsonSchemaStore.getJsonSchemaConfigurations()];
for (const schemaConfig of schemaStoreConfigs) {
if (schemaConfig.fileMatch) {
Expand All @@ -73,48 +74,25 @@ export class JsonClientContribution extends BaseLanguageClientContribution {
}
}
}
if (client) {
client.sendNotification('json/schemaAssociations', this.schemaRegistry);
}
}

protected async setJsonPreferencesSchemas(schemaConfigs: JsonSchemaConfiguration[], scope: PreferenceScope, workspaceRoot?: string): Promise<void> {
await this.asyncForEach(schemaConfigs, async (schemaConfig: JsonSchemaConfiguration) => {
await this.asyncForEach(schemaConfig.fileMatch, async (fileMatch: string) => {
protected setJsonPreferencesSchemas(schemaConfigs: JsonSchemaConfiguration[], scope: PreferenceScope, rootPath?: string): void {
schemaConfigs.forEach((schemaConfig: JsonSchemaConfiguration) => {
schemaConfig.fileMatch.forEach((fileMatch: string) => {
if (!fileMatch.startsWith('/') && !fileMatch.match(/\w+:/)) {
fileMatch = '/' + fileMatch;
}

if (workspaceRoot) {
workspaceRoot = new URI(workspaceRoot).path.toString();
if (scope !== PreferenceScope.User) {
fileMatch = new Path(workspaceRoot).join(fileMatch).normalize().toString();
let url = schemaConfig.url;
if (rootPath) {
fileMatch = new Path(rootPath).join(fileMatch).normalize().toString();
if (url.match(rootPath)) {
url = new URI(new Path(url).toString()).toString();
} else if ((url.startsWith('.') || url.startsWith('/') || url.match(/^\w+\//))) {
url = new URI(rootPath).resolve(url).normalizePath().toString();
}
}

const fileUri = new URI(schemaConfig.url);
if (fileUri.scheme === 'file') {
await this.fileSystem.exists(fileUri.toString()).then(async fileExists => {
const filePath = fileUri.path.toString();
if (fileExists) {
this.schemaRegistry[fileMatch] = [filePath];
} else {
if (workspaceRoot && !filePath.startsWith(workspaceRoot)) {
const absolutePath = new Path(workspaceRoot).join(filePath).normalize().toString();
await this.fileSystem.exists(absolutePath).then(exists => {
if (exists) {
this.schemaRegistry[fileMatch] = [absolutePath];
} else {
console.error('JSON schema configuration for fileMatch: \'' + fileMatch + '\' and url: \'' + absolutePath + '\' could not be registered.');
}
});
} else {
console.error('JSON schema configuration for fileMatch: \'' + fileMatch + '\' and url: \'' + filePath + '\' could not be registered.');
}
}
});
} else {
this.schemaRegistry[fileMatch] = [schemaConfig.url];
if (url) {
this.schemaRegistry[fileMatch] = [url];
}
});
});
Expand Down Expand Up @@ -171,42 +149,22 @@ export class JsonClientContribution extends BaseLanguageClientContribution {
}
}

protected async initializeJsonPreferencesAssociations(): Promise<void> {
const userPreferenceValues = this.preferenceService.inspect<JsonSchemaConfiguration[]>('json.schemas');
if (userPreferenceValues) {
if (userPreferenceValues.globalValue) {
await this.setJsonPreferencesSchemas(userPreferenceValues.globalValue, PreferenceScope.User);
protected initializeJsonPreferencesAssociations(): void {
const userSettings = this.preferenceService.inspect<JsonSchemaConfiguration[]>('json.schemas');
if (userSettings) {
if (userSettings.globalValue) {
this.setJsonPreferencesSchemas(userSettings.globalValue, PreferenceScope.User);
}
}

if (this.workspaceService.isMultiRootWorkspaceOpened) {
await this.asyncForEach(this.workspace.workspaceFolders, async (workspaceFolder: { name: string; uri: { path: string; }; }) => {
this.workspace.workspaceFolders.forEach((workspaceFolder: { name: string; uri: { path: string; }; }) => {
const workspaceFolderPath = workspaceFolder.uri.path;
const multiRootInspectValue = this.preferenceService.inspect<JsonSchemaConfiguration[]>('json.schemas', workspaceFolderPath);
if (multiRootInspectValue) {
if (multiRootInspectValue.workspaceValue) {
await this.setJsonPreferencesSchemas(multiRootInspectValue.workspaceValue, PreferenceScope.Workspace, workspaceFolderPath);
}
if (multiRootInspectValue.workspaceFolderValue) {
await this.setJsonPreferencesSchemas(multiRootInspectValue.workspaceFolderValue, PreferenceScope.Folder, workspaceFolderPath);
}
const folderSettings = this.preferenceService.inspect<JsonSchemaConfiguration[]>('json.schemas', workspaceFolderPath);
if (folderSettings && folderSettings.workspaceFolderValue) {
this.setJsonPreferencesSchemas(folderSettings.workspaceFolderValue, PreferenceScope.Folder, workspaceFolderPath);
}
});
} else {
const workspaceRootPath = this.workspace.rootPath || undefined;
const singleRootInspectValue = this.preferenceService.inspect<JsonSchemaConfiguration[]>('json.schemas', workspaceRootPath);
if (singleRootInspectValue) {
if (singleRootInspectValue.workspaceValue) {
await this.setJsonPreferencesSchemas(singleRootInspectValue.workspaceValue, PreferenceScope.Workspace, workspaceRootPath);
}
}
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
private async asyncForEach(array: any[], callback: any): Promise<void> {
for (const element of array) {
await callback(element);
}
}
}
Expand Down
29 changes: 28 additions & 1 deletion packages/preferences/src/browser/folder-preference-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

import { inject, injectable } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { PreferenceScope } from '@theia/core/lib/browser';
import { PreferenceScope, PreferenceResolveResult } from '@theia/core/lib/browser';
import { AbstractResourcePreferenceProvider } from './abstract-resource-preference-provider';
import { FileStat } from '@theia/filesystem/lib/common';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { JsonSchemaConfiguration } from '@theia/core/src/browser/json-schema-store';
import { Path } from '@theia/core';

export const FolderPreferenceProviderFactory = Symbol('FolderPreferenceProviderFactory');
export interface FolderPreferenceProviderFactory {
Expand Down Expand Up @@ -63,4 +65,29 @@ export class FolderPreferenceProvider extends AbstractResourcePreferenceProvider
return [this.folderUri.toString()];
}

resolve<T>(preferenceName: string, resourceUri?: string): PreferenceResolveResult<T> {
// resolve relative paths for json schema settings in workspace scope
if (preferenceName === 'json.schemas' && this.getScope() === PreferenceScope.Workspace) {
const workspaceSettings = this.getPreferences(resourceUri)[preferenceName];
if (workspaceSettings && resourceUri) {
const rootPath = new URI(resourceUri).path.toString();
workspaceSettings.forEach((schemaConfig: JsonSchemaConfiguration) => {
let url = schemaConfig.url;
if (url.match(rootPath)) {
url = new URI(new Path(url).toString()).toString();
} else if ((url.startsWith('.') || url.startsWith('/') || url.match(/^\w+\//))) {
url = new URI(rootPath).resolve(url).normalizePath().toString();
}
if (url) {
schemaConfig.url = url;
}
});
}
return {
value: workspaceSettings,
configUri: this.getConfigUri(resourceUri)
};
}
return super.resolve(preferenceName, resourceUri);
}
}

0 comments on commit f134faf

Please sign in to comment.