@@ -18,7 +18,7 @@ const {
1818
1919// constants
2020const {
21- // RDF,
21+ RDF,
2222 RDF_LIST,
2323 RDF_FIRST,
2424 RDF_REST,
@@ -61,19 +61,21 @@ api.fromRDF = async (
6161 const defaultGraph = {};
6262 const graphMap = {'@default': defaultGraph};
6363 const referencedOnce = {};
64+ let processCompoundLiterals = false;
6465 if(rdfDirection) {
6566 if(rdfDirection === 'compound-literal') {
66- throw new JsonLdError(
67- 'Unsupported rdfDirection value.',
68- 'jsonld.InvalidRdfDirection',
69- {value: rdfDirection});
67+ processCompoundLiterals = true;
7068 } else if(rdfDirection !== 'i18n-datatype') {
7169 throw new JsonLdError(
7270 'Unknown rdfDirection value.',
7371 'jsonld.InvalidRdfDirection',
7472 {value: rdfDirection});
7573 }
7674 }
75+ let compoundLiteralSubjects;
76+ if(processCompoundLiterals) {
77+ compoundLiteralSubjects = {};
78+ }
7779
7880 for(const quad of dataset) {
7981 // TODO: change 'name' to 'graph'
@@ -82,11 +84,18 @@ api.fromRDF = async (
8284 if(!(name in graphMap)) {
8385 graphMap[name] = {};
8486 }
87+ if(processCompoundLiterals && !(name in compoundLiteralSubjects)) {
88+ compoundLiteralSubjects[name] = {};
89+ }
8590 if(name !== '@default' && !(name in defaultGraph)) {
8691 defaultGraph[name] = {'@id': name};
8792 }
8893
8994 const nodeMap = graphMap[name];
95+ let compoundMap;
96+ if(processCompoundLiterals) {
97+ compoundMap = compoundLiteralSubjects[name];
98+ }
9099
91100 // get subject, predicate, object
92101 const s = quad.subject.value;
@@ -97,6 +106,9 @@ api.fromRDF = async (
97106 nodeMap[s] = {'@id': s};
98107 }
99108 const node = nodeMap[s];
109+ if(processCompoundLiterals && p === RDF + 'direction') {
110+ compoundMap[s] = true;
111+ }
100112
101113 const objectIsNode = o.termType.endsWith('Node');
102114 if(objectIsNode && !(o.value in nodeMap)) {
@@ -208,6 +220,64 @@ api.fromRDF = async (
208220 for(const name in graphMap) {
209221 const graphObject = graphMap[name];
210222
223+ if(processCompoundLiterals) {
224+ if(name in compoundLiteralSubjects) {
225+ const cls = compoundLiteralSubjects[name];
226+ for(const cl of Object.keys(cls)) {
227+ const clEntry = referencedOnce[cl];
228+ if(!clEntry) {
229+ continue;
230+ }
231+ const node = clEntry.node;
232+ const property = clEntry.property;
233+ //const value = clEntry.value;
234+ const clNode = graphObject[cl];
235+ if(!types.isObject(clNode)) {
236+ continue;
237+ }
238+ delete graphObject[cl];
239+ for(const clReference of node[property]) {
240+ if(clReference['@id'] === cl) {
241+ delete clReference['@id'];
242+ }
243+ const value = clNode[RDF + 'value'];
244+ // FIXME: error on !== 1 value
245+ clReference['@value'] = value[0]['@value'];
246+ const language = clNode[RDF + 'language'];
247+ if(language) {
248+ // FIXME: error on !== 1 language value
249+ const v = language[0]['@value'];
250+ if(!v.match(REGEX_BCP47)) {
251+ throw new JsonLdError(
252+ 'Invalid RDF syntax; rdf:language must be valid BCP47.',
253+ 'jsonld.SyntaxError',
254+ {
255+ code: 'invalid language-tagged string',
256+ value: v
257+ });
258+ }
259+ clReference['@language'] = v;
260+ }
261+ const direction = clNode[RDF + 'direction'];
262+ if(direction) {
263+ // FIXME: error on !== 1 direction value
264+ const v = direction[0]['@value'];
265+ if(!(v === 'ltr' || v === 'rtl')) {
266+ throw new JsonLdError(
267+ 'Invalid RDF syntax; rdf:direction must be "ltr" or "rtl".',
268+ 'jsonld.SyntaxError',
269+ {
270+ code: 'invalid base direction',
271+ value: v
272+ });
273+ }
274+ clReference['@direction'] = v;
275+ }
276+ }
277+ }
278+ }
279+ }
280+
211281 // no @lists to be converted, continue
212282 if(!(RDF_NIL in graphObject)) {
213283 continue;
@@ -296,7 +366,8 @@ api.fromRDF = async (
296366 *
297367 * @param o the RDF triple object to convert.
298368 * @param useNativeTypes true to output native types, false not to.
299- * @param rdfDirection text direction mode [null, i18n-datatype]
369+ * @param rdfDirection text direction mode [null, i18n-datatype,
370+ * compound-literal]
300371 * @param options top level API options
301372 *
302373 * @return the JSON-LD object.
0 commit comments