libsbgn.js
Version:
SBGN-ML parsing and writing for JavaScript
2,174 lines (1,937 loc) • 48.5 kB
JavaScript
/**
* The API contains two other submodules: {@link libsbgn.render} and {@link libsbgn.annot}
* @module libsbgn
* @namespace libsbgn
*/
var renderExt = require('./libsbgn-render');
var annotExt = require('./libsbgn-annotations');
var xml2js = require('xml2js');
var utils = require('./utilities');
var schematronValidator = require('./schematronValidator');
var checkParams = utils.checkParams;
var ns = {}; // namespace that encapsulates all exportable features
ns.xmlns = "http://sbgn.org/libsbgn/0.3";
// ------- SBGNBase -------
/**
* Parent class for several sbgn elements. Used to provide extension and notes element.
* End users don't need to interact with it. It can be safely ignored.
* @class
* @param {Object} params
* @param {Extension=} params.extension
* @param {Notes=} params.notes
*/
var SBGNBase = function (params) {
var params = checkParams(params, ['extension', 'notes']);
this.extension = params.extension;
this.notes = params.notes;
};
/**
* Allows inheriting objects to get an extension element.
* @param {Extension} extension
*/
SBGNBase.prototype.setExtension = function (extension) {
this.extension = extension;
};
/**
* Allows inheriting objects to get a notes element.
* @param {Notes} notes
*/
SBGNBase.prototype.setNotes = function (notes) {
this.notes = notes;
};
/**
* Add the appropriate properties to jsObj.
* @param {Object} jsObj - xml2js formatted object
*/
SBGNBase.prototype.baseToJsObj = function (jsObj) {
if(this.extension != null) {
jsObj.extension = this.extension.buildJsObj();
}
if(this.notes != null) {
jsObj.notes = this.notes.buildJsObj();
}
};
/**
* Get the appropriate properties from jsObj.
* @param {Object} jsObj - xml2js formatted object
*/
SBGNBase.prototype.baseFromObj = function (jsObj) {
if (jsObj.extension) {
var extension = ns.Extension.fromObj({extension: jsObj.extension[0]});
this.setExtension(extension);
}
if (jsObj.notes) {
var notes = ns.Notes.fromObj({notes: jsObj.notes[0]});
this.setNotes(notes);
}
};
ns.SBGNBase = SBGNBase;
// ------- END SBGNBase -------
// ------- SBGN -------
/**
* Represents the <code><sbgn></code> element.
* @class
* @extends SBGNBase
* @param {Object} params
* @param {string=} params.xmlns
* @param {Map[]=} params.maps
*/
var Sbgn = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['xmlns', 'maps']);
this.xmlns = params.xmlns;
this.maps = params.maps || [];
};
Sbgn.prototype = Object.create(ns.SBGNBase.prototype);
Sbgn.prototype.constructor = Sbgn;
/**
* @param {Map} map
*/
Sbgn.prototype.addMap = function (map) {
this.maps.push(map);
};
/**
* @return {Object} - xml2js formatted object
*/
Sbgn.prototype.buildJsObj = function () {
var sbgnObj = {};
// attributes
var attributes = {};
if(this.xmlns != null) {
attributes.xmlns = this.xmlns;
}
utils.addAttributes(sbgnObj, attributes);
// children
this.baseToJsObj(sbgnObj);
for(var i=0; i < this.maps.length; i++) {
if (i==0) {
sbgnObj.map = [];
}
sbgnObj.map.push(this.maps[i].buildJsObj());
}
return sbgnObj;
};
/**
* @return {string}
*/
Sbgn.prototype.toXML = function () {
return utils.buildString({sbgn: this.buildJsObj()});
};
/**
* @param {String} file
* @return {Issue[]}
*/
Sbgn.doValidation = function (file) {
return schematronValidator.doValidation(file);
};
/**
* @param {String} string
* @return {Sbgn}
*/
Sbgn.fromXML = function (string) {
var sbgn;
function fn (err, result) {
sbgn = Sbgn.fromObj(result);
}
utils.parseString(string, fn);
return sbgn;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Sbgn}
*/
Sbgn.fromObj = function (jsObj) {
if (typeof jsObj.sbgn == 'undefined') {
throw new Error("Bad XML provided, expected tagName sbgn, got: " + Object.keys(jsObj)[0]);
}
var sbgn = new ns.Sbgn();
jsObj = jsObj.sbgn;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return sbgn;
}
if(jsObj.$) { // we have some atributes
var attributes = jsObj.$;
sbgn.xmlns = attributes.xmlns || null;
// getting attribute with 'xmlns' doesn't work if some namespace is defined like 'xmlns:sbgn'
// so if there is some attribute there, and we didn't find the xmlns directly, we need to into it
if(!sbgn.xmlns && Object.keys(attributes).length > 0) {
// sbgn is not supposed to have any other attribute than an xmlns, so we assume the first attr is the xmlns
var key = Object.keys(attributes)[0];
if(key.startsWith('xmlns')) {
sbgn.xmlns = attributes[key];
sbgn.namespacePrefix = key.replace('xmlns:', '');
}
else {
throw new Error("Couldn't find xmlns definition in sbgn element");
}
}
}
if(jsObj.map) {
var maps = jsObj.map;
for (var i=0; i < maps.length; i++) {
var map = ns.Map.fromObj({map: maps[i]});
sbgn.addMap(map);
}
}
sbgn.baseFromObj(jsObj); // call to parent class
return sbgn;
};
ns.Sbgn = Sbgn;
// ------- END SBGN -------
// ------- MAP -------
/**
* Represents the <code><map></code> element.
* @class
* @extends SBGNBase
* @param {Object} params
* @param {string=} params.id
* @param {string=} params.language
* @param {string=} params.version
* @param {Glyph[]=} params.glyphs
* @param {Arc[]=} params.arcs
* @param {Bbox=} params.bbox
* @param {Arcgroup[]=} params.arcgroups
*/
var Map = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['id', 'language', 'version', 'glyphs', 'arcs', 'bbox', 'arcgroups']);
this.id = params.id;
this.language = params.language;
this.version = params.version;
this.bbox = params.bbox;
this.glyphs = params.glyphs || [];
this.arcs = params.arcs || [];
this.arcgroups = params.arcgroups || [];
};
Map.prototype = Object.create(ns.SBGNBase.prototype);
Map.prototype.constructor = Map;
/**
* @param {Glyph} glyph
*/
Map.prototype.addGlyph = function (glyph) {
this.glyphs.push(glyph);
};
/**
* @param {Arc} arc
*/
Map.prototype.addArc = function (arc) {
this.arcs.push(arc);
};
/**
* @param {Bbox} bbox
*/
Map.prototype.setBbox = function (bbox) {
this.bbox = bbox;
};
/**
* @param {Arcgroup} arc
*/
Map.prototype.addArcgroup = function (arcgroup) {
this.arcgroups.push(arcgroup);
};
/**
* @param {string} class_
* @return {Gyph[]}
*/
Map.prototype.getGlyphsByClass = function (class_) {
var resultGlyphs = [];
for(var i=0; i < this.glyphs.length; i++) {
var glyph = this.glyphs[i];
if(glyph.class_ == class_) {
resultGlyphs.push(glyph);
}
}
return resultGlyphs;
};
/**
* @return {Object} - xml2js formatted object
*/
Map.prototype.buildJsObj = function () {
var mapObj = {};
// attributes
var attributes = {};
if(this.id != null) {
attributes.id = this.id;
}
if(this.language != null) {
attributes.language = this.language;
}
if(this.version != null) {
attributes.version = this.version;
}
utils.addAttributes(mapObj, attributes);
// children
this.baseToJsObj(mapObj);
if(this.bbox != null) {
mapObj.bbox = this.bbox.buildJsObj();
}
for(var i=0; i < this.glyphs.length; i++) {
if (i==0) {
mapObj.glyph = [];
}
mapObj.glyph.push(this.glyphs[i].buildJsObj());
}
for(var i=0; i < this.arcs.length; i++) {
if (i==0) {
mapObj.arc = [];
}
mapObj.arc.push(this.arcs[i].buildJsObj());
}
for(var i=0; i < this.arcgroups.length; i++) {
if (i==0) {
mapObj.arcgroup = [];
}
mapObj.arcgroup.push(this.arcgroups[i].buildJsObj());
}
return mapObj;
};
/**
* @return {string}
*/
Map.prototype.toXML = function () {
return utils.buildString({map: this.buildJsObj()});
};
/**
* @param {String} string
* @return {Map}
*/
Map.fromXML = function (string) {
var map;
function fn (err, result) {
map = Map.fromObj(result);
};
utils.parseString(string, fn);
return map;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Map}
*/
Map.fromObj = function (jsObj) {
if (typeof jsObj.map == 'undefined') {
throw new Error("Bad XML provided, expected tagName map, got: " + Object.keys(jsObj)[0]);
}
var map = new ns.Map();
jsObj = jsObj.map;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return map;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
map.id = attributes.id || null;
map.language = attributes.language || null;
map.version = attributes.version || null;
}
if(jsObj.bbox) {
var bbox = ns.Bbox.fromObj({bbox: jsObj.bbox[0]});
map.setBbox(bbox);
}
if(jsObj.glyph) {
var glyphs = jsObj.glyph;
for (var i=0; i < glyphs.length; i++) {
var glyph = ns.Glyph.fromObj({glyph: glyphs[i]});
map.addGlyph(glyph);
}
}
if(jsObj.arc) {
var arcs = jsObj.arc;
for (var i=0; i < arcs.length; i++) {
var arc = ns.Arc.fromObj({arc: arcs[i]});
map.addArc(arc);
}
}
if(jsObj.arcgroup) {
var arcgroups = jsObj.arcgroup;
for (var i=0; i < arcgroups.length; i++) {
var arcgroup = ns.Arcgroup.fromObj({arcgroup: arcgroups[i]});
map.addArcgroup(arcgroup);
}
}
map.baseFromObj(jsObj);
return map;
};
ns.Map = Map;
// ------- END MAP -------
// ------- EXTENSION -------
/**
* Represents the <code><extension></code> element.
* @class
*/
var Extension = function () {
// consider first order children, add them with their tagname as property of this object
// store string if no supported parsing (unrecognized extensions)
// else store instance of the extension
this.list = {};
};
/**
* @param {String|render.RenderInformation|annot.Annotation} extension
*/
Extension.prototype.add = function (extension) {
if (extension instanceof renderExt.RenderInformation) {
this.list['renderInformation'] = extension;
}
else if (extension instanceof annotExt.Annotation) {
this.list['annotation'] = extension;
}
else if(typeof extension == "string") {
var parsedAsObj;
function fn (err, result) {
parsedAsObj = result;
};
utils.parseString(extension, fn);
var name = Object.keys(parsedAsObj)[0];
if(name == "renderInformation") {
var renderInformation = renderExt.RenderInformation.fromXML(extension);
this.list['renderInformation'] = renderInformation;
}
else if(name == "annotation") {
var annotation = annotExt.Annotation.fromXML(extension);
this.list['annotation'] = renderInformation;
}
else {
this.list[name] = extension;
}
}
};
/**
* @param {string} extensionName
* @return {boolean}
*/
Extension.prototype.has = function (extensionName) {
return this.list.hasOwnProperty(extensionName);
};
/**
* @param {string} extensionName
* @return {String|render.RenderInformation|annot.Annotation}
*/
Extension.prototype.get = function (extensionName) {
if (this.has(extensionName)) {
return this.list[extensionName];
}
else {
return null;
}
};
/**
* @return {Object} - xml2js formatted object
*/
Extension.prototype.buildJsObj = function () {
var extensionObj = {};
for (var extInstance in this.list) {
if (extInstance == "renderInformation") {
extensionObj.renderInformation = this.get(extInstance).buildJsObj();
}
else if (extInstance == "annotation") {
extensionObj.annotation = this.get(extInstance).buildJsObj();
}
else {
// unsupported extensions are stored as is, as xml string
// we need to parse it to build the js object
var unsupportedExtObj;
function fn (err, result) {
unsupportedExtObj = result;
};
utils.parseString(this.get(extInstance), fn);
extensionObj[extInstance] = unsupportedExtObj[extInstance];
}
}
return extensionObj;
};
/**
* @return {string}
*/
Extension.prototype.toXML = function () {
return utils.buildString({extension: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Extension}
*/
Extension.fromXML = function (string) {
var extension;
function fn (err, result) {
extension = Extension.fromObj(result);
};
utils.parseString(string, fn);
return extension;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Extension}
*/
Extension.fromObj = function (jsObj) {
if (typeof jsObj.extension == 'undefined') {
throw new Error("Bad XML provided, expected tagName extension, got: " + Object.keys(jsObj)[0]);
}
var extension = new Extension();
jsObj = jsObj.extension;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return extension;
}
//var children = Object.keys(jsObj);
for (var extName in jsObj) {
//var extName = Object.keys(jsObj[i])[0];
var extJsObj = jsObj[extName];
//extension.add(extInstance);
if (extName === 'renderInformation' ||
extName.endsWith(':renderInformation')) {
var renderInformation = renderExt.RenderInformation.fromObj({renderInformation: extJsObj[0]});
extension.add(renderInformation);
}
else if (extName == 'annotation') {
var annotation = annotExt.Annotation.fromObj({annotation: extJsObj[0]});
extension.add(annotation);
}
else { // unsupported extension, we still store the data as is
var unsupportedExt = {};
unsupportedExt[extName] = extJsObj[0]; // make extension serialisable
var stringExt = utils.buildString(unsupportedExt); // serialise to string
extension.add(stringExt); // save it
}
}
return extension;
};
ns.Extension = Extension;
// ------- END EXTENSION -------
// ------- NOTES -------
/**
* Represents the <code><notes></code> element.
* Its single content attribute stores xhtml elements as string.
* @class
*/
var Notes = function () {
this.content = "";
};
/**
* Overwrite the content.
* @param {String} string
*/
Notes.prototype.setContent = function (string) {
this.content = string;
};
/**
* @param {String} string
*/
Notes.prototype.appendContent = function (string) {
this.content += string;
};
/**
* @return {Object} - xml2js formatted object
*/
Notes.prototype.buildJsObj = function () {
var parsedContent = "";
if(this.content != "") { // xml2js refuses to parse empty strings
utils.parseString(this.content, function (err, result) {
parsedContent = result;
});
}
return parsedContent;
};
/**
* @return {string}
*/
Notes.prototype.toXML = function () {
return utils.buildString({notes: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Notes}
*/
Notes.fromXML = function (string) {
var notes;
function fn (err, result) {
notes = Notes.fromObj(result);
};
utils.parseString(string, fn);
return notes;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Notes}
*/
Notes.fromObj = function (jsObj) {
if (typeof jsObj.notes == 'undefined') {
throw new Error("Bad XML provided, expected tagName notes, got: " + Object.keys(jsObj)[0]);
}
var notes = new Notes();
jsObj = jsObj.notes;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return notes;
}
var stringExt = utils.buildString({notes: jsObj}); // serialise to string
// xml2js does weird things when you just want to serialize the content
// need to include the <notes> root to get it properly, and then remove it in the result string.
stringExt = stringExt.replace('<notes>', '');
stringExt = stringExt.replace('</notes>', '');
notes.content = stringExt; // save it
return notes;
};
ns.Notes = Notes;
// ------- END NOTES -------
// ------- GLYPH -------
/**
* Represents the <code><glyph></code> element.
* @class Glyph
* @extends SBGNBase
* @param {Object} params
* @param {string=} params.id
* @param {string=} params.class_
* @param {string=} params.compartmentRef
* @param {string|number=} params.compartmentOrder
* @param {string=} params.mapRef
* @param {string=} params.tagRef
* @param {string=} params.orientation
* @param {Label=} params.label
* @param {Bbox=} params.bbox
* @param {State=} params.state
* @param {Clone=} params.clone
* @param {Callout=} params.callout
* @param {Entity=} params.entity
* @param {Glyph[]=} params.glyphMembers
* @param {Port[]=} params.ports
*/
var Glyph = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['id', 'class_', 'compartmentRef', 'compartmentOrder', 'mapRef',
'tagRef', 'orientation', 'label', 'bbox', 'glyphMembers', 'ports', 'state', 'clone', 'entity', 'callout']);
this.id = params.id;
this.class_ = params.class_;
this.compartmentRef = params.compartmentRef;
this.compartmentOrder = parseFloat(params.compartmentOrder);
this.mapRef = params.mapRef;
this.tagRef = params.tagRef;
this.orientation = params.orientation;
// children
this.label = params.label;
this.state = params.state;
this.clone = params.clone;
this.callout = params.callout;
this.entity = params.entity;
this.bbox = params.bbox;
this.glyphMembers = params.glyphMembers || []; // case of complex, can have arbitrary list of nested glyphs
this.ports = params.ports || [];
};
Glyph.prototype = Object.create(ns.SBGNBase.prototype);
Glyph.prototype.constructor = Glyph;
/**
* @param {Label} label
*/
Glyph.prototype.setLabel = function (label) {
this.label = label;
};
/**
* @param {State} state
*/
Glyph.prototype.setState = function (state) {
this.state = state;
};
/**
* @param {Bbox} bbox
*/
Glyph.prototype.setBbox = function (bbox) {
this.bbox = bbox;
};
/**
* @param {Clone} clone
*/
Glyph.prototype.setClone = function (clone) {
this.clone = clone;
};
/**
* @param {Callout} callout
*/
Glyph.prototype.setCallout = function (callout) {
this.callout = callout;
};
/**
* @param {Entity} entity
*/
Glyph.prototype.setEntity = function (entity) {
this.entity = entity;
};
/**
* @param {Glyph} glyphMember
*/
Glyph.prototype.addGlyphMember = function (glyphMember) {
this.glyphMembers.push(glyphMember);
};
/**
* @param {Port} port
*/
Glyph.prototype.addPort = function (port) {
this.ports.push(port);
};
/**
* @return {Object} - xml2js formatted object
*/
Glyph.prototype.buildJsObj = function () {
var glyphObj = {};
// attributes
var attributes = {};
if(this.id != null) {
attributes.id = this.id;
}
if(this.class_ != null) {
attributes.class = this.class_;
}
if(this.compartmentRef != null) {
attributes.compartmentRef = this.compartmentRef;
}
if(!isNaN(this.compartmentOrder)) {
attributes.compartmentOrder = this.compartmentOrder;
}
if(this.mapRef != null) {
attributes.mapRef = this.mapRef;
}
if(this.tagRef != null) {
attributes.tagRef = this.tagRef;
}
if(this.orientation != null) {
attributes.orientation = this.orientation;
}
utils.addAttributes(glyphObj, attributes);
// children
this.baseToJsObj(glyphObj);
if(this.label != null) {
glyphObj.label = this.label.buildJsObj();
}
if(this.state != null) {
glyphObj.state = this.state.buildJsObj();
}
if(this.clone != null) {
glyphObj.clone = this.clone.buildJsObj();
}
if(this.callout != null) {
glyphObj.callout = this.callout.buildJsObj();
}
if(this.entity != null) {
glyphObj.entity = this.entity.buildJsObj();
}
if(this.bbox != null) {
glyphObj.bbox = this.bbox.buildJsObj();
}
for(var i=0; i < this.glyphMembers.length; i++) {
if (i==0) {
glyphObj.glyph = [];
}
glyphObj.glyph.push(this.glyphMembers[i].buildJsObj());
}
for(var i=0; i < this.ports.length; i++) {
if (i==0) {
glyphObj.port = [];
}
glyphObj.port.push(this.ports[i].buildJsObj());
}
return glyphObj;
};
/**
* @return {string}
*/
Glyph.prototype.toXML = function () {
return utils.buildString({glyph: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Glyph}
*/
Glyph.fromXML = function (string) {
var glyph;
function fn (err, result) {
glyph = Glyph.fromObj(result);
};
utils.parseString(string, fn);
return glyph;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Glyph}
*/
Glyph.fromObj = function (jsObj) {
if (typeof jsObj.glyph == 'undefined') {
throw new Error("Bad XML provided, expected tagName glyph, got: " + Object.keys(jsObj)[0]);
}
var glyph = new ns.Glyph();
jsObj = jsObj.glyph;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return glyph;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
glyph.id = attributes.id || null;
glyph.class_ = attributes.class || null;
glyph.compartmentRef = attributes.compartmentRef || null;
glyph.compartmentOrder = parseFloat(attributes.compartmentOrder);
glyph.mapRef = attributes.mapRef || null;
glyph.tagRef = attributes.tagRef || null;
glyph.orientation = attributes.orientation || null;
}
// children
if(jsObj.label) {
var label = ns.Label.fromObj({label: jsObj.label[0]});
glyph.setLabel(label);
}
if(jsObj.state) {
var state = ns.State.fromObj({state: jsObj.state[0]});
glyph.setState(state);
}
if(jsObj.clone) {
var clone = ns.Clone.fromObj({clone: jsObj.clone[0]});
glyph.setClone(clone);
}
if(jsObj.callout) {
var callout = ns.Callout.fromObj({callout: jsObj.callout[0]});
glyph.setCallout(callout);
}
if(jsObj.entity) {
var entity = ns.Entity.fromObj({entity: jsObj.entity[0]});
glyph.setEntity(entity);
}
if(jsObj.bbox) {
var bbox = ns.Bbox.fromObj({bbox: jsObj.bbox[0]});
glyph.setBbox(bbox);
}
if(jsObj.glyph) {
var glyphs = jsObj.glyph;
for (var i=0; i < glyphs.length; i++) {
var glyphMember = ns.Glyph.fromObj({glyph: glyphs[i]});
glyph.addGlyphMember(glyphMember);
}
}
if(jsObj.port) {
var ports = jsObj.port;
for (var i=0; i < ports.length; i++) {
var port = ns.Port.fromObj({port: ports[i]});
glyph.addPort(port);
}
}
glyph.baseFromObj(jsObj);
return glyph;
};
ns.Glyph = Glyph;
// ------- END GLYPH -------
// ------- LABEL -------
/**
* Represents the <code><label></code> element.
* @class Label
* @extends SBGNBase
* @param {Object} params
* @param {string=} params.text
* @param {Bbox=} params.bbox
*/
var Label = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['text', 'bbox']);
this.text = params.text;
this.bbox = params.bbox;
};
Label.prototype = Object.create(ns.SBGNBase.prototype);
Label.prototype.constructor = ns.Label;
/**
* @param {Bbox} bbox
*/
Label.prototype.setBbox = function (bbox) {
this.bbox = bbox;
};
/**
* @return {Object} - xml2js formatted object
*/
Label.prototype.buildJsObj = function () {
var labelObj = {};
// attributes
var attributes = {};
if(this.text != null) {
attributes.text = this.text;
}
else { // text is a required attribute
attributes.text = "";
}
// ensure encoding of line breaks is always respected
//attributes.text = attributes.text.replace('\n', '\n'); //'
');
utils.addAttributes(labelObj, attributes);
this.baseToJsObj(labelObj);
if(this.bbox != null) {
labelObj.bbox = this.bbox.buildJsObj();
}
return labelObj;
};
/**
* @return {string}
*/
Label.prototype.toXML = function () {
return utils.buildString({label: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Label}
*/
Label.fromXML = function (string) {
var label;
function fn (err, result) {
label = Label.fromObj(result);
};
utils.parseString(string, fn);
return label;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Label}
*/
Label.fromObj = function (jsObj) {
if (typeof jsObj.label == 'undefined') {
throw new Error("Bad XML provided, expected tagName label, got: " + Object.keys(jsObj)[0]);
}
var label = new ns.Label();
jsObj = jsObj.label;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return label;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
label.text = attributes.text || null;
}
if(jsObj.bbox) {
var bbox = ns.Bbox.fromObj({bbox: jsObj.bbox[0]});
label.setBbox(bbox);
}
label.baseFromObj(jsObj);
return label;
};
ns.Label = Label;
// ------- END LABEL -------
// ------- BBOX -------
/**
* Represents the <code><bbox></code> element.
* @class Bbox
* @extends SBGNBase
* @param {Object} params
* @param {string|number=} params.x
* @param {string|number=} params.y
* @param {string|number=} params.w
* @param {string|number=} params.h
*/
var Bbox = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['x', 'y', 'w', 'h']);
this.x = parseFloat(params.x);
this.y = parseFloat(params.y);
this.w = parseFloat(params.w);
this.h = parseFloat(params.h);
};
Bbox.prototype = Object.create(ns.SBGNBase.prototype);
Bbox.prototype.constructor = ns.Bbox;
/**
* @return {Object} - xml2js formatted object
*/
Bbox.prototype.buildJsObj = function () {
var bboxObj = {};
// attributes
var attributes = {};
if(!isNaN(this.x)) {
attributes.x = this.x;
}
if(!isNaN(this.y)) {
attributes.y = this.y;
}
if(!isNaN(this.w)) {
attributes.w = this.w;
}
if(!isNaN(this.h)) {
attributes.h = this.h;
}
utils.addAttributes(bboxObj, attributes);
this.baseToJsObj(bboxObj);
return bboxObj;
};
/**
* @return {string}
*/
Bbox.prototype.toXML = function () {
return utils.buildString({bbox: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Bbox}
*/
Bbox.fromXML = function (string) {
var bbox;
function fn (err, result) {
bbox = Bbox.fromObj(result);
};
utils.parseString(string, fn);
return bbox;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Bbox}
*/
Bbox.fromObj = function (jsObj) {
if (typeof jsObj.bbox == 'undefined') {
throw new Error("Bad XML provided, expected tagName bbox, got: " + Object.keys(jsObj)[0]);
}
var bbox = new ns.Bbox();
jsObj = jsObj.bbox;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return bbox;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
bbox.x = parseFloat(attributes.x);
bbox.y = parseFloat(attributes.y);
bbox.w = parseFloat(attributes.w);
bbox.h = parseFloat(attributes.h);
}
bbox.baseFromObj(jsObj);
return bbox;
};
ns.Bbox = Bbox;
// ------- END BBOX -------
// ------- STATE -------
/**
* Represents the <code><state></code> element.
* @class State
* @param {Object} params
* @param {string=} params.value
* @param {string=} params.variable
*/
var State = function (params) {
var params = checkParams(params, ['value', 'variable']);
this.value = params.value;
this.variable = params.variable;
};
/**
* @return {Object} - xml2js formatted object
*/
State.prototype.buildJsObj = function () {
var stateObj = {};
// attributes
var attributes = {};
if(this.value != null) {
attributes.value = this.value;
}
if(this.variable != null) {
attributes.variable = this.variable;
}
utils.addAttributes(stateObj, attributes);
return stateObj;
};
/**
* @return {string}
*/
State.prototype.toXML = function () {
return utils.buildString({state: this.buildJsObj()})
};
/**
* @param {String} string
* @return {State}
*/
State.fromXML = function (string) {
var state;
function fn (err, result) {
state = State.fromObj(result);
};
utils.parseString(string, fn);
return state;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {State}
*/
State.fromObj = function (jsObj) {
if (typeof jsObj.state == 'undefined') {
throw new Error("Bad XML provided, expected tagName state, got: " + Object.keys(jsObj)[0]);
}
var state = new ns.State();
jsObj = jsObj.state;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return state;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
state.value = attributes.value || null;
state.variable = attributes.variable || null;
}
return state;
};
ns.State = State;
/**
* @class StateType
* @deprecated Replaced by State
*/
ns.StateType = State;
// ------- END STATE -------
// ------- CLONE -------
/**
* Represents the <code><clone></code> element.
* @class Clone
* @param {Object} params
* @param {string=} params.label
*/
var Clone = function (params) {
var params = checkParams(params, ['label']);
this.label = params.label;
};
/**
* @param {Label} label
*/
Clone.prototype.setLabel = function (label) {
this.label = label;
};
/**
* @return {Object} - xml2js formatted object
*/
Clone.prototype.buildJsObj = function () {
var cloneObj = {};
// children
if(this.label != null) {
cloneObj.label = this.label.buildJsObj();
}
return cloneObj;
};
/**
* @return {string}
*/
Clone.prototype.toXML = function () {
return utils.buildString({clone: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Clone}
*/
Clone.fromXML = function (string) {
var clone;
function fn (err, result) {
clone = Clone.fromObj(result);
};
utils.parseString(string, fn);
return clone;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Clone}
*/
Clone.fromObj = function (jsObj) {
if (typeof jsObj.clone == 'undefined') {
throw new Error("Bad XML provided, expected tagName clone, got: " + Object.keys(jsObj)[0]);
}
var clone = new ns.Clone();
jsObj = jsObj.clone;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return clone;
}
// children
if(jsObj.label) {
var label = ns.Label.fromObj({label: jsObj.label[0]});
clone.setLabel(label);
}
return clone;
};
ns.Clone = Clone;
/**
* @class CloneType
* @deprecated Replaced by Clone
*/
ns.CloneType = Clone;
// ------- END CLONE -------
// ------- ENTITYTYPE -------
/**
* Represents the <code><entity></code> element.
* @class Entity
* @param {Object} params
* @param {string=} params.name
*/
var Entity = function (params) {
var params = checkParams(params, ['name']);
this.name = params.name;
};
/**
* @return {Object} - xml2js formatted object
*/
Entity.prototype.buildJsObj = function () {
var entityObj = {};
// attributes
var attributes = {};
if(this.name != null) {
attributes.name = this.name;
}
utils.addAttributes(entityObj, attributes);
return entityObj;
};
/**
* @return {string}
*/
Entity.prototype.toXML = function () {
return utils.buildString({entity: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Entity}
*/
Entity.fromXML = function (string) {
var entity;
function fn (err, result) {
entity = Entity.fromObj(result);
};
utils.parseString(string, fn);
return entity;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Entity}
*/
Entity.fromObj = function (jsObj) {
if (typeof jsObj.entity == 'undefined') {
throw new Error("Bad XML provided, expected tagName entity, got: " + Object.keys(jsObj)[0]);
}
var entity = new ns.Entity();
jsObj = jsObj.entity;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return entity;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
entity.name = attributes.name || null;
}
return entity;
};
ns.Entity = Entity;
/**
* @class EntityType
* @deprecated Replaced by Entity
*/
ns.EntityType = Entity;
// ------- END ENTITYTYPE -------
// ------- PORT -------
/**
* Represents the <code><port></code> element.
* @class Port
* @param {Object} params
* @param {string=} params.id
* @param {string|number=} params.x
* @param {string|number=} params.y
*/
var Port = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['id', 'x', 'y']);
this.id = params.id;
this.x = parseFloat(params.x);
this.y = parseFloat(params.y);
};
Port.prototype = Object.create(ns.SBGNBase.prototype);
Port.prototype.constructor = ns.Port;
/**
* @return {Object} - xml2js formatted object
*/
Port.prototype.buildJsObj = function () {
var portObj = {};
// attributes
var attributes = {};
if(this.id != null) {
attributes.id = this.id;
}
if(!isNaN(this.x)) {
attributes.x = this.x;
}
if(!isNaN(this.y)) {
attributes.y = this.y;
}
utils.addAttributes(portObj, attributes);
this.baseToJsObj(portObj);
return portObj;
};
/**
* @return {string}
*/
Port.prototype.toXML = function () {
return utils.buildString({port: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Port}
*/
Port.fromXML = function (string) {
var port;
function fn (err, result) {
port = Port.fromObj(result);
};
utils.parseString(string, fn);
return port;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Port}
*/
Port.fromObj = function (jsObj) {
if (typeof jsObj.port == 'undefined') {
throw new Error("Bad XML provided, expected tagName port, got: " + Object.keys(jsObj)[0]);
}
var port = new ns.Port();
jsObj = jsObj.port;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return port;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
port.x = parseFloat(attributes.x);
port.y = parseFloat(attributes.y);
port.id = attributes.id || null;
}
port.baseFromObj(jsObj);
return port;
};
ns.Port = Port;
// ------- END PORT -------
// ------- ARC -------
/**
* Represents the <code><arc></code> element.
* @class Arc
* @param {Object} params
* @param {string=} params.id
* @param {string=} params.class_
* @param {string=} params.source
* @param {string=} params.target
* @param {Start=} params.start
* @param {End=} params.end
* @param {Next=} params.nexts
* @param {Glyph[]=} params.glyphs The arc's cardinality. Possibility to have more than one glyph is left open.
*/
var Arc = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['id', 'class_', 'source', 'target', 'start', 'end', 'nexts', 'glyphs']);
this.id = params.id;
this.class_ = params.class_;
this.source = params.source;
this.target = params.target;
this.start = params.start;
this.end = params.end;
this.nexts = params.nexts || [];
this.glyphs = params.glyphs || [];
};
Arc.prototype = Object.create(ns.SBGNBase.prototype);
Arc.prototype.constructor = ns.Arc;
/**
* @param {Start} start
*/
Arc.prototype.setStart = function (start) {
this.start = start;
};
/**
* @param {End} end
*/
Arc.prototype.setEnd = function (end) {
this.end = end;
};
/**
* @param {Next} next
*/
Arc.prototype.addNext = function (next) {
this.nexts.push(next);
};
/**
* @param {Glyph} glyph
*/
Arc.prototype.addGlyph = function (glyph) {
this.glyphs.push(glyph);
};
/**
* @return {Object} - xml2js formatted object
*/
Arc.prototype.buildJsObj = function () {
var arcObj = {};
// attributes
var attributes = {};
if(this.id != null) {
attributes.id = this.id;
}
if(this.class_ != null) {
attributes.class = this.class_;
}
if(this.source != null) {
attributes.source = this.source;
}
if(this.target != null) {
attributes.target = this.target;
}
utils.addAttributes(arcObj, attributes);
// children
this.baseToJsObj(arcObj);
for(var i=0; i < this.glyphs.length; i++) {
if (i==0) {
arcObj.glyph = [];
}
arcObj.glyph.push(this.glyphs[i].buildJsObj());
}
if(this.start != null) {
arcObj.start = this.start.buildJsObj();
}
if(this.state != null) {
arcObj.state = this.state.buildJsObj();
}
for(var i=0; i < this.nexts.length; i++) {
if (i==0) {
arcObj.next = [];
}
arcObj.next.push(this.nexts[i].buildJsObj());
}
if(this.end != null) {
arcObj.end = this.end.buildJsObj();
}
return arcObj;
};
/**
* @return {string}
*/
Arc.prototype.toXML = function () {
return utils.buildString({arc: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Arc}
*/
Arc.fromXML = function (string) {
var arc;
function fn (err, result) {
arc = Arc.fromObj(result);
};
utils.parseString(string, fn);
return arc;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Arc}
*/
Arc.fromObj = function (jsObj) {
if (typeof jsObj.arc == 'undefined') {
throw new Error("Bad XML provided, expected tagName arc, got: " + Object.keys(jsObj)[0]);
}
var arc = new ns.Arc();
jsObj = jsObj.arc;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return arc;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
arc.id = attributes.id || null;
arc.class_ = attributes.class || null;
arc.source = attributes.source || null;
arc.target = attributes.target || null;
}
// children
if(jsObj.start) {
var start = ns.Start.fromObj({start: jsObj.start[0]});
arc.setStart(start);
}
if(jsObj.next) {
var nexts = jsObj.next;
for (var i=0; i < nexts.length; i++) {
var next = ns.Next.fromObj({next: nexts[i]});
arc.addNext(next);
}
}
if(jsObj.end) {
var end = ns.End.fromObj({end: jsObj.end[0]});
arc.setEnd(end);
}
if(jsObj.glyph) {
var glyphs = jsObj.glyph;
for (var i=0; i < glyphs.length; i++) {
var glyph = ns.Glyph.fromObj({glyph: glyphs[i]});
arc.addGlyph(glyph);
}
}
arc.baseFromObj(jsObj);
return arc;
};
ns.Arc = Arc;
// ------- END ARC -------
// ------- Start -------
/**
* Represents the <code><start></code> element.
* @class Start
* @param {Object} params
* @param {string|number=} params.x
* @param {string|number=} params.y
*/
var Start = function (params) {
var params = checkParams(params, ['x', 'y']);
this.x = parseFloat(params.x);
this.y = parseFloat(params.y);
};
/**
* @return {Object} - xml2js formatted object
*/
Start.prototype.buildJsObj = function () {
var startObj = {};
// attributes
var attributes = {};
if(!isNaN(this.x)) {
attributes.x = this.x;
}
if(!isNaN(this.y)) {
attributes.y = this.y;
}
utils.addAttributes(startObj, attributes);
return startObj;
};
/**
* @return {string}
*/
Start.prototype.toXML = function () {
return utils.buildString({start: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Start}
*/
Start.fromXML = function (string) {
var start;
function fn (err, result) {
start = Start.fromObj(result);
};
utils.parseString(string, fn);
return start;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Start}
*/
Start.fromObj = function (jsObj) {
if (typeof jsObj.start == 'undefined') {
throw new Error("Bad XML provided, expected tagName start, got: " + Object.keys(jsObj)[0]);
}
var start = new ns.Start();
jsObj = jsObj.start;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return start;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
start.x = parseFloat(attributes.x);
start.y = parseFloat(attributes.y);
}
return start;
};
ns.Start = Start;
/**
* @class StartType
* @deprecated Replaced by Start
*/
ns.StartType = Start;
// ------- END Start -------
// ------- End -------
/**
* Represents the <code><end></code> element.
* @class End
* @param {Object} params
* @param {string|number=} params.x
* @param {string|number=} params.y
*/
var End = function (params) {
var params = checkParams(params, ['x', 'y']);
this.x = parseFloat(params.x);
this.y = parseFloat(params.y);
};
/**
* @return {Object} - xml2js formatted object
*/
End.prototype.buildJsObj = function () {
var endObj = {};
// attributes
var attributes = {};
if(!isNaN(this.x)) {
attributes.x = this.x;
}
if(!isNaN(this.y)) {
attributes.y = this.y;
}
utils.addAttributes(endObj, attributes);
return endObj;
};
/**
* @return {string}
*/
End.prototype.toXML = function () {
return utils.buildString({end: this.buildJsObj()})
};
/**
* @param {String} string
* @return {End}
*/
End.fromXML = function (string) {
var end;
function fn (err, result) {
end = End.fromObj(result);
};
utils.parseString(string, fn);
return end;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {End}
*/
End.fromObj = function (jsObj) {
if (typeof jsObj.end == 'undefined') {
throw new Error("Bad XML provided, expected tagName end, got: " + Object.keys(jsObj)[0]);
}
var end = new ns.End();
jsObj = jsObj.end;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return end;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
end.x = parseFloat(attributes.x);
end.y = parseFloat(attributes.y);
}
return end;
};
ns.End = End;
/**
* @class EndType
* @deprecated Replaced by End
*/
ns.EndType = End;
// ------- END End -------
// ------- Next -------
/**
* Represents the <code><next></code> element.
* @class Next
* @param {Object} params
* @param {string|number=} params.x
* @param {string|number=} params.y
*/
var Next = function (params) {
var params = checkParams(params, ['x', 'y']);
this.x = parseFloat(params.x);
this.y = parseFloat(params.y);
};
/**
* @return {Object} - xml2js formatted object
*/
Next.prototype.buildJsObj = function () {
var nextObj = {};
// attributes
var attributes = {};
if(!isNaN(this.x)) {
attributes.x = this.x;
}
if(!isNaN(this.y)) {
attributes.y = this.y;
}
utils.addAttributes(nextObj, attributes);
return nextObj;
};
/**
* @return {string}
*/
Next.prototype.toXML = function () {
return utils.buildString({next: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Next}
*/
Next.fromXML = function (string) {
var next;
function fn (err, result) {
next = Next.fromObj(result);
};
utils.parseString(string, fn);
return next;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Next}
*/
Next.fromObj = function (jsObj) {
if (typeof jsObj.next == 'undefined') {
throw new Error("Bad XML provided, expected tagName next, got: " + Object.keys(jsObj)[0]);
}
var next = new ns.Next();
jsObj = jsObj.next;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return next;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
next.x = parseFloat(attributes.x);
next.y = parseFloat(attributes.y);
}
return next;
};
ns.Next = Next;
/**
* @class NextType
* @deprecated Replaced by Next
*/
ns.NextType = Next;
// ------- END Next -------
// ------- POINT -------
/**
* Represents the <code><point></code> element.
* @class Point
* @param {Object} params
* @param {string|number=} params.x
* @param {string|number=} params.y
*/
var Point = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['x', 'y']);
this.x = parseFloat(params.x);
this.y = parseFloat(params.y);
};
Point.prototype = Object.create(ns.SBGNBase.prototype);
Point.prototype.constructor = Point;
/**
* @return {Object} - xml2js formatted object
*/
Point.prototype.buildJsObj = function () {
var pointJsObj = {};
// attributes
var attributes = {};
if(!isNaN(this.x)) {
attributes.x = this.x;
}
if(!isNaN(this.y)) {
attributes.y = this.y;
}
utils.addAttributes(pointJsObj, attributes);
this.baseToJsObj(pointJsObj);
return pointJsObj;
};
/**
* @return {string}
*/
Point.prototype.toXML = function () {
return utils.buildString({point: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Point}
*/
Point.fromXML = function (string) {
var point;
function fn (err, result) {
point = Point.fromObj(result);
};
utils.parseString(string, fn);
return point;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Point}
*/
Point.fromObj = function (jsObj) {
if (typeof jsObj.point == 'undefined') {
throw new Error("Bad XML provided, expected tagName point, got: " + Object.keys(jsObj)[0]);
}
var point = new ns.Point();
jsObj = jsObj.point;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return point;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
point.x = parseFloat(attributes.x);
point.y = parseFloat(attributes.y);
}
point.baseFromObj(jsObj);
return point;
};
ns.Point = Point;
// ------- END POINT -------
// ------- CALLOUT -------
/**
* Represents the <code><callout></code> element.
* @class Callout
* @param {Object} params
* @param {string=} params.target
* @param {Point=} params.point
*/
var Callout = function (params) {
var params = checkParams(params, ['target', 'point']);
this.target = params.target;
this.point = params.point;
};
/**
* @param {Point} point
*/
Callout.prototype.setPoint = function(point) {
this.point = point;
};
/**
* @return {Object} - xml2js formatted object
*/
Callout.prototype.buildJsObj = function () {
var calloutObj = {};
// attributes
var attributes = {};
if(this.target != null) {
attributes.target = this.target;
}
utils.addAttributes(calloutObj, attributes);
// children
if(this.point != null) {
calloutObj.point = this.point.buildJsObj();
}
return calloutObj;
};
/**
* @return {string}
*/
Callout.prototype.toXML = function () {
return utils.buildString({callout: this.buildJsObj()})
};
/**
* @param {String} string
* @return {Callout}
*/
Callout.fromXML = function (string) {
var callout;
function fn (err, result) {
callout = Callout.fromObj(result);
};
utils.parseString(string, fn);
return callout;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Callout}
*/
Callout.fromObj = function (jsObj) {
if (typeof jsObj.callout == 'undefined') {
throw new Error("Bad XML provided, expected tagName callout, got: " + Object.keys(jsObj)[0]);
}
var callout = new ns.Callout();
jsObj = jsObj.callout;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return callout;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
callout.target = attributes.target || null;
}
// children
if(jsObj.point) {
var point = ns.Point.fromObj({point: jsObj.point[0]});
callout.setPoint(point);
}
return callout;
};
ns.Callout = Callout;
// ------- END CALLOUT -------
// ------- ARCGROUP -------
/**
* Represents the <code><arcgroup></code> element.
* @class
* @extends SBGNBase
* @param {Object} params
* @param {string=} params.class_
* @param {Glyph[]=} params.glyphs
* @param {Arc[]=} params.arcs
*/
var Arcgroup = function (params) {
ns.SBGNBase.call(this, params);
var params = checkParams(params, ['class_', 'glyphs', 'arcs']);
this.class_ = params.class_;
this.glyphs = params.glyphs || [];
this.arcs = params.arcs || [];
};
Arcgroup.prototype = Object.create(ns.SBGNBase.prototype);
Arcgroup.prototype.constructor = Arcgroup;
/**
* @param {Glyph} glyph
*/
Arcgroup.prototype.addGlyph = function (glyph) {
this.glyphs.push(glyph);
};
/**
* @param {Arc} arc
*/
Arcgroup.prototype.addArc = function (arc) {
this.arcs.push(arc);
};
/**
* @return {Object} - xml2js formatted object
*/
Arcgroup.prototype.buildJsObj = function () {
var arcgroupObj = {};
// attributes
var attributes = {};
if(this.class_ != null) {
attributes.class = this.class_;
}
utils.addAttributes(arcgroupObj, attributes);
// children
this.baseToJsObj(arcgroupObj);
for(var i=0; i < this.glyphs.length; i++) {
if (i==0) {
arcgroupObj.glyph = [];
}
arcgroupObj.glyph.push(this.glyphs[i].buildJsObj());
}
for(var i=0; i < this.arcs.length; i++) {
if (i==0) {
arcgroupObj.arc = [];
}
arcgroupObj.arc.push(this.arcs[i].buildJsObj());
}
return arcgroupObj;
};
/**
* @return {string}
*/
Arcgroup.prototype.toXML = function () {
return utils.buildString({arcgroup: this.buildJsObj()});
};
/**
* @param {String} string
* @return {Arcgroup}
*/
Arcgroup.fromXML = function (string) {
var arcgroup;
function fn (err, result) {
arcgroup = Arcgroup.fromObj(result);
};
utils.parseString(string, fn);
return arcgroup;
};
/**
* @param {Object} jsObj - xml2js formatted object
* @return {Arcgroup}
*/
Arcgroup.fromObj = function (jsObj) {
if (typeof jsObj.arcgroup == 'undefined') {
throw new Error("Bad XML provided, expected tagName arcgroup, got: " + Object.keys(jsObj)[0]);
}
var arcgroup = new ns.Arcgroup();
jsObj = jsObj.arcgroup;
if(typeof jsObj != 'object') { // nothing inside, empty xml
return arcgroup;
}
if(jsObj.$) { // we have some attributes
var attributes = jsObj.$;
arcgroup.class_ = attributes.class || null;
}
if(jsObj.glyph) {
var glyphs = jsObj.glyph;
for (var i=0; i < glyphs.length; i++) {
var glyph = ns.Glyph.fromObj({glyph: glyphs[i]});
arcgroup.addGlyph(glyph);
}
}
if(jsObj.arc) {
var arcs = jsObj.arc;
for (var i=0; i < arcs.length; i++) {
var arc = ns.Arc.fromObj({arc: arcs[i]});
arcgroup.addArc(arc);
}
}
arcgroup.baseFromObj(jsObj);
return arcgroup;
};
ns.Arcgroup = Arcgroup;
// ------- END ARCGROUP -------
ns.render = renderExt;
ns.annot = annotExt;
ns.schematronValidator = schematronValidator;
module.exports = ns;