org.eclipse.rdf4j.rio.helpers.RDFStarUtil Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2020 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.rio.helpers;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Triple;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
/**
* Utility methods for RDF-star triples.
*
* @author Pavel Mihaylov
*/
public class RDFStarUtil {
/**
* IRI prefix for RDF-star triples encoded as IRIs.
*/
public static final String TRIPLE_PREFIX = "urn:rdf4j:triple:";
private static final ValueFactory VF = SimpleValueFactory.getInstance();
/**
* Converts the supplied value from RDF-star to an RDF-compatible representation.
*
* RDF-star triples are encoded as IRIs that start with {@link #TRIPLE_PREFIX}, followed by the base64 encoding of
* the N-Triples serialization of the triple.
*
* All other RDF-star values are valid in RDF as well and remain unchanged.
*
* @param value a RDF-star {@link Value} to encode.
* @param
* @return the RDF-compatible encoded value, if a {@link Triple} was supplied, or the supplied value otherwise.
*/
public static T toRDFEncodedValue(T value) {
return value instanceof Triple
? (T) VF.createIRI(TRIPLE_PREFIX + encode(NTriplesUtil.toNTriplesString(value)))
: value;
}
/**
* Converts the supplied value from an RDF-compatible representation to an RDF-star value.
*
* See {@link #toRDFEncodedValue(Value)}.
*
* @param encodedValue an RDF {@link Value} to convert to RDF-star.
* @param
* @return the decoded RDF-star triple, if a {@link Triple} encoded as {@link IRI} was supplied, or the supplied
* value otherwise.
* @throws IllegalArgumentException if the supplied value looked like an RDF-star triple encoded as an IRI but it
* could not be decoded successfully.
*/
public static T fromRDFEncodedValue(T encodedValue) {
try {
return isEncodedTriple(encodedValue)
? (T) NTriplesUtil.parseTriple(decode(
encodedValue.stringValue().substring(TRIPLE_PREFIX.length())), VF)
: encodedValue;
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid RDF-star encoded triple: " + encodedValue);
}
}
/**
* Converts the supplied value from an RDF-compatible representation to an RDF-star value.
*
* See {@link #toRDFEncodedValue(Value)}.
*
* @param encodedValue an RDF {@link Value} to convert to RDF-star.
* @param valueFactory the {@link ValueFactory} to use for parsing the triple.
* @param
* @return the decoded RDF-star triple, if a {@link Triple} encoded as {@link IRI} was supplied, or the supplied
* value otherwise.
* @throws IllegalArgumentException if the supplied value looked like an RDF-star triple encoded as an IRI but it
* could not be decoded successfully.
*/
public static T fromRDFEncodedValue(T encodedValue, ValueFactory valueFactory) {
try {
return isEncodedTriple(encodedValue)
? (T) NTriplesUtil.parseTriple(decode(
encodedValue.stringValue().substring(TRIPLE_PREFIX.length())), valueFactory)
: encodedValue;
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid RDF-star encoded triple: " + encodedValue);
}
}
/**
* Checks if the supplied {@link Value} represents an RDF-star triple encoded as an IRI.
*
* @param value the value to check.
* @return True if the value is an RDF-star triple encoded as an IRI, false otherwise.
*/
public static boolean isEncodedTriple(Value value) {
return value instanceof IRI && value.stringValue().startsWith(TRIPLE_PREFIX);
}
private static String encode(String s) {
return Base64.getUrlEncoder().encodeToString(s.getBytes(StandardCharsets.UTF_8));
}
private static String decode(String s) {
return new String(Base64.getUrlDecoder().decode(s), StandardCharsets.UTF_8);
}
}