Commit a933180b authored by Jean-Sébastien Sottet's avatar Jean-Sébastien Sottet
Browse files

Restore Legacy commits

parents 6f8ad1dc baa0a131
Pipeline #871 passed with stage
in 1 minute and 26 seconds
/**
* Importer Of ArchiMate files
*
©2015 Luxembourg Institute of Science and Technology All Rights Reserved
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Authors : J.S. Sottet
*/
var xpath = require('xpath'),
dom = require('xmldom').DOMParser;
var fs = require('fs');
var JSMF = require('./JSMF_Prototype');
var Model = JSMF.Model;
var Class = JSMF.Class;
var util = require('./JSMF_Util');
var _ = require('lodash');
var inspect = require('eyes').inspector({
maxLength: 9000
});
function importArchi(filepath) {
var ModelE = [];
//Build ArchiMateMetamodel => should be built from M2.ecore file (and restricted to elements of interests - reduced viewpoint).
var M2Archi = new Model("Archi");
var BusinessActor = Class.newInstance("BusinessActor");
BusinessActor.setAttribute("name", String);
BusinessActor.setAttribute("id", String);
ModelE.push(BusinessActor);
var BusinessRole = new Class("BusinessRole");
BusinessRole.setAttribute("name", String);
BusinessRole.setAttribute("id", String);
ModelE.push(BusinessRole);
var BusinessService = new Class("BusinessService");
BusinessService.setAttribute("name", String);
BusinessService.setAttribute("id", String);
ModelE.push(BusinessService);
var BusinessFunction = new Class("BusinessFunction");
ModelE.push(BusinessFunction);
BusinessFunction.setAttribute("name", String);
BusinessFunction.setAttribute("id", String);
var BusinessObject = new Class("BusinessObject");
BusinessObject.setAttribute("name", String);
BusinessObject.setAttribute("id", String);
ModelE.push(BusinessObject);
//Added since version 0.6
var DataObject = new Class("DataObject");
DataObject.setAttribute("name", String);
DataObject.setAttribute("id", String);
ModelE.push(DataObject);
var ApplicationComponent = new Class("ApplicationComponent");
ApplicationComponent.setAttribute("name", String);
ApplicationComponent.setAttribute("id", String);
ModelE.push(ApplicationComponent);
var Contract = new Class("Contract");
Contract.setAttribute("name", String);
Contract.setAttribute("id", String);
ModelE.push(Contract);
//End version 0.6
var Driver = new Class("Driver");
Driver.setAttribute("name", String);
Driver.setAttribute("id", String);
ModelE.push(Driver);
var Goal = new Class("Goal");
Goal.setAttribute("name", String);
Goal.setAttribute("id", String);
ModelE.push(Goal);
var Assessment = new Class("Assessment"); //Assessment
Assessment.setAttribute("name", String);
Assessment.setAttribute("id", String);
ModelE.push(Assessment);
var AggregationRelationship = new Class("AggregationRelationship");
AggregationRelationship.setAttribute("id", String);
AggregationRelationship.setReference("source", Class, 1);
AggregationRelationship.setReference("target", Class, 1);
ModelE.push(AggregationRelationship);
var CompositionRelationsship = new Class("CompositionRelationship");
CompositionRelationsship.setReference("source", Class, 1);
CompositionRelationsship.setReference("target", Class, 1);
ModelE.push(CompositionRelationsship);
var InfluenceRelationship = new Class("InfluenceRelationship");
InfluenceRelationship.setReference("source", Class, 1);
InfluenceRelationship.setReference("target", Class, 1);
ModelE.push(InfluenceRelationship);
var AssociationRelationship = new Class("AssociationRelationship");
AssociationRelationship.setReference("source", Class, 1);
AssociationRelationship.setReference("target", Class, 1);
ModelE.push(AssociationRelationship);
var SpecialisationRelationship = new Class("SpecialisationRelationship");
SpecialisationRelationship.setReference("source", Class, 1);
SpecialisationRelationship.setReference("target", Class, 1);
ModelE.push(SpecialisationRelationship);
var AssigmentRelationship = new Class("AssignmentRelationship");
AssigmentRelationship.setReference("source", Class, 1);
AssigmentRelationship.setReference("target", Class, 1);
ModelE.push(AssigmentRelationship);
var AccessRelationship = new Class("AccessRelationship");
AccessRelationship.setReference("source", Class, 1);
AccessRelationship.setReference("target", Class, 1);
ModelE.push(AccessRelationship);
var UsedByRelationship = new Class("UsedByRelationship");
UsedByRelationship.setReference("source", Class, 1);
UsedByRelationship.setReference("target", Class, 1);
ModelE.push(UsedByRelationship);
M2Archi.setModellingElements(ModelE);
for (i in M2Archi.modellingElements) {
M2Archi.modellingElements[i].setAttribute("id", String);
}
var ArchiSante = new Model("ArchimateSante");
ArchiSante.setReferenceModel = M2Archi;
//Path to the Archi Model File (XMI)
//var domainFile = __dirname + '/'+ '/HealthModeling.txt'
//var domainFile = __dirname + '/'+ 'HealthModelingv6.archimate';
var domainFile = filepath;
fs.readFile(domainFile, {
encoding: "UTF-8"
}, function (err, data) {
//GENERATE XPATH Parser from M2
var doc = new dom().parseFromString(data)
var nodes = xpath.select("//element", doc); // WARNING elemen hard-wired (not a generic EMF term)
for (i in M2Archi.modellingElements) {
var findName = "archimate:"; //WARNING archimate: => should be generated from metamodel
var currentClass = M2Archi.modellingElements[i];
var ClassName = M2Archi.modellingElements[i].__name;
findName += ClassName;
for (var i in nodes) {
var currentType = nodes[i].getAttribute("xsi:type"); //generic?
if (currentType == findName) {
//console.log(currentType, findName);
var s = currentClass.newInstance("x");
for (it in currentClass.__attributes) {
functionName = "set" + it; //- creating the name of the method to be called
s[functionName](nodes[i].getAttribute(it)); // <=> setAttribute(Value)
}
for (it in currentClass.__references) {
referenceFunctionName = "set" + it;
var idReference = nodes[i].getAttribute(it);
_.each(ArchiSante.modellingElements,
function (element, index, list) {
_.each(element,
function (el2, ind2, list2) {
if (el2.id == idReference) {
s[referenceFunctionName](el2);
} // WARNING also Check for unresolved references!
}); //What if element not found?
});
}
ArchiSante.setModellingElement(s);
}
}
}
// WARNING IN CASE OF NON RESOLVABLE REFERENCE use XPATH, KEEP THE LINKS OF UNDEFINED ELEMENT AND RESOLVE THEM AT THE END.
//console.log(idReference);
/* get element with Xpath... but is it necessary? yes maybe for element that have not been created yet!
var referencedNodes = xpath.select("//element[@id='"+idReference+"']",doc); //===> select by ID ?
var IdRef = referencedNodes[0].getAttribute("id");
*/
// END WARNING
// Save Model to the DB - WARNING currently it is not updating but duplicating nodes into DB!!!!!
//ArchiSante.save();
// REFACTORING of model to passe from: Source <- Relation -> Target to Source -> Target
var RefactoredM2Archi = new Model("ArchiRefactored");
var ArchiSanteRefactored = new Model("ArchiSanteRefactored");
ArchiSanteRefactored.setReferenceModel(RefactoredM2Archi);
//console.log(ArchiSanteRefactored);
var TabResolution = [];
var LinkResolve = {};
//1st STEP : Update/Refactor the metamodel according to the relationships to be created
_.each(ArchiSante.modellingElements,
function (element, index, list) {
_.each(element,
function (el1, ind1, list1) {
//console.log(index,el1);
if (el1.source != undefined && el1.target != undefined) {
var sourceOb = el1.source[0];
var targetOb = el1.target[0]; //association of card = 1 so take the first element: [0];
//modify the metamodel in order to add the relation
var M2source = sourceOb.conformsTo(); // WARNING this is not making a copy!
M2source.setReference(index, Class, -1);
//RefactoredM2Archi.setModellingElement(M2source); //not usefull since M2source.setReference modify the original metamodel sourceOb.conformsTo();
}
});
});
//2nde STEP: update the modelling element which are source of associations
_.each(ArchiSante.modellingElements,
function (element, index, list) {
_.each(element,
function (el1, ind1, list1) {
//console.log(index,el1);
if (el1.source != undefined && el1.target != undefined) { //If el = relations
var sourceOb = el1.source[0];
var targetOb = el1.target[0]; //association of card = 1 so take the first element: [0];
//modify the metamodel in order to add the relation
var M2source = sourceOb.conformsTo(); //
// M2source.setReference(index, Class, -1); //targetOb.conformsTo()
var newObject = M2source.newInstance("T");
//Assign the value to the newobject (do not use newObject = sourceOb);
//Assign the value to the newobject (do not use newObject = sourceOb);
ModelCopy(sourceOb, newObject);
LinkResolve = {
origin: sourceOb,
target: newObject,
reference: index,
referee: targetOb
};
TabResolution.push(LinkResolve);
var existingElement = isPresent(newObject, ArchiSanteRefactored);
if (existingElement !== undefined) {
//make the linkresolve pointing at the existing model element and not the new one.
LinkResolve.target = existingElement;
//console.log("Present!");
} else {
ArchiSanteRefactored.setModellingElement(newObject);
}
}
});
});
MatchedSources = [];
MatchedSources = _.map(TabResolution, function (source) {
return source.origin;
});
MatchedM2 = [];
MatchedM2 = _.map(TabResolution, function (source) {
return source.target.conformsTo();
});
UnMatchedM2 = [];
UnMatchedM2 = _.map(TabResolution, function (source) {
return source.referee.conformsTo();
});
// 3 STEP use the resolve Tab to build the association/relationship between the right source and target
_.each(TabResolution,
function (el1, ind1) {
//Target element of the transformation (referee) is already a source of another relation (origin) in matched elements
functionName = "set" + el1.reference;
var targeted={};
if (_.contains(MatchedSources, el1.referee)) {
targeted = _.find(TabResolution, function (current) {
if (current.origin == el1.referee) {
return current;
}
});
el1.target[functionName](targeted.target);
} else { // The element has not already been transformed (i.e., it is not source of an association
//Target metamodel element
M2target = _.find(MatchedM2, function (current) {
return current.__name == el1.referee.conformsTo().__name;
}); //is it always: undefined? e.g., because of the nature of leafObject?
//No elements have been tranformed => keep the old metamodel
if (M2target == undefined) {
M2target = _.find(UnMatchedM2, function (current) {
return current.__name == el1.referee.conformsTo().__name;
});
}
newTarget = M2target.newInstance("newtarget");
ModelCopy(el1.referee, newTarget);
var existingElement = isPresent(newTarget, ArchiSanteRefactored);
if (existingElement !== undefined) {
//element already exists
el1.target[functionName](existingElement);
} else {
el1.target[functionName](newTarget);
ArchiSanteRefactored.setModellingElement(newTarget);
}
}
});
//WARNING address Objects non matched!!! i.e., which have not references
//Save Refactored model
ArchiSanteRefactored.save();
});
}
//Change it by a boolean expression...
function isPresent(ModelElement, TModel) {
//Create the indexM for getting just the subset of elements that have the same (meta)type of ModelElement (i.e., indexation by metaclass name)
var indexM = ModelElement.conformsTo().__name;
var result = _.find(TModel.modellingElements[indexM],
function (current) {
//console.log(ModelElement.id==current.id);
//return objCompare(ModelElement,current);
return ModelElement.id==current.id;
//console.log(deequal(ModelElement,current));
// console.log(util.equals(ModelElement,current));
// return util.equals(ModelElement,current);
});
return result;
}
//Function Compare
function objCompare(a, b) {
function replacer(key, value) {
if (typeof value === 'object' && value !== null && key !== '') {
value = JSON.stringify(value, function(k,v) {
if (typeof v === 'object' && v !== null && k !== '') {
v = undefined
}
return v;
});
}
return value;
}
var sa = JSON.stringify(a, replacer);
var sb = JSON.stringify(b, replacer);
return (sa == sb);
}
//Should be REPORTED AS HELPER or JSMF_UTIL IN JSMF PROTOTYPE
//Copy the element which are the same from sourceME to targetME without changing the metaclass of Source and Target elements
function ModelCopy(SourceME, TargetME) {
_.each(SourceME.conformsTo().__attributes, function (element, index, list) {
if (TargetME.hasOwnProperty(index)) {
var setValue = "set" + index;
TargetME[setValue](SourceME[index]); // or TargetME[index]=SourceME[index] => prefere the current solution because its check name unicity and attribute types!
}
});
//DO the same for the references
//_.each(SourceME.conformsTo()._references, function(element,index,list) {
// DO the affectation of references elements
//});
}
function Remove(TModel, ModelElement) {
var indexM2 = ModelElement.conformsTo().__name;
var indexRM = _.indexOf(TModel.modellingElements[indexM2], ModelElement);
console.log(indexRM);
TModel.modellingElements[indexM2].splice(indexRM, 1);
}
exports.importArchi = importArchi;
/**
* Importer of Ecore files (Metamodel+Model)
*
©2015 Luxembourg Institute of Science and Technology All Rights Reserved
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Authors : J.S. Sottet
*/
/* *********************************
-Ecore
- packages
- multimodels references
- M2
- Resolve Inheritance
- Add enum types
- Add other datatypes
- M1
- Resolve Reference (using Xpath)
******************************************/
var xpath = require('xpath.js')
, dom = require('xmldom').DOMParser;
var fs = require('fs');
//var libxmljs = require("libxmljs");
var JSMF = require('./JSMF_Prototype'); var Model = JSMF.Model; var Class = JSMF.Class;
var _ = require('lodash');
var inspect = require('eyes').inspector({maxLength: 10900});
var xml2js = require('xml2js');
var cheerio = require('cheerio');
var ModelImport = [];
var metaModelFile = __dirname + '/'+ '/TDA.ecore';
var modelFile = __dirname + '/' + 'TDA2.xmi';
//var metaModelFile = __dirname + '/'+ 'JQueryMobile.ecore';
//var modelFile = __dirname + '/' + 'jqm.xmi';
var parser = new xml2js.Parser();
var InjectMetaModel = new Model("Injected");
fs.readFile(metaModelFile, {encoding: "UTF-8"},
function(err, data) {
parser.parseString(data, function (err, domain) {
_.each(domain,function(element,index,list) {
_.each(element.eClassifiers, function(el1,ind1,list1) { //check for packages
var Local = el1.$;
//if(local.xsi:type=='Ecore:EClass') { // ECLass vs EEnum
var MElem = new Class(Local.name);
_.each(el1.eStructuralFeatures, function(att2,ind2,list2) {
var sFeature = att2.$;
//console.log(sFeature['xsi:type']);
switch(sFeature['xsi:type']) { //ADD the other Types ENum, etc...
case 'ecore:EAttribute':
var featureType = _.last(sFeature.eType.split('//'));
var JSMFType='';
switch(featureType) {
case "EString":
JSMFType = String;
break;
case "EInt":
JSMFType = Number;
break;
case "EBoolean":
JSMFType = Boolean;
break;
//WARNING : no else cases, enumeration, etc...
}
if(JSMFType =='') {
JSMFType = String; //By default put a String
//console.log("Warning: no type or not idenfied type");
}
MElem.setAttribute(sFeature.name, JSMFType);
break;
case 'ecore:EReference' :
var referenceType = _.last(sFeature.eType.split('//'));
var card = sFeature.upperBound; //=> TO number
var composite = sFeature.containment;
if(card==undefined) {card=1;}
//resolve reference type after the creation of all classes?
composite = (composite!== undefined)?true:false;
// referenceType is a proxy of the type which has to be resolve with the real metaclass
MElem.setReference(sFeature.name, referenceType, card,undefined,composite); // TO BE set : eOpposite
break;
}
});
InjectMetaModel.setModellingElement(MElem);
});
});
});
resolveReference(InjectMetaModel);
//resolveInheritance(InjectModel);
var injectedmodel = new Model("TDA");
injectedmodel.setReferenceModel(InjectMetaModel);
var rootMetaModelElement = InjectMetaModel.modellingElements['TDAModel'][0];
//var rootMetaModelElement = InjectMetaModel.modellingElements['PageHeader'][0];
//WARNING: hould read the first node instead of creating it from nothing..
var uri = 'lu.tudor.tda:';
var rootModeELement = rootMetaModelElement.newInstance('root');
rootModeELement.setname('Root');
// rootModeELement.settitle('ActorSearch');
fs.readFile(modelFile, {encoding: "UTF-8"},
function(err, data) {
var doc = new dom().parseFromString(data);
buildModelFromRef(doc,injectedmodel,rootModeELement);
//resolveInstanceReference(injectedmodel,doc,rootModeELement);
//injectedmodel.save();
//inspect(injectedmodel);
});
});
//Build a ref xmlpath<->JSMF_Instance?
// use cheerio here
function buildModelFromRef(doc, modelT,currentElement) {
//console.log(currentElement);
var currentM2Element = currentElement.conformsTo();
var addedElement = {};
_.each(currentM2Element.__references, function(elem,index) {
if(elem.composite==true) {
// console.log(index);
var getName = "./"+index; //use cheerio instead
nodes = xpath(doc,getName); //originally xpath.select(getname,doc);
//for each nodes given by xpath query -> should be the right elements at the right level and not all the element as it is now...
for( var i in nodes) {
//Get the class referenced by the current reference index (i.e., type of reference)
var referencedM2Class = currentM2Element.__references[index].type;
//Create a new modelling element for the current reference index
addedElement = referencedM2Class[0].newInstance("a");
//set the model (attributes)
_.each(referencedM2Class[0].__attributes, function(el1,ind1) {
var setterfunction = "set"+ind1;
if(nodes[i]==undefined) {console.log('undefined xml node for: ', ind1, index)}
else {
var attributevalue= nodes[i].getAttribute(ind1);
// set the attribute calling the setter function from a setter String
addedElement[setterfunction](attributevalue);
}
});
//console.log(addedElement.name);
var associationFunction = "set"+index;
//create the relation between currentElement and referenced element
currentElement[associationFunction](addedElement);
//Save the added element to the model
modelT.setModellingElement(addedElement);
// console.log(currentElement.name);
//console.log(addedElement.type, addedElement.name, index);
// Recursive Call (for each referenced element which are containement references)
buildModelFromRef(nodes[i],modelT,addedElement);
}
}
//standard Ecore Reference to be resolve later
else {
var getName = ".";
nodes = xpath(doc,getName);
console.log(index, elem);
}
});
}
//model
function resolveReference(model) { //refModels
var listName= [];
for(z in model.modellingElements) {
listName.push(model.modellingElements[z][0].__name);
}
for(i in model.modellingElements) {
var currentElement = model.modellingElements[i][0];
for(e in currentElement.__references) {
var currentRef = currentElement.__references[e]; //WARNING current Ref can be instance of Array
// the element is present in the current Model
var realType = _.find(model.modellingElements,function(current) {return current[0].__name ==currentRef.type;}); //warning find the first that match, by name
if(realType == undefined) {
// create a proxy element (the referenced model element is present in another model?)
console.log("modelling element not present in loaded models");
} else {
// current element is only a reference to the real element in the model
//console.log(e,currentRef);
model.modellingElements[i][0].setReference(e,realType,currentRef.card,undefined,currentRef.composite); //currentRef.opposite
}
}
}
}
function resolveInheritance(model){
var
}
function resolveInstanceReference(model,doc,currentModelElement) {
var currentM2Element = currentModelElement.conformsTo();
var addedElement = {};
_.each(currentM2Element.__references, function(elem,index) {
console.log('current',index);
if(elem.composite==false) {
console.log(elem);
}
});
}
Example.jpg

41.9 KB

var JSTL = require('../JSTL_Prototype'); var TransformationModule= JSTL.TransformationModule;
var JSMF = require('../JSMF_Prototype'); var Model = JSMF.Model; var Class = JSMF.Class;
//Load the metamodels (in one file for the example)
var MM = require('./MMABExamples.js');
//Load MMArchi
//Load MMSecurity
//Load the model (in one file for the example)
var M = require('./MABExamples.js');
var inspect = require('eyes').inspector({
maxLength: 9000