package ru.semiot.commons.rdf; import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.JsonLdOptions; import com.github.jsonldjava.core.JsonLdProcessor; import com.github.jsonldjava.utils.JsonUtils; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import net.minidev.json.JSONArray; import org.apache.commons.lang3.StringUtils; import org.apache.jena.rdf.model.Model; import org.apache.jena.riot.Lang; import java.io.IOException; import java.io.StringWriter; import java.util.Map; public class ModelJsonLdUtils { private static final JsonLdOptions DEFAULT_OPTIONS = new JsonLdOptions(); private static final String JSONPATH_BN_OBJECTS = "$..[?(@.@id =~ /_:.*/i)]"; private static final String JSONLD_KEY_ID = "@id"; public static Object toJsonLd(Model model) throws IOException { StringWriter writer = new StringWriter(); model.write(writer, Lang.JSONLD.getName()); return JsonUtils.fromString(writer.toString()); } public static Object toJsonLdCompact(Model model, Object frame) throws JsonLdError, IOException { return deleteRedundantBNIds(JsonLdProcessor.compact(JsonLdProcessor.frame( ModelJsonLdUtils.toJsonLd(model), frame, DEFAULT_OPTIONS), frame, DEFAULT_OPTIONS)); } public static Object deleteRedundantBNIds(Object json) throws IOException { String json_str = JsonUtils.toString(json); DocumentContext path = JsonPath.parse(json); JSONArray bnResources = path.read(JSONPATH_BN_OBJECTS); bnResources.stream() .map((resource) -> (Map<String, Object>) resource) .map((Map<String, Object> m) -> (String) m.get(JSONLD_KEY_ID)) .filter((bnId) -> (StringUtils.countMatches(json_str, "\"" + bnId + "\"") < 2)) .forEach((bnId) -> path.delete("$..*[?(@.@id=~/" + bnId + "/i)].@id")); return path.json(); } }