Tabulator v0.8 RDF parser initial commit
This commit is contained in:
parent
b9d7992ba8
commit
53d336681b
|
@ -1,6 +1,6 @@
|
|||
// Identity management and indexing for RDF
|
||||
//
|
||||
// This file provides RDFIndexedFormula a formula (set of triples) which
|
||||
// This file provides IndexedFormula a formula (set of triples) which
|
||||
// indexed by predicate, subject and object.
|
||||
//
|
||||
// It "smushes" (merges into a single node) things which are identical
|
||||
|
@ -15,38 +15,24 @@
|
|||
|
||||
/*jsl:option explicit*/ // Turn on JavaScriptLint variable declaration checking
|
||||
|
||||
owl_ns = "http://www.w3.org/2002/07/owl#";
|
||||
link_ns = "http://www.w3.org/2006/link#";
|
||||
$rdf.IndexedFormula = function() {
|
||||
|
||||
var owl_ns = "http://www.w3.org/2002/07/owl#";
|
||||
// var link_ns = "http://www.w3.org/2007/ont/link#";
|
||||
|
||||
/* hashString functions are used as array indeces. This is done to avoid
|
||||
** conflict with existing properties of arrays such as length and map.
|
||||
** See issue 139.
|
||||
*/
|
||||
RDFLiteral.prototype.hashString = RDFLiteral.prototype.toNT;
|
||||
RDFSymbol.prototype.hashString = RDFSymbol.prototype.toNT;
|
||||
RDFBlankNode.prototype.hashString = RDFBlankNode.prototype.toNT;
|
||||
RDFCollection.prototype.hashString = RDFCollection.prototype.toNT;
|
||||
|
||||
RDFIndexedFormula.prototype = new RDFFormula();
|
||||
RDFIndexedFormula.prototype.constructor = RDFIndexedFormula;
|
||||
// RDFIndexedFormula.superclass = RDFFormula.prototype;
|
||||
RDFIndexedFormula.SuperClass = RDFFormula;
|
||||
|
||||
RDFArrayRemove = function(a, x) { //removes all elements equal to x from a
|
||||
for(var i=0; i<a.length; i++) {
|
||||
if (a[i] == x) {
|
||||
a.splice(i,1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw "RDFArrayRemove: Array did not contain " + x;
|
||||
};
|
||||
|
||||
$rdf.Literal.prototype.hashString = $rdf.Literal.prototype.toNT;
|
||||
$rdf.Symbol.prototype.hashString = $rdf.Symbol.prototype.toNT;
|
||||
$rdf.BlankNode.prototype.hashString = $rdf.BlankNode.prototype.toNT;
|
||||
$rdf.Collection.prototype.hashString = $rdf.Collection.prototype.toNT;
|
||||
|
||||
|
||||
//Stores an associative array that maps URIs to functions
|
||||
function RDFIndexedFormula(features) {
|
||||
this.statements = []; // As in RDFFormula
|
||||
$rdf.IndexedFormula = function(features) {
|
||||
this.statements = []; // As in Formula
|
||||
this.optional = [];
|
||||
this.propertyActions = []; // Array of functions to call when getting statement with {s X o}
|
||||
//maps <uri> to [f(F,s,p,o),...]
|
||||
|
@ -60,12 +46,10 @@ function RDFIndexedFormula(features) {
|
|||
this.whyIndex = []; // Array of statements with X as provenance
|
||||
this.index = [ this.subjectIndex, this.predicateIndex, this.objectIndex, this.whyIndex ];
|
||||
this.namespaces = {} // Dictionary of namespace prefixes
|
||||
if (features == undefined) features = ["sameAs",
|
||||
if (features === undefined) features = ["sameAs",
|
||||
"InverseFunctionalProperty", "FunctionalProperty"];
|
||||
// this.features = features
|
||||
|
||||
// Callbackify?
|
||||
|
||||
function handleRDFType(formula, subj, pred, obj, why) {
|
||||
if (formula.typeCallback != undefined)
|
||||
formula.typeCallback(formula, obj, why);
|
||||
|
@ -85,36 +69,21 @@ function RDFIndexedFormula(features) {
|
|||
'<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>'] = [ handleRDFType ];
|
||||
|
||||
// Assumption: these terms are not redirected @@fixme
|
||||
if (features.indexOf("sameAs") >=0)
|
||||
if ($rdf.Util.ArrayIndexOf(features,"sameAs") >= 0)
|
||||
this.propertyActions['<http://www.w3.org/2002/07/owl#sameAs>'] = [
|
||||
function(formula, subj, pred, obj, why) {
|
||||
// tabulator.log.warn("Equating "+subj.uri+" sameAs "+obj.uri); //@@
|
||||
formula.equate(subj,obj);
|
||||
return true; // true if statement given is NOT needed in the store
|
||||
}]; //sameAs -> equate & don't add to index
|
||||
/*
|
||||
function newPropertyAction(formula, pred, action) {
|
||||
tabulator.log.debug("newPropertyAction: "+pred);
|
||||
if (formula.propertyActions[pred] == undefined)
|
||||
formula.propertyActions[pred] = [];
|
||||
formula.propertyActions[pred].push(action);
|
||||
// Now apply the function to to statements already in the store
|
||||
var toBeFixed = formula.statementsMatching(undefined, pred, undefined);
|
||||
var i;
|
||||
for (i=0; i<toBeFixed.length; i++) { // NOT optimized - sort toBeFixed etc
|
||||
if (action(formula, toBeFixed[i].subject, pred, toBeFixed[i].object)) {
|
||||
tabulator.log.debug("newPropertyAction: NOT removing "+toBeFixed[i]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
if (features.indexOf("InverseFunctionalProperty") >= 0)
|
||||
|
||||
if ($rdf.Util.ArrayIndexOf(features,"InverseFunctionalProperty") >= 0)
|
||||
this.classActions["<"+owl_ns+"InverseFunctionalProperty>"] = [
|
||||
function(formula, subj, pred, obj, addFn) {
|
||||
return formula.newPropertyAction(subj, handle_IFP); // yes subj not pred!
|
||||
}]; //IFP -> handle_IFP, do add to index
|
||||
|
||||
if (features.indexOf("FunctionalProperty") >= 0)
|
||||
if ($rdf.Util.ArrayIndexOf(features,"FunctionalProperty") >= 0)
|
||||
this.classActions["<"+owl_ns+"FunctionalProperty>"] = [
|
||||
function(formula, subj, proj, obj, addFn) {
|
||||
return formula.newPropertyAction(subj, handle_FP);
|
||||
|
@ -123,6 +92,7 @@ function RDFIndexedFormula(features) {
|
|||
function handle_IFP(formula, subj, pred, obj) {
|
||||
var s1 = formula.any(undefined, pred, obj);
|
||||
if (s1 == undefined) return false; // First time with this value
|
||||
// tabulator.log.warn("Equating "+s1.uri+" and "+subj.uri + " because IFP "+pred.uri); //@@
|
||||
formula.equate(s1, subj);
|
||||
return true;
|
||||
} //handle_IFP
|
||||
|
@ -130,17 +100,19 @@ function RDFIndexedFormula(features) {
|
|||
function handle_FP(formula, subj, pred, obj) {
|
||||
var o1 = formula.any(subj, pred, undefined);
|
||||
if (o1 == undefined) return false; // First time with this value
|
||||
// tabulator.log.warn("Equating "+o1.uri+" and "+obj.uri + " because FP "+pred.uri); //@@
|
||||
formula.equate(o1, obj);
|
||||
return true ;
|
||||
} //handle_FP
|
||||
|
||||
} /* end RDFIndexedFormula */
|
||||
|
||||
} /* end IndexedFormula */
|
||||
|
||||
$rdf.IndexedFormula.prototype = new $rdf.Formula();
|
||||
$rdf.IndexedFormula.prototype.constructor = $rdf.IndexedFormula;
|
||||
$rdf.IndexedFormula.SuperClass = $rdf.Formula;
|
||||
|
||||
|
||||
RDFIndexedFormula.prototype.newPropertyAction = function newPropertyAction(pred, action) {
|
||||
tabulator.log.debug("newPropertyAction: "+pred);
|
||||
$rdf.IndexedFormula.prototype.newPropertyAction = function newPropertyAction(pred, action) {
|
||||
//$rdf.log.debug("newPropertyAction: "+pred);
|
||||
var hash = pred.hashString();
|
||||
if (this.propertyActions[hash] == undefined)
|
||||
this.propertyActions[hash] = [];
|
||||
|
@ -154,15 +126,9 @@ RDFIndexedFormula.prototype.newPropertyAction = function newPropertyAction(pred,
|
|||
return done;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
RDFPlainFormula = function() { return RDFIndexedFormula([]); } // No features
|
||||
|
||||
|
||||
RDFIndexedFormula.prototype.setPrefixForURI = function(prefix, nsuri) {
|
||||
$rdf.IndexedFormula.prototype.setPrefixForURI = function(prefix, nsuri) {
|
||||
//TODO:This is a hack for our own issues, which ought to be fixed post-release
|
||||
//See http://dig.csail.mit.edu/cgi-bin/roundup.cgi/tabulator/issue227
|
||||
//See http://dig.csail.mit.edu/cgi-bin/roundup.cgi/$rdf/issue227
|
||||
if(prefix=="tab" && this.namespaces["tab"]) {
|
||||
return;
|
||||
}
|
||||
|
@ -170,33 +136,36 @@ RDFIndexedFormula.prototype.setPrefixForURI = function(prefix, nsuri) {
|
|||
}
|
||||
|
||||
// Deprocated ... name too generic
|
||||
RDFIndexedFormula.prototype.register = function(prefix, nsuri) {
|
||||
$rdf.IndexedFormula.prototype.register = function(prefix, nsuri) {
|
||||
this.namespaces[prefix] = nsuri
|
||||
}
|
||||
|
||||
|
||||
/** simplify graph in store when we realize two identifiers are equal
|
||||
/** simplify graph in store when we realize two identifiers are equivalent
|
||||
|
||||
We replace the bigger with the smaller.
|
||||
|
||||
*/
|
||||
RDFIndexedFormula.prototype.equate = function(u1, u2) {
|
||||
tabulator.log.debug("Equating "+u1+" and "+u2)
|
||||
|
||||
$rdf.IndexedFormula.prototype.equate = function(u1, u2) {
|
||||
// tabulator.log.warn("Equating "+u1+" and "+u2); // @@
|
||||
//@@JAMBO Must canonicalize the uris to prevent errors from a=b=c
|
||||
//03-21-2010
|
||||
u1 = this.canon( u1 );
|
||||
u2 = this.canon( u2 );
|
||||
var d = u1.compareTerm(u2);
|
||||
if (!d) return true; // No information in {a = a}
|
||||
var big, small;
|
||||
if (d < 0) { // u1 less than u2
|
||||
return this.replaceWith(u2, u1);
|
||||
return this.replaceWith(u2, u1);
|
||||
} else {
|
||||
return this.replaceWith(u1, u2);
|
||||
return this.replaceWith(u1, u2);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace big with small, obsoleted with obsoleting.
|
||||
//
|
||||
RDFIndexedFormula.prototype.replaceWith = function(big, small) {
|
||||
tabulator.log.debug("Replacing "+big+" with "+small) // @@
|
||||
$rdf.IndexedFormula.prototype.replaceWith = function(big, small) {
|
||||
//$rdf.log.debug("Replacing "+big+" with "+small) // @@
|
||||
var oldhash = big.hashString();
|
||||
var newhash = small.hashString();
|
||||
|
||||
|
@ -205,7 +174,7 @@ RDFIndexedFormula.prototype.replaceWith = function(big, small) {
|
|||
if (oldlist == undefined) return; // none to move
|
||||
var newlist = ix[newhash];
|
||||
if (newlist == undefined) {
|
||||
ix[newhash] = newlist;
|
||||
ix[newhash] = oldlist;
|
||||
} else {
|
||||
ix[newhash] = oldlist.concat(newlist);
|
||||
}
|
||||
|
@ -219,28 +188,35 @@ RDFIndexedFormula.prototype.replaceWith = function(big, small) {
|
|||
|
||||
this.redirections[oldhash] = small;
|
||||
if (big.uri) {
|
||||
if (this.aliases[newhash] == undefined)
|
||||
this.aliases[newhash] = [];
|
||||
this.aliases[newhash].push(big); // Back link
|
||||
|
||||
this.add(small, this.sym('http://www.w3.org/2006/link#uri'), big.uri)
|
||||
|
||||
// If two things are equal, and one is requested, we should request the other.
|
||||
if (this.sf) {
|
||||
this.sf.nowKnownAs(big, small)
|
||||
}
|
||||
|
||||
//@@JAMBO: must update redirections,aliases from sub-items, too.
|
||||
if (this.aliases[newhash] == undefined)
|
||||
this.aliases[newhash] = [];
|
||||
this.aliases[newhash].push(big); // Back link
|
||||
|
||||
if( this.aliases[oldhash] ) {
|
||||
for( var i = 0; i < this.aliases[oldhash].length; i++ ) {
|
||||
this.redirections[this.aliases[oldhash][i].hashString()] = small;
|
||||
this.aliases[newhash].push(this.aliases[oldhash][i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.add(small, this.sym('http://www.w3.org/2007/ont/link#uri'), big.uri)
|
||||
|
||||
// If two things are equal, and one is requested, we should request the other.
|
||||
if (this.sf) {
|
||||
this.sf.nowKnownAs(big, small)
|
||||
}
|
||||
}
|
||||
|
||||
moveIndex(this.classActions);
|
||||
moveIndex(this.propertyActions);
|
||||
|
||||
tabulator.log.debug("Equate done. "+big+" to be known as "+small)
|
||||
//$rdf.log.debug("Equate done. "+big+" to be known as "+small)
|
||||
return true; // true means the statement does not need to be put in
|
||||
};
|
||||
|
||||
// Return the symbol with canonical URI as smushed
|
||||
RDFIndexedFormula.prototype.canon = function(term) {
|
||||
$rdf.IndexedFormula.prototype.canon = function(term) {
|
||||
if (term == undefined) return term;
|
||||
var y = this.redirections[term.hashString()];
|
||||
if (y == undefined) return term;
|
||||
|
@ -248,7 +224,7 @@ RDFIndexedFormula.prototype.canon = function(term) {
|
|||
}
|
||||
|
||||
// Compare by canonical URI as smushed
|
||||
RDFIndexedFormula.prototype.sameThings = function(x, y) {
|
||||
$rdf.IndexedFormula.prototype.sameThings = function(x, y) {
|
||||
if (x.sameTerm(y)) return true;
|
||||
var x1 = this.canon(x);
|
||||
// alert('x1='+x1);
|
||||
|
@ -260,7 +236,7 @@ RDFIndexedFormula.prototype.sameThings = function(x, y) {
|
|||
}
|
||||
|
||||
// A list of all the URIs by which this thing is known
|
||||
RDFIndexedFormula.prototype.uris = function(term) {
|
||||
$rdf.IndexedFormula.prototype.uris = function(term) {
|
||||
var cterm = this.canon(term)
|
||||
var terms = this.aliases[cterm.hashString()];
|
||||
if (!cterm.uri) return []
|
||||
|
@ -277,27 +253,31 @@ RDFIndexedFormula.prototype.uris = function(term) {
|
|||
//
|
||||
function RDFMakeTerm(formula,val, canonicalize) {
|
||||
if (typeof val != 'object') {
|
||||
if (typeof val == 'string')
|
||||
return new RDFLiteral(val);
|
||||
if (typeof val == 'string')
|
||||
return new $rdf.Literal(val);
|
||||
if (typeof val == 'number')
|
||||
return new RDFLiteral(val); // @@ differet types
|
||||
return new $rdf.Literal(val); // @@ differet types
|
||||
if (typeof val == 'boolean')
|
||||
return new RDFLiteral(val?"1":"0", undefined,
|
||||
RDFSymbol.prototype.XSDboolean);
|
||||
else if (typeof val == 'number')
|
||||
return new RDFLiteral(''+val); // @@ datatypes
|
||||
else if (typeof val == 'undefined')
|
||||
return undefined;
|
||||
else // @@ add converting of dates and numbers
|
||||
throw "Can't make Term from " + val + " of type " + typeof val;
|
||||
return new $rdf.Literal(val?"1":"0", undefined,
|
||||
$rdf.Symbol.prototype.XSDboolean);
|
||||
else if (typeof val == 'number')
|
||||
return new $rdf.Literal(''+val); // @@ datatypes
|
||||
else if (typeof val == 'undefined')
|
||||
return undefined;
|
||||
else // @@ add converting of dates and numbers
|
||||
throw "Can't make Term from " + val + " of type " + typeof val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// add a triple to the store
|
||||
RDFIndexedFormula.prototype.add = function(subj, pred, obj, why) {
|
||||
// Add a triple to the store
|
||||
//
|
||||
// Returns the statement added
|
||||
// (would it be better to return the original formula for chaining?)
|
||||
//
|
||||
$rdf.IndexedFormula.prototype.add = function(subj, pred, obj, why) {
|
||||
var actions, st;
|
||||
if (why == undefined) why = this.fetcher ? this.fetcher.appNode: kb.sym("chrome:theSession"); //system generated
|
||||
if (why == undefined) why = this.fetcher ? this.fetcher.appNode: this.sym("chrome:theSession"); //system generated
|
||||
//defined in source.js, is this OK with identity.js only user?
|
||||
subj = RDFMakeTerm(this, subj);
|
||||
pred = RDFMakeTerm(this, pred);
|
||||
|
@ -307,23 +287,7 @@ RDFIndexedFormula.prototype.add = function(subj, pred, obj, why) {
|
|||
var hash = [ this.canon(subj).hashString(), this.canon(pred).hashString(),
|
||||
this.canon(obj).hashString(), this.canon(why).hashString()];
|
||||
|
||||
/* // Removed TimBL 2007-01-06
|
||||
// Check we don't already know it -- esp when working with dbview
|
||||
// db view has many documents with the same triple - a waste.
|
||||
// but is we want to be able to edit documents, we must maintain the original
|
||||
// triples from each one. We might occasionally want to mutiple provences too
|
||||
// for a full Truth Management System. Maybe this should be run-time option.
|
||||
st = this.anyStatementMatching(subj,pred,obj) // @@@@@@@ temp fix <====WATCH OUT!
|
||||
It is general necessary to know when data has come from >1 place.
|
||||
Maybe this should be a mode?
|
||||
*/
|
||||
// This is wasting time and shouldn't happen at all
|
||||
//st = this.anyStatementMatching(subj,pred,obj,why) // Avoid duplicates
|
||||
//if (st != undefined) return; // already in store
|
||||
|
||||
|
||||
|
||||
// tabulator.log.debug("\nActions for "+s+" "+p+" "+o+". size="+this.statements.length)
|
||||
|
||||
if (this.predicateCallback != undefined)
|
||||
this.predicateCallback(this, pred, why);
|
||||
|
||||
|
@ -338,24 +302,24 @@ RDFIndexedFormula.prototype.add = function(subj, pred, obj, why) {
|
|||
}
|
||||
|
||||
//If we are tracking provenanance, every thing should be loaded into the store
|
||||
//if (done) return new RDFStatement(subj, pred, obj, why); // Don't put it in the store
|
||||
//if (done) return new Statement(subj, pred, obj, why); // Don't put it in the store
|
||||
// still return this statement for owl:sameAs input
|
||||
var st = new RDFStatement(subj, pred, obj, why);
|
||||
var st = new $rdf.Statement(subj, pred, obj, why);
|
||||
for (var i=0; i<4; i++) {
|
||||
var ix = this.index[i];
|
||||
var h = hash[i];
|
||||
if (ix[h] == undefined) ix[h] = [];
|
||||
ix[h].push(st); // Set of things with this as subject
|
||||
ix[h].push(st); // Set of things with this as subject, etc
|
||||
}
|
||||
|
||||
tabulator.log.debug("ADDING {"+subj+" "+pred+" "+obj+"} "+why);
|
||||
//$rdf.log.debug("ADDING {"+subj+" "+pred+" "+obj+"} "+why);
|
||||
this.statements.push(st);
|
||||
return st;
|
||||
}; //add
|
||||
|
||||
|
||||
// Find out whether a given URI is used as symbol in the formula
|
||||
RDFIndexedFormula.prototype.mentionsURI = function(uri) {
|
||||
$rdf.IndexedFormula.prototype.mentionsURI = function(uri) {
|
||||
var hash = '<' + uri + '>';
|
||||
return (!!this.subjectIndex[hash] || !!this.objectIndex[hash]
|
||||
|| !!this.predicateIndex[hash]);
|
||||
|
@ -363,15 +327,15 @@ RDFIndexedFormula.prototype.mentionsURI = function(uri) {
|
|||
|
||||
// Find an unused id for a file being edited: return a symbol
|
||||
// (Note: Slow iff a lot of them -- could be O(log(k)) )
|
||||
RDFIndexedFormula.prototype.nextSymbol = function(doc) {
|
||||
$rdf.IndexedFormula.prototype.nextSymbol = function(doc) {
|
||||
for(var i=0;;i++) {
|
||||
var uri = doc.uri + '#n' + i;
|
||||
if (!this.mentionsURI(uri)) return kb.sym(uri);
|
||||
if (!this.mentionsURI(uri)) return this.sym(uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RDFIndexedFormula.prototype.anyStatementMatching = function(subj,pred,obj,why) {
|
||||
$rdf.IndexedFormula.prototype.anyStatementMatching = function(subj,pred,obj,why) {
|
||||
var x = this.statementsMatching(subj,pred,obj,why,true);
|
||||
if (!x || x == []) return undefined;
|
||||
return x[0];
|
||||
|
@ -380,8 +344,8 @@ RDFIndexedFormula.prototype.anyStatementMatching = function(subj,pred,obj,why) {
|
|||
|
||||
// Return statements matching a pattern
|
||||
// ALL CONVENIENCE LOOKUP FUNCTIONS RELY ON THIS!
|
||||
RDFIndexedFormula.prototype.statementsMatching = function(subj,pred,obj,why,justOne) {
|
||||
tabulator.log.debug("Matching {"+subj+" "+pred+" "+obj+"}");
|
||||
$rdf.IndexedFormula.prototype.statementsMatching = function(subj,pred,obj,why,justOne) {
|
||||
//$rdf.log.debug("Matching {"+subj+" "+pred+" "+obj+"}");
|
||||
|
||||
var pat = [ subj, pred, obj, why ];
|
||||
var pattern = [];
|
||||
|
@ -397,10 +361,16 @@ RDFIndexedFormula.prototype.statementsMatching = function(subj,pred,obj,why,just
|
|||
hash[p] = pattern[p].hashString();
|
||||
}
|
||||
}
|
||||
if (given.length == 0) return this.statements; // Easy
|
||||
if (given.length == 0) {
|
||||
return this.statements;
|
||||
}
|
||||
if (given.length == 1) { // Easy too, we have an index for that
|
||||
var p = given[0];
|
||||
var list = this.index[p][hash[p]];
|
||||
if(list && justOne) {
|
||||
if(list.length>1)
|
||||
list = list.slice(0,1);
|
||||
}
|
||||
return list == undefined ? [] : list;
|
||||
}
|
||||
|
||||
|
@ -437,29 +407,33 @@ RDFIndexedFormula.prototype.statementsMatching = function(subj,pred,obj,why,just
|
|||
}
|
||||
if (st != null) results.push(st);
|
||||
}
|
||||
|
||||
if(justOne) {
|
||||
if(results.length>1)
|
||||
results = results.slice(0,1);
|
||||
}
|
||||
return results;
|
||||
}; // statementsMatching
|
||||
|
||||
|
||||
/** remove a particular statement from the bank **/
|
||||
RDFIndexedFormula.prototype.remove = function (st) {
|
||||
tabulator.log.debug("entering remove w/ st=" + st);
|
||||
$rdf.IndexedFormula.prototype.remove = function (st) {
|
||||
//$rdf.log.debug("entering remove w/ st=" + st);
|
||||
var term = [ st.subject, st.predicate, st.object, st.why];
|
||||
for (var p=0; p<4; p++) {
|
||||
var c = this.canon(term[p]);
|
||||
var h = c.hashString();
|
||||
if (this.index[p][h] == undefined) {
|
||||
tabulator.log.warn ("Statement removal: no index '+p+': "+st);
|
||||
//$rdf.log.warn ("Statement removal: no index '+p+': "+st);
|
||||
} else {
|
||||
RDFArrayRemove(this.index[p][h], st);
|
||||
$rdf.Util.RDFArrayRemove(this.index[p][h], st);
|
||||
}
|
||||
}
|
||||
RDFArrayRemove(this.statements, st);
|
||||
$rdf.Util.RDFArrayRemove(this.statements, st);
|
||||
}; //remove
|
||||
|
||||
/** remove all statements matching args (within limit) **/
|
||||
RDFIndexedFormula.prototype.removeMany = function (subj, pred, obj, why, limit) {
|
||||
tabulator.log.debug("entering removeMany w/ subj,pred,obj,why,limit = " + subj +", "+ pred+", " + obj+", " + why+", " + limit);
|
||||
$rdf.IndexedFormula.prototype.removeMany = function (subj, pred, obj, why, limit) {
|
||||
//$rdf.log.debug("entering removeMany w/ subj,pred,obj,why,limit = " + subj +", "+ pred+", " + obj+", " + why+", " + limit);
|
||||
var sts = this.statementsMatching (subj, pred, obj, why, false);
|
||||
//This is a subtle bug that occcured in updateCenter.js too.
|
||||
//The fact is, this.statementsMatching returns this.whyIndex instead of a copy of it
|
||||
|
@ -468,56 +442,19 @@ RDFIndexedFormula.prototype.removeMany = function (subj, pred, obj, why, limit)
|
|||
var statements = [];
|
||||
for (var i=0;i<sts.length;i++) statements.push(sts[i]);
|
||||
if (limit) statements = statements.slice(0, limit);
|
||||
for (var st in statements) this.remove(statements[st]);
|
||||
for (var i=0;i<statements.length;i++) this.remove(statements[i]);
|
||||
}; //removeMany
|
||||
|
||||
/** Load a resorce into the store **/
|
||||
|
||||
RDFIndexedFormula.prototype.load = function(url) {
|
||||
// get the XML
|
||||
var xhr = Util.XMLHTTPFactory(); // returns a new XMLHttpRequest, or ActiveX XMLHTTP object
|
||||
if (xhr.overrideMimeType) {
|
||||
xhr.overrideMimeType("text/xml");
|
||||
}
|
||||
|
||||
// Get privileges for cross-domain web access
|
||||
if(!isExtension) {
|
||||
try {
|
||||
Util.enablePrivilege("UniversalXPConnect UniversalBrowserRead")
|
||||
} catch(e) {
|
||||
throw ("Failed to get privileges: (see http://dig.csail.mit.edu/2005/ajar/ajaw/Privileges.html)" + e)
|
||||
}
|
||||
}
|
||||
|
||||
xhr.open("GET", url, false); // Synchronous
|
||||
xhr.send("");
|
||||
|
||||
// Get XML DOM Tree
|
||||
|
||||
var nodeTree = xhr.responseXML;
|
||||
if (nodeTree === null && xhr.responseText !== null) {
|
||||
// Only if the server fails to set Content-Type: text/xml AND xmlhttprequest doesn't have the overrideMimeType method
|
||||
nodeTree = (new DOMParser()).parseFromString(xhr.responseText, 'text/xml');
|
||||
}
|
||||
|
||||
// Get RDF statements fromm XML
|
||||
|
||||
// must be an XML document node tree
|
||||
var parser = new RDFParser(this);
|
||||
parser.parse(nodeTree,url);
|
||||
}
|
||||
|
||||
|
||||
/** Utility**/
|
||||
|
||||
/* @method: copyTo
|
||||
@discription: replace @template with @target and add appropriate triples (no triple removed)
|
||||
@description: replace @template with @target and add appropriate triples (no triple removed)
|
||||
one-direction replication
|
||||
*/
|
||||
RDFIndexedFormula.prototype.copyTo = function(template,target,flags){
|
||||
$rdf.IndexedFormula.prototype.copyTo = function(template,target,flags){
|
||||
if (!flags) flags=[];
|
||||
var statList=this.statementsMatching(template);
|
||||
if (flags.indexOf('two-direction')!=-1)
|
||||
if ($rdf.Util.ArrayIndexOf(flags,'two-direction')!=-1)
|
||||
statList.concat(this.statementsMatching(undefined,undefined,template));
|
||||
for (var i=0;i<statList.length;i++){
|
||||
var st=statList[i];
|
||||
|
@ -530,64 +467,50 @@ RDFIndexedFormula.prototype.copyTo = function(template,target,flags){
|
|||
case 'collection':
|
||||
this.add(target,st.predicate,st.object.copy(this));
|
||||
}
|
||||
if (flags.indexOf('delete')!=-1) this.remove(st);
|
||||
if ($rdf.Util.ArrayIndexOf(flags,'delete')!=-1) this.remove(st);
|
||||
}
|
||||
};
|
||||
//for the case when you alter this.value (text modified in userinput.js)
|
||||
RDFLiteral.prototype.copy = function(){
|
||||
return new RDFLiteral(this.value,this.lang,this.datatype);
|
||||
$rdf.Literal.prototype.copy = function(){
|
||||
return new $rdf.Literal(this.value,this.lang,this.datatype);
|
||||
};
|
||||
RDFBlankNode.prototype.copy = function(formula){ //depends on the formula
|
||||
var bnodeNew=new RDFBlankNode();
|
||||
$rdf.BlankNode.prototype.copy = function(formula){ //depends on the formula
|
||||
var bnodeNew=new $rdf.BlankNode();
|
||||
formula.copyTo(this,bnodeNew);
|
||||
return bnodeNew;
|
||||
}
|
||||
/** Full N3 bits -- placeholders only to allow parsing, no functionality! **/
|
||||
|
||||
RDFIndexedFormula.prototype.newUniversal = function(uri) {
|
||||
$rdf.IndexedFormula.prototype.newUniversal = function(uri) {
|
||||
var x = this.sym(uri);
|
||||
if (!this._universalVariables) this._universalVariables = [];
|
||||
this._universalVariables.push(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
RDFIndexedFormula.prototype.newExistential = function(uri) {
|
||||
$rdf.IndexedFormula.prototype.newExistential = function(uri) {
|
||||
if (!uri) return this.bnode();
|
||||
var x = this.sym(uri);
|
||||
return this.declareExistential(x);
|
||||
}
|
||||
|
||||
RDFIndexedFormula.prototype.declareExistential = function(x) {
|
||||
$rdf.IndexedFormula.prototype.declareExistential = function(x) {
|
||||
if (!this._existentialVariables) this._existentialVariables = [];
|
||||
this._existentialVariables.push(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
RDFIndexedFormula.prototype.formula = function(features) {
|
||||
return new RDFIndexedFormula(features);
|
||||
$rdf.IndexedFormula.prototype.formula = function(features) {
|
||||
return new $rdf.IndexedFormula(features);
|
||||
}
|
||||
|
||||
RDFIndexedFormula.prototype.close = function() {
|
||||
$rdf.IndexedFormula.prototype.close = function() {
|
||||
return this;
|
||||
}
|
||||
|
||||
RDFIndexedFormula.prototype.hashString = RDFIndexedFormula.prototype.toNT;
|
||||
|
||||
///////////////////////////// Provenance tracking
|
||||
//
|
||||
// Where did this statement come from?
|
||||
//
|
||||
|
||||
/*
|
||||
RDFStatement.prototype.original = function() {
|
||||
for (var st = this;; st = st.why.premis[0]) {
|
||||
if (st.why.termType && st.why.termType== 'symbol')
|
||||
return this; // This statement came from a document
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$rdf.IndexedFormula.prototype.hashString = $rdf.IndexedFormula.prototype.toNT;
|
||||
|
||||
return $rdf.IndexedFormula;
|
||||
|
||||
}();
|
||||
// ends
|
||||
|
||||
|
|
|
@ -6,74 +6,34 @@
|
|||
// We retpresent a set as an associative array whose value for
|
||||
// each member is set to true.
|
||||
|
||||
/* Not used, bogus. See identity.js for the ones really used.
|
||||
RDFFormula.prototype.statementsMatching = function(s,p,o,w) {
|
||||
var results = []
|
||||
var i
|
||||
var ls = this.statements.length
|
||||
for (i=0; i<ls; i++) {
|
||||
var st = this.statements[i]
|
||||
if (RDFTermMatch(p, st.predicate) && // first as simplest
|
||||
RDFTermMatch(s, st.subject) &&
|
||||
RDFTermMatch(o, st.object) &&
|
||||
RDFTermMatch(w, st.why)) {
|
||||
results[st] = true @@@@ sould use numeric indexed array
|
||||
}
|
||||
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
RDFFormula.prototype.anyStatementMatching = function(s,p,o,w) {
|
||||
var ls = this.statements.length
|
||||
var i
|
||||
for (i=0; i<ls; i++) {
|
||||
var st = this.statements[i]
|
||||
if (RDFTermMatch(p, st.predicate) && // first as simplest
|
||||
RDFTermMatch(s, st.subject) &&
|
||||
RDFTermMatch(o, st.object) &&
|
||||
RDFTermMatch(w, st.why)) {
|
||||
return st
|
||||
}
|
||||
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
function RDFTermMatch(pattern, term) {
|
||||
if (typeof pattern == 'undefined') return true;
|
||||
return pattern.sameTerm(term)
|
||||
}
|
||||
|
||||
RDFSymbol.prototype.sameTerm = function(other) {
|
||||
$rdf.Symbol.prototype.sameTerm = function(other) {
|
||||
if (!other) { return false }
|
||||
return ((this.termType == other.termType) && (this.uri == other.uri))
|
||||
}
|
||||
|
||||
RDFBlankNode.prototype.sameTerm = function(other) {
|
||||
$rdf.BlankNode.prototype.sameTerm = function(other) {
|
||||
if (!other) { return false }
|
||||
return ((this.termType == other.termType) && (this.id == other.id))
|
||||
}
|
||||
|
||||
RDFLiteral.prototype.sameTerm = function(other) {
|
||||
$rdf.Literal.prototype.sameTerm = function(other) {
|
||||
if (!other) { return false }
|
||||
return ((this.termType == other.termType)
|
||||
&& (this.value == other.value)
|
||||
&& (this.lang == other.lang) &&
|
||||
((!this.datatype && !other.datatype)
|
||||
|| this.datatype.sameTerm(other.datatype)))
|
||||
|| (this.datatype && this.datatype.sameTerm(other.datatype))))
|
||||
}
|
||||
|
||||
RDFVariable.prototype.sameTerm = function (other) {
|
||||
$rdf.Variable.prototype.sameTerm = function (other) {
|
||||
if (!other) { return false }
|
||||
return((this.termType == other.termType) && (this.uri == other.uri))
|
||||
}
|
||||
|
||||
RDFCollection.prototype.sameTerm = RDFBlankNode.prototype.sameTerm
|
||||
$rdf.Collection.prototype.sameTerm = $rdf.BlankNode.prototype.sameTerm
|
||||
|
||||
RDFFormula.prototype.sameTerm = function (other) {
|
||||
$rdf.Formula.prototype.sameTerm = function (other) {
|
||||
return this.hashString() == other.hashString();
|
||||
}
|
||||
// Comparison for ordering
|
||||
|
@ -85,18 +45,16 @@ RDFFormula.prototype.sameTerm = function (other) {
|
|||
// arbitrary: we want the value actually used to be the literal
|
||||
// (or list or formula).
|
||||
|
||||
RDFLiteral.prototype.classOrder = 1
|
||||
// RDFList.prototype.classOrder = 2
|
||||
// RDFSet.prototype.classOrder = 3
|
||||
RDFCollection.prototype.classOrder = 3
|
||||
RDFFormula.prototype.classOrder = 4
|
||||
RDFSymbol.prototype.classOrder = 5
|
||||
RDFBlankNode.prototype.classOrder = 6
|
||||
$rdf.Literal.prototype.classOrder = 1
|
||||
$rdf.Collection.prototype.classOrder = 3
|
||||
$rdf.Formula.prototype.classOrder = 4
|
||||
$rdf.Symbol.prototype.classOrder = 5
|
||||
$rdf.BlankNode.prototype.classOrder = 6
|
||||
|
||||
// Compaisons return sign(self - other)
|
||||
// Literals must come out before terms for smushing
|
||||
|
||||
RDFLiteral.prototype.compareTerm = function(other) {
|
||||
$rdf.Literal.prototype.compareTerm = function(other) {
|
||||
if (this.classOrder < other.classOrder) return -1
|
||||
if (this.classOrder > other.classOrder) return +1
|
||||
if (this.value < other.value) return -1
|
||||
|
@ -104,7 +62,7 @@ RDFLiteral.prototype.compareTerm = function(other) {
|
|||
return 0
|
||||
}
|
||||
|
||||
RDFSymbol.prototype.compareTerm = function(other) {
|
||||
$rdf.Symbol.prototype.compareTerm = function(other) {
|
||||
if (this.classOrder < other.classOrder) return -1
|
||||
if (this.classOrder > other.classOrder) return +1
|
||||
if (this.uri < other.uri) return -1
|
||||
|
@ -112,7 +70,7 @@ RDFSymbol.prototype.compareTerm = function(other) {
|
|||
return 0
|
||||
}
|
||||
|
||||
RDFBlankNode.prototype.compareTerm = function(other) {
|
||||
$rdf.BlankNode.prototype.compareTerm = function(other) {
|
||||
if (this.classOrder < other.classOrder) return -1
|
||||
if (this.classOrder > other.classOrder) return +1
|
||||
if (this.id < other.id) return -1
|
||||
|
@ -120,14 +78,14 @@ RDFBlankNode.prototype.compareTerm = function(other) {
|
|||
return 0
|
||||
}
|
||||
|
||||
RDFCollection.prototype.compareTerm = RDFBlankNode.prototype.compareTerm
|
||||
$rdf.Collection.prototype.compareTerm = $rdf.BlankNode.prototype.compareTerm
|
||||
|
||||
// Convenience routines
|
||||
|
||||
// Only one of s p o can be undefined, and w is optional.
|
||||
RDFFormula.prototype.each = function(s,p,o,w) {
|
||||
$rdf.Formula.prototype.each = function(s,p,o,w) {
|
||||
var results = []
|
||||
var st, sts = this.statementsMatching(s,p,o,w)
|
||||
var st, sts = this.statementsMatching(s,p,o,w,false)
|
||||
var i, n=sts.length
|
||||
if (typeof s == 'undefined') {
|
||||
for (i=0; i<n; i++) {st=sts[i]; results.push(st.subject)}
|
||||
|
@ -141,7 +99,7 @@ RDFFormula.prototype.each = function(s,p,o,w) {
|
|||
return results
|
||||
}
|
||||
|
||||
RDFFormula.prototype.any = function(s,p,o,w) {
|
||||
$rdf.Formula.prototype.any = function(s,p,o,w) {
|
||||
var st = this.anyStatementMatching(s,p,o,w)
|
||||
if (typeof st == 'undefined') return undefined;
|
||||
|
||||
|
@ -152,27 +110,20 @@ RDFFormula.prototype.any = function(s,p,o,w) {
|
|||
return undefined
|
||||
}
|
||||
|
||||
RDFFormula.prototype.the = function(s,p,o,w) {
|
||||
$rdf.Formula.prototype.holds = function(s,p,o,w) {
|
||||
var st = this.anyStatementMatching(s,p,o,w)
|
||||
if (typeof st == 'undefined') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
$rdf.Formula.prototype.the = function(s,p,o,w) {
|
||||
// the() should contain a check there is only one
|
||||
var x = this.any(s,p,o,w)
|
||||
if (typeof x == 'undefined')
|
||||
tabulator.log.error("No value found for the(){" + s + " " + p + " " + o + "}.")
|
||||
$rdf.log.error("No value found for the(){" + s + " " + p + " " + o + "}.")
|
||||
return x
|
||||
}
|
||||
|
||||
RDFFormula.prototype.whether = function(s,p,o,w) {
|
||||
return this.statementsMatching(s,p,o,w).length;
|
||||
$rdf.Formula.prototype.whether = function(s,p,o,w) {
|
||||
return this.statementsMatching(s,p,o,w,false).length;
|
||||
}
|
||||
|
||||
// Not a method. For use in sorts
|
||||
function RDFComparePredicateObject(self, other) {
|
||||
var x = self.predicate.compareTerm(other.predicate)
|
||||
if (x !=0) return x
|
||||
return self.object.compareTerm(other.object)
|
||||
}
|
||||
function RDFComparePredicateSubject(self, other) {
|
||||
var x = self.predicate.compareTerm(other.predicate)
|
||||
if (x !=0) return x
|
||||
return self.subject.compareTerm(other.subject)
|
||||
}
|
||||
// ends
|
||||
|
|
|
@ -1,5 +1,74 @@
|
|||
// Things we need to define to make converted pythn code work in js
|
||||
// environment of tabulator
|
||||
/**
|
||||
*
|
||||
* UTF-8 data encode / decode
|
||||
* http://www.webtoolkit.info/
|
||||
*
|
||||
**/
|
||||
|
||||
$rdf.N3Parser = function () {
|
||||
|
||||
function hexify(str) { // also used in parser
|
||||
return encodeURI(str);
|
||||
}
|
||||
|
||||
var Utf8 = {
|
||||
|
||||
// public method for url encoding
|
||||
encode : function (string) {
|
||||
string = string.replace(/\r\n/g,"\n");
|
||||
var utftext = "";
|
||||
|
||||
for (var n = 0; n < string.length; n++) {
|
||||
|
||||
var c = string.charCodeAt(n);
|
||||
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
}
|
||||
else if((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return utftext;
|
||||
},
|
||||
|
||||
// public method for url decoding
|
||||
decode : function (utftext) {
|
||||
var string = "";
|
||||
var i = 0;
|
||||
|
||||
while ( i < utftext.length ) {
|
||||
|
||||
var c = utftext.charCodeAt(i);
|
||||
if (c < 128) {
|
||||
string += String.fromCharCode(c);
|
||||
i++;
|
||||
}
|
||||
else if((c > 191) && (c < 224)) {
|
||||
string += String.fromCharCode(((c & 31) << 6)
|
||||
| (utftext.charCodeAt(i+1) & 63));
|
||||
i += 2;
|
||||
}
|
||||
else {
|
||||
string += String.fromCharCode(((c & 15) << 12)
|
||||
| ((utftext.charCodeAt(i+1) & 63) << 6)
|
||||
| (utftext.charCodeAt(i+2) & 63));
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
}// Things we need to define to make converted pythn code work in js
|
||||
// environment of $rdf
|
||||
|
||||
var RDFSink_forSomeSym = "http://www.w3.org/2000/10/swap/log#forSome";
|
||||
var RDFSink_forAllSym = "http://www.w3.org/2000/10/swap/log#forAll";
|
||||
|
@ -7,27 +76,27 @@ var Logic_NS = "http://www.w3.org/2000/10/swap/log#";
|
|||
|
||||
// pyjs seems to reference runtime library which I didn't find
|
||||
|
||||
pyjslib_Tuple = function(theList) { return theList };
|
||||
var pyjslib_Tuple = function(theList) { return theList };
|
||||
|
||||
pyjslib_List = function(theList) { return theList };
|
||||
var pyjslib_List = function(theList) { return theList };
|
||||
|
||||
pyjslib_Dict = function(listOfPairs) {
|
||||
var pyjslib_Dict = function(listOfPairs) {
|
||||
if (listOfPairs.length > 0)
|
||||
throw "missing.js: oops nnonempty dict not imp";
|
||||
return [];
|
||||
}
|
||||
|
||||
pyjslib_len = function(s) { return s.length }
|
||||
var pyjslib_len = function(s) { return s.length }
|
||||
|
||||
pyjslib_slice = function(str, i, j) {
|
||||
var pyjslib_slice = function(str, i, j) {
|
||||
if (typeof str.slice == 'undefined')
|
||||
throw '@@ mising.js: No .slice function for '+str+' of type '+(typeof str)
|
||||
if ((typeof j == 'undefined') || (j ==null)) return str.slice(i);
|
||||
return str.slice(i, j) // @ exactly the same spec?
|
||||
}
|
||||
StopIteration = Error('dummy error stop iteration')
|
||||
var StopIteration = Error('dummy error stop iteration');
|
||||
|
||||
pyjslib_Iterator = function(theList) {
|
||||
var pyjslib_Iterator = function(theList) {
|
||||
this.last = 0;
|
||||
this.li = theList;
|
||||
this.next = function() {
|
||||
|
@ -35,43 +104,54 @@ pyjslib_Iterator = function(theList) {
|
|||
return this.li[this.last++];
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
ord = function(str) {
|
||||
var ord = function(str) {
|
||||
return str.charCodeAt(0)
|
||||
}
|
||||
|
||||
string_find = function(str, s) {
|
||||
var string_find = function(str, s) {
|
||||
return str.indexOf(s)
|
||||
}
|
||||
|
||||
assertFudge = function(condition, desc) {
|
||||
var assertFudge = function(condition, desc) {
|
||||
if (condition) return;
|
||||
if (desc) throw "python Assertion failed: "+desc;
|
||||
throw "(python) Assertion failed.";
|
||||
}
|
||||
|
||||
|
||||
stringFromCharCode = function(uesc) {
|
||||
var stringFromCharCode = function(uesc) {
|
||||
return String.fromCharCode(uesc);
|
||||
}
|
||||
|
||||
|
||||
String.prototype.encode = function(encoding) {
|
||||
if (encoding != 'utf-8') throw "UTF8_converter: can only do utf-8"
|
||||
return Utf8.encode(this);
|
||||
}
|
||||
String.prototype.decode = function(encoding) {
|
||||
if (encoding != 'utf-8') throw "UTF8_converter: can only do utf-8"
|
||||
//return Utf8.decode(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
uripath_join = function(base, given) {
|
||||
return Util.uri.join(given, base) // sad but true
|
||||
|
||||
|
||||
var uripath_join = function(base, given) {
|
||||
return $rdf.Util.uri.join(given, base) // sad but true
|
||||
}
|
||||
|
||||
var becauseSubexpression = null; // No reason needed
|
||||
var diag_tracking = 0;
|
||||
var diag_chatty_flag = 0;
|
||||
diag_progress = function(str) { tabulator.log.debug(str); }
|
||||
var diag_progress = function(str) { /*$rdf.log.debug(str);*/ }
|
||||
|
||||
// why_BecauseOfData = function(doc, reason) { return doc };
|
||||
|
||||
|
||||
RDF_type_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
|
||||
DAML_sameAs_URI = "http://www.w3.org/2002/07/owl#sameAs";
|
||||
var RDF_type_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
|
||||
var DAML_sameAs_URI = "http://www.w3.org/2002/07/owl#sameAs";
|
||||
|
||||
/*
|
||||
function SyntaxError(details) {
|
||||
|
@ -235,7 +315,7 @@ __SinkParser.prototype.feed = function(octets) {
|
|||
So if there is more data to feed to the
|
||||
parser, it should be straightforward to recover.*/
|
||||
|
||||
var str = octets;
|
||||
var str = octets.decode("utf-8");
|
||||
var i = 0;
|
||||
while ((i >= 0)) {
|
||||
var j = this.skipSpace(str, i);
|
||||
|
@ -267,18 +347,17 @@ __SinkParser.prototype.tok = function(tok, str, i) {
|
|||
/*
|
||||
Check for keyword. Space must have been stripped on entry and
|
||||
we must not be at end of file.*/
|
||||
|
||||
var whitespace = "\t\n\v\f\r ";
|
||||
if ((pyjslib_slice(str, i, ( i + 1 ) ) == "@")) {
|
||||
var i = ( i + 1 ) ;
|
||||
}
|
||||
else {
|
||||
if ((this.keywords.indexOf(tok) < 0)) {
|
||||
if (($rdf.Util.ArrayIndexOf(this.keywords,tok) < 0)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
var k = ( i + pyjslib_len(tok) ) ;
|
||||
if ((pyjslib_slice(str, i, k) == tok) && (_notQNameChars.indexOf(str[k]) >= 0)) {
|
||||
if ((pyjslib_slice(str, i, k) == tok) && (_notQNameChars.indexOf(str.charAt(k)) >= 0)) {
|
||||
return k;
|
||||
}
|
||||
else {
|
||||
|
@ -320,7 +399,7 @@ __SinkParser.prototype.directive = function(str, i) {
|
|||
var x = __x.next();
|
||||
|
||||
|
||||
if ((this._variables.indexOf(x) < 0) || (this._parentVariables.indexOf(x) >= 0)) {
|
||||
if ($rdf.Util.ArrayIndexOf(this._variables,x) < 0 || ($rdf.Util.ArrayIndexOf(this._parentVariables,x) >= 0)) {
|
||||
this._variables[x] = ( this._context.newUniversal(x));
|
||||
}
|
||||
|
||||
|
@ -862,7 +941,7 @@ __SinkParser.prototype.commaSeparatedList = function(str, j, res, ofUris) {
|
|||
throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF found expecting comma sep list");
|
||||
return i;
|
||||
}
|
||||
if ((str[i] == ".")) {
|
||||
if ((str.charAt(i) == ".")) {
|
||||
return j;
|
||||
}
|
||||
if (ofUris) {
|
||||
|
@ -965,7 +1044,7 @@ __SinkParser.prototype.uri_ref2 = function(str, i, res) {
|
|||
}
|
||||
}
|
||||
var symb = this._store.sym( ( ns + ln ) );
|
||||
if ((this._variables.indexOf(symb) >= 0)) {
|
||||
if (($rdf.Util.ArrayIndexOf(this._variables, symb) >= 0)) {
|
||||
res.push(this._variables[symb]);
|
||||
}
|
||||
else {
|
||||
|
@ -977,7 +1056,7 @@ __SinkParser.prototype.uri_ref2 = function(str, i, res) {
|
|||
if ((i < 0)) {
|
||||
return -1;
|
||||
}
|
||||
if ((str[i] == "?")) {
|
||||
if ((str.charAt(i) == "?")) {
|
||||
var v = new pyjslib_List([]);
|
||||
var j = this.variable(str, i, v);
|
||||
if ((j > 0)) {
|
||||
|
@ -986,11 +1065,11 @@ __SinkParser.prototype.uri_ref2 = function(str, i, res) {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
else if ((str[i] == "<")) {
|
||||
else if ((str.charAt(i) == "<")) {
|
||||
var i = ( i + 1 ) ;
|
||||
var st = i;
|
||||
while ((i < pyjslib_len(str))) {
|
||||
if ((str[i] == ">")) {
|
||||
if ((str.charAt(i) == ">")) {
|
||||
var uref = pyjslib_slice(str, st, i);
|
||||
if (this._baseURI) {
|
||||
var uref = uripath_join(this._baseURI, uref);
|
||||
|
@ -1002,7 +1081,7 @@ __SinkParser.prototype.uri_ref2 = function(str, i, res) {
|
|||
var uref = ( uref + "#" ) ;
|
||||
}
|
||||
var symb = this._store.sym(uref);
|
||||
if ((this._variables.indexOf(symb) >= 0)) {
|
||||
if (($rdf.Util.ArrayIndexOf(this._variables,symb) >= 0)) {
|
||||
res.push(this._variables[symb]);
|
||||
}
|
||||
else {
|
||||
|
@ -1020,7 +1099,7 @@ __SinkParser.prototype.uri_ref2 = function(str, i, res) {
|
|||
if ((j < 0)) {
|
||||
return -1;
|
||||
}
|
||||
if ((this.keywords.indexOf(v[0]) >= 0)) {
|
||||
if (($rdf.Util.ArrayIndexOf(this.keywords, v[0]) >= 0)) {
|
||||
throw BadSyntax(this._thisDoc, this.lines, str, i, ( ( "Keyword \"" + v[0] ) + "\" not allowed here." ) );
|
||||
}
|
||||
res.push(this._store.sym( ( this._bindings[""] + v[0] ) ));
|
||||
|
@ -1034,28 +1113,24 @@ __SinkParser.prototype.skipSpace = function(str, i) {
|
|||
/*
|
||||
Skip white space, newlines and comments.
|
||||
return -1 if EOF, else position of first non-ws character*/
|
||||
|
||||
while (1) {
|
||||
eol.lastIndex = 0;
|
||||
var m = eol.exec(str.slice(i));
|
||||
if ((m == null)) {
|
||||
break;
|
||||
var tmp = str;
|
||||
var whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
|
||||
for (var j = (i ? i : 0); j < str.length; j++) {
|
||||
if (whitespace.indexOf(str.charAt(j)) === -1) {
|
||||
if( str.charAt(j)==='#' ) {
|
||||
str = str.slice(i).replace(/^[^\n]*\n/,"");
|
||||
i=0;
|
||||
j=-1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.lines = ( this.lines + 1 ) ;
|
||||
i += eol.lastIndex;
|
||||
this.previousLine = this.startOfLine;
|
||||
this.startOfLine = i;
|
||||
tabulator.log.debug( ( ( ( "N3 line " + this.lines ) + " " ) + str.slice(this.previousLine, this.startOfLine) ) );
|
||||
}
|
||||
ws.lastIndex = 0;
|
||||
var m = ws.exec(str.slice(i));
|
||||
if ((m != null) && (m[0] != "")) {
|
||||
i += ws.lastIndex;
|
||||
}
|
||||
if ((i == pyjslib_len(str))) {
|
||||
val = (tmp.length - str.length) + j;
|
||||
if( val === tmp.length ) {
|
||||
return -1;
|
||||
}
|
||||
return i;
|
||||
return val;
|
||||
};
|
||||
__SinkParser.prototype.variable = function(str, i, res) {
|
||||
/*
|
||||
|
@ -1071,11 +1146,11 @@ __SinkParser.prototype.variable = function(str, i, res) {
|
|||
}
|
||||
var j = ( j + 1 ) ;
|
||||
var i = j;
|
||||
if (("0123456789-".indexOf(str[j]) >= 0)) {
|
||||
throw BadSyntax(this._thisDoc, this.lines, str, j, ( ( "Varible name can't start with '" + str[j] ) + "s'" ) );
|
||||
if (("0123456789-".indexOf(str.charAt(j)) >= 0)) {
|
||||
throw BadSyntax(this._thisDoc, this.lines, str, j, ( ( "Varible name can't start with '" + str.charAt(j) ) + "s'" ) );
|
||||
return -1;
|
||||
}
|
||||
while ((i < pyjslib_len(str)) && (_notNameChars.indexOf(str[i]) < 0)) {
|
||||
while ((i < pyjslib_len(str)) && (_notNameChars.indexOf(str.charAt(i)) < 0)) {
|
||||
var i = ( i + 1 ) ;
|
||||
}
|
||||
if ((this._parentContext == null)) {
|
||||
|
@ -1093,7 +1168,7 @@ __SinkParser.prototype.bareWord = function(str, i, res) {
|
|||
if ((j < 0)) {
|
||||
return -1;
|
||||
}
|
||||
var ch = str[j];
|
||||
var ch = str.charAt(j);
|
||||
if (("0123456789-".indexOf(ch) >= 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1101,7 +1176,7 @@ __SinkParser.prototype.bareWord = function(str, i, res) {
|
|||
return -1;
|
||||
}
|
||||
var i = j;
|
||||
while ((i < pyjslib_len(str)) && (_notNameChars.indexOf(str[i]) < 0)) {
|
||||
while ((i < pyjslib_len(str)) && (_notNameChars.indexOf(str.charAt(i)) < 0)) {
|
||||
var i = ( i + 1 ) ;
|
||||
}
|
||||
res.push(pyjslib_slice(str, j, i));
|
||||
|
@ -1119,7 +1194,7 @@ __SinkParser.prototype.qname = function(str, i, res) {
|
|||
if ((i < 0)) {
|
||||
return -1;
|
||||
}
|
||||
var c = str[i];
|
||||
var c = str.charAt(i);
|
||||
if (("0123456789-+".indexOf(c) >= 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1127,7 +1202,7 @@ __SinkParser.prototype.qname = function(str, i, res) {
|
|||
var ln = c;
|
||||
var i = ( i + 1 ) ;
|
||||
while ((i < pyjslib_len(str))) {
|
||||
var c = str[i];
|
||||
var c = str.charAt(i);
|
||||
if ((_notNameChars.indexOf(c) < 0)) {
|
||||
var ln = ( ln + c ) ;
|
||||
var i = ( i + 1 ) ;
|
||||
|
@ -1140,12 +1215,12 @@ __SinkParser.prototype.qname = function(str, i, res) {
|
|||
else {
|
||||
var ln = "";
|
||||
}
|
||||
if ((i < pyjslib_len(str)) && (str[i] == ":")) {
|
||||
if ((i < pyjslib_len(str)) && (str.charAt(i) == ":")) {
|
||||
var pfx = ln;
|
||||
var i = ( i + 1 ) ;
|
||||
var ln = "";
|
||||
while ((i < pyjslib_len(str))) {
|
||||
var c = str[i];
|
||||
var c = str.charAt(i);
|
||||
if ((_notNameChars.indexOf(c) < 0)) {
|
||||
var ln = ( ln + c ) ;
|
||||
var i = ( i + 1 ) ;
|
||||
|
@ -1158,7 +1233,7 @@ __SinkParser.prototype.qname = function(str, i, res) {
|
|||
return i;
|
||||
}
|
||||
else {
|
||||
if (ln && this.keywordsSet && (this.keywords.indexOf(ln) < 0)) {
|
||||
if (ln && this.keywordsSet && ($rdf.Util.ArrayIndexOf(this.keywords, ln) < 0)) {
|
||||
res.push(new pyjslib_Tuple(["", ln]));
|
||||
return i;
|
||||
}
|
||||
|
@ -1178,7 +1253,7 @@ __SinkParser.prototype.object = function(str, i, res) {
|
|||
else {
|
||||
var i = j;
|
||||
}
|
||||
if ((str[i] == "\"")) {
|
||||
if ((str.charAt(i) == "\"")) {
|
||||
if ((pyjslib_slice(str, i, ( i + 3 ) ) == "\"\"\"")) {
|
||||
var delim = "\"\"\"";
|
||||
}
|
||||
|
@ -1211,7 +1286,7 @@ __SinkParser.prototype.nodeOrLiteral = function(str, i, res) {
|
|||
else {
|
||||
var i = j;
|
||||
}
|
||||
var ch = str[i];
|
||||
var ch = str.charAt(i);
|
||||
if (("-+0987654321".indexOf(ch) >= 0)) {
|
||||
number_syntax.lastIndex = 0;
|
||||
var m = number_syntax.exec(str.slice(i));
|
||||
|
@ -1221,17 +1296,17 @@ __SinkParser.prototype.nodeOrLiteral = function(str, i, res) {
|
|||
var j = ( i + number_syntax.lastIndex ) ;
|
||||
var val = pyjslib_slice(str, i, j);
|
||||
if ((val.indexOf("e") >= 0)) {
|
||||
res.push(this._store.literal(parseFloat(val), undefined, kb.sym(FLOAT_DATATYPE)));
|
||||
res.push(this._store.literal(parseFloat(val), undefined, this._store.sym(FLOAT_DATATYPE)));
|
||||
}
|
||||
else if ((pyjslib_slice(str, i, j).indexOf(".") >= 0)) {
|
||||
res.push(this._store.literal(parseFloat(val), undefined, kb.sym(DECIMAL_DATATYPE)));
|
||||
res.push(this._store.literal(parseFloat(val), undefined, this._store.sym(DECIMAL_DATATYPE)));
|
||||
}
|
||||
else {
|
||||
res.push(this._store.literal(parseInt(val), undefined, kb.sym(INTEGER_DATATYPE)));
|
||||
res.push(this._store.literal(parseInt(val), undefined, this._store.sym(INTEGER_DATATYPE)));
|
||||
}
|
||||
return j;
|
||||
}
|
||||
if ((str[i] == "\"")) {
|
||||
if ((str.charAt(i) == "\"")) {
|
||||
if ((pyjslib_slice(str, i, ( i + 3 ) ) == "\"\"\"")) {
|
||||
var delim = "\"\"\"";
|
||||
}
|
||||
|
@ -1283,7 +1358,7 @@ __SinkParser.prototype.strconst = function(str, i, delim) {
|
|||
if ((pyjslib_slice(str, j, i) == delim)) {
|
||||
return new pyjslib_Tuple([i, ustr]);
|
||||
}
|
||||
if ((str[j] == "\"")) {
|
||||
if ((str.charAt(j) == "\"")) {
|
||||
var ustr = ( ustr + "\"" ) ;
|
||||
var j = ( j + 1 ) ;
|
||||
continue;
|
||||
|
@ -1295,7 +1370,7 @@ __SinkParser.prototype.strconst = function(str, i, delim) {
|
|||
}
|
||||
var i = ( ( j + interesting.lastIndex ) - 1 ) ;
|
||||
var ustr = ( ustr + pyjslib_slice(str, j, i) ) ;
|
||||
var ch = str[i];
|
||||
var ch = str.charAt(i);
|
||||
if ((ch == "\"")) {
|
||||
var j = i;
|
||||
continue;
|
||||
|
@ -1322,7 +1397,7 @@ __SinkParser.prototype.strconst = function(str, i, delim) {
|
|||
}
|
||||
var k = string_find("abfrtvn\\\"", ch);
|
||||
if ((k >= 0)) {
|
||||
var uch = "\a\b\f\r\t\v\n\\\""[k];
|
||||
var uch = "\a\b\f\r\t\v\n\\\"".charAt(k);
|
||||
var ustr = ( ustr + uch ) ;
|
||||
var j = ( j + 1 ) ;
|
||||
}
|
||||
|
@ -1387,7 +1462,36 @@ __SinkParser.prototype.UEscape = function(str, i, startline) {
|
|||
var uch = stringFromCharCode( ( ( "0x" + pyjslib_slice(value, 2, 10) ) - 0 ) );
|
||||
return new pyjslib_Tuple([j, uch]);
|
||||
};
|
||||
|
||||
function OLD_BadSyntax(uri, lines, str, i, why) {
|
||||
return new __OLD_BadSyntax(uri, lines, str, i, why);
|
||||
}
|
||||
function __OLD_BadSyntax(uri, lines, str, i, why) {
|
||||
this._str = str.encode("utf-8");
|
||||
this._str = str;
|
||||
this._i = i;
|
||||
this._why = why;
|
||||
this.lines = lines;
|
||||
this._uri = uri;
|
||||
}
|
||||
__OLD_BadSyntax.prototype.toString = function() {
|
||||
var str = this._str;
|
||||
var i = this._i;
|
||||
var st = 0;
|
||||
if ((i > 60)) {
|
||||
var pre = "...";
|
||||
var st = ( i - 60 ) ;
|
||||
}
|
||||
else {
|
||||
var pre = "";
|
||||
}
|
||||
if (( ( pyjslib_len(str) - i ) > 60)) {
|
||||
var post = "...";
|
||||
}
|
||||
else {
|
||||
var post = "";
|
||||
}
|
||||
return "Line %i of <%s>: Bad syntax (%s) at ^ in:\n\"%s%s^%s%s\"" % new pyjslib_Tuple([ ( this.lines + 1 ) , this._uri, this._why, pre, pyjslib_slice(str, st, i), pyjslib_slice(str, i, ( i + 60 ) ), post]);
|
||||
};
|
||||
function BadSyntax(uri, lines, str, i, why) {
|
||||
return ( ( ( ( ( ( ( ( "Line " + ( lines + 1 ) ) + " of <" ) + uri ) + ">: Bad syntax: " ) + why ) + "\nat: \"" ) + pyjslib_slice(str, i, ( i + 30 ) ) ) + "\"" ) ;
|
||||
}
|
||||
|
@ -1420,4 +1524,6 @@ function stripCR(str) {
|
|||
function dummyWrite(x) {
|
||||
}
|
||||
|
||||
return SinkParser;
|
||||
|
||||
}();
|
||||
|
|
|
@ -61,7 +61,9 @@
|
|||
* @constructor
|
||||
* @param {RDFStore} store An RDFStore object
|
||||
*/
|
||||
function RDFParser(store) {
|
||||
$rdf.RDFParser = function (store) {
|
||||
var RDFParser = {};
|
||||
|
||||
/** Standard namespaces that we know how to handle @final
|
||||
* @member RDFParser
|
||||
*/
|
||||
|
@ -111,7 +113,7 @@ function RDFParser(store) {
|
|||
|
||||
/** Add a symbol of a certain type to the this frame */
|
||||
'addSymbol': function (type, uri) {
|
||||
uri = Util.uri.join(uri, this['base'])
|
||||
uri = $rdf.Util.uri.join(uri, this['base'])
|
||||
this['node'] = this['store']['sym'](uri)
|
||||
this['nodeType'] = type
|
||||
},
|
||||
|
@ -129,7 +131,7 @@ function RDFParser(store) {
|
|||
}
|
||||
if (this['parent']['rdfid'] != null) { // reify
|
||||
var triple = this['store']['sym'](
|
||||
Util.uri.join("#"+this['parent']['rdfid'],
|
||||
$rdf.Util.uri.join("#"+this['parent']['rdfid'],
|
||||
this['base']))
|
||||
this['store']['add'](triple,
|
||||
this['store']['sym'](
|
||||
|
@ -236,6 +238,29 @@ function RDFParser(store) {
|
|||
}
|
||||
}
|
||||
|
||||
//from the OpenLayers source .. needed to get around IE problems.
|
||||
this['getAttributeNodeNS'] = function(node, uri, name) {
|
||||
var attributeNode = null;
|
||||
if(node.getAttributeNodeNS) {
|
||||
attributeNode = node.getAttributeNodeNS(uri, name);
|
||||
} else {
|
||||
var attributes = node.attributes;
|
||||
var potentialNode, fullName;
|
||||
for(var i=0; i<attributes.length; ++i) {
|
||||
potentialNode = attributes[i];
|
||||
if(potentialNode.namespaceURI == uri) {
|
||||
fullName = (potentialNode.prefix) ?
|
||||
(potentialNode.prefix + ":" + name) : name;
|
||||
if(fullName == potentialNode.nodeName) {
|
||||
attributeNode = potentialNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return attributeNode;
|
||||
}
|
||||
|
||||
/** Our triple store reference @private */
|
||||
this['store'] = store
|
||||
/** Our identified blank nodes @private */
|
||||
|
@ -259,8 +284,7 @@ function RDFParser(store) {
|
|||
this['cleanParser']()
|
||||
|
||||
// figure out the root element
|
||||
var root = document.documentElement; //this is faster, I think, cross-browser issue? well, DOM 2
|
||||
/*
|
||||
//var root = document.documentElement; //this is faster, I think, cross-browser issue? well, DOM 2
|
||||
if (document['nodeType'] == RDFParser['nodeType']['DOCUMENT']) {
|
||||
for (var c=0; c<children['length']; c++) {
|
||||
if (children[c]['nodeType']
|
||||
|
@ -278,7 +302,6 @@ function RDFParser(store) {
|
|||
+ ". Halting. ")
|
||||
return false
|
||||
}
|
||||
*/
|
||||
|
||||
this['why'] = why
|
||||
|
||||
|
@ -296,11 +319,23 @@ function RDFParser(store) {
|
|||
this['parseDOM'] = function (frame) {
|
||||
// a DOM utility function used in parsing
|
||||
var elementURI = function (el) {
|
||||
var result = "";
|
||||
if (el['namespaceURI'] == null) {
|
||||
throw new Error("RDF/XML syntax error: No namespace for "
|
||||
+el['localName']+" in "+this.base)
|
||||
}
|
||||
return el['namespaceURI'] + el['localName']
|
||||
if( el['namespaceURI'] ) {
|
||||
result = result + el['namespaceURI'];
|
||||
}
|
||||
if( el['localName'] ) {
|
||||
result = result + el['localName'];
|
||||
} else if( el['nodeName'] ) {
|
||||
if(el['nodeName'].indexOf(":")>=0)
|
||||
result = result + el['nodeName'].split(":")[1];
|
||||
else
|
||||
result = result + el['nodeName'];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
var dig = true // if we'll dig down in the tree on the next iter
|
||||
|
||||
|
@ -325,9 +360,9 @@ function RDFParser(store) {
|
|||
if (!frame['parent'] || !frame['parent']['nodeType']
|
||||
|| frame['parent']['nodeType'] == frame['ARC']) {
|
||||
// we need a node
|
||||
var about =dom['getAttributeNodeNS'](
|
||||
var about =this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"about")
|
||||
var rdfid =dom['getAttributeNodeNS'](
|
||||
var rdfid =this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"ID")
|
||||
if (about && rdfid) {
|
||||
throw new Error("RDFParser: " + dom['nodeName']
|
||||
|
@ -341,7 +376,7 @@ function RDFParser(store) {
|
|||
dom['removeAttributeNode'](rdfid)
|
||||
}
|
||||
else if (about == null && rdfid == null) {
|
||||
var bnid = dom['getAttributeNodeNS'](
|
||||
var bnid = this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"nodeID")
|
||||
if (bnid) {
|
||||
frame['addBNode'](bnid['nodeValue'])
|
||||
|
@ -354,7 +389,7 @@ function RDFParser(store) {
|
|||
}
|
||||
|
||||
// Typed nodes
|
||||
var rdftype = dom['getAttributeNodeNS'](
|
||||
var rdftype = this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"type")
|
||||
if (RDFParser['ns']['RDF']+"Description"
|
||||
!= elementURI(dom)) {
|
||||
|
@ -365,7 +400,7 @@ function RDFParser(store) {
|
|||
this['store']['sym'](
|
||||
RDFParser['ns']['RDF']+"type"),
|
||||
this['store']['sym'](
|
||||
Util.uri.join(
|
||||
$rdf.Util.uri.join(
|
||||
rdftype['nodeValue'],
|
||||
frame['base'])),
|
||||
this['why'])
|
||||
|
@ -390,7 +425,7 @@ function RDFParser(store) {
|
|||
|
||||
// save the arc's rdf:ID if it has one
|
||||
if (this['reify']) {
|
||||
var rdfid = dom['getAttributeNodeNS'](
|
||||
var rdfid = this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"ID")
|
||||
if (rdfid) {
|
||||
frame['rdfid'] = rdfid['nodeValue']
|
||||
|
@ -398,9 +433,9 @@ function RDFParser(store) {
|
|||
}
|
||||
}
|
||||
|
||||
var parsetype = dom['getAttributeNodeNS'](
|
||||
var parsetype = this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"parseType")
|
||||
var datatype = dom['getAttributeNodeNS'](
|
||||
var datatype = this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"datatype")
|
||||
if (datatype) {
|
||||
frame['datatype'] = datatype['nodeValue']
|
||||
|
@ -432,9 +467,9 @@ function RDFParser(store) {
|
|||
}
|
||||
|
||||
if (attrs['length'] != 0) {
|
||||
var resource = dom['getAttributeNodeNS'](
|
||||
var resource = this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"resource")
|
||||
var bnid = dom['getAttributeNodeNS'](
|
||||
var bnid = this['getAttributeNodeNS'](dom,
|
||||
RDFParser['ns']['RDF'],"nodeID")
|
||||
|
||||
frame = this['buildFrame'](frame)
|
||||
|
@ -549,7 +584,7 @@ function RDFParser(store) {
|
|||
if (attrs[x].name.slice(0,6)=='xmlns:') {
|
||||
var uri = attrs[x].nodeValue;
|
||||
// alert('base for namespac attr:'+this.base);
|
||||
if (this.base) uri = Util.uri.join(uri, this.base);
|
||||
if (this.base) uri = $rdf.Util.uri.join(uri, this.base);
|
||||
this.store.setPrefixForURI(attrs[x].name.slice(6),
|
||||
uri);
|
||||
}
|
||||
|
@ -559,4 +594,4 @@ function RDFParser(store) {
|
|||
}
|
||||
return frame
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
** in XML (from mhausenblas)
|
||||
*/
|
||||
|
||||
__Serializer = function(){
|
||||
// @@@ Check the whole toStr thing tosee whetehr it still makes sense -- tbl
|
||||
//
|
||||
$rdf.Serializer = function() {
|
||||
|
||||
var __Serializer = function( store ){
|
||||
this.flags = "";
|
||||
this.base = null;
|
||||
this.prefixes = [];
|
||||
|
@ -15,11 +19,12 @@ __Serializer = function(){
|
|||
this.prefixchars = "abcdefghijklmnopqustuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
this.incoming = null; // Array not calculated yet
|
||||
this.formulas = []; // remebering original formulae from hashes
|
||||
this.store = store;
|
||||
|
||||
/* pass */
|
||||
}
|
||||
|
||||
Serializer = function() {return new __Serializer()};
|
||||
var Serializer = function( store ) {return new __Serializer( store )};
|
||||
|
||||
__Serializer.prototype.setBase = function(base)
|
||||
{ this.base = base };
|
||||
|
@ -42,7 +47,7 @@ __Serializer.prototype.fromStr = function(s) {
|
|||
if (!x) alert('No formula object for '+s)
|
||||
return x;
|
||||
}
|
||||
return kb.fromNT(s);
|
||||
return this.store.fromNT(s);
|
||||
};
|
||||
|
||||
|
||||
|
@ -75,11 +80,14 @@ __Serializer.prototype.makeUpPrefix = function(uri) {
|
|||
|
||||
function canUse(pp) {
|
||||
if (namespaces[pp]) return false; // already used
|
||||
|
||||
sz.prefixes[uri] = pp;
|
||||
pok = pp;
|
||||
return true
|
||||
}
|
||||
for (var ns in sz.prefixes) namespaces[sz.prefixes[ns]] = ns; // reverse index
|
||||
for (var ns in sz.prefixes) {
|
||||
namespaces[sz.prefixes[ns]] = ns; // reverse index
|
||||
}
|
||||
if ('#/'.indexOf(p[p.length-1]) >= 0) p = p.slice(0, -1);
|
||||
var slash = p.lastIndexOf('/');
|
||||
if (slash >= 0) p = p.slice(slash+1);
|
||||
|
@ -97,62 +105,152 @@ __Serializer.prototype.makeUpPrefix = function(uri) {
|
|||
}
|
||||
|
||||
|
||||
/* The scan is to find out which nodes will have to be the roots of trees
|
||||
** in the serialized form. This will be any symbols, and any bnodes
|
||||
** which hve more or less than one incoming arc, and any bnodes which have
|
||||
** one incoming arc but it is an uninterrupted loop of such nodes back to itself.
|
||||
** This should be kept linear time with repect to the number of statements.
|
||||
** Note it does not use any indexing.
|
||||
*/
|
||||
|
||||
|
||||
// Todo:
|
||||
// - Sort the statements by subject, pred, object
|
||||
// - do stuff about the docu first and then (or first) about its primary topic.
|
||||
|
||||
__Serializer.prototype.rootSubjects = function(sts) {
|
||||
var incoming = {};
|
||||
var subjects = {};
|
||||
var incoming = [];
|
||||
var subjects = [];
|
||||
var sz = this;
|
||||
var allBnodes = {};
|
||||
|
||||
/* This scan is to find out which nodes will have to be the roots of trees
|
||||
** in the serialized form. This will be any symbols, and any bnodes
|
||||
** which hve more or less than one incoming arc, and any bnodes which have
|
||||
** one incoming arc but it is an uninterrupted loop of such nodes back to itself.
|
||||
** This should be kept linear time with repect to the number of statements.
|
||||
** Note it does not use any indexing of the store.
|
||||
*/
|
||||
|
||||
|
||||
tabulator.log.debug('serialize.js Find bnodes with only one incoming arc\n')
|
||||
for (var i = 0; i<sts.length; i++) {
|
||||
var st = sts[i];
|
||||
[ st.subject, st.predicate, st.object].map(function(y){
|
||||
if (y.termType =='bnode'){allBnodes[y.toNT()] = true}});
|
||||
var x = sts[i].object;
|
||||
if (!incoming[x]) incoming[x] = [];
|
||||
incoming[x].push(sts[i].subject) // List of things which will cause this to be printed
|
||||
var ss = subjects[sz.toStr(sts[i].subject)]; // Statements with this as subject
|
||||
incoming[x].push(st.subject) // List of things which will cause this to be printed
|
||||
var ss = subjects[sz.toStr(st.subject)]; // Statements with this as subject
|
||||
if (!ss) ss = [];
|
||||
ss.push(sts[i]);
|
||||
subjects[this.toStr(sts[i].subject)] = ss; // Make hash. @@ too slow for formula?
|
||||
tabulator.log.debug(' sz potential subject: '+sts[i].subject)
|
||||
ss.push(st);
|
||||
subjects[this.toStr(st.subject)] = ss; // Make hash. @@ too slow for formula?
|
||||
//$rdf.log.debug(' sz potential subject: '+sts[i].subject)
|
||||
}
|
||||
|
||||
var roots = [];
|
||||
var loopBreakers = {};
|
||||
|
||||
function accountedFor(x, start) {
|
||||
if (x.termType != 'bnode') return true; // will be subject
|
||||
var zz = incoming[x];
|
||||
if (!zz || zz.length != 1) return true;
|
||||
if (loopBreakers[x]) return true;
|
||||
if (zz[0] == start) return false;
|
||||
return accountedFor(zz[0], start);
|
||||
}
|
||||
for (var xNT in subjects) {
|
||||
var x = sz.fromStr(xNT);
|
||||
if ((x.termType != 'bnode') || !incoming[x] || (incoming[x].length != 1)){
|
||||
roots.push(x);
|
||||
tabulator.log.debug(' sz actual subject -: ' + x)
|
||||
//$rdf.log.debug(' sz actual subject -: ' + x)
|
||||
continue;
|
||||
}
|
||||
if (accountedFor(incoming[x][0]), x) {
|
||||
continue;
|
||||
}
|
||||
roots.push(x);
|
||||
tabulator.log.debug(' sz potential subject *: '+sts[i].subject)
|
||||
loopBreakers[x] = 1;
|
||||
}
|
||||
this.incoming = incoming; // Keep for serializing
|
||||
return [roots, subjects];
|
||||
this.incoming = incoming; // Keep for serializing @@ Bug for nested formulas
|
||||
|
||||
//////////// New bit for CONNECTED bnode loops:frootshash
|
||||
|
||||
// This scans to see whether the serialization is gpoing to lead to a bnode loop
|
||||
// and at the same time accumulates a list of all bnodes mentioned.
|
||||
// This is in fact a cut down N3 serialization
|
||||
/*
|
||||
tabulator.log.debug('serialize.js Looking for connected bnode loops\n')
|
||||
for (var i=0; i<sts.length; i++) { // @@TBL
|
||||
// dump('\t'+sts[i]+'\n');
|
||||
}
|
||||
var doneBnodesNT = {};
|
||||
function dummyPropertyTree(subject, subjects, rootsHash) {
|
||||
// dump('dummyPropertyTree('+subject+'...)\n');
|
||||
var sts = subjects[sz.toStr(subject)]; // relevant statements
|
||||
for (var i=0; i<sts.length; i++) {
|
||||
dummyObjectTree(sts[i].object, subjects, rootsHash);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a set of statements into a nested tree of lists and strings
|
||||
// @param force, "we know this is a root, do it anyway. It isn't a loop."
|
||||
function dummyObjectTree(obj, subjects, rootsHash, force) {
|
||||
// dump('dummyObjectTree('+obj+'...)\n');
|
||||
if (obj.termType == 'bnode' && (subjects[sz.toStr(obj)] &&
|
||||
(force || (rootsHash[obj.toNT()] == undefined )))) {// and there are statements
|
||||
if (doneBnodesNT[obj.toNT()]) { // Ah-ha! a loop
|
||||
throw "Serializer: Should be no loops "+obj;
|
||||
}
|
||||
doneBnodesNT[obj.toNT()] = true;
|
||||
return dummyPropertyTree(obj, subjects, rootsHash);
|
||||
}
|
||||
return dummyTermToN3(obj, subjects, rootsHash);
|
||||
}
|
||||
|
||||
// Scan for bnodes nested inside lists too
|
||||
function dummyTermToN3(expr, subjects, rootsHash) {
|
||||
if (expr.termType == 'bnode') doneBnodesNT[expr.toNT()] = true;
|
||||
tabulator.log.debug('serialize: seen '+expr);
|
||||
if (expr.termType == 'collection') {
|
||||
for (i=0; i<expr.elements.length; i++) {
|
||||
if (expr.elements[i].termType == 'bnode')
|
||||
dummyObjectTree(expr.elements[i], subjects, rootsHash);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// The tree for a subject
|
||||
function dummySubjectTree(subject, subjects, rootsHash) {
|
||||
// dump('dummySubjectTree('+subject+'...)\n');
|
||||
if (subject.termType == 'bnode' && !incoming[subject])
|
||||
return dummyObjectTree(subject, subjects, rootsHash, true); // Anonymous bnode subject
|
||||
dummyTermToN3(subject, subjects, rootsHash);
|
||||
dummyPropertyTree(subject, subjects, rootsHash);
|
||||
}
|
||||
*/
|
||||
// Now do the scan using existing roots
|
||||
tabulator.log.debug('serialize.js Dummy serialize to check for missing nodes')
|
||||
var rootsHash = {};
|
||||
for (var i = 0; i< roots.length; i++) rootsHash[roots[i].toNT()] = true;
|
||||
/*
|
||||
for (var i=0; i<roots.length; i++) {
|
||||
var root = roots[i];
|
||||
dummySubjectTree(root, subjects, rootsHash);
|
||||
}
|
||||
// dump('Looking for mising bnodes...\n')
|
||||
|
||||
// Now in new roots for anythig not acccounted for
|
||||
// Now we check for any bndoes which have not been covered.
|
||||
// Such bnodes must be in isolated rings of pure bnodes.
|
||||
// They each have incoming link of 1.
|
||||
|
||||
tabulator.log.debug('serialize.js Looking for connected bnode loops\n')
|
||||
for (;;) {
|
||||
var bnt;
|
||||
var found = null;
|
||||
for (bnt in allBnodes) { // @@ Note: not repeatable. No canonicalisation
|
||||
if (doneBnodesNT[bnt]) continue;
|
||||
found = bnt; // Ah-ha! not covered
|
||||
break;
|
||||
}
|
||||
if (found == null) break; // All done - no bnodes left out/
|
||||
// dump('Found isolated bnode:'+found+'\n');
|
||||
doneBnodesNT[bnt] = true;
|
||||
var root = this.store.fromNT(found);
|
||||
roots.push(root); // Add a new root
|
||||
rootsHash[found] = true;
|
||||
tabulator.log.debug('isolated bnode:'+found+', subjects[found]:'+subjects[found]+'\n');
|
||||
if (subjects[found] == undefined) {
|
||||
for (var i=0; i<sts.length; i++) {
|
||||
// dump('\t'+sts[i]+'\n');
|
||||
}
|
||||
throw "Isolated node should be a subject" +found;
|
||||
}
|
||||
dummySubjectTree(root, subjects, rootsHash); // trace out the ring
|
||||
}
|
||||
// dump('Done bnode adjustments.\n')
|
||||
*/
|
||||
return {'roots':roots, 'subjects':subjects,
|
||||
'rootsHash': rootsHash, 'incoming': incoming};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
@ -169,7 +267,6 @@ __Serializer.prototype._notNameChars =
|
|||
__Serializer.prototype.statementsToN3 = function(sts) {
|
||||
var indent = 4;
|
||||
var width = 80;
|
||||
// var subjects = null; // set later
|
||||
var sz = this;
|
||||
|
||||
var namespaceCounts = []; // which have been used
|
||||
|
@ -253,37 +350,36 @@ __Serializer.prototype.statementsToN3 = function(sts) {
|
|||
////////////////////////////////////////////// Structure for N3
|
||||
|
||||
|
||||
// Convert a set of statements into a nested tree of lists and strings
|
||||
function statementListToTree(statements) {
|
||||
// print('Statement tree for '+statements.length);
|
||||
var res = [];
|
||||
var pair = sz.rootSubjects(statements);
|
||||
var roots = pair[0];
|
||||
// print('Roots: '+roots)
|
||||
var subjects = pair[1];
|
||||
var stats = sz.rootSubjects(statements);
|
||||
var roots = stats.roots;
|
||||
var results = []
|
||||
for (var i=0; i<roots.length; i++) {
|
||||
var root = roots[i];
|
||||
results.push(subjectTree(root, subjects))
|
||||
results.push(subjectTree(root, stats))
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// The tree for a subject
|
||||
function subjectTree(subject, subjects) {
|
||||
if (subject.termType == 'bnode' && !sz.incoming[subject])
|
||||
return objectTree(subject, subjects).concat(["."]); // Anonymous bnode subject
|
||||
return [ termToN3(subject, subjects) ].concat([propertyTree(subject, subjects)]).concat(["."]);
|
||||
function subjectTree(subject, stats) {
|
||||
if (subject.termType == 'bnode' && !stats.incoming[subject])
|
||||
return objectTree(subject, stats, true).concat(["."]); // Anonymous bnode subject
|
||||
return [ termToN3(subject, stats) ].concat([propertyTree(subject, stats)]).concat(["."]);
|
||||
}
|
||||
|
||||
|
||||
// The property tree for a single subject or anonymous node
|
||||
function propertyTree(subject, subjects) {
|
||||
function propertyTree(subject, stats) {
|
||||
// print('Proprty tree for '+subject);
|
||||
var results = []
|
||||
var lastPred = null;
|
||||
var sts = subjects[sz.toStr(subject)]; // relevant statements
|
||||
var sts = stats.subjects[sz.toStr(subject)]; // relevant statements
|
||||
if (typeof sts == 'undefined') {
|
||||
alert('Cant find statements for '+subject);
|
||||
throw('Cant find statements for '+subject);
|
||||
}
|
||||
sts.sort();
|
||||
var objects = [];
|
||||
|
@ -297,34 +393,31 @@ __Serializer.prototype.statementsToN3 = function(sts) {
|
|||
objects = [];
|
||||
}
|
||||
results.push(predMap[st.predicate.uri] ?
|
||||
predMap[st.predicate.uri] : termToN3(st.predicate, subjects));
|
||||
predMap[st.predicate.uri] : termToN3(st.predicate, stats));
|
||||
}
|
||||
lastPred = st.predicate.uri;
|
||||
objects.push(objectTree(st.object, subjects));
|
||||
objects.push(objectTree(st.object, stats));
|
||||
}
|
||||
results=results.concat([objects]);
|
||||
return results;
|
||||
}
|
||||
|
||||
// Convert a set of statements into a nested tree of lists and strings
|
||||
function objectTree(obj, subjects) {
|
||||
if (obj.termType == 'bnode' && subjects[sz.toStr(obj)]) // and there are statements
|
||||
return ['['].concat(propertyTree(obj, subjects)).concat([']']);
|
||||
return termToN3(obj, subjects);
|
||||
function objectTree(obj, stats, force) {
|
||||
if (obj.termType == 'bnode' &&
|
||||
stats.subjects[sz.toStr(obj)] && // and there are statements
|
||||
(force || stats.rootsHash[obj.toNT()] == undefined)) // and not a root
|
||||
return ['['].concat(propertyTree(obj, stats)).concat([']']);
|
||||
return termToN3(obj, stats);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////// Atomic Terms
|
||||
|
||||
// Deal with term level things and nesting with no bnode structure
|
||||
|
||||
function termToN3(expr, subjects) {
|
||||
function termToN3(expr, stats) {
|
||||
switch(expr.termType) {
|
||||
case 'bnode':
|
||||
case 'variable': return expr.toNT();
|
||||
case 'literal':
|
||||
var str = stringToN3(expr.value);
|
||||
if (expr.lang) str+= '@' + expr.lang;
|
||||
if (expr.dt) str+= '^^' + termToN3(expr.dt, subjects);
|
||||
if (expr.datatype) str+= '^^' + termToN3(expr.datatype, stats);
|
||||
return str;
|
||||
case 'symbol':
|
||||
return symbolToN3(expr.uri);
|
||||
|
@ -335,7 +428,7 @@ __Serializer.prototype.statementsToN3 = function(sts) {
|
|||
case 'collection':
|
||||
var res = ['('];
|
||||
for (i=0; i<expr.elements.length; i++) {
|
||||
res.push( [ objectTree(expr.elements[i], subjects) ]);
|
||||
res.push( [ objectTree(expr.elements[i], stats) ]);
|
||||
}
|
||||
res.push(')');
|
||||
return res;
|
||||
|
@ -346,6 +439,10 @@ __Serializer.prototype.statementsToN3 = function(sts) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////// Atomic Terms
|
||||
|
||||
// Deal with term level things and nesting with no bnode structure
|
||||
|
||||
function symbolToN3(uri) { // c.f. symbolString() in notation3.py
|
||||
var j = uri.indexOf('#');
|
||||
if (j<0 && sz.flags.indexOf('/') < 0) {
|
||||
|
@ -379,7 +476,7 @@ __Serializer.prototype.statementsToN3 = function(sts) {
|
|||
}
|
||||
}
|
||||
if (sz.flags.indexOf('r') < 0 && sz.base)
|
||||
uri = Util.uri.refTo(sz.base, uri);
|
||||
uri = $rdf.Util.uri.refTo(sz.base, uri);
|
||||
else if (sz.flags.indexOf('u') >= 0)
|
||||
uri = backslashUify(uri);
|
||||
else uri = hexify(uri);
|
||||
|
@ -489,7 +586,6 @@ function backslashUify(str) {
|
|||
__Serializer.prototype.statementsToXML = function(sts) {
|
||||
var indent = 4;
|
||||
var width = 80;
|
||||
// var subjects = null; // set later
|
||||
var sz = this;
|
||||
|
||||
var namespaceCounts = []; // which have been used
|
||||
|
@ -552,137 +648,90 @@ __Serializer.prototype.statementsToXML = function(sts) {
|
|||
|
||||
function statementListToXMLTree(statements) {
|
||||
sz.suggestPrefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
|
||||
var res = [];
|
||||
var pair = sz.rootSubjects(statements);
|
||||
var roots = pair[0];
|
||||
var subjects = pair[1];
|
||||
var stats = sz.rootSubjects(statements);
|
||||
var roots = stats.roots;
|
||||
results = []
|
||||
for (var i=0; i<roots.length; i++) {
|
||||
root = roots[i];
|
||||
results.push(subjectXMLTree(root, subjects))
|
||||
results.push(subjectXMLTree(root, stats))
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
function escapeForXML(str) {
|
||||
if (typeof str == 'undefined') return '@@@undefined@@@@';
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
|
||||
return str.replace(/&/g, '&').replace(/</g, '<')
|
||||
}
|
||||
|
||||
function relURI(term) {
|
||||
return escapeForXML((sz.base) ? Util.uri.refTo(this.base, term.uri) : term.uri);
|
||||
return escapeForXML((sz.base) ? $rdf.Util.uri.refTo(this.base, term.uri) : term.uri);
|
||||
}
|
||||
|
||||
// The tree for a subject
|
||||
function subjectXMLTree(subject, subjects, referenced) {
|
||||
const liPrefix = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#_';
|
||||
|
||||
var type = null;
|
||||
|
||||
var results = []
|
||||
var sts = subjects[sz.toStr(subject)]; // relevant statements
|
||||
// Sort only on the predicate, leave the order at object
|
||||
// level undisturbed. This leaves multilingual content in
|
||||
// the order of entry (for partner literals), which helps
|
||||
// readability.
|
||||
//
|
||||
// For the predicate sort, we attempt to split the uri
|
||||
// as a hint to the sequence, as sequenced items seems
|
||||
// to be of the form http://example.com#_1, http://example.com#_2,
|
||||
// et cetera. Probably not the most optimal of fixes, but
|
||||
// it does work.
|
||||
sts.sort(function(a,b){
|
||||
var aa = a.predicate.uri.split('#_');
|
||||
var bb = a.predicate.uri.split('#_');
|
||||
if (aa[0] > bb[0]) {
|
||||
return 1;
|
||||
} else if (aa[0] < bb[0]) {
|
||||
return -1;
|
||||
} else {
|
||||
if ("undefined" !== typeof aa[1] && "undefined" !== typeof bb[1]) {
|
||||
if (parseInt(aa[1], 10) > parseInt(bb[1], 10)) {
|
||||
return 1;
|
||||
} else if (parseInt(aa[1], 10) < parseInt(bb[1], 10)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
for (var i=0; i<sts.length; i++) {
|
||||
var st = sts[i];
|
||||
|
||||
if(st.predicate.uri == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' && !type && st.object.termType == "symbol") {
|
||||
// look for a type
|
||||
type = st.object;
|
||||
} else {
|
||||
// see whether predicate can be replaced with "li"
|
||||
if(st.predicate.uri.substr(0, liPrefix.length) == liPrefix) {
|
||||
var number = st.predicate.uri.substr(liPrefix.length);
|
||||
|
||||
// make sure these are actually numeric list items
|
||||
var intNumber = parseInt(number);
|
||||
if(number == intNumber.toString()) {
|
||||
// was numeric; don't need to worry about ordering since we've already
|
||||
// sorted the statements
|
||||
st.predicate = RDFSymbol('http://www.w3.org/1999/02/22-rdf-syntax-ns#li');
|
||||
}
|
||||
}
|
||||
|
||||
switch (st.object.termType) {
|
||||
case 'bnode':
|
||||
if(sz.incoming[st.object].length == 1) {
|
||||
results = results.concat(['<'+qname(st.predicate)+'>',
|
||||
subjectXMLTree(st.object, subjects, true),
|
||||
'</'+qname(st.predicate)+'>']);
|
||||
} else {
|
||||
results = results.concat(['<'+qname(st.predicate)+' rdf:nodeID="'
|
||||
+st.object.toNT().slice(2)+'"/>']);
|
||||
}
|
||||
break;
|
||||
case 'symbol':
|
||||
results = results.concat(['<'+qname(st.predicate)+' rdf:resource="'
|
||||
+ relURI(st.object)+'"/>']);
|
||||
break;
|
||||
case 'literal':
|
||||
results = results.concat(['<'+qname(st.predicate)
|
||||
+ (st.object.dt ? ' rdf:datatype="'+escapeForXML(st.object.dt.uri)+'"' : '')
|
||||
+ (st.object.lang ? ' xml:lang="'+st.object.lang+'"' : '')
|
||||
+ '>' + escapeForXML(st.object.value)
|
||||
+ '</'+qname(st.predicate)+'>']);
|
||||
break;
|
||||
case 'collection':
|
||||
results = results.concat(['<'+qname(st.predicate)+' rdf:parseType="Collection">',
|
||||
collectionXMLTree(st.object, subjects),
|
||||
'</'+qname(st.predicate)+'>']);
|
||||
break;
|
||||
default:
|
||||
throw "Can't serialize object of type "+st.object.termType +" into XML";
|
||||
|
||||
} // switch
|
||||
}
|
||||
}
|
||||
|
||||
var tag = type ? qname(type) : 'rdf:Description';
|
||||
|
||||
attrs = '';
|
||||
function subjectXMLTree(subject, stats) {
|
||||
var start
|
||||
if (subject.termType == 'bnode') {
|
||||
if(!referenced || sz.incoming[subject].length != 1) { // not an anonymous bnode
|
||||
attrs = ' rdf:nodeID="'+subject.toNT().slice(2)+'"';
|
||||
if (!stats.incoming[subject]) { // anonymous bnode
|
||||
var start = '<rdf:Description>';
|
||||
} else {
|
||||
var start = '<rdf:Description rdf:nodeID="'+subject.toNT().slice(2)+'">';
|
||||
}
|
||||
} else {
|
||||
attrs = ' rdf:about="'+ relURI(subject)+'"';
|
||||
var start = '<rdf:Description rdf:about="'+ relURI(subject)+'">';
|
||||
}
|
||||
|
||||
return [ '<' + tag + attrs + '>' ].concat([results]).concat(["</"+ tag +">"]);
|
||||
return [ start ].concat(
|
||||
[propertyXMLTree(subject, stats)]).concat(["</rdf:Description>"]);
|
||||
}
|
||||
|
||||
function collectionXMLTree(subject, subjects) {
|
||||
function collectionXMLTree(subject, stats) {
|
||||
res = []
|
||||
for (var i=0; i< subject.elements.length; i++) {
|
||||
res.push(subjectXMLTree(subject.elements[i], subjects));
|
||||
res.push(subjectXMLTree(subject.elements[i], stats));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// The property tree for a single subject or anonymos node
|
||||
function propertyXMLTree(subject, stats) {
|
||||
var results = []
|
||||
var sts = stats.subjects[sz.toStr(subject)]; // relevant statements
|
||||
if (sts == undefined) return results; // No relevant statements
|
||||
sts.sort();
|
||||
for (var i=0; i<sts.length; i++) {
|
||||
var st = sts[i];
|
||||
switch (st.object.termType) {
|
||||
case 'bnode':
|
||||
if(stats.rootsHash[st.object.toNT()]) { // This bnode has been done as a root -- no content here @@ what bout first time
|
||||
results = results.concat(['<'+qname(st.predicate)+' rdf:nodeID="'+st.object.toNT().slice(2)+'">',
|
||||
'</'+qname(st.predicate)+'>']);
|
||||
} else {
|
||||
results = results.concat(['<'+qname(st.predicate)+' rdf:parseType="Resource">',
|
||||
propertyXMLTree(st.object, stats),
|
||||
'</'+qname(st.predicate)+'>']);
|
||||
}
|
||||
break;
|
||||
case 'symbol':
|
||||
results = results.concat(['<'+qname(st.predicate)+' rdf:resource="'
|
||||
+ relURI(st.object)+'"/>']);
|
||||
break;
|
||||
case 'literal':
|
||||
results = results.concat(['<'+qname(st.predicate)
|
||||
+ (st.object.datatype ? ' rdf:datatype="'+escapeForXML(st.object.datatype.uri)+'"' : '')
|
||||
+ (st.object.lang ? ' xml:lang="'+st.object.lang+'"' : '')
|
||||
+ '>' + escapeForXML(st.object.value)
|
||||
+ '</'+qname(st.predicate)+'>']);
|
||||
break;
|
||||
case 'collection':
|
||||
results = results.concat(['<'+qname(st.predicate)+' rdf:parseType="Collection">',
|
||||
collectionXMLTree(st.object, stats),
|
||||
'</'+qname(st.predicate)+'>']);
|
||||
break;
|
||||
default:
|
||||
throw "Can't serialize object of type "+st.object.termType +" into XML";
|
||||
|
||||
} // switch
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
function qname(term) {
|
||||
|
@ -730,3 +779,7 @@ __Serializer.prototype.statementsToXML = function(sts) {
|
|||
|
||||
} // End @@ body
|
||||
|
||||
return Serializer;
|
||||
|
||||
}();
|
||||
|
||||
|
|
|
@ -8,224 +8,245 @@
|
|||
// W3C open source licence 2005.
|
||||
//
|
||||
|
||||
RDFTracking = 0 // Are we requiring reasons for statements?
|
||||
|
||||
//takes in an object and makes it an object if it's a literal
|
||||
function makeTerm(val) {
|
||||
// tabulator.log.debug("Making term from " + val)
|
||||
if (typeof val == 'object') return val;
|
||||
if (typeof val == 'string') return new RDFLiteral(val);
|
||||
if (typeof val == 'number') return new RDFLiteral(val); // @@ differet types
|
||||
if (typeof val == 'boolean') return new RDFLiteral(val?"1":"0", undefined,
|
||||
RDFSymbol.prototype.XSDboolean);
|
||||
if (typeof val == 'undefined') return undefined;
|
||||
alert("Can't make term from " + val + " of type " + typeof val);
|
||||
}
|
||||
|
||||
|
||||
// Symbol
|
||||
|
||||
function RDFEmpty() {
|
||||
$rdf.Empty = function() {
|
||||
return this;
|
||||
}
|
||||
RDFEmpty.prototype.termType = 'empty'
|
||||
RDFEmpty.prototype.toString = function () { return "()" }
|
||||
RDFEmpty.prototype.toNT = function () { return "@@" }
|
||||
};
|
||||
|
||||
function RDFSymbol_toNT(x) {
|
||||
return ("<" + x.uri + ">")
|
||||
$rdf.Empty.prototype.termType = 'empty';
|
||||
$rdf.Empty.prototype.toString = function () { return "()" };
|
||||
$rdf.Empty.prototype.toNT = $rdf.Empty.prototype.toString;
|
||||
|
||||
$rdf.Symbol = function( uri ) {
|
||||
this.uri = uri;
|
||||
this.value = uri; // -- why? -tim
|
||||
return this;
|
||||
}
|
||||
|
||||
function toNT() {
|
||||
return RDFSymbol_toNT(this)
|
||||
}
|
||||
|
||||
function RDFSymbol(uri) {
|
||||
this.uri = uri
|
||||
return this
|
||||
}
|
||||
|
||||
RDFSymbol.prototype.termType = 'symbol'
|
||||
RDFSymbol.prototype.toString = toNT
|
||||
RDFSymbol.prototype.toNT = toNT
|
||||
|
||||
// Some precalculaued symbols
|
||||
|
||||
RDFSymbol.prototype.XSDboolean = new RDFSymbol('http://www.w3.org/2001/XMLSchema#boolean');
|
||||
RDFSymbol.prototype.integer = new RDFSymbol('http://www.w3.org/2001/XMLSchema#integer');
|
||||
$rdf.Symbol.prototype.termType = 'symbol';
|
||||
$rdf.Symbol.prototype.toString = function () { return ("<" + this.uri + ">"); };
|
||||
$rdf.Symbol.prototype.toNT = $rdf.Symbol.prototype.toString;
|
||||
|
||||
// Some precalculated symbols
|
||||
$rdf.Symbol.prototype.XSDboolean = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#boolean');
|
||||
$rdf.Symbol.prototype.XSDdecimal = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#decimal');
|
||||
$rdf.Symbol.prototype.XSDfloat = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#float');
|
||||
$rdf.Symbol.prototype.XSDinteger = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#integer');
|
||||
$rdf.Symbol.prototype.XSDdateTime = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#dateTime');
|
||||
$rdf.Symbol.prototype.integer = new $rdf.Symbol('http://www.w3.org/2001/XMLSchema#integer'); // Used?
|
||||
|
||||
// Blank Node
|
||||
|
||||
var RDFNextId = 0; // Gobal genid
|
||||
RDFGenidPrefix = "genid:"
|
||||
NTAnonymousNodePrefix = "_:n"
|
||||
if (typeof $rdf.NextId != 'undefined') {
|
||||
$rdf.log.error('Attempt to re-zero existing blank node id counter at '+$rdf.NextId);
|
||||
} else {
|
||||
$rdf.NextId = 0; // Global genid
|
||||
}
|
||||
$rdf.NTAnonymousNodePrefix = "_:n";
|
||||
|
||||
function RDFBlankNode(id) {
|
||||
$rdf.BlankNode = function ( id ) {
|
||||
/*if (id)
|
||||
this.id = id;
|
||||
else*/
|
||||
this.id = RDFNextId++
|
||||
this.id = $rdf.NextId++
|
||||
this.value = id ? id : this.id.toString();
|
||||
return this
|
||||
}
|
||||
};
|
||||
|
||||
RDFBlankNode.prototype.termType = 'bnode'
|
||||
|
||||
RDFBlankNode.prototype.toNT = function() {
|
||||
return NTAnonymousNodePrefix + this.id
|
||||
}
|
||||
RDFBlankNode.prototype.toString = RDFBlankNode.prototype.toNT
|
||||
$rdf.BlankNode.prototype.termType = 'bnode';
|
||||
$rdf.BlankNode.prototype.toNT = function() {
|
||||
return $rdf.NTAnonymousNodePrefix + this.id
|
||||
};
|
||||
$rdf.BlankNode.prototype.toString = $rdf.BlankNode.prototype.toNT;
|
||||
|
||||
// Literal
|
||||
|
||||
function RDFLiteral(value, lang, datatype) {
|
||||
$rdf.Literal = function (value, lang, datatype) {
|
||||
this.value = value
|
||||
this.lang=lang; // string
|
||||
this.datatype=datatype; // term
|
||||
this.toString = RDFLiteralToString
|
||||
this.toNT = RDFLiteral_toNT
|
||||
return this
|
||||
if (lang == "" || lang == null) this.lang = undefined;
|
||||
else this.lang = lang; // string
|
||||
if (datatype == null) this.datatype = undefined;
|
||||
else this.datatype = datatype; // term
|
||||
return this;
|
||||
}
|
||||
|
||||
RDFLiteral.prototype.termType = 'literal'
|
||||
|
||||
function RDFLiteral_toNT() {
|
||||
$rdf.Literal.prototype.termType = 'literal'
|
||||
$rdf.Literal.prototype.toString = function() {
|
||||
return ''+this.value;
|
||||
};
|
||||
$rdf.Literal.prototype.toNT = function() {
|
||||
var str = this.value
|
||||
if (typeof str != 'string') {
|
||||
if (typeof str == 'number') return ''+str;
|
||||
throw Error("Value of RDF literal is not string: "+str)
|
||||
}
|
||||
str = str.replace(/\\/g, '\\\\'); // escape
|
||||
str = str.replace(/\"/g, '\\"');
|
||||
str = '"' + str + '"' //'
|
||||
str = str.replace(/\\/g, '\\\\'); // escape backslashes
|
||||
str = str.replace(/\"/g, '\\"'); // escape quotes
|
||||
str = str.replace(/\n/g, '\\n'); // escape newlines
|
||||
str = '"' + str + '"' //';
|
||||
|
||||
if (this.datatype){
|
||||
str = str + '^^' + this.datatype//.toNT()
|
||||
str = str + '^^' + this.datatype.toNT()
|
||||
}
|
||||
if (this.lang) {
|
||||
str = str + "@" + this.lang
|
||||
str = str + "@" + this.lang;
|
||||
}
|
||||
return str
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
function RDFLiteralToString() {
|
||||
return ''+this.value
|
||||
}
|
||||
|
||||
RDFLiteral.prototype.toString = RDFLiteralToString
|
||||
RDFLiteral.prototype.toNT = RDFLiteral_toNT
|
||||
$rdf.Collection = function() {
|
||||
this.id = $rdf.NextId++; // Why need an id? For hashstring.
|
||||
this.elements = [];
|
||||
this.closed = false;
|
||||
};
|
||||
|
||||
function RDFCollection() {
|
||||
this.id = RDFNextId++
|
||||
this.elements = []
|
||||
this.closed = false
|
||||
}
|
||||
$rdf.Collection.prototype.termType = 'collection';
|
||||
|
||||
RDFCollection.prototype.termType = 'collection'
|
||||
$rdf.Collection.prototype.toNT = function() {
|
||||
return $rdf.NTAnonymousNodePrefix + this.id
|
||||
};
|
||||
|
||||
RDFCollection.prototype.toNT = function() {
|
||||
return NTAnonymousNodePrefix + this.id
|
||||
}
|
||||
RDFCollection.prototype.toString = RDFCollection.prototype.toNT
|
||||
$rdf.Collection.prototype.toString = function() {
|
||||
var str='(';
|
||||
for (var i=0; i<this.elements.length; i++)
|
||||
str+= this.elements[i] + ' ';
|
||||
return str + ')';
|
||||
};
|
||||
|
||||
RDFCollection.prototype.append = function (el) {
|
||||
$rdf.Collection.prototype.append = function (el) {
|
||||
this.elements.push(el)
|
||||
}
|
||||
RDFCollection.prototype.unshift=function(el){
|
||||
$rdf.Collection.prototype.unshift=function(el){
|
||||
this.elements.unshift(el);
|
||||
}
|
||||
RDFCollection.prototype.shift=function(){
|
||||
$rdf.Collection.prototype.shift=function(){
|
||||
return this.elements.shift();
|
||||
}
|
||||
|
||||
RDFCollection.prototype.close = function () {
|
||||
$rdf.Collection.prototype.close = function () {
|
||||
this.closed = true
|
||||
}
|
||||
|
||||
|
||||
// Convert Javascript representation to RDF term object
|
||||
//
|
||||
$rdf.term = function(val) {
|
||||
if (typeof val == 'object')
|
||||
if (val instanceof Date) {
|
||||
var d2=function(x) {return(''+(100+x)).slice(1,3)}; // format as just two digits
|
||||
return new $rdf.Literal(
|
||||
''+ val.getUTCFullYear() + '-'+
|
||||
d2(val.getUTCMonth()+1) +'-'+d2(val.getUTCDate())+
|
||||
'T'+d2(val.getUTCHours())+':'+d2(val.getUTCMinutes())+
|
||||
':'+d2(val.getUTCSeconds())+'Z',
|
||||
undefined, $rdf.Symbol.prototype.XSDdateTime);
|
||||
|
||||
}
|
||||
else if (val instanceof Array) {
|
||||
var x = new $rdf.Collection();
|
||||
for (var i=0; i<val.length; i++) x.append($rdf.term(val[i]));
|
||||
return x;
|
||||
}
|
||||
else return val;
|
||||
if (typeof val == 'string') return new $rdf.Literal(val);
|
||||
if (typeof val == 'number') {
|
||||
var dt;
|
||||
if ((''+val).indexOf('e')>=0) dt = $rdf.Symbol.prototype.XSDfloat;
|
||||
else if ((''+val).indexOf('.')>=0) dt = $rdf.Symbol.prototype.XSDdecimal;
|
||||
else dt = $rdf.Symbol.prototype.XSDinteger;
|
||||
return new $rdf.Literal(val, undefined, dt);
|
||||
}
|
||||
if (typeof val == 'boolean') return new $rdf.Literal(val?"1":"0", undefined,
|
||||
$rdf.Symbol.prototype.XSDboolean);
|
||||
if (typeof val == 'undefined') return undefined;
|
||||
throw ("Can't make term from " + val + " of type " + typeof val);
|
||||
}
|
||||
|
||||
// Statement
|
||||
//
|
||||
// This is a triple with an optional reason.
|
||||
//
|
||||
// The reason can point to provenece or inference
|
||||
//
|
||||
function RDFStatement_toNT() {
|
||||
return (this.subject.toNT() + " "
|
||||
+ this.predicate.toNT() + " "
|
||||
+ this.object.toNT() +" .")
|
||||
}
|
||||
|
||||
function RDFStatement(subject, predicate, object, why) {
|
||||
this.subject = makeTerm(subject)
|
||||
this.predicate = makeTerm(predicate)
|
||||
this.object = makeTerm(object)
|
||||
$rdf.Statement = function(subject, predicate, object, why) {
|
||||
this.subject = $rdf.term(subject)
|
||||
this.predicate = $rdf.term(predicate)
|
||||
this.object = $rdf.term(object)
|
||||
if (typeof why !='undefined') {
|
||||
this.why = why
|
||||
} else if (RDFTracking) {
|
||||
tabulator.log.debug("WARNING: No reason on "+subject+" "+predicate+" "+object)
|
||||
this.why = why;
|
||||
}
|
||||
return this
|
||||
return this;
|
||||
}
|
||||
|
||||
RDFStatement.prototype.toNT = RDFStatement_toNT
|
||||
RDFStatement.prototype.toString = RDFStatement_toNT
|
||||
|
||||
$rdf.st= function(subject, predicate, object, why) {
|
||||
return new $rdf.Statement(subject, predicate, object, why);
|
||||
};
|
||||
|
||||
$rdf.Statement.prototype.toNT = function() {
|
||||
return (this.subject.toNT() + " "
|
||||
+ this.predicate.toNT() + " "
|
||||
+ this.object.toNT() +" .");
|
||||
};
|
||||
|
||||
$rdf.Statement.prototype.toString = $rdf.Statement.prototype.toNT;
|
||||
|
||||
// Formula
|
||||
//
|
||||
// Set of statements.
|
||||
|
||||
function RDFFormula() {
|
||||
$rdf.Formula = function() {
|
||||
this.statements = []
|
||||
this.constraints = []
|
||||
this.initBindings = []
|
||||
this.optional = []
|
||||
this.superFormula = null;
|
||||
return this
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
function RDFFormula_toNT() {
|
||||
// throw 'Who called me?';
|
||||
|
||||
$rdf.Formula.prototype.termType = 'formula';
|
||||
$rdf.Formula.prototype.toNT = function() {
|
||||
return "{" + this.statements.join('\n') + "}"
|
||||
}
|
||||
};
|
||||
$rdf.Formula.prototype.toString = $rdf.Formula.prototype.toNT;
|
||||
|
||||
//RDFQueryFormula.prototype = new RDFFormula()
|
||||
//RDFQueryFormula.termType = 'queryFormula'
|
||||
RDFFormula.prototype.termType = 'formula'
|
||||
RDFFormula.prototype.toNT = RDFFormula_toNT
|
||||
RDFFormula.prototype.toString = RDFFormula_toNT
|
||||
|
||||
RDFFormula.prototype.add = function(subj, pred, obj, why) {
|
||||
this.statements.push(new RDFStatement(subj, pred, obj, why))
|
||||
$rdf.Formula.prototype.add = function(subj, pred, obj, why) {
|
||||
this.statements.push(new $rdf.Statement(subj, pred, obj, why))
|
||||
}
|
||||
|
||||
// Convenience methods on a formula allow the creation of new RDF terms:
|
||||
|
||||
RDFFormula.prototype.sym = function(uri,name) {
|
||||
$rdf.Formula.prototype.sym = function(uri,name) {
|
||||
if (name != null) {
|
||||
if (!tabulator.ns[uri]) throw 'The prefix "'+uri+'" is not set in the API';
|
||||
uri = tabulator.ns[uri] + name
|
||||
throw "This feature (kb.sym with 2 args) is removed. Do not assume prefix mappings."
|
||||
if (!$rdf.ns[uri]) throw 'The prefix "'+uri+'" is not set in the API';
|
||||
uri = $rdf.ns[uri] + name
|
||||
}
|
||||
return new RDFSymbol(uri)
|
||||
return new $rdf.Symbol(uri)
|
||||
}
|
||||
|
||||
RDFFormula.prototype.literal = function(val, lang, dt) {
|
||||
return new RDFLiteral(val.toString(), lang, dt)
|
||||
$rdf.sym = function(uri) { return new $rdf.Symbol(uri); };
|
||||
|
||||
$rdf.Formula.prototype.literal = function(val, lang, dt) {
|
||||
return new $rdf.Literal(val.toString(), lang, dt)
|
||||
}
|
||||
$rdf.lit = $rdf.Formula.prototype.literal;
|
||||
|
||||
$rdf.Formula.prototype.bnode = function(id) {
|
||||
return new $rdf.BlankNode(id)
|
||||
}
|
||||
|
||||
RDFFormula.prototype.bnode = function(id) {
|
||||
return new RDFBlankNode(id)
|
||||
$rdf.Formula.prototype.formula = function() {
|
||||
return new $rdf.Formula()
|
||||
}
|
||||
|
||||
RDFFormula.prototype.formula = function() {
|
||||
return new RDFFormula()
|
||||
$rdf.Formula.prototype.collection = function () { // obsolete
|
||||
return new $rdf.Collection()
|
||||
}
|
||||
|
||||
RDFFormula.prototype.collection = function () { // obsolete
|
||||
return new RDFCollection()
|
||||
}
|
||||
|
||||
RDFFormula.prototype.list = function (values) {
|
||||
li = new RDFCollection();
|
||||
$rdf.Formula.prototype.list = function (values) {
|
||||
li = new $rdf.Collection();
|
||||
if (values) {
|
||||
for(var i = 0; i<values.length; i++) {
|
||||
li.append(values[i]);
|
||||
|
@ -234,58 +255,46 @@ RDFFormula.prototype.list = function (values) {
|
|||
return li;
|
||||
}
|
||||
|
||||
RDFFormula.instances={};
|
||||
RDFFormula.prototype.registerFormula = function(accesskey){
|
||||
var superFormula = this.superFormula || this;
|
||||
RDFFormula.instances[accesskey] = this;
|
||||
var formulaTerm = superFormula.bnode();
|
||||
superFormula.add(formulaTerm, tabulator.ns.rdf('type'),superFormula.sym("http://www.w3.org/2000/10/swap/log#Formula"));
|
||||
superFormula.add(formulaTerm, tabulator.ns.foaf('name'), superFormula.literal(accesskey));
|
||||
superFormula.add(formulaTerm, tabulator.ns.link('accesskey'), superFormula.literal(accesskey));
|
||||
//RDFFormula.instances.push("accesskey");
|
||||
}
|
||||
|
||||
|
||||
/* Variable
|
||||
**
|
||||
** Variables are placeholders used in patterns to be matched.
|
||||
** In cwm they are symbols which are the formula's list of quantified variables.
|
||||
** In sparl they are not visibily URIs. Here we compromise, by having
|
||||
** a common special base URI for variables.
|
||||
** a common special base URI for variables. Their names are uris,
|
||||
** but the ? nottaion has an implicit base uri of 'varid:'
|
||||
*/
|
||||
|
||||
RDFVariableBase = "varid:"; // We deem variabe x to be the symbol varid:x
|
||||
|
||||
function RDFVariable(rel) {
|
||||
this.uri = URIjoin(rel, RDFVariableBase);
|
||||
$rdf.Variable = function(rel) {
|
||||
this.base = "varid:"; // We deem variabe x to be the symbol varid:x
|
||||
this.uri = $rdf.Util.uri.join(rel, this.base);
|
||||
return this;
|
||||
}
|
||||
|
||||
RDFVariable.prototype.termType = 'variable';
|
||||
RDFVariable.prototype.toNT = function() {
|
||||
if (this.uri.slice(0, RDFVariableBase.length) == RDFVariableBase) {
|
||||
return '?'+ this.uri.slice(RDFVariableBase.length);} // @@ poor man's refTo
|
||||
$rdf.Variable.prototype.termType = 'variable';
|
||||
$rdf.Variable.prototype.toNT = function() {
|
||||
if (this.uri.slice(0, this.base.length) == this.base) {
|
||||
return '?'+ this.uri.slice(this.base.length);} // @@ poor man's refTo
|
||||
return '?' + this.uri;
|
||||
};
|
||||
|
||||
RDFVariable.prototype.toString = RDFVariable.prototype.toNT;
|
||||
RDFVariable.prototype.classOrder = 7;
|
||||
$rdf.Variable.prototype.toString = $rdf.Variable.prototype.toNT;
|
||||
$rdf.Variable.prototype.classOrder = 7;
|
||||
|
||||
RDFFormula.prototype.variable = function(name) {
|
||||
return new RDFVariable(name);
|
||||
$rdf.variable = $rdf.Formula.prototype.variable = function(name) {
|
||||
return new $rdf.Variable(name);
|
||||
};
|
||||
|
||||
RDFVariable.prototype.hashString = RDFVariable.prototype.toNT;
|
||||
$rdf.Variable.prototype.hashString = $rdf.Variable.prototype.toNT;
|
||||
|
||||
|
||||
// The namespace function generator
|
||||
|
||||
function RDFNamespace(nsuri) {
|
||||
return function(ln) { return new RDFSymbol(nsuri+(ln===undefined?'':ln)) }
|
||||
$rdf.Namespace = function (nsuri) {
|
||||
return function(ln) { return new $rdf.Symbol(nsuri+(ln===undefined?'':ln)) }
|
||||
}
|
||||
|
||||
RDFFormula.prototype.ns = function(nsuri) {
|
||||
return function(ln) { return new RDFSymbol(nsuri+(ln===undefined?'':ln)) }
|
||||
$rdf.Formula.prototype.ns = function(nsuri) {
|
||||
return function(ln) { return new $rdf.Symbol(nsuri+(ln===undefined?'':ln)) }
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,21 +302,44 @@ RDFFormula.prototype.ns = function(nsuri) {
|
|||
//
|
||||
// The bnode bit should not be used on program-external values; designed
|
||||
// for internal work such as storing a bnode id in an HTML attribute.
|
||||
// Not coded for literals.
|
||||
// This will only parse the strings generated by the vaious toNT() methods.
|
||||
|
||||
RDFFormula.prototype.fromNT = function(str) {
|
||||
$rdf.Formula.prototype.fromNT = function(str) {
|
||||
var len = str.length
|
||||
var ch = str.slice(0,1)
|
||||
if (ch == '<') return this.sym(str.slice(1,len-1))
|
||||
if (ch == '<') return $rdf.sym(str.slice(1,len-1))
|
||||
if (ch == '"') {
|
||||
var lang = undefined;
|
||||
var dt = undefined;
|
||||
var k = str.lastIndexOf('"');
|
||||
if (k < len-1) {
|
||||
if (str[k+1] == '@') lang = str.slice(k+2,len);
|
||||
else if (str.slice(k+1,k+3) == '^^') dt = $rdf.fromNT(str.slice(k+3,len));
|
||||
else throw "Can't convert string from NT: "+str
|
||||
}
|
||||
var str = (str.slice(1,k));
|
||||
str = str.replace(/\\"/g, '"'); // unescape quotes '
|
||||
str = str.replace(/\\n/g, '\n'); // unescape newlines
|
||||
str = str.replace(/\\\\/g, '\\'); // unescape backslashes
|
||||
return $rdf.lit(str, lang, dt);
|
||||
}
|
||||
if (ch == '_') {
|
||||
var x = new RDFBlankNode();
|
||||
var x = new $rdf.BlankNode();
|
||||
x.id = parseInt(str.slice(3));
|
||||
RDFNextId--
|
||||
$rdf.NextId--
|
||||
return x
|
||||
}
|
||||
throw "Can't convert from NT"+str;
|
||||
if (ch == '?') {
|
||||
var x = new $rdf.Variable(str.slice(1));
|
||||
return x;
|
||||
}
|
||||
throw "Can't convert from NT: "+str;
|
||||
|
||||
//alert("Can't yet convert from NT: '"+str+"', "+str[0])
|
||||
}
|
||||
$rdf.fromNT = $rdf.Formula.prototype.fromNT; // Not for inexpert user
|
||||
|
||||
// Convenience - and more conventional name:
|
||||
|
||||
$rdf.graph = function(){return new $rdf.IndexedFormula();};
|
||||
|
||||
// ends
|
||||
|
|
|
@ -12,11 +12,10 @@
|
|||
// See also http://www.w3.org/2000/10/swap/uripath.py
|
||||
//
|
||||
|
||||
if (typeof Util == "undefined") { Util = {}}
|
||||
if (typeof Util.uri == "undefined") { Util.uri = {}}
|
||||
if (typeof $rdf.Util.uri == "undefined") { $rdf.Util.uri = {}; };
|
||||
|
||||
Util.uri.join = function (given, base) {
|
||||
// if (typeof tabulator.log.debug != 'undefined') tabulator.log.debug(" URI given="+given+" base="+base)
|
||||
$rdf.Util.uri.join = function (given, base) {
|
||||
// if (typeof $rdf.log.debug != 'undefined') $rdf.log.debug(" URI given="+given+" base="+base)
|
||||
var baseHash = base.indexOf('#')
|
||||
if (baseHash > 0) base = base.slice(0, baseHash)
|
||||
if (given.length==0) return base // before chopping its filename off
|
||||
|
@ -64,35 +63,38 @@ Util.uri.join = function (given, base) {
|
|||
path = path + given
|
||||
while (path.match(/[^\/]*\/\.\.\//)) // must apply to result of prev
|
||||
path = path.replace( /[^\/]*\/\.\.\//, '') // ECMAscript spec 7.8.5
|
||||
path = path.replace( /\.\//g, '') // spec vague on escaping
|
||||
path = path.replace( /\.\//g, '') // spec vague on escaping
|
||||
path = path.replace( /\/\.$/, '/' )
|
||||
return base.slice(0, baseSingle) + path
|
||||
}
|
||||
|
||||
var tIOService;
|
||||
if (typeof( isExtension ) != "undefined" && isExtension) {
|
||||
tIOService = Components.classes['@mozilla.org/network/io-service;1']
|
||||
if (typeof tabulator != 'undefined' && tabulator.isExtension) {
|
||||
$rdf.Util.uri.join2 = function (given, base){
|
||||
var tIOService = Components.classes['@mozilla.org/network/io-service;1']
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
Util.uri.join2 = function (given, base){
|
||||
var baseURI = tIOService.newURI(base, null, null);
|
||||
return tIOService.newURI(baseURI.resolve(given), null, null).spec;
|
||||
|
||||
var baseURI = tIOService.newURI(base, null, null);
|
||||
return tIOService.newURI(baseURI.resolve(given), null, null).spec;
|
||||
}
|
||||
} else
|
||||
Util.uri.join2 = Util.uri.join;
|
||||
$rdf.Util.uri.join2 = $rdf.Util.uri.join;
|
||||
|
||||
// refTo: Make a URI relative to a given base
|
||||
//
|
||||
// based on code in http://www.w3.org/2000/10/swap/uripath.py
|
||||
//
|
||||
Util.uri.commonHost = new RegExp("^[-_a-zA-Z0-9.]+:(//[^/]*)?/[^/]*$");
|
||||
Util.uri.refTo = function(base, uri) {
|
||||
$rdf.Util.uri.commonHost = new RegExp("^[-_a-zA-Z0-9.]+:(//[^/]*)?/[^/]*$");
|
||||
|
||||
$rdf.Util.uri.hostpart = function(u) { var m = /[^\/]*\/\/([^\/]*)\//.exec(u); return m? m[1]: '' };
|
||||
|
||||
$rdf.Util.uri.refTo = function(base, uri) {
|
||||
if (!base) return uri;
|
||||
if (base == uri) return "";
|
||||
var i =0; // How much are they identical?
|
||||
while (i<uri.length && i < base.length)
|
||||
if (uri[i] == base[i]) i++;
|
||||
else break;
|
||||
if (base.slice(0,i).match(Util.uri.commonHost)) {
|
||||
if (base.slice(0,i).match($rdf.Util.uri.commonHost)) {
|
||||
var k = uri.indexOf('//');
|
||||
if (k<0) k=-2; // no host
|
||||
var l = uri.indexOf('/', k+2); // First *single* slash
|
||||
|
@ -119,15 +121,20 @@ Util.uri.refTo = function(base, uri) {
|
|||
|
||||
|
||||
/** returns URI without the frag **/
|
||||
Util.uri.docpart = function (uri) {
|
||||
$rdf.Util.uri.docpart = function (uri) {
|
||||
var i = uri.indexOf("#")
|
||||
if (i < 0) return uri
|
||||
return uri.slice(0,i)
|
||||
}
|
||||
|
||||
/** The document in which something a thing defined **/
|
||||
$rdf.Util.uri.document = function (x) {
|
||||
return $rdf.sym($rdf.Util.uri.docpart(x.uri));
|
||||
}
|
||||
|
||||
/** return the protocol of a uri **/
|
||||
/** return null if there isn't one **/
|
||||
Util.uri.protocol = function (uri) {
|
||||
$rdf.Util.uri.protocol = function (uri) {
|
||||
var index = uri.indexOf(':');
|
||||
if (index >= 0)
|
||||
return uri.slice(0, index);
|
||||
|
@ -135,9 +142,4 @@ Util.uri.protocol = function (uri) {
|
|||
return null;
|
||||
} //protocol
|
||||
|
||||
URIjoin = Util.uri.join
|
||||
uri_docpart = Util.uri.docpart
|
||||
uri_protocol = Util.uri.protocol
|
||||
|
||||
|
||||
//ends
|
||||
|
|
Loading…
Reference in New Issue
Block a user