UNPKG

@yellicode/elements

Version:

The meta model API for Yellicode - an extensible code generator.

176 lines (175 loc) 8.04 kB
/* * Copyright (c) 2020 Yellicode * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import * as Interfaces from "./interfaces"; import { ElementTypeUtility } from './utils'; import { BasicTypeResolver } from './type-resolver'; var ElementMapImpl = /** @class */ (function () { function ElementMapImpl(customTypeResolver) { this.elementsById = {}; this.specializationsById = {}; this.associationsByEndId = {}; this.externalTypeResolver = new BasicTypeResolver(customTypeResolver); // TODO: do we need UnlimitedNatural? If so, it should be exported by './primitives'. } ElementMapImpl.prototype.addElement = function (element, elementData) { if (this.elementsById.hasOwnProperty(element.id)) { if (element.elementType !== Interfaces.ElementType.primitiveType) console.warn("Duplicate element id '" + element.id + "'."); return; } this.elementsById[element.id] = element; // TODO: the elementData argument and the lines below should be removed // once the DataToModelConverter is replaced by the ModelSerializer. // Add generalizations to the specialization map if (ElementTypeUtility.isClassifier(element.elementType) && elementData) { this.addSpecializations(element, elementData); } // Add association ends to the assciationEnd map if (ElementTypeUtility.isAssociation(element.elementType) && elementData) { this.addAssociationEnds(element, elementData); } }; ElementMapImpl.prototype.addAssociationEnds = function (association, associationData) { var _this = this; // Get memberEnds of assocationData instead of association itself: the ends will not be set here as they are not resolved yet // by DataToModelConverter.resolveAssociationReferences(). if (!associationData.memberEnds) return; associationData.memberEnds.forEach(function (endId) { // An association end can only be part of one association. _this.addAssociationByEndId(endId, association); }); }; ElementMapImpl.prototype.addAssociationByEndId = function (endId, association) { // An association end can only be part of one association. if (this.associationsByEndId.hasOwnProperty(endId)) { console.warn("Association end with id '" + endId + "' is already part of another association than " + association.id + "."); } this.associationsByEndId[endId] = association; }; ElementMapImpl.prototype.removeAssociationByEndId = function (endId) { delete this.associationsByEndId[endId]; }; ElementMapImpl.prototype.addSpecializations = function (classifier, classifierData) { var _this = this; if (!classifierData.generalizations) return; // Enumerate the classifierData instead of the classifier itself: the generalizations will not be set here as they are not resolved yet classifierData.generalizations.forEach(function (g) { // g is a Generalization of element, so element is a Specialization of g _this.addSpecialization(g.general, classifier); // if (this.specializationsById.hasOwnProperty(g.general)) { // dictionaryEntry = this.specializationsById[g.general]; // dictionaryEntry.push(classifier); // } else { // this.specializationsById[g.general] = [classifier]; // } }); }; ElementMapImpl.prototype.addSpecialization = function (generalId, specialization) { var dictionaryEntry; if (this.specializationsById.hasOwnProperty(generalId)) { dictionaryEntry = this.specializationsById[generalId]; dictionaryEntry.push(specialization); } else { this.specializationsById[generalId] = [specialization]; } }; ElementMapImpl.prototype.removeSpecialization = function (generalId, specialization) { if (!this.specializationsById.hasOwnProperty(generalId)) return; var dictionaryEntry = this.specializationsById[generalId]; var ix = dictionaryEntry.indexOf(specialization); if (ix > -1) dictionaryEntry.splice(ix, 1); }; // public removeGeneral(generalId: string): void { // if (!this.specializationsById.hasOwnProperty(generalId)) // return; // // First remove the general from all it's specializations // const dictionaryEntry = this.specializationsById[generalId]; // dictionaryEntry.forEach(specialization => { // const ix = specialization.generalizations.findIndex(g => g.general.id === generalId); // if (ix > -1) // specialization.generalizations.splice(ix, 1); // }) // // Then remove from the map entirely // delete this.specializationsById[generalId]; // } ElementMapImpl.prototype.getAssociationHavingMemberEnd = function (end) { if (!end || !end.id) return null; if (!this.associationsByEndId.hasOwnProperty(end.id)) return null; return this.associationsByEndId[end.id]; }; ElementMapImpl.prototype.hasElement = function (id) { return this.elementsById.hasOwnProperty(id); }; ElementMapImpl.prototype.getElementById = function (id) { if (!id || id.length === 0) return null; // Is the element an external or built-in type? var externalType = this.externalTypeResolver.resolve(id); if (externalType) return externalType; if (this.elementsById.hasOwnProperty(id)) return this.elementsById[id]; else { // console.warn(`Unkown element id '${id}'.`); return null; } }; ElementMapImpl.prototype.getElementsByIdList = function (idList) { var _this = this; var result = []; if (idList == null) return result; idList.forEach(function (id) { var element = _this.getElementById(id); if (element != null) result.push(element); }); return result; }; ElementMapImpl.prototype.getSpecializationsOf = function (generalId) { if (!this.specializationsById.hasOwnProperty(generalId)) return []; return this.specializationsById[generalId]; }; ElementMapImpl.prototype.getAllSpecializationsOf = function (generalId) { if (!this.specializationsById.hasOwnProperty(generalId)) return []; var specialMap = {}; this.getAllSpecializationsRecursive(generalId, specialMap); // Convert the result to an array var result = []; for (var specializationId in specialMap) { result.push(specialMap[specializationId]); } return result; }; ElementMapImpl.prototype.getAllSpecializationsRecursive = function (generalId, specialMap) { var _this = this; if (!this.specializationsById.hasOwnProperty(generalId)) { return; } var directSpecializations = this.specializationsById[generalId]; directSpecializations.forEach(function (s) { if (!specialMap.hasOwnProperty(s.id) && !s.isOrphaned()) { specialMap[s.id] = s; } // Get the specializations of this specialization _this.getAllSpecializationsRecursive(s.id, specialMap); }); }; return ElementMapImpl; }()); export { ElementMapImpl };