ingenta-lens
Version:
A novel way of seeing content.
102 lines (83 loc) • 2.25 kB
JavaScript
"use strict";
var _ = require("underscore");
var Property = function(graph, path) {
if (!path) {
throw new Error("Illegal argument: path is null/undefined.");
}
this.graph = graph;
this.schema = graph.schema;
_.extend(this, this.resolve(path));
};
Property.Prototype = function() {
this.resolve = function(path) {
var node = this.graph;
var parent = node;
var type = "graph";
var key;
var value;
var idx = 0;
for (; idx < path.length; idx++) {
// TODO: check if the property references a node type
if (type === "graph" || this.schema.types[type] !== undefined) {
// remember the last node type
parent = this.graph.get(path[idx]);
if (parent === undefined) {
//throw new Error("Key error: could not find element for path " + JSON.stringify(path));
return undefined;
}
node = parent;
type = this.schema.properties(parent.type);
value = node;
key = undefined;
} else {
if (parent === undefined) {
//throw new Error("Key error: could not find element for path " + JSON.stringify(path));
return undefined;
}
key = path[idx];
var propName = path[idx];
type = type[propName];
value = parent[key];
if (idx < path.length-1) {
parent = parent[propName];
}
}
}
return {
node: node,
parent: parent,
type: type,
key: key,
value: value
};
};
this.get = function() {
if (this.key !== undefined) {
return this.parent[this.key];
} else {
return this.node;
}
};
this.set = function(value) {
if (this.key !== undefined) {
this.parent[this.key] = this.schema.parseValue(this.baseType, value);
} else {
throw new Error("'set' is only supported for node properties.");
}
};
};
Property.prototype = new Property.Prototype();
Object.defineProperties(Property.prototype, {
baseType: {
get: function() {
if (_.isArray(this.type)) return this.type[0];
else return this.type;
}
},
path: {
get: function() {
return [this.node.id, this.key];
}
}
});
module.exports = Property;