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 static com.github.jsonldjava.utils.Obj.newMap;
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;
/**
* 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(JsonLdConsts.CONTEXT)) {
context = ((Map) context).get(JsonLdConsts.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 = newMap();
} else {
final Map tmp = newMap();
// TODO: SPEC: doesn't specify to use vocab = true here
tmp.put(activeCtx.compactIri(JsonLdConsts.GRAPH, true), compacted);
compacted = tmp;
}
}
if (compacted != null) {
final Object returnedContext = returnedContext(context, opts);
if(returnedContext != null) {
// TODO: figure out if we can make "@context" appear at the start of
// the keySet
((Map) compacted).put(JsonLdConsts.CONTEXT, returnedContext);
}
}
// 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.getDocument();
// TODO: figure out how to deal with remote context
} catch (final Exception e) {
throw new JsonLdError(Error.LOADING_DOCUMENT_FAILED, e);
}
// 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(JsonLdConsts.CONTEXT)) {
exCtx = ((Map) exCtx).get(JsonLdConsts.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(JsonLdConsts.GRAPH)
&& ((Map) expanded).size() == 1) {
expanded = ((Map) expanded).get(JsonLdConsts.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(JsonLdConsts.CONTEXT)) {
context = ((Map) context).get(JsonLdConsts.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 = newMap();
nodeMap.put(JsonLdConsts.DEFAULT, newMap());
// 2)
new JsonLdApi(opts).generateNodeMap(expanded, nodeMap);
// 3)
final Map defaultGraph = (Map) nodeMap
.remove(JsonLdConsts.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 = newMap();
entry.put(JsonLdConsts.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(JsonLdConsts.GRAPH)) {
entry.put(JsonLdConsts.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(JsonLdConsts.ID) && node.size() == 1)) {
((List) entry.get(JsonLdConsts.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(JsonLdConsts.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(JsonLdConsts.GRAPH);
final Map rval = newMap();
final Object returnedContext = returnedContext(context, opts);
if(returnedContext != null) {
rval.put(JsonLdConsts.CONTEXT, returnedContext);
}
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
// 2. Set expanded input to the result of using the expand method using
// input and options.
final Object expandedInput = expand(input, opts);
// 3. Set expanded frame to the result of using the expand method using
// frame and options with expandContext set to null and the
// frameExpansion option set to true.
final Object savedExpandedContext = opts.getExpandContext();
opts.setExpandContext(null);
opts.setFrameExpansion(true);
final List expandedFrame = expand(frame, opts);
opts.setExpandContext(savedExpandedContext);
// 4. Set context to the value of @context from frame, if it exists, or
// to a new empty
// context, otherwise.
final JsonLdApi api = new JsonLdApi(expandedInput, opts);
final Object context = ((Map) frame).get(JsonLdConsts.CONTEXT);
final Context activeCtx = api.context.parse(context);
final List framed = api.frame(expandedInput, expandedFrame);
if (opts.getPruneBlankNodeIdentifiers()) {
JsonLdUtils.pruneBlankNodes(framed);
}
Object compacted = api.compact(activeCtx, null, framed, opts.getCompactArrays());
final Map rval = newMap();
final Object returnedContext = returnedContext(context, opts);
if(returnedContext != null) {
rval.put(JsonLdConsts.CONTEXT, returnedContext);
}
final boolean addGraph = ((!(compacted instanceof List)) && !opts.getOmitGraph());
if (addGraph && !(compacted instanceof List)) {
final List tmp = new ArrayList();
tmp.add(compacted);
compacted = tmp;
}
if (addGraph || (compacted instanceof List)) {
final String alias = activeCtx.compactIri(JsonLdConsts.GRAPH);
rval.put(alias, compacted);
} else if (!addGraph && (compacted instanceof Map)) {
rval.putAll((Map) compacted);
}
JsonLdUtils.removePreserve(activeCtx, rval, opts);
return rval;
}
/**
* Builds the context to be returned in framing, flattening and compaction algorithms.
* In cases where the context is empty or from an unexpected type, it returns null.
* When JsonLdOptions compactArrays is set to true and the context contains a List with a single element,
* the element is returned instead of the list
*/
private static Object returnedContext(Object context, JsonLdOptions opts) {
if (context != null &&
((context instanceof Map && !((Map) context).isEmpty())
|| (context instanceof List && !((List) context).isEmpty())
|| (context instanceof String && !((String) context).isEmpty()))) {
if (context instanceof List && ((List) context).size() == 1
&& opts.getCompactArrays()) {
return ((List) context).get(0);
}
return context;
} else {
return null;
}
}
/**
* 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(JsonLdConsts.APPLICATION_NQUADS, new NQuadRDFParser());
}
};
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 = JsonLdConsts.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 (JsonLdConsts.EXPANDED.equals(options.outputForm)) {
return rval;
} else if (JsonLdConsts.COMPACTED.equals(options.outputForm)) {
return compact(rval, dataset.getContext(), options);
} else if (JsonLdConsts.FLATTENED.equals(options.outputForm)) {
return flatten(rval, dataset.getContext(), options);
} else {
throw new JsonLdError(JsonLdError.Error.UNKNOWN_ERROR,
"Output form was unknown: " + options.outputForm);
}
}
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 The result of executing
* {@link JsonLdTripleCallback#call(RDFDataset)} on the results, or
* if {@link JsonLdOptions#format} is not null, a result in that
* format if it is found, or otherwise the raw {@link RDFDataset}.
* @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(JsonLdConsts.CONTEXT)) {
dataset.parseContext(e.get(JsonLdConsts.CONTEXT));
}
}
}
if (callback != null) {
return callback.call(dataset);
}
if (options.format != null) {
if (JsonLdConsts.APPLICATION_NQUADS.equals(options.format)) {
return new NQuadTripleCallback().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 = options.copy();
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(""));
}
}