@eclipse-emfcloud/model-service
Version:
Model service framework
116 lines • 5.22 kB
JavaScript
;
// *****************************************************************************
// Copyright (C) 2023-2024 STMicroelectronics.
//
// 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: MIT License which is
// available at https://opensource.org/licenses/MIT.
//
// SPDX-License-Identifier: EPL-2.0 OR MIT
// *****************************************************************************
Object.defineProperty(exports, "__esModule", { value: true });
exports.createModelServiceModelManager = void 0;
const model_manager_1 = require("@eclipse-emfcloud/model-manager");
const model_manager_2 = require("@eclipse-emfcloud/model-manager/lib/api/model-manager");
const lodash_1 = require("lodash");
const model_trigger_engine_1 = require("./model-trigger-engine");
/**
* Create a new model manager for model services.
* @returns the model manager
*/
const createModelServiceModelManager = () => {
return new ModelServiceModelManagerImpl(new model_trigger_engine_1.ModelTriggerEngine());
};
exports.createModelServiceModelManager = createModelServiceModelManager;
/**
* Implementation of the model manager with triggers.
*/
class ModelServiceModelManagerImpl extends model_manager_2.ModelManagerImpl {
constructor(triggerEngine) {
super(new CoreModelServiceModelManager(triggerEngine));
this.triggerEngine = triggerEngine;
}
}
/**
* Implementation of the core model manager with triggers.
*/
class CoreModelServiceModelManager extends model_manager_1.CoreModelManagerImpl {
constructor(triggerEngine) {
super((workingCopyManager) => {
workingCopyManager.createFollowUpCommand = (commandResult) => this.applyTriggers(workingCopyManager, commandResult);
return new model_manager_1.CoreCommandStackImpl(workingCopyManager);
});
this.triggerEngine = triggerEngine;
}
setModel(modelId, model) {
super.setModel(modelId, model);
// Super would have thrown if the model had already been present
for (const next of this.subscriptions(modelId)) {
const sub = next;
sub.onModelLoaded?.(modelId);
}
}
removeModel(modelId) {
const result = super.removeModel(modelId);
if (result) {
for (const next of this.subscriptions(modelId)) {
const sub = next;
sub.onModelUnloaded?.(modelId, result);
}
}
return result;
}
/**
* Apply any follow-up patches to the given `commandResult` provided by registered triggers.
*
* @param commandResult description of changes executed/undone/redone in the models
* @returns a command, if any, applying the triggered patches that follow up the original changes
*/
async applyTriggers(workingCopyManager, commandResult) {
if (!commandResult) {
return undefined;
}
let result;
for (const [command, delta] of commandResult) {
const { modelId, model, previousModelState } = this.getModelFromCommand(command, workingCopyManager);
if (modelId == null || model == null || previousModelState == null) {
// Cannot run triggers without a model ID
continue;
}
// Get a safe copy of the previous model state for triggers to use
const safePreviousModelState = (0, lodash_1.cloneDeep)(previousModelState);
const triggerPatch = await this.triggerEngine.applyModelTriggers(modelId, model, delta, safePreviousModelState);
if (triggerPatch) {
const patchCommand = new model_manager_1.PatchCommand('Apply triggers', modelId, triggerPatch);
result = result ? (0, model_manager_1.append)(result, patchCommand) : patchCommand;
}
}
return result;
}
/**
* Extract from a command appearing in an execution/undo/redo result the model
* that it modified, together with its ID.
*
* @param command a command keyed in the result map of command execution/undo/redo
* @param workingCopyManager to get the working copies of models edited by the `command`
* @returns the identified model that the command modified
*/
getModelFromCommand(command, workingCopyManager) {
// Compound commands do not appear in a command-result map. If somehow they do, then
// that is an error elsewhere
const modelId = (0, model_manager_1.isCompoundCommand)(command) ? undefined : command.modelId;
const model = modelId
? workingCopyManager.getWorkingCopy(modelId)
: undefined;
const previousModelState = modelId
? workingCopyManager.getModel(modelId)
: undefined;
return { modelId, model, previousModelState };
}
}
//# sourceMappingURL=model-service-model-manager.js.map