1package gojsonld
2
3// /**
4//  * Compacts the given input using the context according to the steps in the
5//  * <a href="http://www.w3.org/TR/json-ld-api/#compaction-algorithm">
6//  * Compaction algorithm</a>.
7//  *
8//  * @param input
9//  *            The input JSON-LD object.
10//  * @param context
11//  *            The context object to use for the compaction algorithm.
12//  * @param opts
13//  *            The {@link JsonLdOptions} that are to be sent to the
14//  *            compaction algorithm.
15//  * @return The compacted JSON-LD document
16//  * @throws JsonLdError
17//  *             If there is an error while compacting.
18//  */
19// public static Map<String, Object> compact(Object input, Object context, JsonLdOptions opts)
20//         throws JsonLdError {
21//     // 1)
22//     // TODO: look into java futures/promises
23
24//     // 2-6) NOTE: these are all the same steps as in expand
25//     final Object expanded = expand(input, opts);
26//     // 7)
27//     if (context instanceof Map && ((Map<String, Object>) context).containsKey("@context")) {
28//         context = ((Map<String, Object>) context).get("@context");
29//     }
30//     Context activeCtx = new Context(opts);
31//     activeCtx = activeCtx.parse(context);
32//     // 8)
33//     Object compacted = new JsonLdApi(opts).compact(activeCtx, null, expanded,
34//             opts.getCompactArrays());
35
36//     // final step of Compaction Algorithm
37//     // TODO: SPEC: the result result is a NON EMPTY array,
38//     if (compacted instanceof List) {
39//         if (((List<Object>) compacted).isEmpty()) {
40//             compacted = new LinkedHashMap<String, Object>();
41//         } else {
42//             final Map<String, Object> tmp = new LinkedHashMap<String, Object>();
43//             // TODO: SPEC: doesn't specify to use vocab = true here
44//             tmp.put(activeCtx.compactIri("@graph", true), compacted);
45//             compacted = tmp;
46//         }
47//     }
48//     if (compacted != null && context != null) {
49//         // TODO: figure out if we can make "@context" appear at the start of
50//         // the keySet
51//         if ((context instanceof Map && !((Map<String, Object>) context).isEmpty())
52//                 || (context instanceof List && !((List<Object>) context).isEmpty())) {
53//             ((Map<String, Object>) compacted).put("@context", context);
54//         }
55//     }
56
57//     // 9)
58//     return (Map<String, Object>) compacted;
59// }
60
61// /**
62//  * Expands the given input according to the steps in the <a
63//  * href="http://www.w3.org/TR/json-ld-api/#expansion-algorithm">Expansion
64//  * algorithm</a>.
65//  *
66//  * @param input
67//  *            The input JSON-LD object.
68//  * @param opts
69//  *            The {@link JsonLdOptions} that are to be sent to the expansion
70//  *            algorithm.
71//  * @return The expanded JSON-LD document
72//  * @throws JsonLdError
73//  *             If there is an error while expanding.
74//  */
75// public static List<Object> expand(Object input, JsonLdOptions opts) throws JsonLdError {
76//     // 1)
77//     // TODO: look into java futures/promises
78
79//     // 2) TODO: better verification of DOMString IRI
80//     if (input instanceof String && ((String) input).contains(":")) {
81//         try {
82//             final RemoteDocument tmp = opts.getDocumentLoader().loadDocument((String) input);
83//             input = tmp.document;
84//             // TODO: figure out how to deal with remote context
85//         } catch (final Exception e) {
86//             throw new JsonLdError(Error.LOADING_DOCUMENT_FAILED, e.getMessage());
87//         }
88//         // if set the base in options should override the base iri in the
89//         // active context
90//         // thus only set this as the base iri if it's not already set in
91//         // options
92//         if (opts.getBase() == null) {
93//             opts.setBase((String) input);
94//         }
95//     }
96
97//     // 3)
98//     Context activeCtx = new Context(opts);
99//     // 4)
100//     if (opts.getExpandContext() != null) {
101//         Object exCtx = opts.getExpandContext();
102//         if (exCtx instanceof Map && ((Map<String, Object>) exCtx).containsKey("@context")) {
103//             exCtx = ((Map<String, Object>) exCtx).get("@context");
104//         }
105//         activeCtx = activeCtx.parse(exCtx);
106//     }
107
108//     // 5)
109//     // TODO: add support for getting a context from HTTP when content-type
110//     // is set to a jsonld compatable format
111
112//     // 6)
113//     Object expanded = new JsonLdApi(opts).expand(activeCtx, input);
114
115//     // final step of Expansion Algorithm
116//     if (expanded instanceof Map && ((Map) expanded).containsKey("@graph")
117//             && ((Map) expanded).size() == 1) {
118//         expanded = ((Map<String, Object>) expanded).get("@graph");
119//     } else if (expanded == null) {
120//         expanded = new ArrayList<Object>();
121//     }
122
123//     // normalize to an array
124//     if (!(expanded instanceof List)) {
125//         final List<Object> tmp = new ArrayList<Object>();
126//         tmp.add(expanded);
127//         expanded = tmp;
128//     }
129//     return (List<Object>) expanded;
130// }
131
132// /**
133//  * Expands the given input according to the steps in the <a
134//  * href="http://www.w3.org/TR/json-ld-api/#expansion-algorithm">Expansion
135//  * algorithm</a>, using the default {@link JsonLdOptions}.
136//  *
137//  * @param input
138//  *            The input JSON-LD object.
139//  * @return The expanded JSON-LD document
140//  * @throws JsonLdError
141//  *             If there is an error while expanding.
142//  */
143// public static List<Object> expand(Object input) throws JsonLdError {
144//     return expand(input, new JsonLdOptions(""));
145// }
146
147// public static Object flatten(Object input, Object context, JsonLdOptions opts)
148//         throws JsonLdError {
149//     // 2-6) NOTE: these are all the same steps as in expand
150//     final Object expanded = expand(input, opts);
151//     // 7)
152//     if (context instanceof Map && ((Map<String, Object>) context).containsKey("@context")) {
153//         context = ((Map<String, Object>) context).get("@context");
154//     }
155//     // 8) NOTE: blank node generation variables are members of JsonLdApi
156//     // 9) NOTE: the next block is the Flattening Algorithm described in
157//     // http://json-ld.org/spec/latest/json-ld-api/#flattening-algorithm
158
159//     // 1)
160//     final Map<String, Object> nodeMap = new LinkedHashMap<String, Object>();
161//     nodeMap.put("@default", new LinkedHashMap<String, Object>());
162//     // 2)
163//     new JsonLdApi(opts).generateNodeMap(expanded, nodeMap);
164//     // 3)
165//     final Map<String, Object> defaultGraph = (Map<String, Object>) nodeMap.remove("@default");
166//     // 4)
167//     for (final String graphName : nodeMap.keySet()) {
168//         final Map<String, Object> graph = (Map<String, Object>) nodeMap.get(graphName);
169//         // 4.1+4.2)
170//         Map<String, Object> entry;
171//         if (!defaultGraph.containsKey(graphName)) {
172//             entry = new LinkedHashMap<String, Object>();
173//             entry.put("@id", graphName);
174//             defaultGraph.put(graphName, entry);
175//         } else {
176//             entry = (Map<String, Object>) defaultGraph.get(graphName);
177//         }
178//         // 4.3)
179//         // TODO: SPEC doesn't specify that this should only be added if it
180//         // doesn't exists
181//         if (!entry.containsKey("@graph")) {
182//             entry.put("@graph", new ArrayList<Object>());
183//         }
184//         final List<String> keys = new ArrayList<String>(graph.keySet());
185//         Collections.sort(keys);
186//         for (final String id : keys) {
187//             final Map<String, Object> node = (Map<String, Object>) graph.get(id);
188//             if (!(node.containsKey("@id") && node.size() == 1)) {
189//                 ((List<Object>) entry.get("@graph")).add(node);
190//             }
191//         }
192
193//     }
194//     // 5)
195//     final List<Object> flattened = new ArrayList<Object>();
196//     // 6)
197//     final List<String> keys = new ArrayList<String>(defaultGraph.keySet());
198//     Collections.sort(keys);
199//     for (final String id : keys) {
200//         final Map<String, Object> node = (Map<String, Object>) defaultGraph.get(id);
201//         if (!(node.containsKey("@id") && node.size() == 1)) {
202//             flattened.add(node);
203//         }
204//     }
205//     // 8)
206//     if (context != null && !flattened.isEmpty()) {
207//         Context activeCtx = new Context(opts);
208//         activeCtx = activeCtx.parse(context);
209//         // TODO: only instantiate one jsonldapi
210//         Object compacted = new JsonLdApi(opts).compact(activeCtx, null, flattened,
211//                 opts.getCompactArrays());
212//         if (!(compacted instanceof List)) {
213//             final List<Object> tmp = new ArrayList<Object>();
214//             tmp.add(compacted);
215//             compacted = tmp;
216//         }
217//         final String alias = activeCtx.compactIri("@graph");
218//         final Map<String, Object> rval = activeCtx.serialize();
219//         rval.put(alias, compacted);
220//         return rval;
221//     }
222//     return flattened;
223// }
224
225// /**
226//  * Flattens the given input and compacts it using the passed context
227//  * according to the steps in the <a
228//  * href="http://www.w3.org/TR/json-ld-api/#flattening-algorithm">Flattening
229//  * algorithm</a>:
230//  *
231//  * @param input
232//  *            The input JSON-LD object.
233//  * @param opts
234//  *            The {@link JsonLdOptions} that are to be sent to the
235//  *            flattening algorithm.
236//  * @return The flattened JSON-LD document
237//  * @throws JsonLdError
238//  *             If there is an error while flattening.
239//  */
240// public static Object flatten(Object input, JsonLdOptions opts) throws JsonLdError {
241//     return flatten(input, null, opts);
242// }
243
244// /**
245//  * Frames the given input using the frame according to the steps in the <a
246//  * href="http://json-ld.org/spec/latest/json-ld-framing/#framing-algorithm">
247//  * Framing Algorithm</a>.
248//  *
249//  * @param input
250//  *            The input JSON-LD object.
251//  * @param frame
252//  *            The frame to use when re-arranging the data of input; either
253//  *            in the form of an JSON object or as IRI.
254//  * @param opts
255//  *            The {@link JsonLdOptions} that are to be sent to the framing
256//  *            algorithm.
257//  * @return The framed JSON-LD document
258//  * @throws JsonLdError
259//  *             If there is an error while framing.
260//  */
261// public static Map<String, Object> frame(Object input, Object frame, JsonLdOptions opts)
262//         throws JsonLdError {
263
264//     if (frame instanceof Map) {
265//         frame = JsonLdUtils.clone(frame);
266//     }
267//     // TODO string/IO input
268
269//     final Object expandedInput = expand(input, opts);
270//     final List<Object> expandedFrame = expand(frame, opts);
271
272//     final JsonLdApi api = new JsonLdApi(expandedInput, opts);
273//     final List<Object> framed = api.frame(expandedInput, expandedFrame);
274//     final Context activeCtx = api.context.parse(((Map<String, Object>) frame).get("@context"));
275
276//     Object compacted = api.compact(activeCtx, null, framed);
277//     if (!(compacted instanceof List)) {
278//         final List<Object> tmp = new ArrayList<Object>();
279//         tmp.add(compacted);
280//         compacted = tmp;
281//     }
282//     final String alias = activeCtx.compactIri("@graph");
283//     final Map<String, Object> rval = activeCtx.serialize();
284//     rval.put(alias, compacted);
285//     JsonLdUtils.removePreserve(activeCtx, rval, opts);
286//     return rval;
287// }
288
289// /**
290//  * A registry for RDF Parsers (in this case, JSONLDSerializers) used by
291//  * fromRDF if no specific serializer is specified and options.format is set.
292//  *
293//  * TODO: this would fit better in the document loader class
294//  */
295// private static Map<String, RDFParser> rdfParsers = new LinkedHashMap<String, RDFParser>() {
296//     {
297//         // automatically register nquad serializer
298//         put("application/nquads", new NQuadRDFParser());
299//         put("text/turtle", new TurtleRDFParser());
300//     }
301// };
302
303// public static void registerRDFParser(String format, RDFParser parser) {
304//     rdfParsers.put(format, parser);
305// }
306
307// public static void removeRDFParser(String format) {
308//     rdfParsers.remove(format);
309// }
310
311// /**
312//  * Converts an RDF dataset to JSON-LD.
313//  *
314//  * @param dataset
315//  *            a serialized string of RDF in a format specified by the format
316//  *            option or an RDF dataset to convert.
317//  * @param options
318//  *            the options to use: [format] the format if input is not an
319//  *            array: 'application/nquads' for N-Quads (default).
320//  *            [useRdfType] true to use rdf:type, false to use @type
321//  *            (default: false). [useNativeTypes] true to convert XSD types
322//  *            into native types (boolean, integer, double), false not to
323//  *            (default: true).
324//  * @return A JSON-LD object.
325//  * @throws JsonLdError
326//  *             If there is an error converting the dataset to JSON-LD.
327//  */
328// public static Object fromRDF(Object dataset, JsonLdOptions options) throws JsonLdError {
329//     // handle non specified serializer case
330
331//     RDFParser parser = null;
332
333//     if (options.format == null && dataset instanceof String) {
334//         // attempt to parse the input as nquads
335//         options.format = "application/nquads";
336//     }
337
338//     if (rdfParsers.containsKey(options.format)) {
339//         parser = rdfParsers.get(options.format);
340//     } else {
341//         throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, options.format);
342//     }
343
344//     // convert from RDF
345//     return fromRDF(dataset, options, parser);
346// }
347
348// /**
349//  * Converts an RDF dataset to JSON-LD, using the default
350//  * {@link JsonLdOptions}.
351//  *
352//  * @param dataset
353//  *            a serialized string of RDF in a format specified by the format
354//  *            option or an RDF dataset to convert.
355//  * @return The JSON-LD object represented by the given RDF dataset
356//  * @throws JsonLdError
357//  *             If there was an error converting from RDF to JSON-LD
358//  */
359// public static Object fromRDF(Object dataset) throws JsonLdError {
360//     return fromRDF(dataset, new JsonLdOptions(""));
361// }
362
363// /**
364//  * Converts an RDF dataset to JSON-LD, using a specific instance of
365//  * {@link RDFParser}.
366//  *
367//  * @param input
368//  *            a serialized string of RDF in a format specified by the format
369//  *            option or an RDF dataset to convert.
370//  * @param options
371//  *            the options to use: [format] the format if input is not an
372//  *            array: 'application/nquads' for N-Quads (default).
373//  *            [useRdfType] true to use rdf:type, false to use @type
374//  *            (default: false). [useNativeTypes] true to convert XSD types
375//  *            into native types (boolean, integer, double), false not to
376//  *            (default: true).
377//  * @param parser
378//  *            A specific instance of {@link RDFParser} to use for the
379//  *            conversion.
380//  * @return A JSON-LD object.
381//  * @throws JsonLdError
382//  *             If there is an error converting the dataset to JSON-LD.
383//  */
384// public static Object fromRDF(Object input, JsonLdOptions options, RDFParser parser)
385//         throws JsonLdError {
386
387//     final RDFDataset dataset = parser.parse(input);
388
389//     // convert from RDF
390//     final Object rval = new JsonLdApi(options).fromRDF(dataset);
391
392//     // re-process using the generated context if outputForm is set
393//     if (options.outputForm != null) {
394//         if ("expanded".equals(options.outputForm)) {
395//             return rval;
396//         } else if ("compacted".equals(options.outputForm)) {
397//             return compact(rval, dataset.getContext(), options);
398//         } else if ("flattened".equals(options.outputForm)) {
399//             return flatten(rval, dataset.getContext(), options);
400//         } else {
401//             throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR);
402//         }
403//     }
404//     return rval;
405// }
406
407// /**
408//  * Converts an RDF dataset to JSON-LD, using a specific instance of
409//  * {@link RDFParser}, and the default {@link JsonLdOptions}.
410//  *
411//  * @param input
412//  *            a serialized string of RDF in a format specified by the format
413//  *            option or an RDF dataset to convert.
414//  * @param parser
415//  *            A specific instance of {@link RDFParser} to use for the
416//  *            conversion.
417//  * @return A JSON-LD object.
418//  * @throws JsonLdError
419//  *             If there is an error converting the dataset to JSON-LD.
420//  */
421// public static Object fromRDF(Object input, RDFParser parser) throws JsonLdError {
422//     return fromRDF(input, new JsonLdOptions(""), parser);
423// }
424
425// /**
426//  * Outputs the RDF dataset found in the given JSON-LD object.
427//  *
428//  * @param input
429//  *            the JSON-LD input.
430//  * @param callback
431//  *            A callback that is called when the input has been converted to
432//  *            Quads (null to use options.format instead).
433//  * @param options
434//  *            the options to use: [base] the base IRI to use. [format] the
435//  *            format to use to output a string: 'application/nquads' for
436//  *            N-Quads (default). [loadContext(url, callback(err, url,
437//  *            result))] the context loader.
438//  * @return A JSON-LD object.
439//  * @throws JsonLdError
440//  *             If there is an error converting the dataset to JSON-LD.
441//  */
442// public static Object toRDF(Object input, JsonLdTripleCallback callback, JsonLdOptions options)
443//         throws JsonLdError {
444
445//     final Object expandedInput = expand(input, options);
446
447//     final JsonLdApi api = new JsonLdApi(expandedInput, options);
448//     final RDFDataset dataset = api.toRDF();
449
450//     // generate namespaces from context
451//     if (options.useNamespaces) {
452//         List<Map<String, Object>> _input;
453//         if (input instanceof List) {
454//             _input = (List<Map<String, Object>>) input;
455//         } else {
456//             _input = new ArrayList<Map<String, Object>>();
457//             _input.add((Map<String, Object>) input);
458//         }
459//         for (final Map<String, Object> e : _input) {
460//             if (e.containsKey("@context")) {
461//                 dataset.parseContext(e.get("@context"));
462//             }
463//         }
464//     }
465
466//     if (callback != null) {
467//         return callback.call(dataset);
468//     }
469
470//     if (options.format != null) {
471//         if ("application/nquads".equals(options.format)) {
472//             return new NQuadTripleCallback().call(dataset);
473//         } else if ("text/turtle".equals(options.format)) {
474//             return new TurtleTripleCallback().call(dataset);
475//         } else {
476//             throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, options.format);
477//         }
478//     }
479//     return dataset;
480// }
481
482// /**
483//  * Outputs the RDF dataset found in the given JSON-LD object.
484//  *
485//  * @param input
486//  *            the JSON-LD input.
487//  * @param options
488//  *            the options to use: [base] the base IRI to use. [format] the
489//  *            format to use to output a string: 'application/nquads' for
490//  *            N-Quads (default). [loadContext(url, callback(err, url,
491//  *            result))] the context loader.
492//  * @return A JSON-LD object.
493//  * @throws JsonLdError
494//  *             If there is an error converting the dataset to JSON-LD.
495//  */
496// public static Object toRDF(Object input, JsonLdOptions options) throws JsonLdError {
497//     return toRDF(input, null, options);
498// }
499
500// /**
501//  * Outputs the RDF dataset found in the given JSON-LD object, using the
502//  * default {@link JsonLdOptions}.
503//  *
504//  * @param input
505//  *            the JSON-LD input.
506//  * @param callback
507//  *            A callback that is called when the input has been converted to
508//  *            Quads (null to use options.format instead).
509//  * @return A JSON-LD object.
510//  * @throws JsonLdError
511//  *             If there is an error converting the dataset to JSON-LD.
512//  */
513// public static Object toRDF(Object input, JsonLdTripleCallback callback) throws JsonLdError {
514//     return toRDF(input, callback, new JsonLdOptions(""));
515// }
516
517// /**
518//  * Outputs the RDF dataset found in the given JSON-LD object, using the
519//  * default {@link JsonLdOptions}.
520//  *
521//  * @param input
522//  *            the JSON-LD input.
523//  * @return A JSON-LD object.
524//  * @throws JsonLdError
525//  *             If there is an error converting the dataset to JSON-LD.
526//  */
527// public static Object toRDF(Object input) throws JsonLdError {
528//     return toRDF(input, new JsonLdOptions(""));
529// }
530
531// /**
532//  * Performs RDF dataset normalization on the given JSON-LD input. The output
533//  * is an RDF dataset unless the 'format' option is used.
534//  *
535//  * @param input
536//  *            the JSON-LD input to normalize.
537//  * @param options
538//  *            the options to use: [base] the base IRI to use. [format] the
539//  *            format if output is a string: 'application/nquads' for
540//  *            N-Quads. [loadContext(url, callback(err, url, result))] the
541//  *            context loader.
542//  * @return The JSON-LD object
543//  * @throws JsonLdError
544//  *             If there is an error normalizing the dataset.
545//  */
546// public static Object normalize(Object input, JsonLdOptions options) throws JsonLdError {
547
548//     final JsonLdOptions opts = new JsonLdOptions(options.getBase());
549//     opts.format = null;
550//     final RDFDataset dataset = (RDFDataset) toRDF(input, opts);
551
552//     return new JsonLdApi(options).normalize(dataset);
553// }
554
555// /**
556//  * Performs RDF dataset normalization on the given JSON-LD input. The output
557//  * is an RDF dataset unless the 'format' option is used. Uses the default
558//  * {@link JsonLdOptions}.
559//  *
560//  * @param input
561//  *            the JSON-LD input to normalize.
562//  * @return The JSON-LD object
563//  * @throws JsonLdError
564//  *             If there is an error normalizing the dataset.
565//  */
566// public static Object normalize(Object input) throws JsonLdError {
567//     return normalize(input, new JsonLdOptions(""));
568// }
569