Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.jsonldjava.core.JsonLdProcessor Maven / Gradle / Ivy
package com.github.jsonldjava.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.github.jsonldjava.core.JsonLdError.Error;
import com.github.jsonldjava.impl.NQuadRDFParser;
import com.github.jsonldjava.impl.NQuadTripleCallback;
import com.github.jsonldjava.impl.TurtleRDFParser;
import com.github.jsonldjava.impl.TurtleTripleCallback;
/**
* This class implements the JsonLdProcessor interface , except that it does not currently support
* asynchronous processing, and hence does not return Promises, instead directly
* returning the results.
*
* @author tristan
*
*/
public class JsonLdProcessor {
/**
* Compacts the given input using the context according to the steps in the
*
* Compaction algorithm .
*
* @param input
* The input JSON-LD object.
* @param context
* The context object to use for the compaction algorithm.
* @param opts
* The {@link JsonLdOptions} that are to be sent to the
* compaction algorithm.
* @return The compacted JSON-LD document
* @throws JsonLdError
* If there is an error while compacting.
*/
public static Map compact(Object input, Object context, JsonLdOptions opts)
throws JsonLdError {
// 1)
// TODO: look into java futures/promises
// 2-6) NOTE: these are all the same steps as in expand
final Object expanded = expand(input, opts);
// 7)
if (context instanceof Map && ((Map) context).containsKey("@context")) {
context = ((Map) context).get("@context");
}
Context activeCtx = new Context(opts);
activeCtx = activeCtx.parse(context);
// 8)
Object compacted = new JsonLdApi(opts).compact(activeCtx, null, expanded,
opts.getCompactArrays());
// final step of Compaction Algorithm
// TODO: SPEC: the result result is a NON EMPTY array,
if (compacted instanceof List) {
if (((List) compacted).isEmpty()) {
compacted = new LinkedHashMap();
} else {
final Map tmp = new LinkedHashMap();
// TODO: SPEC: doesn't specify to use vocab = true here
tmp.put(activeCtx.compactIri("@graph", true), compacted);
compacted = tmp;
}
}
if (compacted != null && context != null) {
// TODO: figure out if we can make "@context" appear at the start of
// the keySet
if ((context instanceof Map && !((Map) context).isEmpty())
|| (context instanceof List && !((List) context).isEmpty())) {
((Map) compacted).put("@context", context);
}
}
// 9)
return (Map) compacted;
}
/**
* Expands the given input according to the steps in the Expansion
* algorithm .
*
* @param input
* The input JSON-LD object.
* @param opts
* The {@link JsonLdOptions} that are to be sent to the expansion
* algorithm.
* @return The expanded JSON-LD document
* @throws JsonLdError
* If there is an error while expanding.
*/
public static List expand(Object input, JsonLdOptions opts) throws JsonLdError {
// 1)
// TODO: look into java futures/promises
// 2) TODO: better verification of DOMString IRI
if (input instanceof String && ((String) input).contains(":")) {
try {
final RemoteDocument tmp = opts.getDocumentLoader().loadDocument((String) input);
input = tmp.document;
// TODO: figure out how to deal with remote context
} catch (final Exception e) {
throw new JsonLdError(Error.LOADING_DOCUMENT_FAILED, e.getMessage());
}
// if set the base in options should override the base iri in the
// active context
// thus only set this as the base iri if it's not already set in
// options
if (opts.getBase() == null) {
opts.setBase((String) input);
}
}
// 3)
Context activeCtx = new Context(opts);
// 4)
if (opts.getExpandContext() != null) {
Object exCtx = opts.getExpandContext();
if (exCtx instanceof Map && ((Map) exCtx).containsKey("@context")) {
exCtx = ((Map) exCtx).get("@context");
}
activeCtx = activeCtx.parse(exCtx);
}
// 5)
// TODO: add support for getting a context from HTTP when content-type
// is set to a jsonld compatable format
// 6)
Object expanded = new JsonLdApi(opts).expand(activeCtx, input);
// final step of Expansion Algorithm
if (expanded instanceof Map && ((Map) expanded).containsKey("@graph")
&& ((Map) expanded).size() == 1) {
expanded = ((Map) expanded).get("@graph");
} else if (expanded == null) {
expanded = new ArrayList();
}
// normalize to an array
if (!(expanded instanceof List)) {
final List tmp = new ArrayList();
tmp.add(expanded);
expanded = tmp;
}
return (List) expanded;
}
/**
* Expands the given input according to the steps in the Expansion
* algorithm , using the default {@link JsonLdOptions}.
*
* @param input
* The input JSON-LD object.
* @return The expanded JSON-LD document
* @throws JsonLdError
* If there is an error while expanding.
*/
public static List expand(Object input) throws JsonLdError {
return expand(input, new JsonLdOptions(""));
}
public static Object flatten(Object input, Object context, JsonLdOptions opts)
throws JsonLdError {
// 2-6) NOTE: these are all the same steps as in expand
final Object expanded = expand(input, opts);
// 7)
if (context instanceof Map && ((Map) context).containsKey("@context")) {
context = ((Map) context).get("@context");
}
// 8) NOTE: blank node generation variables are members of JsonLdApi
// 9) NOTE: the next block is the Flattening Algorithm described in
// http://json-ld.org/spec/latest/json-ld-api/#flattening-algorithm
// 1)
final Map nodeMap = new LinkedHashMap();
nodeMap.put("@default", new LinkedHashMap());
// 2)
new JsonLdApi(opts).generateNodeMap(expanded, nodeMap);
// 3)
final Map defaultGraph = (Map) nodeMap.remove("@default");
// 4)
for (final String graphName : nodeMap.keySet()) {
final Map graph = (Map) nodeMap.get(graphName);
// 4.1+4.2)
Map entry;
if (!defaultGraph.containsKey(graphName)) {
entry = new LinkedHashMap();
entry.put("@id", graphName);
defaultGraph.put(graphName, entry);
} else {
entry = (Map) defaultGraph.get(graphName);
}
// 4.3)
// TODO: SPEC doesn't specify that this should only be added if it
// doesn't exists
if (!entry.containsKey("@graph")) {
entry.put("@graph", new ArrayList());
}
final List keys = new ArrayList(graph.keySet());
Collections.sort(keys);
for (final String id : keys) {
final Map node = (Map) graph.get(id);
if (!(node.containsKey("@id") && node.size() == 1)) {
((List) entry.get("@graph")).add(node);
}
}
}
// 5)
final List flattened = new ArrayList();
// 6)
final List keys = new ArrayList(defaultGraph.keySet());
Collections.sort(keys);
for (final String id : keys) {
final Map node = (Map) defaultGraph.get(id);
if (!(node.containsKey("@id") && node.size() == 1)) {
flattened.add(node);
}
}
// 8)
if (context != null && !flattened.isEmpty()) {
Context activeCtx = new Context(opts);
activeCtx = activeCtx.parse(context);
// TODO: only instantiate one jsonldapi
Object compacted = new JsonLdApi(opts).compact(activeCtx, null, flattened,
opts.getCompactArrays());
if (!(compacted instanceof List)) {
final List tmp = new ArrayList();
tmp.add(compacted);
compacted = tmp;
}
final String alias = activeCtx.compactIri("@graph");
final Map rval = activeCtx.serialize();
rval.put(alias, compacted);
return rval;
}
return flattened;
}
/**
* Flattens the given input and compacts it using the passed context
* according to the steps in the Flattening
* algorithm :
*
* @param input
* The input JSON-LD object.
* @param opts
* The {@link JsonLdOptions} that are to be sent to the
* flattening algorithm.
* @return The flattened JSON-LD document
* @throws JsonLdError
* If there is an error while flattening.
*/
public static Object flatten(Object input, JsonLdOptions opts) throws JsonLdError {
return flatten(input, null, opts);
}
/**
* Frames the given input using the frame according to the steps in the
* Framing Algorithm .
*
* @param input
* The input JSON-LD object.
* @param frame
* The frame to use when re-arranging the data of input; either
* in the form of an JSON object or as IRI.
* @param opts
* The {@link JsonLdOptions} that are to be sent to the framing
* algorithm.
* @return The framed JSON-LD document
* @throws JsonLdError
* If there is an error while framing.
*/
public static Map frame(Object input, Object frame, JsonLdOptions opts)
throws JsonLdError {
if (frame instanceof Map) {
frame = JsonLdUtils.clone(frame);
}
// TODO string/IO input
final Object expandedInput = expand(input, opts);
final List expandedFrame = expand(frame, opts);
final JsonLdApi api = new JsonLdApi(expandedInput, opts);
final List framed = api.frame(expandedInput, expandedFrame);
final Context activeCtx = api.context.parse(((Map) frame).get("@context"));
Object compacted = api.compact(activeCtx, null, framed);
if (!(compacted instanceof List)) {
final List tmp = new ArrayList();
tmp.add(compacted);
compacted = tmp;
}
final String alias = activeCtx.compactIri("@graph");
final Map rval = activeCtx.serialize();
rval.put(alias, compacted);
JsonLdUtils.removePreserve(activeCtx, rval, opts);
return rval;
}
/**
* A registry for RDF Parsers (in this case, JSONLDSerializers) used by
* fromRDF if no specific serializer is specified and options.format is set.
*
* TODO: this would fit better in the document loader class
*/
private static Map rdfParsers = new LinkedHashMap() {
{
// automatically register nquad serializer
put("application/nquads", new NQuadRDFParser());
put("text/turtle", new TurtleRDFParser());
}
};
public static void registerRDFParser(String format, RDFParser parser) {
rdfParsers.put(format, parser);
}
public static void removeRDFParser(String format) {
rdfParsers.remove(format);
}
/**
* Converts an RDF dataset to JSON-LD.
*
* @param dataset
* a serialized string of RDF in a format specified by the format
* option or an RDF dataset to convert.
* @param options
* the options to use: [format] the format if input is not an
* array: 'application/nquads' for N-Quads (default).
* [useRdfType] true to use rdf:type, false to use @type
* (default: false). [useNativeTypes] true to convert XSD types
* into native types (boolean, integer, double), false not to
* (default: true).
* @return A JSON-LD object.
* @throws JsonLdError
* If there is an error converting the dataset to JSON-LD.
*/
public static Object fromRDF(Object dataset, JsonLdOptions options) throws JsonLdError {
// handle non specified serializer case
RDFParser parser = null;
if (options.format == null && dataset instanceof String) {
// attempt to parse the input as nquads
options.format = "application/nquads";
}
if (rdfParsers.containsKey(options.format)) {
parser = rdfParsers.get(options.format);
} else {
throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, options.format);
}
// convert from RDF
return fromRDF(dataset, options, parser);
}
/**
* Converts an RDF dataset to JSON-LD, using the default
* {@link JsonLdOptions}.
*
* @param dataset
* a serialized string of RDF in a format specified by the format
* option or an RDF dataset to convert.
* @return The JSON-LD object represented by the given RDF dataset
* @throws JsonLdError
* If there was an error converting from RDF to JSON-LD
*/
public static Object fromRDF(Object dataset) throws JsonLdError {
return fromRDF(dataset, new JsonLdOptions(""));
}
/**
* Converts an RDF dataset to JSON-LD, using a specific instance of
* {@link RDFParser}.
*
* @param input
* a serialized string of RDF in a format specified by the format
* option or an RDF dataset to convert.
* @param options
* the options to use: [format] the format if input is not an
* array: 'application/nquads' for N-Quads (default).
* [useRdfType] true to use rdf:type, false to use @type
* (default: false). [useNativeTypes] true to convert XSD types
* into native types (boolean, integer, double), false not to
* (default: true).
* @param parser
* A specific instance of {@link RDFParser} to use for the
* conversion.
* @return A JSON-LD object.
* @throws JsonLdError
* If there is an error converting the dataset to JSON-LD.
*/
public static Object fromRDF(Object input, JsonLdOptions options, RDFParser parser)
throws JsonLdError {
final RDFDataset dataset = parser.parse(input);
// convert from RDF
final Object rval = new JsonLdApi(options).fromRDF(dataset);
// re-process using the generated context if outputForm is set
if (options.outputForm != null) {
if ("expanded".equals(options.outputForm)) {
return rval;
} else if ("compacted".equals(options.outputForm)) {
return compact(rval, dataset.getContext(), options);
} else if ("flattened".equals(options.outputForm)) {
return flatten(rval, dataset.getContext(), options);
} else {
throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR);
}
}
return rval;
}
/**
* Converts an RDF dataset to JSON-LD, using a specific instance of
* {@link RDFParser}, and the default {@link JsonLdOptions}.
*
* @param input
* a serialized string of RDF in a format specified by the format
* option or an RDF dataset to convert.
* @param parser
* A specific instance of {@link RDFParser} to use for the
* conversion.
* @return A JSON-LD object.
* @throws JsonLdError
* If there is an error converting the dataset to JSON-LD.
*/
public static Object fromRDF(Object input, RDFParser parser) throws JsonLdError {
return fromRDF(input, new JsonLdOptions(""), parser);
}
/**
* Outputs the RDF dataset found in the given JSON-LD object.
*
* @param input
* the JSON-LD input.
* @param callback
* A callback that is called when the input has been converted to
* Quads (null to use options.format instead).
* @param options
* the options to use: [base] the base IRI to use. [format] the
* format to use to output a string: 'application/nquads' for
* N-Quads (default). [loadContext(url, callback(err, url,
* result))] the context loader.
* @return A JSON-LD object.
* @throws JsonLdError
* If there is an error converting the dataset to JSON-LD.
*/
public static Object toRDF(Object input, JsonLdTripleCallback callback, JsonLdOptions options)
throws JsonLdError {
final Object expandedInput = expand(input, options);
final JsonLdApi api = new JsonLdApi(expandedInput, options);
final RDFDataset dataset = api.toRDF();
// generate namespaces from context
if (options.useNamespaces) {
List> _input;
if (input instanceof List) {
_input = (List>) input;
} else {
_input = new ArrayList>();
_input.add((Map) input);
}
for (final Map e : _input) {
if (e.containsKey("@context")) {
dataset.parseContext(e.get("@context"));
}
}
}
if (callback != null) {
return callback.call(dataset);
}
if (options.format != null) {
if ("application/nquads".equals(options.format)) {
return new NQuadTripleCallback().call(dataset);
} else if ("text/turtle".equals(options.format)) {
return new TurtleTripleCallback().call(dataset);
} else {
throw new JsonLdError(JsonLdError.Error.UNKNOWN_FORMAT, options.format);
}
}
return dataset;
}
/**
* Outputs the RDF dataset found in the given JSON-LD object.
*
* @param input
* the JSON-LD input.
* @param options
* the options to use: [base] the base IRI to use. [format] the
* format to use to output a string: 'application/nquads' for
* N-Quads (default). [loadContext(url, callback(err, url,
* result))] the context loader.
* @return A JSON-LD object.
* @throws JsonLdError
* If there is an error converting the dataset to JSON-LD.
*/
public static Object toRDF(Object input, JsonLdOptions options) throws JsonLdError {
return toRDF(input, null, options);
}
/**
* Outputs the RDF dataset found in the given JSON-LD object, using the
* default {@link JsonLdOptions}.
*
* @param input
* the JSON-LD input.
* @param callback
* A callback that is called when the input has been converted to
* Quads (null to use options.format instead).
* @return A JSON-LD object.
* @throws JsonLdError
* If there is an error converting the dataset to JSON-LD.
*/
public static Object toRDF(Object input, JsonLdTripleCallback callback) throws JsonLdError {
return toRDF(input, callback, new JsonLdOptions(""));
}
/**
* Outputs the RDF dataset found in the given JSON-LD object, using the
* default {@link JsonLdOptions}.
*
* @param input
* the JSON-LD input.
* @return A JSON-LD object.
* @throws JsonLdError
* If there is an error converting the dataset to JSON-LD.
*/
public static Object toRDF(Object input) throws JsonLdError {
return toRDF(input, new JsonLdOptions(""));
}
/**
* Performs RDF dataset normalization on the given JSON-LD input. The output
* is an RDF dataset unless the 'format' option is used.
*
* @param input
* the JSON-LD input to normalize.
* @param options
* the options to use: [base] the base IRI to use. [format] the
* format if output is a string: 'application/nquads' for
* N-Quads. [loadContext(url, callback(err, url, result))] the
* context loader.
* @return The JSON-LD object
* @throws JsonLdError
* If there is an error normalizing the dataset.
*/
public static Object normalize(Object input, JsonLdOptions options) throws JsonLdError {
final JsonLdOptions opts = new JsonLdOptions(options.getBase());
opts.format = null;
final RDFDataset dataset = (RDFDataset) toRDF(input, opts);
return new JsonLdApi(options).normalize(dataset);
}
/**
* Performs RDF dataset normalization on the given JSON-LD input. The output
* is an RDF dataset unless the 'format' option is used. Uses the default
* {@link JsonLdOptions}.
*
* @param input
* the JSON-LD input to normalize.
* @return The JSON-LD object
* @throws JsonLdError
* If there is an error normalizing the dataset.
*/
public static Object normalize(Object input) throws JsonLdError {
return normalize(input, new JsonLdOptions(""));
}
}