Skip to content

Commit

Permalink
#315 Refactor base protocol
Browse files Browse the repository at this point in the history
Adapt integration code to conform to the changes of :
eclipse-glsp/glsp-client#132

Also:
-Fix bug and typo in glsp-theia-container-module
-Cleanup implementation of glsp-client-contribution and ensure that the ready() promise resolves AFTER the server has been initialized.
- Remove unncessary injected `TheiaGLSPConnector`in `GLSPTheiaDiagramServer`
- Re-add WorkflowGLSPClientContribution (provides custom initialize options)
- Add utility function for configuring a digram server. 

Requires eclipse-glsp/glsp-client#132
Part-of eclipse-glsp/glsp/issues/315
  • Loading branch information
tortmayr committed Aug 16, 2021
1 parent 870a4cc commit 9b69bd0
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import 'sprotty-theia/css/theia-sprotty.css';

import { createWorkflowDiagramContainer } from '@eclipse-glsp-examples/workflow-glsp/lib';
import { GLSPDiagramConfiguration } from '@eclipse-glsp/theia-integration';
import { configureDiagramServer, GLSPDiagramConfiguration } from '@eclipse-glsp/theia-integration';
import { Container, injectable } from '@theia/core/shared/inversify';

import { WorkflowLanguage } from '../../common/workflow-language';
Expand All @@ -28,7 +28,7 @@ export class WorkflowDiagramConfiguration extends GLSPDiagramConfiguration {

doCreateContainer(widgetId: string): Container {
const container = createWorkflowDiagramContainer(widgetId);
this.configureDiagramServer(container, WorkflowDiagramServer);
configureDiagramServer(container, WorkflowDiagramServer);
return container;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { ContainerContext, GLSPTheiaFrontendModule } from '@eclipse-glsp/theia-integration';
import { ContainerContext, GLSPClientContribution, GLSPTheiaFrontendModule } from '@eclipse-glsp/theia-integration';
import { CommandContribution, MenuContribution } from '@theia/core';
import { KeybindingContext, KeybindingContribution } from '@theia/core/lib/browser';
import { DiagramConfiguration } from 'sprotty-theia';
Expand All @@ -34,6 +34,7 @@ import {
WorkflowTaskEditMenuContribution
} from './diagram/workflow-task-editing-context-menu';
import { ExampleNavigationCommandContribution } from './external-navigation-example/external-navigation-example';
import { WorkflowGLSPClientContribution } from './workflow-glsp-client-contribution';

export class WorkflowTheiaFrontendModule extends GLSPTheiaFrontendModule {
protected enableCopyPaste = true;
Expand Down Expand Up @@ -61,6 +62,10 @@ export class WorkflowTheiaFrontendModule extends GLSPTheiaFrontendModule {
context.bind(CommandContribution).toService(WorkflowDiagramReadonlyViewContribution);
}

bindGLSPClientContribution(context: ContainerContext): void {
context.bind(GLSPClientContribution).to(WorkflowGLSPClientContribution);
}

}

export default new WorkflowTheiaFrontendModule();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/********************************************************************************
* Copyright (c) 2019-2021 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { Args } from '@eclipse-glsp/client';
import { BaseGLSPClientContribution } from '@eclipse-glsp/theia-integration/lib/browser';
import { injectable } from '@theia/core/shared/inversify';

import { MaybePromise } from '../../../../../glsp-client/packages/protocol/lib';
import { WorkflowLanguage } from '../common/workflow-language';

export interface WorkflowInitializeOptions {
timestamp: Date;
message: string;
}

@injectable()
export class WorkflowGLSPClientContribution extends BaseGLSPClientContribution {
readonly id = WorkflowLanguage.contributionId;
readonly fileExtensions = WorkflowLanguage.fileExtensions;

protected createInitializeOptions(): MaybePromise<Args | undefined> {
return {
['timestamp']: new Date().toString(),
['message']: 'Custom Options Available'
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
ServerMessageAction,
ServerStatusAction
} from '@eclipse-glsp/client';
import { GLSPClient } from '@eclipse-glsp/protocol';
import { GLSPClient, InitializeResult } from '@eclipse-glsp/protocol';
import { ContributionProvider, MessageService } from '@theia/core';
import { ConfirmDialog, WidgetManager } from '@theia/core/lib/browser';
import { Message, MessageType } from '@theia/core/lib/common';
Expand Down Expand Up @@ -76,11 +76,13 @@ export abstract class BaseTheiaGLSPConnector implements TheiaGLSPConnector {

connect(diagramServer: TheiaDiagramServer): void {
this.servers.set(diagramServer.clientId, diagramServer);
this.glspClient.then(client => client.initializeClientSession({ clientSessionId: diagramServer.clientId, diagramType: this.diagramType }));
diagramServer.connect(this);
}

disconnect(diagramServer: TheiaDiagramServer): void {
this.servers.delete(diagramServer.clientId);
this.glspClient.then(client => client.disposeClientSession({ clientSessionId: diagramServer.clientId }));
diagramServer.disconnect();
}

Expand Down Expand Up @@ -214,13 +216,17 @@ export abstract class BaseTheiaGLSPConnector implements TheiaGLSPConnector {
}

sendMessage(message: ActionMessage): void {
this.glspClientContribution.glspClient.then(client => client.sendActionMessage(message));
this.glspClient.then(client => client.sendActionMessage(message));
}

getGLSPClient(): Promise<GLSPClient> {
get glspClient(): Promise<GLSPClient> {
return this.glspClientContribution.glspClient;
}

get initializeResult(): Promise<InitializeResult> {
return this.glspClientContribution.initializeResult;
}

onMessageReceived(message: ActionMessage): void {
const diagramServer = this.servers.get(message.clientId);
if (diagramServer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export abstract class GLSPDiagramConfiguration implements DiagramConfiguration {

createContainer(widgetId: string): Container {
const container = this.doCreateContainer(widgetId);

this.initializeContainer(container);
return container;
}
Expand All @@ -69,9 +70,11 @@ export abstract class GLSPDiagramConfiguration implements DiagramConfiguration {
configureActionHandler(container, NavigateToExternalTargetAction.KIND, TheiaNavigateToExternalTargetHandler);
}

protected configureDiagramServer<T>(container: Container, server: { new(...args: any[]): T }): void {
container.bind(TYPES.ModelSource).to(server).inSingletonScope();
container.bind(TheiaDiagramServer).toService(server);
}
}

export function configureDiagramServer<T>(container: Container, server: { new(...args: any[]): T }): void {
container.bind(server).toSelf().inSingletonScope();
container.bind(TYPES.ModelSource).toService(server);
container.bind(TheiaDiagramServer).toService(server);
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { EditMode, GLSPActionDispatcher } from '@eclipse-glsp/client';
import { configureServerActions, EditMode, GLSPActionDispatcher } from '@eclipse-glsp/client';
import {
ApplicationShell,
FrontendApplicationContribution,
Expand Down Expand Up @@ -81,8 +81,11 @@ export abstract class GLSPDiagramManager extends DiagramManager {
protected _diagramConnector: TheiaGLSPConnector;

@postConstruct()
protected initialize(): void {
this.connectorProvider(this.diagramType).then(connector => this._diagramConnector = connector);
protected async initialize(): Promise<void> {
this._diagramConnector = await this.connectorProvider(this.diagramType);
if (!this._diagramConnector) {
throw new Error(`No diagram connector is registered for diagramType: ${this.diagramType}!`);
}
}

async doOpen(widget: DiagramWidget, options?: WidgetOpenerOptions): Promise<void> {
Expand All @@ -103,6 +106,8 @@ export abstract class GLSPDiagramManager extends DiagramManager {
const widgetId = this.createWidgetId(options);
const config = this.getDiagramConfiguration(options);
const diContainer = config.createContainer(clientId);
const initializeResult = await this.diagramConnector.initializeResult;
await configureServerActions(initializeResult, this.diagramType, diContainer);
const widget = new GLSPDiagramWidget(options, widgetId, diContainer, this.editorPreferences, this.theiaSelectionService, this.diagramConnector);
widget.listenToFocusState(this.shell);
return widget;
Expand Down Expand Up @@ -138,7 +143,7 @@ export abstract class GLSPDiagramManager extends DiagramManager {
return 0;
}

get diagramConnector(): TheiaGLSPConnector | undefined {
get diagramConnector(): TheiaGLSPConnector {
return this._diagramConnector;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2019-2020 EclipseSource and others.
* Copyright (c) 2019-2021 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -16,15 +16,13 @@
import {
Args,
DiagramServer,
DisposeClientSessionAction,
EditorContextService,
EnableToolPaletteAction,
FocusStateChangedAction,
FocusTracker,
GLSP_TYPES,
IActionDispatcher,
ICopyPasteHandler,
InitializeClientSessionAction,
ModelSource,
RequestModelAction,
RequestTypeHintsAction,
Expand All @@ -40,10 +38,11 @@ import { SelectionService } from '@theia/core/lib/common/selection-service';
import { Container } from '@theia/core/shared/inversify';
import { EditorPreferences } from '@theia/editor/lib/browser';
import { pickBy } from 'lodash';
import { DiagramWidget, DiagramWidgetOptions, isDiagramWidgetContainer, TheiaSprottyConnector } from 'sprotty-theia';
import { DiagramWidget, DiagramWidgetOptions, isDiagramWidgetContainer } from 'sprotty-theia';

import { GLSPWidgetOpenerOptions, GLSPWidgetOptions } from './glsp-diagram-manager';
import { DirtyStateNotifier, GLSPTheiaDiagramServer } from './glsp-theia-diagram-server';
import { TheiaGLSPConnector } from './theia-glsp-connector';

export class GLSPDiagramWidget extends DiagramWidget implements SaveableSource {

Expand All @@ -53,15 +52,14 @@ export class GLSPDiagramWidget extends DiagramWidget implements SaveableSource {
protected requestModelOptions: Args;

constructor(options: DiagramWidgetOptions & GLSPWidgetOpenerOptions, readonly widgetId: string, readonly diContainer: Container,
readonly editorPreferences: EditorPreferences, readonly theiaSelectionService: SelectionService, readonly connector?: TheiaSprottyConnector) {
readonly editorPreferences: EditorPreferences, readonly theiaSelectionService: SelectionService, readonly connector: TheiaGLSPConnector) {
super(options, widgetId, diContainer, connector);
this.saveable = new SaveableGLSPModelSource(this.actionDispatcher, this.diContainer.get<ModelSource>(TYPES.ModelSource));
this.updateSaveable();
this.title.caption = this.uri.path.toString();
const prefUpdater = editorPreferences.onPreferenceChanged(() => this.updateSaveable());
this.toDispose.push(prefUpdater);
this.toDispose.push(this.saveable);
this.toDispose.push(Disposable.create(() => this.actionDispatcher.dispatch(new DisposeClientSessionAction(this.widgetId))));
}

protected updateSaveable(): void {
Expand All @@ -74,23 +72,27 @@ export class GLSPDiagramWidget extends DiagramWidget implements SaveableSource {
if (modelSource instanceof DiagramServer) {
modelSource.clientId = this.id;
}
if (modelSource instanceof GLSPTheiaDiagramServer && this.connector) {
if (modelSource instanceof GLSPTheiaDiagramServer) {
this.connector.connect(modelSource);
}

this.disposed.connect(() => {
if (modelSource instanceof GLSPTheiaDiagramServer && this.connector) {
if (modelSource instanceof GLSPTheiaDiagramServer) {
this.connector.disconnect(modelSource);
}
});

this.actionDispatcher.dispatch(new InitializeClientSessionAction(this.widgetId));
// Filter options to only contain defined primitive values
const definedOptions: any = pickBy(this.options, v => v !== undefined && typeof v !== 'object');
this.requestModelOptions = {
sourceUri: this.uri.path.toString(),
...definedOptions
};

this.dispatchInitialActions();
}

protected dispatchInitialActions(): void {
this.actionDispatcher.dispatch(new RequestModelAction(this.requestModelOptions));
this.actionDispatcher.dispatch(new RequestTypeHintsAction(this.options.diagramType));
this.actionDispatcher.dispatch(new EnableToolPaletteAction());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,23 @@ import {
SourceUriAware
} from '@eclipse-glsp/client';
import { Emitter, Event } from '@theia/core/lib/common';
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
import { injectable } from '@theia/core/shared/inversify';
import { TheiaDiagramServer } from 'sprotty-theia';

import { TheiaGLSPConnector } from './theia-glsp-connector';
import { isTheiaGLSPConnector, TheiaGLSPConnector } from './theia-glsp-connector';

const receivedFromServerProperty = '__receivedFromServer';

@injectable()
export class GLSPTheiaDiagramServer extends TheiaDiagramServer implements DirtyStateNotifier, SourceUriAware {

@inject(TheiaGLSPConnector) protected readonly theiaConnector: TheiaGLSPConnector;

readonly dirtyStateChangeEmitter: Emitter<DirtyState> = new Emitter<DirtyState>();

protected dirtyState: DirtyState = { isDirty: false };

@postConstruct()
protected postConstruct(): void {
this.connect(this.theiaConnector);
}

initialize(registry: ActionHandlerRegistry): void {
registry.register(SetDirtyStateAction.KIND, this);
registry.register(ServerMessageAction.KIND, this);
registry.register(ExportSvgAction.KIND, this);
registerDefaultGLSPServerActions(registry, this);
registry.register(SetDirtyStateAction.KIND, this);
}

public getSourceURI(): string {
Expand Down Expand Up @@ -97,9 +88,19 @@ export class GLSPTheiaDiagramServer extends TheiaDiagramServer implements DirtyS
}

protected handleServerMessageAction(status: ServerMessageAction): boolean {
this.theiaConnector.showMessage(this.clientId, status);
this.connector.showMessage(this.clientId, status);
return false;
}

get connector(): TheiaGLSPConnector {
if (!this._connector) {
throw Error('TheiaDiagramServer is not connected.');
}
if (!isTheiaGLSPConnector(this._connector)) {
throw new Error('Connector needs to be a instance of "TheiaGLSPConnector');
}
return this._connector;
}
}
export class SetDirtyStateAction implements Action {
static readonly KIND = 'setDirtyState';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { InstanceRegistry, ServerMessageAction } from '@eclipse-glsp/client';
import { InitializeResult } from '@eclipse-glsp/protocol';
import { injectable, multiInject, optional } from '@theia/core/shared/inversify';
import { TheiaSprottyConnector } from 'sprotty-theia';

Expand All @@ -22,9 +23,16 @@ export const TheiaGLSPConnector = Symbol('TheiaGLSPConnector');
export interface TheiaGLSPConnector extends TheiaSprottyConnector {
readonly diagramType: string;
readonly diagramManagerId: string;
readonly initializeResult: Promise<InitializeResult>;
showMessage(widgetId: string, action: ServerMessageAction): void;
}

export function isTheiaGLSPConnector(connector?: TheiaSprottyConnector): connector is TheiaGLSPConnector {
return connector !== undefined && 'diagramType' in connector && typeof connector['diagramType'] === 'string'
&& 'diagramManagerId' in connector && typeof connector['diagramManagerId'] === 'string' &&
'showMessage' in connector && typeof connector['showMessage'] === 'function';
}

@injectable()
export class TheiaGLSPConnectorRegistry extends InstanceRegistry<TheiaGLSPConnector> {
constructor(@multiInject(TheiaGLSPConnector) @optional() connectors: TheiaGLSPConnector[]) {
Expand Down
Loading

0 comments on commit 9b69bd0

Please sign in to comment.