Created
March 13, 2012 21:50
-
-
Save melvincarvalho/2031978 to your computer and use it in GitHub Desktop.
rdfapi.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * @fileOverview | |
| * | |
| * rdfapi - see: <http://webr3.org/apps/play/api/lib> | |
| * | |
| * @author Nathan <http://webr3.org/nathan#me> | |
| * @version 2010-10-29T03:30:00Z | |
| * @license http://creativecommons.org/publicdomain/zero/1.0/ | |
| * | |
| * source: <http://webr3.org/apps/play/api/> To the extent possible under law, | |
| * <http://webr3.org/nathan#me> has waived all copyright and related or | |
| * neighboring rights to this work. | |
| * | |
| * all code in this library is 100% unique to this library and nothing is | |
| * begged, stolen or borrowed, thus no other licenses are affected. | |
| */ | |
| /** | |
| * Core RDF API Interfaces | |
| */ | |
| rdfapi = function() { | |
| api = {}; | |
| /** | |
| * RDFNode | |
| */ | |
| api.RDFNode = function() {}; | |
| api.RDFNode.prototype = { | |
| value: null, | |
| equals: function(other) { | |
| if( this.nodeType() != other.nodeType() ) return false; | |
| switch(this.nodeType()) { | |
| case "IRI": | |
| case "BlankNode": | |
| return this.value == other.value; | |
| case "PlainLiteral": | |
| return this.language == other.language && this.value == other.value; | |
| case "TypedLiteral": | |
| return this.type.equals(other.type) && this.value == other.value; | |
| } | |
| return this.toNT() == other.toNT() | |
| }, | |
| nodeType: function() { return "RDFNode" }, | |
| toNT: function() { return "" }, | |
| toString: function() { return this.value }, | |
| encodeString: function(s) { | |
| var out = ""; | |
| var skip = false; | |
| var _g1 = 0, _g = s.length; | |
| while(_g1 < _g) { | |
| var i = _g1++; | |
| if(!skip) { | |
| var code = s.charCodeAt(i); | |
| if(55296 <= code && code <= 56319) { | |
| var low = s.charCodeAt(i + 1); | |
| code = (code - 55296) * 1024 + (low - 56320) + 65536; | |
| skip = true | |
| } | |
| if(code > 1114111) { throw new Error("Char out of range"); } | |
| var hex = "00000000".concat((new Number(code)).toString(16).toUpperCase()); | |
| if(code >= 65536) { | |
| out += "\\U" + hex.slice(-8) | |
| } else { | |
| if(code >= 127 || code <= 31) { | |
| switch(code) { | |
| case 9: out += "\\t"; break; | |
| case 10: out += "\\n"; break; | |
| case 13: out += "\\r"; break; | |
| default: out += "\\u" + hex.slice(-4); break | |
| } | |
| } else { | |
| switch(code) { | |
| case 34: out += '\\"'; break; | |
| case 92: out += "\\\\"; break; | |
| default: out += s.charAt(i); break | |
| } | |
| } | |
| } | |
| } else { | |
| skip = !skip | |
| } | |
| } | |
| return out | |
| } | |
| }; | |
| /** | |
| * BlankNode | |
| */ | |
| api.BlankNode = function() { this.value = "_:b" + (new String(++api.BlankNode.NEXTID)).toString() }; | |
| api.BlankNode.NEXTID = 0; | |
| api.BlankNode.prototype = { | |
| __proto__: api.RDFNode.prototype, | |
| nodeType: function() { return "BlankNode"; }, | |
| toNT: function() { return this.value; } | |
| }; | |
| /** | |
| * PlainLiteral | |
| */ | |
| api.PlainLiteral = function(value, language) { this.value = value; this.language = language }; | |
| api.PlainLiteral.prototype = { | |
| __proto__: api.RDFNode.prototype, | |
| language: null, | |
| nodeType: function() { return "PlainLiteral" }, | |
| toNT: function() { | |
| var string = '"' + this.encodeString(this.value) + '"'; | |
| return this.language == null ? string : string.concat("@" + this.language) | |
| } | |
| }; | |
| /** | |
| * TypedLiteral | |
| */ | |
| api.TypedLiteral = function(value, type) { this.value = value; this.type = type }; | |
| api.TypedLiteral.prototype = { | |
| __proto__: api.RDFNode.prototype, | |
| type: null, | |
| nodeType: function() { return "TypedLiteral"; }, | |
| toNT: function() { return '"' + this.encodeString(this.value) + '"^^<' + this.type + ">"; } | |
| }; | |
| /** | |
| * RDFTriple | |
| */ | |
| api.RDFTriple = function(s, p, o) { this.subject = s; this.property = p; this.object = o; }; | |
| api.RDFTriple.prototype = { | |
| object: null, property: null, subject: null, | |
| toString: function() { return this.subject.toNT() + " " + this.property.toNT() + " " + this.object.toNT() + " ." }, | |
| equals: function(t) { return this.subject.equals(t.subject) && this.property.equals(t.property) && this.object.equals(t.object) } | |
| }; | |
| /** | |
| * IRI | |
| */ | |
| api.IRI = function(iri) { this.value = iri }; | |
| api.IRI.SCHEME_MATCH = new RegExp("^[a-z0-9-.+]+:", "i"); | |
| api.IRI.prototype = { | |
| __proto__: api.RDFNode.prototype, | |
| nodeType: function() { return "IRI" }, | |
| toNT: function() { return"<" + this.encodeString(this.value) + ">" }, | |
| defrag: function() { | |
| var i = this.value.indexOf("#"); | |
| return (i < 0) ? this : new api.IRI(this.value.slice(0, i)) | |
| }, | |
| isAbsolute: function() { | |
| return this.scheme() != null && this.heirpart() != null && this.fragment() == null | |
| }, | |
| toAbsolute: function() { | |
| if(this.scheme() == null && this.heirpart() == null) { throw new Error("IRI must have a scheme and a heirpart!"); } | |
| return this.resolveReference(this.value).defrag() | |
| }, | |
| authority: function() { | |
| var heirpart = this.heirpart(); | |
| if(heirpart.substring(0, 2) != "//") { return null } | |
| var authority = heirpart.slice(2); | |
| var q = authority.indexOf("/"); | |
| return q >= 0 ? authority.substring(0, q) : authority | |
| }, | |
| fragment: function() { | |
| var i = this.value.indexOf("#"); | |
| return (i < 0) ? null : this.value.slice(i) | |
| }, | |
| heirpart: function() { | |
| var heirpart = this.value; | |
| var q = heirpart.indexOf("?"); | |
| if(q >= 0) { | |
| heirpart = heirpart.substring(0, q) | |
| } else { | |
| q = heirpart.indexOf("#"); | |
| if(q >= 0) { heirpart = heirpart.substring(0, q) } | |
| } | |
| var q2 = this.scheme(); | |
| if(q2 != null) { heirpart = heirpart.slice(1 + q2.length) } | |
| return heirpart | |
| }, | |
| host: function() { | |
| var host = this.authority(); | |
| var q = host.indexOf("@"); | |
| if(q >= 0) { host = host.slice(++q) } | |
| if(host.indexOf("[") == 0) { | |
| q = host.indexOf("]"); | |
| if(q > 0) { return host.substring(0, q) } | |
| } | |
| q = host.lastIndexOf(":"); | |
| return q >= 0 ? host.substring(0, q) : host | |
| }, | |
| path: function() { | |
| var q = this.authority(); | |
| if(q == null) { return this.heirpart() } | |
| return this.heirpart().slice(q.length + 2) | |
| }, | |
| port: function() { | |
| var host = this.authority(); | |
| var q = host.indexOf("@"); | |
| if(q >= 0) { host = host.slice(++q) } | |
| if(host.indexOf("[") == 0) { | |
| q = host.indexOf("]"); | |
| if(q > 0) { return host.substring(0, q) } | |
| } | |
| q = host.lastIndexOf(":"); | |
| if(q < 0) { return null } | |
| host = host.slice(++q); | |
| return host.length == 0 ? null : host | |
| }, | |
| query: function() { | |
| var q = this.value.indexOf("?"); | |
| if(q < 0) { return null } | |
| var f = this.value.indexOf("#"); | |
| if(f < 0) { return this.value.slice(q) } | |
| return this.value.substring(q, f) | |
| }, | |
| removeDotSegments: function(input) { | |
| var output = ""; | |
| var q = 0; | |
| while(input.length > 0) { | |
| if(input.substr(0, 3) == "../" || input.substr(0, 2) == "./") { | |
| input = input.slice(input.indexOf("/")) | |
| }else { | |
| if(input == "/.") { | |
| input = "/" | |
| }else { | |
| if(input.substr(0, 3) == "/./") { | |
| input = input.slice(2) | |
| }else { | |
| if(input.substr(0, 4) == "/../" || input == "/..") { | |
| (input == "/..") ? input = "/" : input = input.slice(3); | |
| q = output.lastIndexOf("/"); | |
| (q >= 0) ? output = output.substring(0, q) : output = ""; | |
| }else { | |
| if(input.substr(0, 2) == ".." || input.substr(0, 1) == ".") { | |
| input = input.slice(input.indexOf(".")); | |
| q = input.indexOf("."); | |
| if(q >= 0) { input = input.slice(q) } | |
| }else { | |
| if(input.substr(0, 1) == "/") { | |
| output += "/"; | |
| input = input.slice(1) | |
| } | |
| q = input.indexOf("/"); | |
| if(q < 0) { | |
| output += input; | |
| input = "" | |
| }else { | |
| output += input.substring(0, q); | |
| input = input.slice(q) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return output | |
| }, | |
| resolveReference: function(ref) { | |
| var reference; | |
| if(typeof ref == "string") { | |
| reference = new api.IRI(ref) | |
| }else if(ref.nodeType && ref.nodeType() == "IRI") { | |
| reference = ref | |
| }else { | |
| throw new Error("Expected IRI or String"); | |
| } | |
| var T = {scheme:"", authority:"", path:"", query:"", fragment:""}; | |
| var q = ""; | |
| if(reference.scheme() != null) { | |
| T.scheme = reference.scheme(); | |
| q = reference.authority(); | |
| T.authority += q != null ? "//" + q : ""; | |
| T.path = this.removeDotSegments(reference.path()); | |
| q = reference.query(); | |
| T.query += q != null ? q : "" | |
| }else { | |
| q = reference.authority(); | |
| if(q != null) { | |
| T.authority = q != null ? "//" + q : ""; | |
| T.path = this.removeDotSegments(reference.path()); | |
| q = reference.query(); | |
| T.query += q != null ? q : "" | |
| }else { | |
| q = reference.path(); | |
| if(q == "" || q == null) { | |
| T.path = this.path(); | |
| q = reference.query(); | |
| if(q != null) { | |
| T.query += q | |
| }else { | |
| q = this.query(); | |
| T.query += q != null ? q : "" | |
| } | |
| }else { | |
| if(q.substring(0, 1) == "/") { | |
| T.path = this.removeDotSegments(q) | |
| }else { | |
| if(this.path() != null) { | |
| var q2 = this.path().lastIndexOf("/"); | |
| if(q2 >= 0) { | |
| T.path = this.path().substring(0, ++q2) | |
| } | |
| T.path += reference.path() | |
| }else { | |
| T.path = "/" + q | |
| } | |
| T.path = this.removeDotSegments(T.path) | |
| } | |
| q = reference.query(); | |
| T.query += q != null ? q : "" | |
| } | |
| q = this.authority(); | |
| T.authority = q != null ? "//" + q : "" | |
| } | |
| T.scheme = this.scheme() | |
| } | |
| q = reference.fragment(); | |
| T.fragment = q != null ? q : ""; | |
| return new api.IRI(T.scheme + ":" + T.authority + T.path + T.query + T.fragment) | |
| }, | |
| scheme: function() { | |
| var scheme = this.value.match(api.IRI.SCHEME_MATCH); | |
| return (scheme == null) ? null : scheme.shift().slice(0, -1) | |
| }, | |
| userinfo: function() { | |
| var authority = this.authority(); | |
| var q = authority.indexOf("@"); | |
| return (q < 0) ? null : authority.substring(0, q) | |
| } | |
| }; | |
| /** | |
| * Data implements DocumentData | |
| */ | |
| api.Data = function() { this.graph = new api.Graph; this.context = new api.Context }; | |
| api.Data.prototype = { | |
| context: null, graph: null, | |
| createContext: function() { return new api.Context } | |
| }; | |
| /** | |
| * Graph (fast, indexed) implements RDFGraph | |
| */ | |
| api.Graph = function(a) { | |
| this.length = 0; | |
| this.graph = []; | |
| this.index = {}; | |
| if(Array.isArray(a)) this.importArray(a); | |
| }; | |
| api.Graph.prototype = { | |
| length: null, graph: null, | |
| importArray: function(a) { while( a.length > 0) { this.add(a.pop()) } }, | |
| get: function(index) { return this.graph[index] }, | |
| add: function(triple) { | |
| if(!this.index[triple.subject.value]) this.index[triple.subject.value] = {}; | |
| if(!this.index[triple.subject.value][triple.property.value]) this.index[triple.subject.value][triple.property.value] = []; | |
| if(this.index[triple.subject.value][triple.property.value].some(function(o){return o.equals(triple.object)})) return; | |
| this.length++; | |
| this.index[triple.subject.value][triple.property.value].push(triple.object); | |
| this.graph.push(triple); | |
| }, | |
| merge: function(s) { | |
| var _g1 = 0, _g = s.length; | |
| while(_g1 < _g) { | |
| var i = _g1++; | |
| this.add(s.get(i)) | |
| } | |
| }, | |
| every: function(filter) { return this.graph.every(filter) }, | |
| some: function(filter) { return this.graph.some(filter) }, | |
| forEach: function(callbck) { this.graph.forEach(callbck) }, | |
| filter: function(filter) { return new api.Graph(this.graph.filter(filter)); }, | |
| apply: function(filter) { this.graph = this.graph.filter(filter); this.length = this.graph.length; }, | |
| iterator: function() { return new api.GraphIterator(this) }, | |
| toArray: function() { return this.graph.slice() } | |
| }; | |
| /** | |
| * SlowGraph implements RDFGraph | |
| */ | |
| api.SlowGraph = function(a) { | |
| this.length = 0; | |
| this.graph = new Array | |
| if(Array.isArray(a)) this.importArray(a); | |
| }; | |
| api.SlowGraph.prototype = { | |
| length: null, graph: null, | |
| importArray: function(a) { while( a.length > 0) { this.add(a.pop()) } }, | |
| get: function(index) { return this.graph[index] }, | |
| add: function(triple) { | |
| if(this.graph.some(function(t){ return t.equals(triple); } )) { return } | |
| this.length++; | |
| this.graph.push(triple) | |
| }, | |
| merge: function(s) { | |
| var _g1 = 0, _g = s.length; | |
| while(_g1 < _g) { | |
| var i = _g1++; | |
| this.add(s.get(i)) | |
| } | |
| }, | |
| every: function(filter) { return this.graph.every(filter) }, | |
| some: function(filter) { return this.graph.some(filter) }, | |
| forEach: function(callbck) { this.graph.forEach(callbck) }, | |
| filter: function(filter) { return new api.SlowGraph(this.graph.filter(filter)); }, | |
| apply: function(filter) { this.graph = this.graph.filter(filter); this.length = this.graph.length; }, | |
| iterator: function() { return new api.GraphIterator(this) }, | |
| toArray: function() { return this.graph.slice() } | |
| }; | |
| /** | |
| * GraphIterator | |
| */ | |
| api.GraphIterator = function(graph) { this.graph = graph; this.cur = 0 }; | |
| api.GraphIterator.prototype = { | |
| cur: null, graph: null, | |
| hasNext: function() { return this.cur < this.graph.length }, | |
| next: function() { return this.graph.get(this.cur++) } | |
| }; | |
| /** | |
| * Context implements DataContext | |
| */ | |
| api.Context = function() { | |
| this.curieMap = new Hash; | |
| this.converterMap = new Hash; | |
| this._loadDefaultPrefixMap(); | |
| this._loadDefaultTypeConverters() | |
| }; | |
| api.Context.prototype = { | |
| base: null, converterMap: null, curieMap: null, | |
| createBlankNode: function() { return new api.BlankNode }, | |
| createIRI: function(iri) { | |
| var resolved = new api.IRI(iri); | |
| if(resolved.scheme() == null && this.base != null) { resolved = this.base.resolveReference(resolved) } | |
| return resolved | |
| }, | |
| createPlainLiteral: function(value, language) { return new api.PlainLiteral(value, language) }, | |
| createTypedLiteral: function(value, type) { | |
| type = this._resolveType(type); | |
| return new api.TypedLiteral(value, this.createIRI(type)) | |
| }, | |
| createTriple: function(s, p, o) { return new api.RDFTriple(s, p, o) }, | |
| createGraph: function(a) { return new api.Graph(a) }, | |
| getMapping: function() { return this.curieMap }, | |
| setMapping: function(prefix, iri) { | |
| if(prefix.slice(-1) == ":") { prefix = prefix.slice(0, -1) } | |
| var prefixIRI = new api.IRI(iri); | |
| this.curieMap.set(prefix.toLowerCase(), prefixIRI); | |
| return function(suffix) { return new api.IRI(prefixIRI.toString().concat(suffix)) } | |
| }, | |
| resolveCurie: function(curie) { | |
| var index = curie.indexOf(":"); | |
| if(index < 0) { return null } | |
| var prefix = curie.slice(0, index).toLowerCase(); | |
| var iri = this.curieMap.get(prefix); | |
| if(iri == null) { return null } | |
| var resolved = new api.IRI(iri.value.concat(curie.slice(++index))); | |
| if(resolved.scheme() == null && this.base != null) { resolved = this.base.resolveReference(resolved) } | |
| return resolved | |
| }, | |
| convertTypedLiteral: function(tl) { | |
| var converter = this.converterMap.get(tl.type.toString()); | |
| if(converter != null) { | |
| try { | |
| return converter(tl.value, tl.type) | |
| } catch(e) { } | |
| } | |
| return tl; | |
| }, | |
| registerTypeConversion: function(iri, converter) { | |
| var type = this._resolveType(iri); | |
| var oldConverter = this.converterMap.get(type); | |
| this.converterMap.remove(type); | |
| if(converter != null) this.converterMap.set(type, converter); | |
| return oldConverter ? oldConverter : null; | |
| }, | |
| _resolveType: function(type) { | |
| if(type.slice(0, 2) == "^^") { type = type.slice(2) } | |
| var resolved = type.substring(0, 3) == "xsd" ? this.resolveCurie(type) : this.createIRI(type); | |
| return resolved == null ? type : resolved.value | |
| }, | |
| _loadDefaultTypeConverters: function() { | |
| var stringConverter = function(value, inputType) { return new String(value) }; | |
| this.registerTypeConversion("xsd:string", stringConverter); | |
| var booleanConverter = function(value, inputType) { return(new Boolean(value)).valueOf() }; | |
| this.registerTypeConversion("xsd:boolean", booleanConverter); | |
| var numberConverter = function(value, inputType) { return(new Number(value)).valueOf() }; | |
| this.registerTypeConversion("xsd:float", numberConverter); | |
| this.registerTypeConversion("xsd:integer", numberConverter); | |
| this.registerTypeConversion("xsd:long", numberConverter); | |
| this.registerTypeConversion("xsd:double", numberConverter); | |
| this.registerTypeConversion("xsd:decimal", numberConverter); | |
| this.registerTypeConversion("xsd:nonPositiveInteger", numberConverter); | |
| this.registerTypeConversion("xsd:nonNegativeInteger", numberConverter); | |
| this.registerTypeConversion("xsd:negativeInteger", numberConverter); | |
| this.registerTypeConversion("xsd:int", numberConverter); | |
| this.registerTypeConversion("xsd:unsignedLong", numberConverter); | |
| this.registerTypeConversion("xsd:positiveInteger", numberConverter); | |
| this.registerTypeConversion("xsd:short", numberConverter); | |
| this.registerTypeConversion("xsd:unsignedInt", numberConverter); | |
| this.registerTypeConversion("xsd:byte", numberConverter); | |
| this.registerTypeConversion("xsd:unsignedShort", numberConverter); | |
| this.registerTypeConversion("xsd:unsignedByte", numberConverter); | |
| var dateConverter = function(value, inputType) { return new Date(value) }; | |
| this.registerTypeConversion("xsd:date", dateConverter); | |
| this.registerTypeConversion("xsd:time", dateConverter); | |
| this.registerTypeConversion("xsd:dateTime", dateConverter) | |
| }, | |
| _loadDefaultPrefixMap: function() { | |
| this.setMapping("owl", "http://www.w3.org/2002/07/owl#"); | |
| this.setMapping("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); | |
| this.setMapping("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); | |
| this.setMapping("rdfa", "http://www.w3.org/ns/rdfa#"); | |
| this.setMapping("xhv", "http://www.w3.org/1999/xhtml/vocab#"); | |
| this.setMapping("xml", "http://www.w3.org/XML/1998/namespace"); | |
| this.setMapping("xsd", "http://www.w3.org/2001/XMLSchema#"); | |
| this.setMapping("grddl", "http://www.w3.org/2003/g/data-view#"); | |
| this.setMapping("powder", "http://www.w3.org/2007/05/powder#"); | |
| this.setMapping("powders", "http://www.w3.org/2007/05/powder-s#"); | |
| this.setMapping("rif", "http://www.w3.org/2007/rif#"); | |
| this.setMapping("atom", "http://www.w3.org/2005/Atom/"); | |
| this.setMapping("xhtml", "http://www.w3.org/1999/xhtml#"); | |
| this.setMapping("formats", "http://www.w3.org/ns/formats/"); | |
| this.setMapping("xforms", "http://www.w3.org/2002/xforms/"); | |
| this.setMapping("xhtmlvocab", "http://www.w3.org/1999/xhtml/vocab/"); | |
| this.setMapping("xpathfn", "http://www.w3.org/2005/xpath-functions#"); | |
| this.setMapping("http", "http://www.w3.org/2006/http#"); | |
| this.setMapping("link", "http://www.w3.org/2006/link#"); | |
| this.setMapping("time", "http://www.w3.org/2006/time#"); | |
| this.setMapping("acl", "http://www.w3.org/ns/auth/acl#"); | |
| this.setMapping("cert", "http://www.w3.org/ns/auth/cert#"); | |
| this.setMapping("rsa", "http://www.w3.org/ns/auth/rsa#"); | |
| this.setMapping("crypto", "http://www.w3.org/2000/10/swap/crypto#"); | |
| this.setMapping("list", "http://www.w3.org/2000/10/swap/list#"); | |
| this.setMapping("log", "http://www.w3.org/2000/10/swap/log#"); | |
| this.setMapping("math", "http://www.w3.org/2000/10/swap/math#"); | |
| this.setMapping("os", "http://www.w3.org/2000/10/swap/os#"); | |
| this.setMapping("string", "http://www.w3.org/2000/10/swap/string#"); | |
| this.setMapping("doc", "http://www.w3.org/2000/10/swap/pim/doc#"); | |
| this.setMapping("contact", "http://www.w3.org/2000/10/swap/pim/contact#"); | |
| this.setMapping("p3p", "http://www.w3.org/2002/01/p3prdfv1#"); | |
| this.setMapping("swrl", "http://www.w3.org/2003/11/swrl#"); | |
| this.setMapping("swrlb", "http://www.w3.org/2003/11/swrlb#"); | |
| this.setMapping("exif", "http://www.w3.org/2003/12/exif/ns#"); | |
| this.setMapping("earl", "http://www.w3.org/ns/earl#"); | |
| this.setMapping("ma", "http://www.w3.org/ns/ma-ont#"); | |
| this.setMapping("sawsdl", "http://www.w3.org/ns/sawsdl#"); | |
| this.setMapping("sd", "http://www.w3.org/ns/sparql-service-description#"); | |
| this.setMapping("skos", "http://www.w3.org/2004/02/skos/core#"); | |
| this.setMapping("fresnel", "http://www.w3.org/2004/09/fresnel#"); | |
| this.setMapping("gen", "http://www.w3.org/2006/gen/ont#"); | |
| this.setMapping("timezone", "http://www.w3.org/2006/timezone#"); | |
| this.setMapping("skosxl", "http://www.w3.org/2008/05/skos-xl#"); | |
| this.setMapping("org", "http://www.w3.org/ns/org#"); | |
| this.setMapping("ical", "http://www.w3.org/2002/12/cal/ical#"); | |
| this.setMapping("wgs84", "http://www.w3.org/2003/01/geo/wgs84_pos#"); | |
| this.setMapping("vcard", "http://www.w3.org/2006/vcard/ns#"); | |
| this.setMapping("turtle", "http://www.w3.org/2008/turtle#"); | |
| this.setMapping("pointers", "http://www.w3.org/2009/pointers#"); | |
| this.setMapping("dcat", "http://www.w3.org/ns/dcat#"); | |
| this.setMapping("imreg", "http://www.w3.org/2004/02/image-regions#"); | |
| this.setMapping("rdfg", "http://www.w3.org/2004/03/trix/rdfg-1/"); | |
| this.setMapping("swp", "http://www.w3.org/2004/03/trix/swp-2/"); | |
| this.setMapping("rei", "http://www.w3.org/2004/06/rei#"); | |
| this.setMapping("wairole", "http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#"); | |
| this.setMapping("states", "http://www.w3.org/2005/07/aaa#"); | |
| this.setMapping("wn20schema", "http://www.w3.org/2006/03/wn/wn20/schema/"); | |
| this.setMapping("httph", "http://www.w3.org/2007/ont/httph#"); | |
| this.setMapping("act", "http://www.w3.org/2007/rif-builtin-action#"); | |
| this.setMapping("common", "http://www.w3.org/2007/uwa/context/common.owl#"); | |
| this.setMapping("dcn", "http://www.w3.org/2007/uwa/context/deliverycontext.owl#"); | |
| this.setMapping("hard", "http://www.w3.org/2007/uwa/context/hardware.owl#"); | |
| this.setMapping("java", "http://www.w3.org/2007/uwa/context/java.owl#"); | |
| this.setMapping("loc", "http://www.w3.org/2007/uwa/context/location.owl#"); | |
| this.setMapping("net", "http://www.w3.org/2007/uwa/context/network.owl#"); | |
| this.setMapping("push", "http://www.w3.org/2007/uwa/context/push.owl#"); | |
| this.setMapping("soft", "http://www.w3.org/2007/uwa/context/software.owl#"); | |
| this.setMapping("web", "http://www.w3.org/2007/uwa/context/web.owl#"); | |
| this.setMapping("content", "http://www.w3.org/2008/content#"); | |
| this.setMapping("vs", "http://www.w3.org/2003/06/sw-vocab-status/ns#"); | |
| this.setMapping("air", "http://dig.csail.mit.edu/TAMI/2007/amord/air#"); | |
| this.setMapping("ex", "http://example.org/"); | |
| this.setMapping("dc", "http://purl.org/dc/terms/"); | |
| this.setMapping("dc11", "http://purl.org/dc/elements/1.1/"); | |
| this.setMapping("dctype", "http://purl.org/dc/dcmitype/"); | |
| this.setMapping("foaf", "http://xmlns.com/foaf/0.1/"); | |
| this.setMapping("cc", "http://creativecommons.org/ns#"); | |
| this.setMapping("opensearch", "http://a9.com/-/spec/opensearch/1.1/"); | |
| this.setMapping("void", "http://rdfs.org/ns/void#"); | |
| this.setMapping("sioc", "http://rdfs.org/sioc/ns#"); | |
| this.setMapping("sioca", "http://rdfs.org/sioc/actions#"); | |
| this.setMapping("sioct", "http://rdfs.org/sioc/types#"); | |
| this.setMapping("lgd", "http://linkedgeodata.org/vocabulary#"); | |
| this.setMapping("moat", "http://moat-project.org/ns#"); | |
| this.setMapping("days", "http://ontologi.es/days#"); | |
| this.setMapping("giving", "http://ontologi.es/giving#"); | |
| this.setMapping("lang", "http://ontologi.es/lang/core#"); | |
| this.setMapping("like", "http://ontologi.es/like#"); | |
| this.setMapping("status", "http://ontologi.es/status#"); | |
| this.setMapping("og", "http://opengraphprotocol.org/schema/"); | |
| this.setMapping("protege", "http://protege.stanford.edu/system#"); | |
| this.setMapping("dady", "http://purl.org/NET/dady#"); | |
| this.setMapping("uri", "http://purl.org/NET/uri#"); | |
| this.setMapping("audio", "http://purl.org/media/audio#"); | |
| this.setMapping("video", "http://purl.org/media/video#"); | |
| this.setMapping("gridworks", "http://purl.org/net/opmv/types/gridworks#"); | |
| this.setMapping("hcterms", "http://purl.org/uF/hCard/terms/"); | |
| this.setMapping("bio", "http://purl.org/vocab/bio/0.1/"); | |
| this.setMapping("cs", "http://purl.org/vocab/changeset/schema#"); | |
| this.setMapping("geographis", "http://telegraphis.net/ontology/geography/geography#"); | |
| this.setMapping("doap", "http://usefulinc.com/ns/doap#"); | |
| this.setMapping("daml", "http://www.daml.org/2001/03/daml+oil#"); | |
| this.setMapping("geonames", "http://www.geonames.org/ontology#"); | |
| this.setMapping("sesame", "http://www.openrdf.org/schema/sesame#"); | |
| this.setMapping("cv", "http://rdfs.org/resume-rdf/"); | |
| this.setMapping("wot", "http://xmlns.com/wot/0.1/"); | |
| this.setMapping("media", "http://purl.org/microformat/hmedia/"); | |
| this.setMapping("ctag", "http://commontag.org/ns#") | |
| } | |
| }; | |
| return api; | |
| }(); | |
| /** | |
| * rdfapi.querylangs | |
| */ | |
| (function(api) { | |
| if(!api.querylangs) { api.querylangs = {} } | |
| /** | |
| * RDF Selectors, implements DataQuery | |
| */ | |
| api.querylangs.RDFSelector = function(context) { | |
| this.context = context | |
| }; | |
| api.querylangs.RDFSelector.PATH_START = new RegExp("^[^!\\^]+", "ig"); | |
| api.querylangs.RDFSelector.PATH_PARTS = new RegExp("[!\\^][^!\\^]+", "ig"); | |
| api.querylangs.RDFSelector.prototype = { | |
| context: null, | |
| select: function(query, graph) { | |
| var _ = this; | |
| var refs = query.match(api.querylangs.RDFSelector.PATH_START).map(function(s, i, a) { return _.context.resolveCurie(s).toNT() }); | |
| var parts = query.match(api.querylangs.RDFSelector.PATH_PARTS); | |
| var part = ""; | |
| while(parts.length > 1) { | |
| part = parts.shift(); | |
| var tempRefs = [[]]; | |
| var p = [_.context.resolveCurie(part.slice(1))]; | |
| switch(part.charAt(0)) { | |
| case "!": | |
| refs.forEach(function(tempRefs, p) { | |
| return function(ref, i, a) { | |
| graph.forEach(function(tempRefs, p) { | |
| return function(t, i1, s) { | |
| if(t.subject.toNT() == ref && t.property.equals(p[0]) && !tempRefs[0].contains(t.object.toNT())) { | |
| tempRefs[0].push(t.object.toNT()) | |
| } | |
| } | |
| }(tempRefs, p)) | |
| } | |
| }(tempRefs, p)); | |
| break; | |
| case "^": | |
| refs.forEach(function(tempRefs, p) { | |
| return function(ref, i, a) { | |
| graph.forEach(function(tempRefs, p) { | |
| return function(t, i1, s) { | |
| if(t.object.toNT() == ref && t.property.equals(p[0]) && !tempRefs[0].contains(t.subject.toNT())) { | |
| tempRefs[0].push(t.subject.toNT()) | |
| } | |
| } | |
| }(tempRefs, p)) | |
| } | |
| }(tempRefs, p)); | |
| break | |
| } | |
| refs = tempRefs[0] | |
| } | |
| part = parts.pop(); | |
| var curiemap = new Object({}); | |
| parts = part.slice(1).split(",").map(function(s, i, a) { | |
| var c = _.context.resolveCurie(s).toNT(); | |
| curiemap[c] = s; | |
| return c | |
| }); | |
| var out = new Array; | |
| refs.forEach(function(ref, i, a) { | |
| var row = new Object({}); | |
| parts.forEach(function(p, i1, a1) { row[curiemap[p]] = [] }); | |
| row["uri"] = ref; | |
| out.push(row) | |
| }); | |
| var working = graph; | |
| if(part.charAt(0) == "!") { | |
| working.filter(function(t, i, s) { | |
| return refs.contains(t.subject.toNT()) | |
| }).forEach(function(t, i, s) { | |
| if(parts.contains(t.property.toNT())) { | |
| out[refs.indexOf(t.subject.toNT())][curiemap[t.property.toNT()]].push(t.object) | |
| } | |
| }) | |
| }else { | |
| working.filter(function(t, i, s) { | |
| return refs.contains(t.object.toNT()) | |
| }).forEach(function(t, i, s) { | |
| if(parts.contains(t.property.toNT())) { | |
| out[refs.indexOf(t.object.toNT())][curiemap[t.property.toNT()]].push(t.subject) | |
| } | |
| }) | |
| } | |
| return out | |
| } | |
| }; | |
| })(rdfapi); | |
| /** | |
| * Parsers | |
| */ | |
| (function(api) { | |
| if(!api.parsers) { api.parsers = {} } | |
| api.parsers.u8 = new RegExp("\\\\U([A-F0-9]{8})", "g"); | |
| api.parsers.u4 = new RegExp("\\\\u([A-F0-9]{4})", "g"); | |
| api.parsers.hexToChar = function(hex) { | |
| var result = ""; | |
| var n = parseInt(hex, 16); | |
| if(n <= 65535) { | |
| result += String.fromCharCode(n) | |
| } else if(n <= 1114111) { | |
| n -= 65536; | |
| result += String.fromCharCode(55296 + (n >> 10), 56320 + (n & 1023)) | |
| } else { throw new Error("code point isn't known: " + n); } | |
| return result | |
| }; | |
| api.parsers.decodeString = function(str) { | |
| str = str.replace(api.parsers.u8, function(matchstr, parens) { return api.parsers.hexToChar(parens) }); | |
| str = str.replace(api.parsers.u4, function(matchstr, parens) { return api.parsers.hexToChar(parens) }); | |
| str = str.replace(new RegExp("\\\\t", "g"), "\t"); | |
| str = str.replace(new RegExp("\\\\n", "g"), "\n"); | |
| str = str.replace(new RegExp("\\\\r", "g"), "\r"); | |
| str = str.replace(new RegExp('\\\\"', "g"), '"'); | |
| str = str.replace(new RegExp("\\\\\\\\", "g"), "\\"); | |
| return str | |
| }; | |
| /** | |
| * NTriples implements DataParser | |
| * doc param of parse() and process() must be a string | |
| */ | |
| api.parsers.NTriples = function(context) { | |
| this.context = context; | |
| this.bnHash = new Hash | |
| }; | |
| api.parsers.NTriples.isComment = new RegExp("^[ \t]*#", ""); | |
| api.parsers.NTriples.isEmptyLine = new RegExp("^[ \t]*$", ""); | |
| api.parsers.NTriples.initialWhitespace = new RegExp("^[ \t]+", ""); | |
| api.parsers.NTriples.trailingWhitespace = new RegExp("[. \t]+$", ""); | |
| api.parsers.NTriples.whitespace = new RegExp("[ \t]+", ""); | |
| api.parsers.NTriples.objectMatcher = new RegExp("^([^ \t]+)[ \t]+([^ \t]+)[ \t]+(.*)$", ""); | |
| api.parsers.NTriples.trailingLanguage = new RegExp("@([a-z]+[-a-z0-9]+)$", ""); | |
| api.parsers.NTriples.typedLiteralMatcher = new RegExp('^"(.*)"(.{2})<([^>]+)>$', ""); | |
| api.parsers.NTriples.eolMatcher = new RegExp("\r\n|\n|\r", "g"); | |
| api.parsers.NTriples.prototype = { | |
| context: null, quick: null, bnHash: null, graph: null, filter: null, processor: null, | |
| parse: function(toparse, cb, filter, graph) { | |
| this.graph = graph == null ? this.context.createGraph() : graph; | |
| this.filter = filter; | |
| this.quick = false; | |
| this.internalParse(toparse); | |
| if(cb != null) cb(this.graph); | |
| return true; | |
| }, | |
| process: function(toparse, processor, filter) { | |
| this.processor = processor; | |
| this.filter = filter; | |
| this.quick = true; | |
| return this.internalParse(toparse) | |
| }, | |
| getBlankNode: function(id) { | |
| if(this.bnHash.exists(id)) { return this.bnHash.get(id) } | |
| var bn = this.context.createBlankNode(); | |
| this.bnHash.set(id, bn); | |
| return bn | |
| }, | |
| internalParse: function(toparse) { | |
| var data = new String(toparse); | |
| var lines = data.split(api.parsers.NTriples.eolMatcher); | |
| var _ = this; | |
| lines.forEach(function(a, b, c) { _.readLine(a, b, c) }); | |
| return true | |
| }, | |
| negotiateLiteral: function(plain) { | |
| if(plain.slice(-1) == '"') { return this.context.createPlainLiteral(api.parsers.decodeString(plain.slice(1, -1))) } | |
| var lang = plain.match(api.parsers.NTriples.trailingLanguage); | |
| if(lang != null) { return this.context.createPlainLiteral(api.parsers.decodeString(plain.slice(1, -1 - lang.shift().length)), lang.pop()) } | |
| var parts = plain.match(api.parsers.NTriples.typedLiteralMatcher); | |
| return this.context.createTypedLiteral(api.parsers.decodeString(parts[1]), parts.pop()) | |
| }, | |
| readLine: function(line, index, array) { | |
| if(api.parsers.NTriples.isComment.test(line) || api.parsers.NTriples.isEmptyLine.test(line)) { return } | |
| line = line.replace(api.parsers.NTriples.initialWhitespace, "").replace(api.parsers.NTriples.trailingWhitespace, ""); | |
| var spo = line.split(api.parsers.NTriples.whitespace, 2); | |
| spo.push(line.replace(api.parsers.NTriples.objectMatcher, "$3")); | |
| var s; | |
| if(spo[0].charAt(0) == "<") { | |
| s = this.context.createIRI(api.parsers.decodeString(spo[0].slice(1, -1))) | |
| }else { | |
| s = this.getBlankNode(spo[0].slice(2)) | |
| } | |
| spo.shift(); | |
| var p = this.context.createIRI(spo.shift().slice(1, -1)); | |
| var o; | |
| switch(spo[0].charAt(0)) { | |
| case "<": | |
| o = this.context.createIRI(api.parsers.decodeString(spo[0].slice(1, -1))); | |
| break; | |
| case "_": | |
| o = this.getBlankNode(spo[0].slice(2)); | |
| break; | |
| default: | |
| o = this.negotiateLiteral(spo[0]); | |
| break | |
| } | |
| var triple = this.context.createTriple(s, p, o); | |
| var $use = true; | |
| if(this.filter != null) { $use = this.filter(triple, null, null) } | |
| if(!$use) { return; } | |
| this.quick ? this.processor(triple) : this.graph.add(triple); | |
| } | |
| }; | |
| /** | |
| * Turtle implements DataParser | |
| * doc param of parse() and process() must be a string | |
| */ | |
| api.parsers.Turtle = function(context) { | |
| this.context = context; | |
| this.bnHash = new Hash | |
| }; | |
| api.parsers.Turtle.isWhitespace = new RegExp("^[ \t\r\n#]+", ""); | |
| api.parsers.Turtle.initialWhitespace = new RegExp("^[ \t\r\n]+", ""); | |
| api.parsers.Turtle.initialComment = new RegExp("^#[^\r\n]*", ""); | |
| api.parsers.Turtle.simpleToken = new RegExp("^[^ \t\r\n]+", ""); | |
| api.parsers.Turtle.simpleObjectToken = new RegExp("^[^ \t\r\n;,]+", ""); | |
| api.parsers.Turtle.tokenInteger = new RegExp("^(-|\\+)?[0-9]+$", ""); | |
| api.parsers.Turtle.tokenDouble = new RegExp("^(-|\\+)?(([0-9]+\\.[0-9]*[eE]{1}(-|\\+)?[0-9]+)|(\\.[0-9]+[eE]{1}(-|\\+)?[0-9]+)|([0-9]+[eE]{1}(-|\\+)?[0-9]+))$", ""); | |
| api.parsers.Turtle.tokenDecimal = new RegExp("^(-|\\+)?[0-9]*\\.[0-9]+?$", ""); | |
| api.parsers.Turtle.prototype = { | |
| bnHash: null, context: null, filter: null, processor: null, quick: null, graph: null, | |
| parse: function(doc, cb, filter, graph) { | |
| this.graph = graph == null ? this.context.createGraph() : graph; | |
| this.filter = filter; | |
| this.quick = false; | |
| this.parseStatements(new String(doc)); | |
| if(cb != null) cb(this.graph); | |
| return true; | |
| }, | |
| process: function(doc, processor, filter) { | |
| this.processor = processor; this.filter = filter; this.quick = true; | |
| return this.parseStatements(new String(doc)) | |
| }, | |
| t: function() { return{o:null} }, | |
| parseStatements: function(s) { | |
| s = s.toString(); | |
| while(s.length > 0) { | |
| s = this.skipWS(s); | |
| if(s.length == 0) return true; | |
| s.charAt(0) == "@" ? s = this.consumeDirective(s) : s = this.consumeStatement(s); | |
| this.expect(s, "."); | |
| s = this.skipWS(s.slice(1)) | |
| } | |
| return true | |
| }, | |
| add: function(t) { | |
| var $use = true; | |
| if(this.filter != null) { $use = this.filter(t, null, null) } | |
| if(!$use) { return } | |
| this.quick ? this.processor(t) : this.graph.add(t); | |
| }, | |
| consumeBlankNode: function(s, t) { | |
| t.o = this.context.createBlankNode(); | |
| s = this.skipWS(s.slice(1)); | |
| if(s.charAt(0) == "]") { return s.slice(1) } | |
| s = this.skipWS(this.consumePredicateObjectList(s, t)); | |
| this.expect(s, "]"); | |
| return this.skipWS(s.slice(1)) | |
| }, | |
| consumeCollection: function(s, subject) { | |
| subject.o = this.context.createBlankNode(); | |
| var listject = this.t(); | |
| listject.o = subject.o; | |
| s = this.skipWS(s.slice(1)); | |
| var cont = s.charAt(0) != ")"; | |
| if(!cont) { subject.o = this.context.resolveCurie("rdf:nil") } | |
| while(cont) { | |
| var o = this.t(); | |
| switch(s.charAt(0)) { | |
| case "[": s = this.consumeBlankNode(s, o); break; | |
| case "_": s = this.consumeKnownBlankNode(s, o); break; | |
| case "(": s = this.consumeCollection(s, o); break; | |
| case "<": s = this.consumeURI(s, o); break; | |
| case '"': s = this.consumeLiteral(s, o); break; | |
| default: | |
| var token = s.match(api.parsers.Turtle.simpleObjectToken).shift(); | |
| if(token.charAt(token.length - 1) == ")") { token = token.substring(0, token.length - 1) } | |
| if(token == "false" || token == "true") { | |
| o.o = this.context.createTypedLiteral(token, "xsd:boolean") | |
| } else if(token.indexOf(":") > -1) { | |
| o.o = this.context.resolveCurie(token) | |
| } else if(api.parsers.Turtle.tokenInteger.test(token)) { | |
| o.o = this.context.createTypedLiteral(token, "xsd:integer") | |
| } else if(api.parsers.Turtle.tokenDouble.test(token)) { | |
| o.o = this.context.createTypedLiteral(token, "xsd:double") | |
| } else if(api.parsers.Turtle.tokenDecimal.test(token)) { | |
| o.o = this.context.createTypedLiteral(token, "xsd:decimal") | |
| } else { | |
| throw new Error("unrecognised token: " + token); | |
| } | |
| s = s.slice(token.length); | |
| break | |
| } | |
| this.add(this.context.createTriple(listject.o, this.context.resolveCurie("rdf:first"), o.o)); | |
| s = this.skipWS(s); | |
| cont = s.charAt(0) != ")"; | |
| if(cont) { | |
| this.add(this.context.createTriple(listject.o, this.context.resolveCurie("rdf:rest"), listject.o = this.context.createBlankNode())) | |
| } else { | |
| this.add(this.context.createTriple(listject.o, this.context.resolveCurie("rdf:rest"), this.context.resolveCurie("rdf:nil"))) | |
| } | |
| } | |
| return this.skipWS(s.slice(1)) | |
| }, | |
| consumeDirective: function(s) { | |
| var p = 0; | |
| if(s.substring(1, 7) == "prefix") { | |
| s = this.skipWS(s.slice(7)); | |
| p = s.indexOf(":"); | |
| var prefix = s.substring(0, p); | |
| s = this.skipWS(s.slice(++p)); | |
| this.expect(s, "<"); | |
| this.context.setMapping(prefix, api.parsers.decodeString(s.substring(1, p = s.indexOf(">")))); | |
| s = this.skipWS(s.slice(++p)) | |
| } else if(s.substring(1, 5) == "base") { | |
| s = this.skipWS(s.slice(5)); | |
| this.expect(s, "<"); | |
| this.context.base = this.context.createIRI(api.parsers.decodeString(s.substring(1, p = s.indexOf(">")))); | |
| s = this.skipWS(s.slice(++p)) | |
| } else { | |
| throw new Error("Unknown directive: " + s.substring(0, 50)); | |
| } | |
| return s | |
| }, | |
| consumeKnownBlankNode: function(s, t) { | |
| this.expect(s, "_:"); | |
| var bname = s.slice(2).match(api.parsers.Turtle.simpleToken).shift(); | |
| t.o = this.getBlankNode(bname); | |
| return s.slice(bname.length + 2) | |
| }, | |
| consumeLiteral: function(s, o) { | |
| var value = ""; | |
| var hunt = true; | |
| var end = 0; | |
| if(s.substring(0, 3) == '"""') { | |
| end = 3; | |
| while(hunt) { | |
| end = s.indexOf('"""', end); | |
| if(hunt = s.charAt(end - 1) == "\\") { end++ } | |
| } | |
| value = s.substring(3, end); | |
| s = s.slice(value.length + 6) | |
| } else { | |
| while(hunt) { | |
| end = s.indexOf('"', end + 1); | |
| hunt = s.charAt(end - 1) == "\\" | |
| } | |
| value = s.substring(1, end); | |
| s = s.slice(value.length + 2) | |
| } | |
| value = api.parsers.decodeString(value); | |
| switch(s.charAt(0)) { | |
| case "@": | |
| var token = s.match(api.parsers.Turtle.simpleObjectToken).shift(); | |
| o.o = this.context.createPlainLiteral(value, token.slice(1)); | |
| s = s.slice(token.length); | |
| break; | |
| case "^": | |
| var token = s.match(api.parsers.Turtle.simpleObjectToken).shift().slice(2); | |
| if(token.charAt(0) == "<") { | |
| o.o = this.context.createTypedLiteral(value, token.substring(1, token.length - 1)) | |
| } else { | |
| o.o = this.context.createTypedLiteral(value, token) | |
| } | |
| s = s.slice(token.length + 2); | |
| break; | |
| default: | |
| o.o = this.context.createPlainLiteral(value); | |
| break | |
| } | |
| return s | |
| }, | |
| consumeObjectList: function(s, subject, property) { | |
| var cont = true; | |
| while(cont) { | |
| var o = this.t(); | |
| switch(s.charAt(0)) { | |
| case "[": s = this.consumeBlankNode(s, o); break; | |
| case "_": s = this.consumeKnownBlankNode(s, o); break; | |
| case "(": s = this.consumeCollection(s, o); break; | |
| case "<": s = this.consumeURI(s, o); break; | |
| case '"': s = this.consumeLiteral(s, o); break; | |
| default: | |
| var token = s.match(api.parsers.Turtle.simpleObjectToken).shift(); | |
| if(token.charAt(token.length - 1) == ".") { | |
| token = token.substring(0, token.length - 1) | |
| } | |
| if(token == "false" || token == "true") { | |
| o.o = this.context.createTypedLiteral(token, "xsd:boolean") | |
| } else if(token.indexOf(":") > -1) { | |
| o.o = this.context.resolveCurie(token) | |
| } else if(api.parsers.Turtle.tokenInteger.test(token)) { | |
| o.o = this.context.createTypedLiteral(token, "xsd:integer") | |
| } else if(api.parsers.Turtle.tokenDouble.test(token)) { | |
| o.o = this.context.createTypedLiteral(token, "xsd:double") | |
| } else if(api.parsers.Turtle.tokenDecimal.test(token)) { | |
| o.o = this.context.createTypedLiteral(token, "xsd:decimal") | |
| } else { | |
| throw new Error("unrecognised token: " + token); | |
| } | |
| s = s.slice(token.length); | |
| break | |
| } | |
| this.add(this.context.createTriple(subject.o, property, o.o)); | |
| s = this.skipWS(s); | |
| cont = s.charAt(0) == ","; | |
| if(cont) { s = this.skipWS(s.slice(1)) } | |
| } | |
| return s | |
| }, | |
| consumePredicateObjectList: function(s, subject) { | |
| var cont = true; | |
| while(cont) { | |
| var predicate = s.match(api.parsers.Turtle.simpleToken).shift(); | |
| var property = null; | |
| if(predicate == "a") { | |
| property = this.context.resolveCurie("rdf:type") | |
| } else { | |
| switch(predicate.charAt(0)) { | |
| case "<": property = this.context.createIRI(api.parsers.decodeString(predicate.substring(1, predicate.indexOf(">")))); break; | |
| default: property = this.context.resolveCurie(predicate); break | |
| } | |
| } | |
| s = this.skipWS(s.slice(predicate.length)); | |
| s = this.consumeObjectList(s, subject, property); | |
| cont = s.charAt(0) == ";"; | |
| if(cont) { s = this.skipWS(s.slice(1)) } | |
| } | |
| return s | |
| }, | |
| consumeQName: function(s, t) { | |
| var qname = s.match(api.parsers.Turtle.simpleToken).shift(); | |
| t.o = this.context.resolveCurie(qname); | |
| return s.slice(qname.length) | |
| }, | |
| consumeStatement: function(s) { | |
| var t = this.t(); | |
| switch(s.charAt(0)) { | |
| case "[": | |
| s = this.consumeBlankNode(s, t); | |
| if(s.charAt(0) == ".") { return s } | |
| break; | |
| case "_": s = this.consumeKnownBlankNode(s, t); break; | |
| case "(": s = this.consumeCollection(s, t); break; | |
| case "<": s = this.consumeURI(s, t); break; | |
| default: s = this.consumeQName(s, t); break | |
| } | |
| s = this.consumePredicateObjectList(this.skipWS(s), t); | |
| return s | |
| }, | |
| consumeURI: function(s, t) { | |
| this.expect(s, "<"); | |
| var p = 0; | |
| t.o = this.context.createIRI(api.parsers.decodeString(s.substring(1, p = s.indexOf(">")))); | |
| return s.slice(++p) | |
| }, | |
| expect: function(s, t) { | |
| if(s.substring(0, t.length) == t) { return } | |
| throw new Error("Expected token: " + t + " at " + s.substring(0, 50)); | |
| }, | |
| getBlankNode: function(id) { | |
| if(this.bnHash.exists(id)) { return this.bnHash.get(id) } | |
| var bn = this.context.createBlankNode(); | |
| this.bnHash.set(id, bn); | |
| return bn | |
| }, | |
| skipWS: function(s) { | |
| while(api.parsers.Turtle.isWhitespace.test(s.charAt(0))) { | |
| s = s.replace(api.parsers.Turtle.initialWhitespace, ""); | |
| if(s.charAt(0) == "#") { s = s.replace(api.parsers.Turtle.initialComment, "") } | |
| } | |
| return s | |
| } | |
| }; | |
| /** | |
| * RDFXML implements DataParser | |
| * doc argument of parse() and process() must be a DOM document | |
| */ | |
| api.parsers.RDFXML = function(context) { | |
| this.context = context; | |
| this.bnHash = new Hash | |
| }; | |
| api.parsers.RDFXML.NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; | |
| api.parsers.RDFXML.NS_RDFS = "http://www.w3.org/2000/01/rdf-schema#"; | |
| api.parsers.RDFXML.RDF_TYPE = new api.IRI(api.parsers.RDFXML.NS_RDF + "type"); | |
| api.parsers.RDFXML.RDF_RDF = new api.IRI(api.parsers.RDFXML.NS_RDF + "RDF"); | |
| api.parsers.RDFXML.RDF_DESCRIPTION = new api.IRI(api.parsers.RDFXML.NS_RDF + "Description"); | |
| api.parsers.RDFXML.RDF_STATEMENT = new api.IRI(api.parsers.RDFXML.NS_RDF + "Statement"); | |
| api.parsers.RDFXML.RDF_SUBJECT = new api.IRI(api.parsers.RDFXML.NS_RDF + "subject"); | |
| api.parsers.RDFXML.RDF_PREDICATE = new api.IRI(api.parsers.RDFXML.NS_RDF + "predicate"); | |
| api.parsers.RDFXML.RDF_OBJECT = new api.IRI(api.parsers.RDFXML.NS_RDF + "object"); | |
| api.parsers.RDFXML.RDF_LI = new api.IRI(api.parsers.RDFXML.NS_RDF + "li"); | |
| api.parsers.RDFXML.RDF_FIRST = new api.IRI(api.parsers.RDFXML.NS_RDF + "first"); | |
| api.parsers.RDFXML.RDF_REST = new api.IRI(api.parsers.RDFXML.NS_RDF + "rest"); | |
| api.parsers.RDFXML.RDF_NIL = new api.IRI(api.parsers.RDFXML.NS_RDF + "nil"); | |
| api.parsers.RDFXML.prototype = { | |
| base: null, bnHash: null, context: null, filter: null, processor: null, quick: null, graph: null, | |
| parse: function(toparse, cb, filter, graph) { | |
| this.graph = graph == null ? new api.Graph : graph; | |
| this.filter = filter; | |
| this.quick = false; | |
| this.parseStatements(toparse) | |
| if( cb != null ) cb(this.graph) | |
| return; | |
| }, | |
| process: function(doc, processor, filter) { | |
| this.processor = processor; | |
| this.filter = filter; | |
| this.quick = true; | |
| return this.parseStatements(doc) | |
| }, | |
| add: function(t) { | |
| var $use = true; | |
| if(this.filter != null) $use = this.filter(t, null, null); | |
| if(!$use) return; | |
| this.quick ? this.processor(t) : this.graph.add(t); | |
| }, | |
| addArc: function(frame, arc) { | |
| if(arc.equals(api.parsers.RDFXML.RDF_LI)) arc = this.context.resolveCurie("rdf:_" + frame.parent.listIndex++) | |
| this.addSymbol(frame, 2, arc.toString()) | |
| }, | |
| addBNode: function(frame, s) { | |
| s != null ? frame.node = this.getBlankNode(s) : frame.node = this.context.createBlankNode(); | |
| frame.nodeType = 1; | |
| if(this.isTripleToLoad(frame)) this.addFrame(frame); | |
| }, | |
| addCollection: function(frame) { | |
| frame.collection = true; | |
| this.addBNode(frame) | |
| }, | |
| addFrame: function(frame) { | |
| this.add(this.createTriple(frame.parent.parent.node, frame.parent.node, frame.node)); | |
| if(frame.rdfid != null || frame.parent.rdfid != null) { | |
| if(frame.parent.rdfid != null && frame.rdfid == null) frame.rdfid = frame.parent.rdfid; | |
| var s = frame.base.resolveReference("#".concat(frame.rdfid)); | |
| this.add(this.createTriple(s, api.parsers.RDFXML.RDF_TYPE, api.parsers.RDFXML.RDF_STATEMENT)); | |
| this.add(this.createTriple(s, api.parsers.RDFXML.RDF_SUBJECT, frame.parent.parent.node)); | |
| this.add(this.createTriple(s, api.parsers.RDFXML.RDF_PREDICATE, frame.parent.node)); | |
| this.add(this.createTriple(s, api.parsers.RDFXML.RDF_OBJECT, frame.node)) | |
| } | |
| }, | |
| addLiteral: function(frame, value) { | |
| frame.nodeType = 1; | |
| if(frame.parent.datatype != null) { | |
| frame.node = this.context.createTypedLiteral(value == null ? frame.element.nodeValue : value, frame.parent.datatype) | |
| } else { | |
| frame.node = this.context.createPlainLiteral(value == null ? frame.element.nodeValue : value, frame.lang) | |
| } | |
| if(this.isTripleToLoad(frame)) this.addFrame(frame) | |
| }, | |
| addNode: function(frame, s) { | |
| this.addSymbol(frame, 1, s); | |
| if(this.isTripleToLoad(frame)) this.addFrame(frame) | |
| }, | |
| addSymbol: function(frame, nodeType, val) { | |
| frame.node = frame.base.resolveReference(val); | |
| frame.nodeType = nodeType | |
| }, | |
| buildFrame: function(parent, element) { | |
| var frame = {parent:parent, element:element, lastChild:0, base:null, lang:null, node:null, nodeType:null, listIndex:1, rdfid:null, datatype:null, collection:false}; | |
| if(parent != null) { | |
| frame.base = parent.base; | |
| frame.lang = parent.lang | |
| } | |
| if(element == null || element.nodeType == 3 || element.nodeType == 4) return frame | |
| var d = element.getAttributeNode("xml:base"); | |
| if(d != null) { | |
| frame.base = this.context.createIRI(d.nodeValue); | |
| element.removeAttribute("xml:base") | |
| } | |
| d = element.getAttributeNode("xml:lang"); | |
| if(d != null) { | |
| frame.lang = d.nodeValue; | |
| element.removeAttribute("xml:lang") | |
| } | |
| var a = element.attributes; | |
| var i = a.length - 1; | |
| while(i > -1) { | |
| if(a.item(i).nodeName.substring(0, 3) == "xml") { | |
| if(a.item(i).name.substring(0, 6) == "xmlns:") { | |
| var c = a.item(i).nodeValue; | |
| if(this.base != null) { | |
| c = this.base.resolveReference(c).toString() | |
| } | |
| this.context.setMapping(a.item(i).name.slice(6), c) | |
| } | |
| element.removeAttributeNode(a.item(i)) | |
| } | |
| i-- | |
| } | |
| return frame | |
| }, | |
| createTriple: function(s, p, o) { return this.context.createTriple(s, p, o) }, | |
| getBlankNode: function(id) { | |
| if(this.bnHash.exists(id)) return this.bnHash.get(id) | |
| var bn = this.context.createBlankNode(); | |
| this.bnHash.set(id, bn); | |
| return bn | |
| }, | |
| isTripleToLoad: function(frame) { | |
| return frame.parent != null && frame.parent.parent != null && frame.nodeType == 1 && frame.parent.nodeType == 2 && frame.parent.parent.nodeType == 1 | |
| }, | |
| parseDOM: function(frame) { | |
| var dig = true; | |
| while(frame.parent != null) { | |
| var e = frame.element; | |
| if(e.nodeType == 3 || e.nodeType == 4) { | |
| this.addLiteral(frame) | |
| }else { | |
| if(!api.parsers.RDFXML.RDF_RDF.equals(this.resolveNamespaceURI(e))) { | |
| if(frame.parent != null && frame.parent.collection) { | |
| frame.parent.listIndex++; | |
| this.addArc(frame, api.parsers.RDFXML.RDF_FIRST); | |
| frame = this.buildFrame(frame, frame.element); | |
| frame.parent.element = null | |
| } | |
| if(frame.parent == null || frame.parent.nodeType == null || frame.parent.nodeType == 2) { | |
| var about = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "about"); | |
| var rdfid = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "ID"); | |
| if(about != null && rdfid != null) { | |
| throw new Error("RDFParser: " + e.nodeName + " has both rdf:id and rdf:about, only one may be specified"); | |
| } | |
| if(about == null && rdfid != null) { | |
| this.addNode(frame, "#" + rdfid.nodeValue); | |
| e.removeAttributeNode(rdfid) | |
| }else { | |
| if(about == null && rdfid == null) { | |
| if((about = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "nodeID")) != null) { | |
| this.addBNode(frame, about.nodeValue); | |
| e.removeAttributeNode(about) | |
| }else { | |
| this.addBNode(frame) | |
| } | |
| }else { | |
| this.addNode(frame, about.nodeValue); | |
| e.removeAttributeNode(about) | |
| } | |
| } | |
| about = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "type"); | |
| if(!this.resolveNamespaceURI(e).equals(api.parsers.RDFXML.RDF_DESCRIPTION)) { | |
| about = {nodeValue:this.resolveNamespaceURI(e)} | |
| } | |
| if(about != null) { | |
| this.add(this.createTriple(frame.node, api.parsers.RDFXML.RDF_TYPE, frame.base.resolveReference(about.nodeValue))); | |
| if(about.nodeName != null) { | |
| e.removeAttributeNode(about) | |
| } | |
| } | |
| var f = e.attributes.length - 1; | |
| while(f > -1) { | |
| this.add(this.createTriple(frame.node, this.resolveNamespaceURI(e.attributes.item(f)), this.context.createPlainLiteral(e.attributes.item(f).nodeValue, frame.lang))); | |
| f-- | |
| } | |
| }else { | |
| this.addArc(frame, this.resolveNamespaceURI(e)); | |
| var rdfid = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "ID"); | |
| if(rdfid != null) { | |
| frame.rdfid = rdfid.nodeValue; | |
| e.removeAttributeNode(rdfid) | |
| } | |
| var datatype = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "datatype"); | |
| if(datatype != null) { | |
| frame.datatype = datatype.nodeValue; | |
| e.removeAttributeNode(datatype) | |
| } | |
| var c = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "parseType"); | |
| if(c != null) { | |
| switch(c.nodeValue) { | |
| case "Literal": | |
| frame.datatype = api.parsers.RDFXML.NS_RDF + "XMLLiteral"; | |
| frame = this.buildFrame(frame); | |
| var xml = ''; | |
| var ii = 0; | |
| while(ii < e.childNodes.length) { | |
| var tempnode = e.childNodes.item(ii++); | |
| if(tempnode.nodeType == 3) { | |
| xml += tempnode.nodeValue; | |
| } else { | |
| xml += (new XMLSerializer).serializeToString(e.firstElementChild); | |
| } | |
| } | |
| this.addLiteral(frame, xml); | |
| dig = false; | |
| break; | |
| case "Resource": | |
| frame = this.buildFrame(frame, frame.element); | |
| frame.parent.element = null; | |
| this.addBNode(frame); | |
| break; | |
| case "Collection": | |
| frame = this.buildFrame(frame, frame.element); | |
| frame.parent.element = null; | |
| this.addCollection(frame); | |
| break | |
| } | |
| e.removeAttributeNode(c) | |
| } | |
| if(e.attributes.length != 0) { | |
| var f = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "resource"); | |
| c = e.getAttributeNodeNS(api.parsers.RDFXML.NS_RDF, "nodeID"); | |
| frame = this.buildFrame(frame); | |
| if(f != null) { | |
| this.addNode(frame, f.nodeValue); | |
| e.removeAttributeNode(f) | |
| }else { | |
| if(c != null) { | |
| this.addBNode(frame, c.nodeValue); | |
| e.removeAttributeNode(c) | |
| }else { | |
| this.addBNode(frame) | |
| } | |
| } | |
| var i = e.attributes.length - 1; | |
| while(i > -1) { | |
| var n = this.buildFrame(frame); | |
| f = e.attributes.item(i); | |
| this.addArc(n, this.resolveNamespaceURI(f)); | |
| if(this.resolveNamespaceURI(f).equals(api.parsers.RDFXML.RDF_TYPE)) { | |
| this.addNode(this.buildFrame(n), f.nodeValue) | |
| }else { | |
| this.addLiteral(this.buildFrame(n), f.nodeValue) | |
| } | |
| i-- | |
| } | |
| }else { | |
| if(e.childNodes.length == 0) { | |
| this.addLiteral(this.buildFrame(frame), "") | |
| } | |
| } | |
| } | |
| } | |
| } | |
| e = frame.element; | |
| while(frame.parent != null) { | |
| var pf = frame; | |
| while(e == null) { | |
| frame = frame.parent; | |
| e = frame.element | |
| } | |
| var c = e.childNodes.item(frame.lastChild); | |
| if(c == null || !dig) { | |
| if(frame.collection) { | |
| this.add(this.createTriple(frame.node, api.parsers.RDFXML.RDF_REST, api.parsers.RDFXML.RDF_NIL)) | |
| } | |
| if((frame = frame.parent) == null) { | |
| break | |
| } | |
| e = frame.element; | |
| dig = true | |
| }else { | |
| if(c.nodeType != 1 && c.nodeType != 3 && c.nodeType != 4 || (c.nodeType == 3 || c.nodeType == 4) && e.childNodes.length != 1) { | |
| frame.lastChild++ | |
| }else { | |
| if(frame.collection && frame.listIndex > 1) { | |
| var rest = this.context.createBlankNode(); | |
| this.add(this.createTriple(frame.node, api.parsers.RDFXML.RDF_REST, rest)); | |
| pf.node = rest | |
| } | |
| frame.lastChild++; | |
| frame = this.buildFrame(pf, e.childNodes.item(frame.lastChild - 1)); | |
| break | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| parseStatements: function(doc) { | |
| this.base = this.context.base; | |
| var rootFrame = this.buildFrame(null, null); | |
| rootFrame.base = this.base; | |
| this.parseDOM(this.buildFrame(rootFrame, doc.documentElement)); | |
| return true | |
| }, | |
| resolveNamespaceURI: function(e) { | |
| if(e.namespaceURI == null) { | |
| throw new Error("RDF/XML syntax error: No namespace for " + e.localName + " in " + this.base); | |
| } | |
| return this.context.createIRI(e.namespaceURI + e.localName) | |
| } | |
| }; | |
| })(rdfapi); | |
| /** | |
| * Serializers | |
| */ | |
| (function(api) { | |
| if(!api.serializers) { api.serializers = {} } | |
| /** | |
| * NTriples implements DataSerializer | |
| */ | |
| api.serializers.NTriples = function(context) {}; | |
| api.serializers.NTriples.prototype = { | |
| serialize: function(graph) { return graph.toArray().join("\n") } | |
| }; | |
| /** | |
| * Turtle implements DataSerializer | |
| */ | |
| api.serializers.Turtle = function(context) { | |
| this.context = context; | |
| this.createPrefixMap() | |
| }; | |
| api.serializers.Turtle.NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; | |
| api.serializers.Turtle.RDF_TYPE = new api.IRI(api.serializers.Turtle.NS_RDF + "type"); | |
| api.serializers.Turtle.RDF_RDF = new api.IRI(api.serializers.Turtle.NS_RDF + "RDF"); | |
| api.serializers.Turtle.RDF_FIRST = new api.IRI(api.serializers.Turtle.NS_RDF + "first"); | |
| api.serializers.Turtle.RDF_REST = new api.IRI(api.serializers.Turtle.NS_RDF + "rest"); | |
| api.serializers.Turtle.RDF_NIL = new api.IRI(api.serializers.Turtle.NS_RDF + "nil"); | |
| api.serializers.Turtle.prototype = { | |
| context: null, index: null, lists: null, prefixMap: null, usedPrefixes: null, nonAnonBNodes: null, skipSubjects: null, | |
| serialize: function(graph) { | |
| this.initiate(); | |
| graph = this.suckLists(graph); | |
| var _ = this; | |
| graph.forEach(function(t, i, s) { _.addTripleToIndex(t, i, s) }); | |
| return this.render() | |
| }, | |
| addTripleToIndex: function(t, i, s) { | |
| if(t.object.nodeType() == "BlankNode") { | |
| this.nonAnonBNodes.set(t.object.toString(), this.nonAnonBNodes.exists(t.object.toString()) ? this.nonAnonBNodes.get(t.object.toString()) + 1 : 1) | |
| } | |
| var s1 = this.shrink(t.subject); | |
| var p = this.shrink(t.property, true); | |
| if(!this.index.exists(s1)) { this.index.set(s1, new Hash) } | |
| if(!this.index.get(s1).exists(p)) { this.index.get(s1).set(p, new Array) } | |
| this.index.get(s1).get(p).push(t.object) | |
| }, | |
| anonBNode: function(subject, indent) { return this.propertyObjectChain(this.index.get(subject), indent) }, | |
| createPrefixMap: function() { | |
| var m = this.context.getMapping(); | |
| var p = this.prefixMap = new Hash; | |
| m.keys().forEach(function(k, i, a) { p.set(m.get(k).toString(), k.concat(":")) }) | |
| }, | |
| initiate: function() { | |
| this.index = new Hash; | |
| this.usedPrefixes = new Array; | |
| this.nonAnonBNodes = new Hash; | |
| this.skipSubjects = new Array; | |
| this.lists = new Hash | |
| }, | |
| output: function(o) { | |
| if(o.nodeType() == "IRI") { return this.shrink(o) } | |
| if(o.nodeType() == "TypedLiteral") { | |
| if(o.type.equals(this.context.resolveCurie("xsd:integer"))) { return o.value } | |
| } | |
| return o.toNT() | |
| }, | |
| propertyObjectChain: function(po, indent) { | |
| if(!po) return; | |
| if(indent == null) { indent = 2 } | |
| var out = ""; | |
| var _ = this; | |
| var properties = po.keys(); | |
| properties.sort(); | |
| if(properties.contains("a")) { | |
| properties.remove("a"); | |
| properties.unshift("a") | |
| } | |
| properties.forEach(function(property, pi, pa) { | |
| out = out + (pi > 0 ? (new Array(indent + 1)).join(" ") : "") + property + " "; | |
| po.get(property).forEach(function(o, oi, oa) { | |
| var oindent = ""; | |
| if(oa.length > 2) { | |
| oindent = "\n" + (new Array(indent + 2 + 1)).join(" ") | |
| } | |
| if(o.toString().charAt(0) == "_" && !_.nonAnonBNodes.exists(o.toString())) { | |
| if(_.lists.exists(o.toNT())) { | |
| out = out + _.renderList(o.toNT(), indent + 3) | |
| }else { | |
| out = out + oindent + "[ " + _.anonBNode(o.toString(), indent + 2 + 2) + oindent + (oa.length == 1 ? " " : "") + "]" | |
| } | |
| }else { | |
| out = out + oindent + _.output(o) | |
| } | |
| if(oa.length - 1 != oi) { | |
| if(oa.length > 2) { | |
| out = out + "," + (new Array(indent + 2 + 2)).join(" ") | |
| }else { | |
| out = out + ", " | |
| } | |
| } | |
| }); | |
| out = out + (pa.length - 1 == pi ? "" : ";\n") | |
| }); | |
| return out | |
| }, | |
| render: function() { | |
| var out = new Array; | |
| var _ = this; | |
| this.skipSubjects = this.nonAnonBNodes.keys(); | |
| this.nonAnonBNodes.keys().forEach(function(k, i, a) { if(_.nonAnonBNodes.get(k) == 1) { _.nonAnonBNodes.remove(k) } }); | |
| this.index.keys().forEach(function(subject, $is, $as) { | |
| var single = ""; | |
| if(subject.charAt(0) == "_") { | |
| if(!_.nonAnonBNodes.exists(subject) && !_.skipSubjects.contains(subject)) { | |
| if(_.lists.exists(subject)) { | |
| single = _.renderList(subject, 2) + " " + _.propertyObjectChain(_.index.get(subject)) | |
| } else { | |
| single = "[ " + _.anonBNode(subject, 2) + "\n]" | |
| } | |
| } | |
| } else { | |
| single = subject + " " + _.propertyObjectChain(_.index.get(subject)) | |
| } | |
| if(single.length > 0) { out.push(single + " .\n") } | |
| }); | |
| if(this.usedPrefixes.length > 0) { | |
| var invertedMap = new Hash; | |
| this.prefixMap.keys().forEach(function(k, i, h) { if(_.usedPrefixes.contains(k)) { invertedMap.set(_.prefixMap.get(k), k) } }); | |
| var prefixes = invertedMap.keys(); | |
| prefixes.sort(); | |
| prefixes.reverse(); | |
| out.unshift(""); | |
| prefixes.forEach(function(s, i, a) { out.unshift("@prefix " + s + " <" + invertedMap.get(s) + "> .") }) | |
| } | |
| return out.join("\n") | |
| }, | |
| renderList: function(o, indent) { | |
| var _ = this; | |
| var list = new Array; | |
| _.lists.get(o).forEach(function(n, i, a) { list.push(_.output(n)) }); | |
| var lis = new Array; | |
| var liststring = ""; | |
| while(list.length > 0) { | |
| var li = list.shift(); | |
| if(liststring.length + li.length < 75) { | |
| liststring = liststring.concat(li + " ") | |
| } else { | |
| lis.push(liststring); | |
| liststring = li + " " | |
| } | |
| } | |
| lis.push(liststring); | |
| var nl = lis.length == 1 ? " " : "\n" + (new Array(indent)).join(" "); | |
| return"(" + nl + lis.join(nl) + (lis.length == 1 ? "" : "\n") + ")" | |
| }, | |
| shrink: function(n, property) { | |
| if(property == null) { property = false } | |
| if(property && n.equals(api.serializers.Turtle.RDF_TYPE)) { return "a" } | |
| if(n.equals(api.serializers.Turtle.RDF_NIL)) { return "()" } | |
| var _g = 0, _g1 = this.prefixMap.keys(); | |
| while(_g < _g1.length) { | |
| var i = _g1[_g]; | |
| ++_g; | |
| if(n.toString().startsWith(i)) { | |
| if(!this.usedPrefixes.contains(i)) { this.usedPrefixes.push(i) } | |
| return n.toString().replace(i, this.prefixMap.get(i)) | |
| } | |
| } | |
| return n.toNT() | |
| }, | |
| suckLists: function(graph) { | |
| var sFilter = function(n) { return function(t, i, s) { return t.subject.equals(n) } }; | |
| var pFilter = function(n) { return function(t, i, s) { return t.property.equals(n) } }; | |
| var poFilter = function(p, o) { return function(t, i, s) { return t.property.equals(p) && t.object.equals(o) } }; | |
| var tFilter = function(a) { return function(t, i, s) { return!(t.subject.equals(a.subject) && t.property.equals(a.property) && t.object.equals(a.object)) } }; | |
| var members = graph.filter(function(t, i, s) { return t.property.equals(api.serializers.Turtle.RDF_FIRST) || t.property.equals(api.serializers.Turtle.RDF_REST) }); | |
| members.forEach(function(t, i, s) { graph = graph.filter(tFilter(t)) }); | |
| var ends = members.filter(function(t, i, s) { return t.object.equals(api.serializers.Turtle.RDF_NIL) }); | |
| var _ = this; | |
| ends.forEach(function(n, i, s) { | |
| var tmplist = new Array; | |
| var q = n; | |
| var start = null; | |
| while(q != null) { | |
| start = q.subject; | |
| tmplist.unshift(members.filter(sFilter(start)).filter(pFilter(api.serializers.Turtle.RDF_FIRST)).toArray().pop().object); | |
| members = members.filter(function(t, i1, s1) { return!t.subject.equals(start) }); | |
| q = members.filter(poFilter(api.serializers.Turtle.RDF_REST, start)).toArray().pop() | |
| } | |
| _.lists.set(start.toNT(), tmplist) | |
| }); | |
| return graph | |
| } | |
| }; | |
| })(rdfapi); | |
| /** | |
| * rdfapi.filters | |
| */ | |
| (function(api) { | |
| api.filters = { | |
| s: function(s) { return function(t) { return s.equals(t.subject); }; }, | |
| p: function(p) { return function(t) { return p.equals(t.property); }; }, | |
| o: function(o) { return function(t) { return o.equals(t.object); }; }, | |
| sp: function(s,p) { return function(t) { return s.equals(t.subject) && p.equals(t.property); }; }, | |
| so: function(s,o) { return function(t) { return s.equals(t.subject) && o.equals(t.object); }; }, | |
| po: function(p,o) { return function(t) { return p.equals(t.property) && o.equals(t.object); }; }, | |
| spo: function(s,p,o) { return function(t) { return s.equals(t.subject) && p.equals(t.property) && o.equals(t.object); }; }, | |
| describes: function(resource) { return function(t) { return resource.equals(t.subject) || resource.equals(t.object); }; } | |
| }; | |
| })(rdfapi); | |
| /** | |
| * rdfapi | |
| */ | |
| (function(api) { | |
| api.data = null; | |
| api.proxy = null; | |
| api.log = function(o) { console.log(o); }; | |
| api.singlify = function(graph) { | |
| var equivs = graph.filter( api.filters.p(api.resolve('owl:sameAs')) ); | |
| while(equivs.length > 0) { | |
| var rescount = {}; | |
| api.uniqueResources(equivs).forEach( function(r) { | |
| rescount[r.toNT()] = api.filterCount(graph,api.filters.describes(r)); | |
| }); | |
| equivs.forEach( function(t) { | |
| if(t.subject.nodeType() == 'BlankNode' && t.object.nodeType() == 'IRI') { | |
| api.replace(graph, t.subject, t.object); | |
| } else if(t.subject.nodeType() == 'IRI' && t.object.nodeType() == 'BlankNode') { | |
| api.replace(graph, t.object, t.subject); | |
| } else if(rescount[t.subject.toNT()] < rescount[t.object.toNT()]) { | |
| api.replace(graph, t.subject, t.object); | |
| } else if(rescount[t.subject.toNT()] > rescount[t.object.toNT()]) { | |
| api.replace(graph, t.object, t.subject); | |
| } else if(t.subject.nodeType() == 'IRI' && t.object.nodeType() == 'IRI') { | |
| if(t.subject.toString().length > t.object.toString().length) { | |
| api.replace(graph, t.subject, t.object); | |
| } else { | |
| api.replace(graph, t.object, t.subject); | |
| } | |
| } | |
| }); | |
| equivs = graph.filter( api.filters.p(api.resolve('owl:sameAs')) ); | |
| } | |
| }; | |
| api.replace = function(graph,o,n) { | |
| api.log("replacing " + o.toNT() + " with " + n.toNT()); | |
| var sfilter = api.filters.describes(o); | |
| graph.filter( sfilter ).forEach( function(t) { | |
| if(t.subject.equals(o)) { | |
| graph.add( api.t(n,t.property,t.object) ); | |
| } else if(t.object.equals(o)) { | |
| graph.add( api.t(t.subject,t.property,n) ); | |
| } | |
| }); | |
| graph.apply( function(t) { return !sfilter(t) && !t.subject.equals(t.object); }); | |
| if(o.nodeType() != 'BlankNode') { | |
| graph.add( api.t(n,api.resolve("link:uri"),o) ); | |
| } | |
| }; | |
| api.filterCount = function(graph,filter) { | |
| var ctr = 0; | |
| graph.forEach(function(t) { if(filter(t)) { ++ctr; } }); | |
| return ctr; | |
| }; | |
| api.uniqueResources = function(graph) { | |
| var resources = []; | |
| graph.forEach( function(t) { | |
| resources.push(t.subject); | |
| if(t.object.nodeType() == 'IRI' || t.object.nodeType() == 'BlankNode') resources.push(t.object); | |
| }); | |
| var out = []; | |
| while(resources.length>0) { | |
| var test = resources.pop(); | |
| if(!out.some(function(o){return test.equals(o);})) out.push(test); | |
| } | |
| return out; | |
| }; | |
| api.iri = function(iri) { | |
| iri = iri.toString(); | |
| if(iri.startsWith('<') && iri.endsWith('>') ) { iri = iri.slice(1,iri.length-1); } | |
| return api.data.context.createIRI(iri); | |
| }; | |
| api.resolve = function(curie) { return api.data.context.resolveCurie(curie); }; | |
| api.link = function(s,p,o) { | |
| s = api.blankNodeOrIRI(s); | |
| o = api.blankNodeOrIRI(o); | |
| return api.data.context.createTriple(s,api.iri(p),o); | |
| } | |
| api.blankNodeOrIRI = function(o) { | |
| if(typeof o == "string") { | |
| if(o.substring(0,2) == "_:") { | |
| var b = api.data.context.createBlankNode(); | |
| b.value = o; | |
| o = b; | |
| } else { | |
| o = api.iri(o); | |
| } | |
| } | |
| return o; | |
| } | |
| api.t = function(s,p,o) { return api.data.context.createTriple(s,p,o); } | |
| api.select = function(query,graph) { return new api.querylangs.RDFSelector(api.data.context).select(query,graph); }; | |
| api.errorHandler = null; | |
| api.get = function(iri, cback, async) { | |
| if(async == null) { async = true } | |
| var oldiri = iri.toString(); | |
| iri = (new api.IRI(iri.toString())).defrag().toString(); | |
| var xhr = new XMLHttpRequest; | |
| xhr.onreadystatechange = function(e) { | |
| var _ = this; | |
| if(_.readyState == 4) { | |
| if(_.status == 200) { | |
| try { | |
| cback(_); | |
| } catch (e) { | |
| if(api.errorHandler != null) { | |
| api.errorHandler(e); | |
| } else { throw e; } | |
| } | |
| } else if(api.errorHandler != null) { api.errorHandler(new Error("Failed to load resource " + oldiri + " the server responded with a status of " + _.status)) }; | |
| } | |
| }; | |
| if(api.proxy != null) { iri = api.proxy + iri; } | |
| xhr.open("GET", iri, async); | |
| xhr.followRedirects = true; | |
| xhr.timeout = 40000; | |
| xhr.setRequestHeader("Accept", "application/rdf+xml;q=0.9, application/x-turtle;q=0.9, application/turtle;q=0.9, text/rdf+n3;q=0.9, text/turtle;q=0.9, text/rdf;q=0.9, application/n3;q=0.8, text/n3;q=0.8, application/xml;q=0.7, text/*;q=0.6, */*;q=0"); | |
| xhr.send(); | |
| return | |
| }; | |
| api.negotiate = function(xhr,ctx,iri) { | |
| var parser = null; | |
| var doc = xhr.responseText; | |
| var ctype = xhr.getResponseHeader("Content-Type"); | |
| if(ctype != null) { | |
| var p = ctype.indexOf(";"); | |
| if(p > -1) { ctype = ctype.substring(0, p) } | |
| }else { | |
| ctype = "" | |
| } | |
| switch(ctype) { | |
| case "application/rdf+xml": case "application/xml": case "text/xml": | |
| parser = new api.parsers.RDFXML(ctx); | |
| doc = xhr.responseXML; | |
| break; | |
| case "text/turtle": case "application/x-turtle": case "application/turtle": case "text/rdf+n3": case "text/n3": case "application/n3": | |
| parser = new api.parsers.Turtle(ctx); | |
| break; | |
| case "text/rdf": case "text/text": case "text/plain": case "text/html": case "": | |
| if(xhr.responseXML) { | |
| parser = new api.parsers.RDFXML(ctx); | |
| doc = xhr.responseXML; | |
| } else { | |
| if(doc.indexOf("xmlns:rdf=") > -1) { | |
| parser = new api.parsers.RDFXML(ctx); | |
| doc = new DOMParser().parseFromString(doc, "text/xml"); | |
| } else { | |
| parser = new api.parsers.Turtle(ctx); | |
| } | |
| } | |
| break; | |
| } | |
| if(parser == null) { throw new Error(iri.toString() + " Unrecognized mediatype: '" + ctype + "'"); } | |
| return [parser,doc,ctype]; | |
| }; | |
| api.parse = function(iri, cb, filter, graph) { | |
| var async = cb != null; | |
| iri = api.data.context.createIRI(iri.toString()); | |
| var ctx = api.data.createContext(); | |
| ctx.base = iri; | |
| this.get(iri.toString(), function(xhr) { | |
| var parts = api.negotiate(xhr,ctx,iri); | |
| try { | |
| parts[0].parse(parts[1], cb, filter, graph); | |
| } catch(e) { throw new Error( iri.toString() + " [ " + parts[2] + " ] - " + e.toString() ); } | |
| }, async); | |
| return true | |
| }; | |
| api.process = function(iri, processor, filter) { | |
| var async = true; | |
| iri = api.data.context.createIRI(iri.toString()); | |
| var ctx = api.data.createContext(); | |
| ctx.base = iri; | |
| this.get(iri.toString(), function(xhr) { | |
| var parts = api.negotiate(xhr,ctx,iri); | |
| parts[0].process(parts[1], processor, filter); | |
| }, async); | |
| return true | |
| }; | |
| api.nt = function(graph) { return new api.serializers.NTriples(api.data.context).serialize(graph); }; | |
| api.turtle = function(graph) { return new api.serializers.Turtle(api.data.context).serialize(graph); }; | |
| })(rdfapi); | |
| Hash = function(p) { this.empty() }; | |
| Hash.prototype = { | |
| h: null, | |
| get: function(k) { return this.h[k] }, | |
| set: function(k, v) { this.h[k] = v }, | |
| empty: function() { this.h = {} }, | |
| exists: function(k) { return this.h.hasOwnProperty(k) }, | |
| iterator: function() { return this.h.iterator() }, | |
| keys: function() { return this.h.instanceKeys() }, | |
| remove: function(k) { | |
| var r = this.get(k); | |
| delete this.h[k]; | |
| return r | |
| }, | |
| toArray: function() { | |
| var a = new Array; | |
| var _ = this; | |
| this.keys().forEach(function(k) { a.push(_.get(k)) }); | |
| return a | |
| }, | |
| toString: function() { return JSON.stringify(this.h) } | |
| }; | |
| /** | |
| * ECMAScript-262 v5 Compatability | |
| */ | |
| Array.isArray = Array.isArray || function(o) { return Object.prototype.toString.call(o) === '[object Array]'; }; | |
| Array.prototype.some = Array.prototype.some || function(fun /*, thisp */) { | |
| "use strict"; | |
| if (this === void 0 || this === null) throw new TypeError(); | |
| var t = Object(this); | |
| var len = t.length >>> 0; | |
| if (typeof fun !== "function") throw new TypeError(); | |
| var thisp = arguments[1]; | |
| for (var i = 0; i < len; i++) { | |
| if (i in t && fun.call(thisp, t[i], i, t)) return true; | |
| } | |
| return false; | |
| }; | |
| Array.prototype.every = Array.prototype.every || function(fun /*, thisp */) { | |
| "use strict"; | |
| if (this === void 0 || this === null) throw new TypeError(); | |
| var t = Object(this); | |
| var len = t.length >>> 0; | |
| if (typeof fun !== "function") throw new TypeError(); | |
| var thisp = arguments[1]; | |
| for (var i = 0; i < len; i++) { | |
| if (i in t && !fun.call(thisp, t[i], i, t)) return false; | |
| } | |
| return true; | |
| }; | |
| Array.prototype.forEach = Array.prototype.forEach || function(fun /*, thisp */) { | |
| "use strict"; | |
| if (this === void 0 || this === null) throw new TypeError(); | |
| var t = Object(this); | |
| var len = t.length >>> 0; | |
| if (typeof fun !== "function") throw new TypeError(); | |
| var thisp = arguments[1]; | |
| for (var i = 0; i < len; i++) { | |
| if (i in t) fun.call(thisp, t[i], i, t); | |
| } | |
| }; | |
| Array.prototype.filter = Array.prototype.filter || function(fun /*, thisp */) { | |
| "use strict"; | |
| if (this === void 0 || this === null) throw new TypeError(); | |
| var t = Object(this); | |
| var len = t.length >>> 0; | |
| if (typeof fun !== "function") throw new TypeError(); | |
| var res = []; | |
| var thisp = arguments[1]; | |
| for (var i = 0; i < len; i++) { | |
| if (i in t) { | |
| var val = t[i]; | |
| if( fun.call(thisp, val, i, t)) res.push(val); | |
| } | |
| } | |
| return res; | |
| }; | |
| /** | |
| * Custom stuff that may get factored out.. | |
| */ | |
| Object.prototype.iterator = function() { | |
| var o = this.instanceKeys(); | |
| var y = this; | |
| return { | |
| cur:0, arr:o, | |
| hasNext: function() { return this.cur < this.arr.length }, | |
| next:function() { return y[this.arr[this.cur++]] } | |
| } | |
| }; | |
| Object.prototype.instanceKeys = function(proto) { | |
| var keys = []; | |
| proto = !proto; | |
| for(var i in this) { | |
| if(proto && Object.prototype[i]) { continue } | |
| keys.push(i) | |
| } | |
| return keys | |
| }; | |
| String.prototype.endsWith = function(s, i) { | |
| if(i) { return s.toLowerCase() == this.substring(this.length - s.length).toLowerCase() } | |
| return s == this.substring(this.length - s.length) | |
| }; | |
| String.prototype.startsWith = function(s, i) { | |
| if(i) { return s.toLowerCase() == this.substring(0, s.length).toLowerCase() } | |
| return s == this.substring(0, s.length) | |
| }; | |
| Array.prototype.remove = Array.prototype.indexOf ? function(obj) { | |
| var idx = this.indexOf(obj); | |
| if(idx == -1) { return false } | |
| this.splice(idx, 1); | |
| return true | |
| } : function(obj) { | |
| var i = 0; | |
| var l = this.length; | |
| while(i < l) { | |
| if(this[i] == obj) { | |
| this.splice(i, 1); | |
| return true | |
| } | |
| i++ | |
| } | |
| return false | |
| }; | |
| Array.prototype.iterator = function() { | |
| return { | |
| cur: 0, arr: this, | |
| hasNext: function() { return this.cur < this.arr.length }, | |
| next: function() { return this.arr[this.cur++] } | |
| } | |
| }; | |
| Array.prototype.contains = function(i) { return this.indexOf(i) >= 0 }; | |
| /** | |
| * Instantiation | |
| */ | |
| rdfapi.data = new rdfapi.Data; | |
| if(typeof exports != "undefined") { | |
| exports = rdfapi; // we require this.. .. .... | |
| } else if(typeof document == 'object') { | |
| document.data = rdfapi.data; // note that they're the same.. | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment