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

last changes

parent 8b0faae3
/**
* 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
*/
var CircularJSON = require('circular-json');
var fs = require('fs');
//var inspect = require('eyes').inspector({maxLength: 10900});
var JSMF = require('./JSMF_Prototype');
Class = JSMF.Class;
Model = JSMF.Model;
function saveModel(model,path) {
//prepare for M2 modelling elements
//var pathTest = __dirname + '/' + 'testFile';
var serializedResult = CircularJSON.stringify(model);
//does not includes the attributes
fs.writeFile(path, serializedResult, function(err) {
if(err) {
console.log('err');
throw(err);
} else {
console.log('Saved');
}
});
}
function readModel(path) {
console.log(path);
var raw = fs.readFileSync(path);
console.log(raw);
var unserializedResult = CircularJSON.parse(raw);
return unserializedResult;
}
module.exports = {
saveModel: function(model,path) {
return saveModel(model,path);
},
readModel: function(path) {
return readModel(path);
}
};
......@@ -91,7 +91,6 @@ for(i in ModelElement.conformsTo().__attributes) {
});
}
function queryGeneration(ModelElement) {
var queryPart="";
for(i in ModelElement.conformsTo().__attributes) {
......@@ -124,49 +123,61 @@ function deleteAllNodes(ModelElement) {
//DeleteNodeWithLabelAndProperties = avoid to resolve IDS check!!!
function saveModel(Model) {
//building element list
//building element list
modelElements = [];
for(meta in Model.modellingElements) {
for(j in Model.modellingElements[meta]) {
modelElements.push(Model.modellingElements[meta][j]);
}
}
//inspect(modelElements);
//inspect(modelElements);
//create node before references, using async lib
async.eachSeries(modelElements, function(element, callback) {
async.eachSeries(modelElements, function(element, callback) {
var pushObject = {};
for(i in element.conformsTo().__attributes) {
pushObject[i] = element[i];
}
for(i in element.conformsTo().__attributes) {
pushObject[i] = element[i];
}
var labelMetaClass = element.conformsTo().__name;
var labelModelName = Model.__name;
var labelMetaClass = element.conformsTo().__name;
var labelModelName = Model.__name;
//WARNING We are in presence of undefined metaelement OR a metaclass
if(labelMetaClass==undefined) {
labelMetaClass = Model.__name+"_Class_Undefined";
//WARNING We are in presence of undefined metaelement OR a metaclass
if(labelMetaClass==undefined) {
labelMetaClass = Model.__name+"_Class_Undefined";
}
//use async read... then
db.readNodesWithLabelsAndProperties(labelMetaClass, pushObject, function (err, result) {
if(result!=undefined){
if(result.length!=0) {
//Always return the first value (oldest node)
var idSource = result[0]._id;
console.log(idSource);
}
//add test if pushObject == ?
db.insertNode(pushObject ,
[labelMetaClass,Model.__name], //Add Model.__name as label to the object (Utility of labelModelName?)
function(err, result) {
if(err) {
throw err;
} else {
idSource = result._id;
console.log('Object of Type: '+labelMetaClass+' Added');
callback();
}
});
console.log(idSource);
if(idSource==undefined) {
console.log('pushOBJ',pushObject,labelMetaClass);
db.insertNode(pushObject ,
[labelMetaClass,Model.__name], //Add Model.__name as label to the object (Utility of labelModelName?)
function(err, result) {
if(err) {
throw err;
} else {
idSource = result._id;
console.log('Object of Type: '+labelMetaClass+' Added');
callback();
}
});
} else {console.log('node already present in model: should update node'); callback();}
}
});
}, function (res) {
console.log("All nodes pushed into Neo4J... pushing associations");
async.eachSeries(modelElements, function(element, callback5) {
//console.dir("Elements: "+element);
//createReferencesBVERSION(element,callback5);
createReferencesCVERSION(element,callback5);
}, function(res2) {
createReferencesCVERSION(element,callback5);
}, function(res2) {
console.log("Model pushed fully into Neo4J");
});
});
......@@ -229,7 +240,7 @@ function createReferencesBVERSION(ModelElement, callback5) {
//debug
//console.log('SOURCE! MATCH (n:'+querysourceType+') WHERE '+querySource+' RETURN n');
db.cypherQuery('MATCH (n:'+querysourceType+') WHERE '+querySource+' RETURN n', null, function (err, result) {
if(result.data.lenght!=0) {
if(result.data.length!=0) {
//Always return the first value (oldest node)
idSource = result.data[0]._id;
} else {console.log("Error object not found in Database")};
......@@ -270,7 +281,7 @@ function createReferencesBVERSION(ModelElement, callback5) {
}
});// end dbInsert
}, function(err) {
//callback5(); //all relation are supposed to be pushed into DB
//callback5(); //all relation are supposed to be pushed into db
});
callback5();
}); //end parallel
......@@ -291,111 +302,82 @@ function createReferencesCVERSION(ModelElement, callback5) {
var targetElements=[];
var labelMetaClass = ModelElement.conformsTo().__name;
var pushObject = {};
var labelMetaClass = ModelElement.conformsTo().__name;
var pushObject = {};
var associatedObjectValues = ModelElement.associated;
var associatedObjectValues = ModelElement.associated;
console.log(associatedObjectValues);
//console.log(associatedObjectValues);
for(i in ModelElement.conformsTo().__attributes) {
pushObject[i] = ModelElement[i];
}
for(i in ModelElement.conformsTo().__attributes) {
pushObject[i] = ModelElement[i];
}
for(i in ModelElement.conformsTo().__references) {
currentRelationElement = ModelElement[i];
relationLabel = i;
for(relIt in currentRelationElement) {
//console.log('TOTO',relIt, currentRelationElement[relIt]);
targetElements.push({label: relationLabel, el :currentRelationElement[relIt], id: relIt});
}
}
//inspect(targetElements);
currentRelationElement = ModelElement[i];
relationLabel = i;
for(relIt in currentRelationElement) {
//console.log('TOTO',relIt, currentRelationElement[relIt]);
targetElements.push({label: relationLabel, el :currentRelationElement[relIt], id: relIt});
}
}
//if referenceElement is not empty
async.parallelLimit(
[ function(callback1) {
// Get Source ID if references...
//debug
//console.log('ELEM', labelMetaClass,pushObject);
db.readNodesWithLabelsAndProperties(labelMetaClass, pushObject, function (err, result) {
if(result!=undefined){
if(result.lenght!=0) {
//Always return the first value (oldest node)
idSource = result[0]._id;
} else { console.log("Error object not found in Database")};
} else {console.log("Error object not found in Database");}
callback1();
});
}, function(callback3) {
async.eachSeries(targetElements, function(element,callback2) {
var pushObject = {};
//console.log('TOTO',element);
var labelMetaClass = element.el.conformsTo().__name;
for(j in element.el.conformsTo().__attributes) {
pushObject[j] = element.el[j];
}
//debug
db.readNodesWithLabelsAndProperties(labelMetaClass,pushObject, function (err, result) {
if(result.length!=0) {
idTargets.push({label: element.label, el:result[0]._id, id:element.id});
//idTarget = result[0]._id;
} else {console.log("Error object not found in Database");}
callback2();
});
}, function(err) {
if(err) {
console.log(err);
}
callback3();
});
}],
10, //up to 10 queries in parallel (WARNING arbitrary limit).
function(err) {
async.parallelLimit([
function(callback1) {
// Get Source ID if references...
//debug
//console.log('ELEM', labelMetaClass,pushObject);
db.readNodesWithLabelsAndProperties(labelMetaClass, pushObject, function (err, result) {
if(result!=undefined){
if(result.length!=0) {
//Always return the first value (oldest node)
idSource = result[0]._id;
} else { console.log("Error object not found in Database 3")};
} else {console.log("Error object not found in Database 4");}
callback1();
});
}, function(callback3) {
async.eachSeries(targetElements, function(element,callback2) {
var pushObject = {};
//console.log('TOTO',element);
var labelMetaClass = element.el.conformsTo().__name;
for(j in element.el.conformsTo().__attributes) {
pushObject[j] = element.el[j];
}
//debug
db.readNodesWithLabelsAndProperties(labelMetaClass,pushObject, function (err, result) {
if(result.length!=0) {
idTargets.push({label: element.label, el:result[0]._id, id:element.id});
//idTarget = result[0]._id;
} else {console.log("Error object not found in Database 5");}
callback2();
});
}, function(err) {
if(err) {
console.log(err);
}
callback3();
});
}],
10, //up to 10 queries in parallel (WARNING arbitrary limit).
function(err) {
//console.log(idTargets);
async.eachSeries(idTargets, function(relation, callback6) {
//DEbug //console.log("insertion! "+ idSource+"->"+relation.el+" with label "+ relation.label);
objectAssociation = _.select(ModelElement.associated, {ref:relation.label})[relation.id].associated;
// for( iteration in
db.insertRelationship(idSource,relation.el, relation.label,objectAssociation, function(err, result){ // let see if transition should support some properties...
if(err) {
throw err;
} else {
relationid = result._id;
console.log("Reference created "+relation.label);
callback6();
}
});// end dbInsert
//DEbug //console.log("insertion! "+ idSource+"->"+relation.el+" with label "+ relation.label);
objectAssociation = _.select(ModelElement.associated, {ref:relation.label})[relation.id].associated;
// for( iteration in
db.insertRelationship(idSource,relation.el, relation.label,objectAssociation, function(err, result){ // let see if transition should support some properties...
if(err) {
throw err;
} else {
relationid = result._id;
console.log("Reference created "+relation.label);
callback6();
}
});// end dbInsert
}, function(err) {
//callback5(); //all relation are supposed to be pushed into DB
//callback5(); //all relation are supposed to be pushed into db
});
callback5();
}); //end parallel
}
/*
function createNode(ModelElement) {
var pushObject = {};
var pushRelation = {};
var relationLabel;
var idSource;
//Insert a node conforms to the model schema
for(i in ModelElement.conformsTo().__attributes) {
pushObject[i] = ModelElement[i];
}
db.insertNode(pushObject ,
ModelElement.conformsTo().__name,
function(err, result) {
if(err) {
throw err;
} else {
idSource = result._id;
//console.log(idSource);
console.log('Object of Type: '+ModelElement.conformsTo().__name+' Added');
//console.log(pushObject); //dump object
}
});
return idSource;
}
*/
}
\ No newline at end of file
......@@ -133,12 +133,17 @@ Model.prototype.contains = function (ModelElement) {
return result;
}
//Get all element of a given metatype (Classifier)
Model.prototype.Filter = function(Classifier) {
return this.modellingElements[Classifier.__name] ;
return this.modellingElements[Classifier.__name] ;
}
//Get all model elements that get a property
// get all model elements that do not have such property
// get all model element that have a given relation name a -Rname-> b
Model.prototype.setReferenceModel = function (metamodel) {
this.referenceModel = metamodel;
}
......@@ -207,15 +212,18 @@ Class.prototype.getAllReferences = function() {
}
Class.prototype.getAllAttributes = function() {
var ret = [];
var result=[];
result.push(this.__attributes)
var allsuperTypes = this.getInheritanceChain([]);
result.push(this.conformsTo().__attributes)
var allsuperTypes = this.conformsTo().getInheritanceChain([]);
for(var i in allsuperTypes) {
refSuperType = allsuperTypes[i];
result.push(refSuperType.__attributes);
}
return result;
//return result;
_.each(result, function(elem,index) {
ret.push(this[index]);
});
}
//Instance of MetaClass is conforms to Class.
......@@ -233,7 +241,6 @@ Class.prototype.setReference = function (name, type, cardinality, opposite, comp
"card": cardinality,
"associated":associated
}
//To be TESTED
if (opposite !== undefined) {
var tmp = this.__references[name];
tmp.opposite = opposite;
......@@ -266,19 +273,34 @@ Enum.prototype.getValue= function(name) {
return this.__literals[name];
}
Enum.prototype.isEnum = function() {
return true;
}
/****************************************************************************************
* Building Instance: attributes and references conforms to metamodel elements
****************************************************************************************/
function makeAssignation(ob, index, attype) {
//if attype = primitive JS type else ...
var type = new attype;
return function (param) {
if (param.__proto__ == type.__proto__) { //Strict equal?
ob[index] = param;
} else {
console.log("Assigning wrong type: " + param.__proto__ + " expected " + type.__proto__);
}
};
if ((typeof attype === 'function') && (typeof attype.isEnum !== 'undefined') && (attype.isEnum())) {
return function (param) {
var val = attype.getValue(param);
if (val !== undefined) {
ob[index] = val;
} else {
console.log("Error when assigning enum value: "+param);
}
};
} else {
var type = new attype;
return function (param) {
if (param.__proto__ == type.__proto__) { //Strict equal?
ob[index] = param;
} else {
console.log("Assigning wrong type: " + param.__proto__ + " expected " + type.__proto__);
}
};
}
}
// Adding the creation of opposite except for ARRAY of Type
......@@ -383,6 +405,28 @@ Class.prototype.newInstance = function (name) {
result.conformsTo = function () {
return self;
};
result.newInstance = function(name) {
var nminusone = {};
//Step 1 promote result
//that help in getting all reference and attributes
//Step 2 instanciate the promoted class,
nminusone.name=name;
//nminusone.chiChain=result.chiChain;
//chiChain.push(result);
nminusone.chiChain=[Class, self,result]; //index 0 = higher element
//keep the conformsTo() chain?
nminusone.conformsTo = function() {
return result;
}
return nminusone;
};
return result;
};
......
var JSMF = require('./JSMF_Prototype');
var Model = JSMF.Model;
var Class = JSMF.Class;
var _ = require('lodash');
//Copy the element which are the same from sourceME to targetME without changing the metaclass of Source and Target elements
function AttributesModelCopy(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 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
//});
}
//extract model of a metamodel ->should only promote/demote models -> chain of conformance to be kept
function demote(MetaModel) {
var result = new Model(MetaModel.__name + "_Demoted");
var tabresolution = [];
var resolve = {};
var M3Class = new Class("M3Class");
M3Class.setAttribute("_name", String);
//first round -> building metaclass
for (e in MetaModel.modellingElements) {
for (j in MetaModel.modellingElements[e]) {
var currentClass = MetaModel.modellingElements[e][j];
for (i in currentClass.__attributes) {
M3Class.setAttribute(i, String);
}
for (i in currentClass.__references) {
M3Class.setReference(i, M3Class, -1);
}
}
}
//Second Round -> building instance
for (e in MetaModel.modellingElements) {
for (j in MetaModel.modellingElements[e]) {
var currentClass = MetaModel.modellingElements[e][j];
var test = M3Class.newInstance("");
test.set_name(currentClass.__name);
for (i in currentClass.__attributes) {
var currenttype = currentClass.__attributes[i].toString().split(" ")[1].replace("()", "");
var method = "set" + i;
test[method](currenttype);
}
}
result.setModellingElement(test);
resolve = {
source: currentClass,
target: test
};
tabresolution.push(resolve);
//console.log(resolve);
}
//Third Round -> building relation
for (e in MetaModel.modellingElements) {
for (j in MetaModel.modellingElements[e]) {
var currentClass = MetaModel.modellingElements[e][j];
for (i in currentClass.__references) {
var target = currentClass.__references[i].type;
//get sources and target of the reference from the resolve link element
var newsourcerefClass = _.find(tabresolution, function (param) {
return param.source == currentClass;
});
var newtargetrefClass = _.find(tabresolution, function (param) {
return param.source == target;
});
var param = {};
if (newtargetrefClass == undefined) {
param = M3Class;
} else {
param = newtargetrefClass.target;
}
var refsetter = "set" + i;
newsourcerefClass.target[refsetter](param);
//newsourcerefClass[refsetter](newtargetrefClass);
}
}
}
// end of process
console.log(result);
//result.save();
return result;
}
//Create a metamodel from model elements
function Promote(model) {
var result = new Model(model.__name+"_promoted");
var M2 = model.referenceModel;
for(i in model.modellingElements) {
var currentelement = model.modellingElements[i];
var M2Class = new CLass(currentelement.__name);
}
}
//Get the metamodel from model
function ExtractMetamodel() {
}
function metamodelEquals(M2elementR,M2elementL) {
var result = true;
return result;
}
//Shallow equals between two JSMF modeling elements
function equals(elementR, elementL) {
var result = true;
if (elementR.conformsTo().__name !== elementL.conformsTo().__name) { //Warning check that these objects are correct too
result = false;
} else {
for (i in elementR.conformsTo().__attributes) {
if (elementR[i] !== elementL[i]) {
result = false;
}
}