|
1 | 1 |
|
2 | 2 | var jsonld = require("jsonld") |
3 | 3 | , uuid = require("uuid") |
4 | | - , IRI = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i; |
| 4 | + , IRI = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i |
| 5 | + , RDFTYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" |
| 6 | + , async = require("async"); |
5 | 7 |
|
6 | 8 | function levelgraphJSONLD(db, jsonldOpts) { |
7 | 9 |
|
@@ -43,59 +45,108 @@ function levelgraphJSONLD(db, jsonldOpts) { |
43 | 45 | callback(null, obj); |
44 | 46 | }); |
45 | 47 |
|
46 | | - expanded.forEach(function(triples) { |
| 48 | + var writeTriples = function(triples) { |
47 | 49 | var subject = triples["@id"]; |
48 | 50 | delete triples["@id"]; |
49 | 51 |
|
50 | 52 | if (!subject) { |
51 | | - subject = (options.base || graphdb.jsond.options.base) + uuid.v1(); |
| 53 | + subject = "_:" + uuid.v1(); |
52 | 54 | } |
53 | 55 |
|
54 | 56 | Object.keys(triples).forEach(function(predicate) { |
| 57 | + if (predicate === "@type") { |
| 58 | + if (!triples[predicate].forEach) { |
| 59 | + triples[predicate] = [triples[predicate]]; |
| 60 | + } |
| 61 | + |
| 62 | + triples[RDFTYPE] = triples[predicate]; |
| 63 | + delete triples[predicate]; |
| 64 | + predicate = RDFTYPE; |
| 65 | + } |
| 66 | + |
55 | 67 | triples[predicate].forEach(function(object) { |
56 | 68 | var triple = { |
57 | 69 | subject: subject |
58 | 70 | , predicate: predicate |
59 | | - , object: object["@id"] || object["@value"] |
| 71 | + , object: (typeof object === 'string') ? object : object["@id"] || object["@value"] |
60 | 72 | }; |
| 73 | + |
| 74 | + if (!triple.object) { |
| 75 | + // the object should be a blank node that points |
| 76 | + // to a another triple |
| 77 | + writeTriples(object); |
| 78 | + triple.object = object["@id"]; |
| 79 | + } |
| 80 | + |
61 | 81 | stream.write(triple); |
62 | 82 | }); |
63 | 83 | }); |
64 | | - }); |
| 84 | + |
| 85 | + triples["@id"] = subject; |
| 86 | + }; |
| 87 | + |
| 88 | + expanded.forEach(writeTriples); |
65 | 89 |
|
66 | 90 | stream.end(); |
67 | 91 | }); |
68 | 92 | }; |
69 | 93 |
|
70 | | - graphdb.jsonld.get = function(iri, context, options, callback) { |
71 | | - |
72 | | - if (typeof options === 'function') { |
73 | | - callback = options; |
74 | | - options = {}; |
| 94 | + var fetchExpandedTriples = function(iri, memo, callback) { |
| 95 | + if (typeof memo === "function") { |
| 96 | + callback = memo; |
| 97 | + memo = {}; |
75 | 98 | } |
76 | 99 |
|
77 | 100 | graphdb.get({ subject: iri }, function(err, triples) { |
78 | 101 | if (err || triples.length === 0) { |
79 | 102 | return callback(err, null); |
80 | 103 | } |
81 | 104 |
|
82 | | - var triples = triples.reduce(function(acc, triple) { |
83 | | - var key; |
| 105 | + async.reduce(triples, memo, function(acc, triple, cb) { |
| 106 | + var key; |
84 | 107 |
|
85 | | - if (!acc[triple.subject]) { |
86 | | - acc[triple.subject] = { "@id": triple.subject }; |
87 | | - } |
88 | | - acc[triple.subject][triple.predicate] = {}; |
89 | | - key = triple.object.match(IRI) ? "@id" : "@value"; |
90 | | - acc[triple.subject][triple.predicate][key] = triple.object; |
| 108 | + if (!acc[triple.subject]) { |
| 109 | + acc[triple.subject] = { "@id": triple.subject }; |
| 110 | + } |
| 111 | + |
| 112 | + if (triple.predicate === RDFTYPE) { |
| 113 | + if (acc[triple.subject]["@type"]) { |
| 114 | + acc[triple.subject]["@type"] = [acc[triple.subject]["@type"]]; |
| 115 | + acc[triple.subject]["@type"].push(triple.object); |
| 116 | + } else { |
| 117 | + acc[triple.subject]["@type"] = triple.object; |
| 118 | + } |
| 119 | + cb(null, acc); |
| 120 | + } else if (triple.object.indexOf("_:") !== 0) { |
| 121 | + acc[triple.subject][triple.predicate] = {}; |
| 122 | + key = (triple.object.match(IRI) || triple.object.indexOf("_:") === 0) ? "@id" : "@value"; |
| 123 | + acc[triple.subject][triple.predicate][key] = triple.object; |
| 124 | + cb(null, acc); |
| 125 | + } else { |
| 126 | + fetchExpandedTriples(triple.object, function(err, expanded) { |
| 127 | + acc[triple.subject][triple.predicate] = expanded[triple.object]; |
| 128 | + cb(err, acc); |
| 129 | + }); |
| 130 | + } |
| 131 | + }, callback); |
| 132 | + }); |
| 133 | + }; |
91 | 134 |
|
92 | | - return acc; |
93 | | - }, {}) |
| 135 | + graphdb.jsonld.get = function(iri, context, options, callback) { |
94 | 136 |
|
95 | | - , expanded = Object.keys(triples).reduce(function(acc, key) { |
96 | | - acc.push(triples[key]); |
97 | | - return acc; |
98 | | - }, []); |
| 137 | + if (typeof options === 'function') { |
| 138 | + callback = options; |
| 139 | + options = {}; |
| 140 | + } |
| 141 | + |
| 142 | + fetchExpandedTriples(iri, function(err, expanded) { |
| 143 | + if (err || expanded === null) { |
| 144 | + return callback(err, expanded); |
| 145 | + } |
| 146 | + expanded = Object.keys(expanded).reduce(function(acc, key) { |
| 147 | + acc.push(expanded[key]); |
| 148 | + return acc; |
| 149 | + }, []); |
99 | 150 |
|
100 | 151 | jsonld.compact(expanded, context, options, callback); |
101 | 152 | }); |
|
0 commit comments