UNPKG

libsbgn.js

Version:

SBGN-ML parsing and writing for JavaScript

229 lines (209 loc) 7.78 kB
var N3 = require('n3'); var ns = {}; ns.prefixes = { rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#", bqmodel: "http://biomodels.net/model-qualifiers/", bqbiol: "http://biomodels.net/biology-qualifiers/", sio: "http://semanticscience.org/resource/", eisbm: "http://www.eisbm.org/"}; // pure shortcut function ns.expandPrefix = function(prefix) { return N3.Util.expandPrefixedName(prefix, ns.prefixes) }; // commonly used strings str_sio223 = "sio:SIO_000223"; str_sio223exp = ns.expandPrefix(str_sio223); str_sio116 = "sio:SIO_000116"; str_sio116exp = ns.expandPrefix(str_sio116); str_rdfvalue = "rdf:value"; str_rdfvalueexp = ns.expandPrefix(str_rdfvalue); str_rdftype = "rdf:type"; str_rdftypeexp = ns.expandPrefix(str_rdftype); str_rdfbag = "rdf:Bag"; str_rdfbagexp = ns.expandPrefix(str_rdfbag); controlledVocabularyList = [ "bqmodel:is", "bqmodel:isDerivedFrom", "bqmodel:isDescribedBy", "bqmodel:isInstanceOf", "bqmodel:hasInstance", "bqbiol:is", "bqbiol:encodes", "bqbiol:hasPart", "bqbiol:hasProperty", "bqbiol:hasVersion", "bqbiol:isDescribedBy", "bqbiol:isEncodedBy", "bqbiol:isHomologTo", "bqbiol:isPartOf", "bqbiol:isPropertyOf", "bqbiol:isVersionOf", "bqbiol:occursIn", "bqbiol:hasTaxon", "sio:SIO_000223" ]; ns.isControlledVocabulary = {}; for(var i=0; i<controlledVocabularyList.length; i++) { var term = controlledVocabularyList[i]; ns.isControlledVocabulary[ns.expandPrefix(term)] = true; } ns.reducePrefix = function (expandedString) { for (var key in ns.prefixes) { var completePrefix = ns.prefixes[key]; if (expandedString.startsWith(completePrefix)) { return expandedString.replace(completePrefix, key+':'); } } // no prefix could be recognized return expandedString; }; ns.getCustomPropertiesOfId = function (graph, id) { var kvresult = {}; //console.log(graph.getTriples()); var propBags = graph.getTriples(id, str_sio223, null); //console.log(propBags); for(var i=0; i<propBags.length; i++) { var propBag = propBags[i].object; //console.log(propBag); var propertyContainers = graph.getTriples(propBag, null, null); //console.log(propertyContainers); for(var j=0; j<propertyContainers.length; j++) { var propertyContainer = propertyContainers[j].object; if(propertyContainer == str_rdfbagexp) { continue; } //console.log("container", propertyContainer); var value = graph.getObjects(propertyContainer, str_rdfvalueexp, null)[0]; value = N3.Util.getLiteralValue(value); var key = graph.getObjects(propertyContainer, str_sio116exp, null)[0]; key = N3.Util.getLiteralValue(key); //console.log(key, value); kvresult[key] = value; } } return kvresult; }; ns.getAllIds = function (graph) { var result = []; var all = graph.getSubjects(); //console.log(graph.getTriples()); //console.log(all); for(var i=0; i<all.length; i++) { if(! N3.Util.isBlank(all[i])) { var subject = all[i]; // potential IDs // now check if they aren't used as object of other triples var idAsObject = graph.countTriples(null, null, subject); if (idAsObject == 0) { // nothing is over this id, true id result.push(subject); } } } return result; }; /** * will add triples to represent key/value properties attached to the id * kvObject can have one or multiple properties */ ns.addCustomProperty = function (graph, id, kvObject) { var sio223Element = ns.getRelationship(graph, id, str_sio223)[0]; // doesn't matter if more than one //console.log("add kv to", hasPropElement); for(var key in kvObject) { // using elemnt count as index may be dangerous if previous manipulation of // the elements has happened. Like removing one. var propIndex = ns.countBagElements(graph, sio223Element) + 1; //console.log("elements in bag:", propIndex); var newBlank = graph.createBlankNode(); //console.log("expand list element", ns.expandPrefix("rdf:_"+propIndex)); graph.addTriple(sio223Element, ns.expandPrefix("rdf:_"+propIndex), newBlank); graph.addTriple(newBlank, str_sio116exp, N3.Util.createLiteral(key)); graph.addTriple(newBlank, str_rdfvalueexp, N3.Util.createLiteral(kvObject[key])); //console.log("added", key, kvObject[key]); } }; ns.hasRelationship = function (graph, id, relationship) { var countProp = graph.countTriples(id, relationship, null); return countProp > 0; }; ns.countBagElements = function(graph, subject) { return graph.countTriples(subject, null, null) - 1; }; ns.getResourcesOfId = function(graph, id) { var result = {}; graph.forEach(function(init_triple){ // iterate over all id relationships // we want everything that is not a simpel key/value property if(init_triple.predicate != str_sio223exp) { var relation = init_triple.predicate; // initialize relation array if never encountered before if(!result.hasOwnProperty(relation)) { result[relation] = []; } // if multiple resources specified, or a single element with several attributes, // blank node is involved, possibly with a bag attribute if(N3.Util.isBlank(init_triple.object)) { var resourceContainer = init_triple.object; graph.forEach(function(triple){ // iterate over the elements of the relationship // relationship may be a bag, and thus contains undesirable rdf:type bag line if(triple.object != str_rdfbagexp) { var resource = triple.object; result[relation].push(resource); } }, resourceContainer, null, null); } else { // simple case, no bag, only 1 resource is linked with 1 attribute var resource = init_triple.object; result[relation].push(resource); } } }, id, null, null); return result; }; /** * returns the id of a newly created blank node representing the HasProperty predicate * if one already exists, returns its id * returns array, potentially several SIO223 present */ ns.getRelationship = function (graph, id, relationship) { if (ns.hasRelationship(graph, id, relationship)) { var object = graph.getObjects(id, relationship, null)[0]; // careful here if (!N3.Util.isBlank(object)){ // object of relationship isn't a bag. Need to turn it into a bag. var newBag = ns.createBag(graph, id, relationship); graph.addTriple(id, relationship, newBag); graph.addTriple(newBag, ns.expandPrefix("rdf:_1"), object); return [newBag]; } else { return graph.getObjects(id, relationship, null); } } else { return [ns.createBag(graph, id, relationship)]; } }; ns.createBag = function (graph, id, relationship) { var newBlank = graph.createBlankNode(); graph.addTriple(id, ns.expandPrefix(relationship), newBlank); graph.addTriple(newBlank, str_rdftypeexp, str_rdfbagexp); return newBlank; }; /** * kvobject contains biology qualifier as key and miriam resource as value */ ns.addResource = function (graph, id, kvObject) { for(var relation in kvObject) { //console.log("relation", relation); var relationElement = ns.getRelationship(graph, id, relation)[0]; // doesn't matter if more than one //console.log("after get relation",relationElement, graph.getTriples(id, relation)); //console.log("after get realtion", graph.getTriples()); // using elemnt count as index may be dangerous if previous manipulation of // the elements has happened. Like removing one. var propIndex = ns.countBagElements(graph, relationElement) + 1; //console.log("elements in bag:", propIndex); //console.log("new blank node", graph.getTriples()); //console.log("Will add", relationElement, ns.expandPrefix("rdf:_"+propIndex), kvObject[relation]); graph.addTriple(relationElement, ns.expandPrefix("rdf:_"+propIndex), kvObject[relation]); //console.log("end result", graph.getTriples()); //console.log("added", relation, kvObject[relation]); } }; module.exports = ns;