@eclipse-emfcloud/model-validation
Version:
Generic model validation framework.
128 lines • 5.53 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
// *****************************************************************************
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModelValidationServiceImpl = void 0;
const isEqual_1 = __importDefault(require("lodash/isEqual"));
const diagnostic_1 = require("./diagnostic");
const model_logger_1 = require("@eclipse-emfcloud/model-logger");
const logger = (0, model_logger_1.getLogger)('model-validation/model-validation-service');
class ModelValidationServiceImpl {
constructor() {
this._validators = new Array();
this._validationState = new Map();
this._subscriptions = new Map();
this._subscriptionsToAllModels = new Array();
}
addValidator(validator) {
this._validators.push(validator);
}
async validate(modelId, model) {
const diagnosticPromises = [];
this._validators.forEach((validator) => {
try {
diagnosticPromises.push(validator.validate(modelId, model));
}
catch (err) {
logger.warn(`An error occurred within a validator during the validation of '${modelId}'. ${err.name}: ${err.message}. Validation continues ignoring the failed validator`);
return;
}
});
const diag = await Promise.allSettled(diagnosticPromises);
const diagnostics = [];
diag.forEach((values) => {
if (values.status === 'fulfilled') {
diagnostics.push(values.value);
}
else {
logger.warn(`An error occurred within a validator during the validation of '${modelId}' (cause: ${values.reason}). Validation continues ignoring the failed validator`);
logger.warn(values.reason);
}
});
const result = (0, diagnostic_1.merge)(...diagnostics);
const previousState = this.getValidationState(modelId);
if (!(0, isEqual_1.default)(result, previousState)) {
this._validationState.set(modelId, result);
this._subscriptions.get(modelId)?.forEach((subscription) => {
try {
subscription.onValidationChanged?.(modelId, model, result);
}
catch (err) {
logger.warn(`An error occurred within the onValidationChanged callback for '${modelId}'. ${err.name}: ${err.message}. Other subscribers will still be notified ignoring the failed callback`);
}
});
this._subscriptionsToAllModels.forEach((subscription) => {
try {
subscription.onValidationChanged?.(modelId, model, result);
}
catch (err) {
logger.warn(`An error occurred within the onValidationChanged callback for '${modelId}'. ${err.name}: ${err.message}. Other subscribers will still be notified ignoring the failed callback`);
}
});
}
return result;
}
getValidationState(modelId) {
return this._validationState.get(modelId);
}
subscribe(...modelIds) {
let subscription;
if (modelIds.length) {
subscription = {
close: () => this.deleteSubscription(subscription),
};
for (const modelId of modelIds) {
this.addSubscription(modelId, subscription);
}
}
else {
subscription = {
close: () => this.deleteAllSubscription(subscription),
};
this.addAllSubscription(subscription);
}
return subscription;
}
addSubscription(modelId, subscription) {
const existingSubscriptions = this._subscriptions.get(modelId) || [];
existingSubscriptions.push(subscription);
this._subscriptions.set(modelId, existingSubscriptions);
}
addAllSubscription(subscription) {
this._subscriptionsToAllModels.push(subscription);
}
deleteSubscription(subscription) {
this._subscriptions.forEach((subscriptions, modelId) => {
const index = subscriptions.findIndex((s) => s === subscription);
if (index > -1) {
subscriptions.splice(index, 1);
}
if (!subscriptions.length) {
this._subscriptions.delete(modelId);
}
});
}
deleteAllSubscription(subscription) {
const index = this._subscriptionsToAllModels.indexOf(subscription);
if (index > -1) {
this._subscriptionsToAllModels.splice(index, 1);
}
}
}
exports.ModelValidationServiceImpl = ModelValidationServiceImpl;
//# sourceMappingURL=model-validation-service.js.map