| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.rdf.rdf4j; |
| |
| import java.util.Arrays; |
| import java.util.EnumSet; |
| import java.util.Objects; |
| import java.util.Set; |
| import java.util.UUID; |
| |
| // To avoid confusion, avoid importing |
| // classes that are in both |
| // commons.rdf and openrdf.model (e.g. IRI, Literal) |
| import org.apache.commons.rdf.api.BlankNode; |
| import org.apache.commons.rdf.api.BlankNodeOrIRI; |
| import org.apache.commons.rdf.api.Dataset; |
| import org.apache.commons.rdf.api.Graph; |
| import org.apache.commons.rdf.api.Quad; |
| import org.apache.commons.rdf.api.RDFTerm; |
| import org.apache.commons.rdf.api.RDF; |
| import org.apache.commons.rdf.api.Triple; |
| import org.apache.commons.rdf.api.TripleLike; |
| import org.apache.commons.rdf.rdf4j.impl.InternalRDF4JFactory; |
| import org.eclipse.rdf4j.model.BNode; |
| import org.eclipse.rdf4j.model.IRI; |
| import org.eclipse.rdf4j.model.Literal; |
| import org.eclipse.rdf4j.model.Model; |
| import org.eclipse.rdf4j.model.Resource; |
| import org.eclipse.rdf4j.model.Statement; |
| import org.eclipse.rdf4j.model.Value; |
| import org.eclipse.rdf4j.model.ValueFactory; |
| import org.eclipse.rdf4j.model.impl.LinkedHashModel; |
| import org.eclipse.rdf4j.model.impl.SimpleValueFactory; |
| import org.eclipse.rdf4j.repository.Repository; |
| import org.eclipse.rdf4j.repository.RepositoryConnection; |
| import org.eclipse.rdf4j.repository.sail.SailRepository; |
| import org.eclipse.rdf4j.sail.Sail; |
| import org.eclipse.rdf4j.sail.memory.MemoryStore; |
| |
| /** |
| * RDF4J implementation of RDF. |
| * <p> |
| * The {@link #RDF4J()} constructor uses a {@link SimpleValueFactory} to create |
| * corresponding RDF4J {@link Value} instances. Alternatively, this factory can |
| * be constructed with a different {@link ValueFactory} using |
| * {@link #RDF4J(ValueFactory)}. |
| * <p> |
| * {@link #asRDFTerm(Value)} can be used to convert any RDF4J {@link Value} to |
| * an RDFTerm. Note that adapted {@link BNode}s are considered equal if they are |
| * converted with the same {@link RDF4J} instance and have the same |
| * {@link BNode#getID()}. |
| * <p> |
| * {@link #createGraph()} creates a new Graph backed by {@link LinkedHashModel}. |
| * To use other models, see {@link #asGraph(Model)}. |
| * <p> |
| * To adapt a RDF4J {@link Repository} as a {@link Dataset} or {@link Graph}, |
| * use {@link #asDataset(Repository, Option...)} or |
| * {@link #asGraph(Repository, Option...)}. |
| * <p> |
| * {@link #asTriple(Statement)} can be used to convert a RDF4J {@link Statement} |
| * to a Commons RDF {@link Triple}, and equivalent {@link #asQuad(Statement)} to |
| * convert a {@link Quad}. |
| * <p> |
| * To convert any {@link Triple} or {@link Quad} to to RDF4J {@link Statement}, |
| * use {@link #asStatement(TripleLike)}. This recognises previously converted |
| * {@link RDF4JTriple}s and {@link RDF4JQuad}s without re-converting their |
| * {@link RDF4JTripleLike#asStatement()}. |
| * <p> |
| * Likewise, {@link #asValue(RDFTerm)} can be used to convert any Commons RDF |
| * {@link RDFTerm} to a corresponding RDF4J {@link Value}. This recognises |
| * previously converted {@link RDF4JTerm}s without re-converting their |
| * {@link RDF4JTerm#asValue()}. |
| * <p> |
| * For the purpose of {@link BlankNode} equivalence, this factory contains an |
| * internal {@link UUID} salt that is used by adapter methods like |
| * {@link #asQuad(Statement)}, {@link #asTriple(Statement)}, |
| * {@link #asRDFTerm(Value)} as well as {@link #createBlankNode(String)}. As |
| * RDF4J {@link BNode} instances from multiple repositories or models may have |
| * the same {@link BNode#getID()}, converting them with the above methods might |
| * cause accidental {@link BlankNode} equivalence. Note that the {@link Graph} |
| * and {@link Dataset} adapter methods like |
| * {@link #asDataset(Repository, Option...)} and |
| * {@link #asGraph(Repository, Option...)} therefore uses a unique {@link RDF4J} |
| * internally. |
| * |
| * @see RDF |
| * |
| */ |
| @SuppressWarnings("PMD.UnnecessaryFullyQualifiedName") // we use fully-qualified names for clarity |
| public final class RDF4J implements RDF { |
| |
| /** |
| * InternalRDF4JFactory is deliberately abstract |
| */ |
| private static final InternalRDF4JFactory RDF4J = new InternalRDF4JFactory() { |
| }; |
| |
| public enum Option { |
| /** |
| * The Graph/Dataset should include any inferred statements |
| */ |
| includeInferred, |
| /** |
| * The graph/dataset should handle {@link Repository#initialize()} (if |
| * needed) and {@link Repository#shutDown()} on {@link Graph#close()} / |
| * {@link Dataset#close()}. |
| */ |
| handleInitAndShutdown |
| } |
| |
| private final UUID salt; |
| |
| private final ValueFactory valueFactory; |
| |
| /** |
| * Construct an {@link RDF4J}. |
| * |
| */ |
| public RDF4J() { |
| this(SimpleValueFactory.getInstance(), UUID.randomUUID()); |
| } |
| |
| /** |
| * Construct an {@link RDF4J}. |
| * <p> |
| * This constructor is intended for use with the value factory from |
| * {@link Repository#getValueFactory()} when using Repository-based graphs |
| * and datasets. |
| * |
| * @param valueFactory |
| * The RDF4J {@link ValueFactory} to use |
| */ |
| public RDF4J(final ValueFactory valueFactory) { |
| this(valueFactory, UUID.randomUUID()); |
| } |
| |
| /** |
| * Construct an {@link RDF4J}. |
| * <p> |
| * This constructor may be used if reproducible |
| * {@link BlankNode#uniqueReference()} in {@link BlankNode} is desirable. |
| * |
| * @param salt |
| * An {@link UUID} salt to be used by any created |
| * {@link BlankNode}s for the purpose of |
| * {@link BlankNode#uniqueReference()} |
| */ |
| public RDF4J(final UUID salt) { |
| this(SimpleValueFactory.getInstance(), salt); |
| } |
| |
| /** |
| * Construct an {@link RDF4J}. |
| * <p> |
| * This constructor may be used if reproducible |
| * {@link BlankNode#uniqueReference()} in {@link BlankNode} is desirable. |
| * |
| * @param valueFactory |
| * The RDF4J {@link ValueFactory} to use |
| * @param salt |
| * An {@link UUID} salt to be used by any created |
| * {@link BlankNode}s for the purpose of |
| * {@link BlankNode#uniqueReference()} |
| */ |
| public RDF4J(final ValueFactory valueFactory, final UUID salt) { |
| this.valueFactory = valueFactory; |
| this.salt = salt; |
| } |
| |
| /** |
| * Adapt a RDF4J {@link Statement} as a Commons RDF {@link Quad}. |
| * <p> |
| * For the purpose of {@link BlankNode} equivalence, this method will use an |
| * internal salt UUID that is unique per instance of {@link RDF4J}. |
| * <p> |
| * <strong>NOTE:</strong> If combining RDF4J {@link Statement}s multiple |
| * repositories or models, then their {@link BNode}s may have the same |
| * {@link BNode#getID()}, which with this method would become equivalent |
| * according to {@link BlankNode#equals(Object)} and |
| * {@link BlankNode#uniqueReference()}, unless a separate {@link RDF4J} |
| * instance is used per RDF4J repository/model. |
| * |
| * @param statement |
| * The statement to convert |
| * @return A {@link RDF4JQuad} that is equivalent to the statement |
| */ |
| public RDF4JQuad asQuad(final Statement statement) { |
| return RDF4J.createQuadImpl(statement, salt); |
| } |
| |
| /** |
| * |
| * Adapt a RDF4J {@link Value} as a Commons RDF {@link RDFTerm}. |
| * <p> |
| * The value will be of the same kind as the term, e.g. a |
| * {@link org.eclipse.rdf4j.model.BNode} is converted to a |
| * {@link org.apache.commons.rdf.api.BlankNode}, a |
| * {@link org.eclipse.rdf4j.model.IRI} is converted to a |
| * {@link org.apache.commons.rdf.api.IRI} and a |
| * {@link org.eclipse.rdf4j.model.Literal}. is converted to a |
| * {@link org.apache.commons.rdf.api.Literal} |
| * <p> |
| * For the purpose of {@link BlankNode} equivalence, this method will use an |
| * internal salt UUID that is unique per instance of {@link RDF4J}. |
| * <p> |
| * <strong>NOTE:</strong> If combining RDF4J values from multiple |
| * repositories or models, then their {@link BNode}s may have the same |
| * {@link BNode#getID()}, which with this method would become equivalent |
| * according to {@link BlankNode#equals(Object)} and |
| * {@link BlankNode#uniqueReference()}, unless a separate {@link RDF4J} |
| * instance is used per RDF4J repository/model. |
| * |
| * @param value |
| * The RDF4J {@link Value} to convert. |
| * @return A {@link RDFTerm} that corresponds to the RDF4J value |
| * @throws IllegalArgumentException |
| * if the value is not a BNode, Literal or IRI |
| */ |
| public RDF4JTerm asRDFTerm(final Value value) { |
| return asRDFTerm(value, salt); |
| } |
| |
| /** |
| * |
| * Adapt a RDF4J |
| * {@link org.eclipse.rdf4j.model.BNode} as a Commons RDF |
| * {@link org.apache.commons.rdf.api.BlankNode} |
| * <p> |
| * For the purpose of {@link BlankNode} equivalence, this method will use an |
| * internal salt UUID that is unique per instance of {@link RDF4J}. |
| * <p> |
| * <strong>NOTE:</strong> If combining RDF4J values from multiple |
| * repositories or models, then their {@link BNode}s may have the same |
| * {@link BNode#getID()}, which with this method would become equivalent |
| * according to {@link BlankNode#equals(Object)} and |
| * {@link BlankNode#uniqueReference()}, unless a separate {@link RDF4J} |
| * instance is used per RDF4J repository/model. |
| * |
| * @param value |
| * The RDF4J {@link BNode} to convert. |
| * @return A {@link RDF4JBlankNode} that corresponds to the RDF4J BNode |
| */ |
| public RDF4JBlankNode asRDFTerm(final BNode value) { |
| return RDF4J.createBlankNodeImpl(value, salt); |
| } |
| |
| /** |
| * |
| * Adapt a RDF4J |
| * {@link org.eclipse.rdf4j.model.Literal} as a Commons RDF |
| * {@link org.apache.commons.rdf.api.Literal} |
| * <p> |
| * @param value |
| * The RDF4J {@link Literal} to convert. |
| * @return A {@link RDF4JLiteral} that corresponds to the RDF4J literal |
| */ |
| public RDF4JLiteral asRDFTerm(final Literal value) { |
| return RDF4J.createLiteralImpl(value); |
| } |
| |
| /** |
| * |
| * Adapt a RDF4J |
| * {@link org.eclipse.rdf4j.model.IRI} as a Commons RDF |
| * {@link org.apache.commons.rdf.api.IRI} |
| * <p> |
| * @param value |
| * The RDF4J {@link Value} to convert. |
| * @return A {@link RDF4JIRI} that corresponds to the RDF4J IRI |
| */ |
| public RDF4JIRI asRDFTerm(final org.eclipse.rdf4j.model.IRI value) { |
| return RDF4J.createIRIImpl(value); |
| } |
| |
| /** |
| * |
| * Adapt a RDF4J |
| * {@link org.eclipse.rdf4j.model.Resource} as a Commons RDF |
| * {@link org.apache.commons.rdf.api.BlankNodeOrIRI} |
| * <p> |
| * @param value |
| * The RDF4J {@link Value} to convert. |
| * @return A {@link RDF4JBlankNodeOrIRI} that corresponds to the RDF4J Resource |
| */ |
| public RDF4JBlankNodeOrIRI asRDFTerm(final org.eclipse.rdf4j.model.Resource value) { |
| if(value instanceof IRI){ |
| return asRDFTerm((IRI)value); |
| } else if (value instanceof BNode){ |
| return asRDFTerm((BNode)value); |
| } |
| throw new IllegalArgumentException("Value is not a BNode or IRI: " + value.getClass()); |
| } |
| |
| /** |
| * Adapt a RDF4J {@link Value} as a Commons RDF {@link RDFTerm}. |
| * <p> |
| * The value will be of the same kind as the term, e.g. a |
| * {@link org.eclipse.rdf4j.model.BNode} is converted to a |
| * {@link org.apache.commons.rdf.api.BlankNode}, a |
| * {@link org.eclipse.rdf4j.model.IRI} is converted to a |
| * {@link org.apache.commons.rdf.api.IRI} and a |
| * {@link org.eclipse.rdf4j.model.Literal}. is converted to a |
| * {@link org.apache.commons.rdf.api.Literal} |
| * |
| * @param value |
| * The RDF4J {@link Value} to convert. |
| * @param salt |
| * A {@link UUID} salt to use for uniquely mapping any |
| * {@link BNode}s. The salt should typically be the same for |
| * multiple statements in the same {@link Repository} or |
| * {@link Model} to ensure {@link BlankNode#equals(Object)} and |
| * {@link BlankNode#uniqueReference()} works as intended. |
| * @return A {@link RDFTerm} that corresponds to the RDF4J value |
| * @throws IllegalArgumentException |
| * if the value is not a BNode, Literal or IRI |
| */ |
| public static RDF4JTerm asRDFTerm(final Value value, final UUID salt) { |
| if (value instanceof BNode) { |
| return RDF4J.createBlankNodeImpl((BNode) value, salt); |
| } |
| if (value instanceof org.eclipse.rdf4j.model.Literal) { |
| return RDF4J.createLiteralImpl((org.eclipse.rdf4j.model.Literal) value); |
| } |
| if (value instanceof org.eclipse.rdf4j.model.IRI) { |
| return RDF4J.createIRIImpl((org.eclipse.rdf4j.model.IRI) value); |
| } |
| throw new IllegalArgumentException("Value is not a BNode, Literal or IRI: " + value.getClass()); |
| } |
| |
| /** |
| * Adapt an RDF4J {@link Repository} as a Commons RDF {@link Dataset}. |
| * <p> |
| * Changes to the dataset are reflected in the repository, and vice versa. |
| * <p> |
| * <strong>Note:</strong> Some operations on the {@link RDF4JDataset} |
| * requires the use of try-with-resources to close underlying |
| * {@link RepositoryConnection}s, including {@link RDF4JDataset#iterate()}, |
| * {@link RDF4JDataset#stream()} and {@link RDF4JDataset#getGraphNames()}. |
| * |
| * @param repository |
| * RDF4J {@link Repository} to connect to. |
| * @param options |
| * Zero or more {@link Option} |
| * @return A {@link Dataset} backed by the RDF4J repository. |
| */ |
| public RDF4JDataset asDataset(final Repository repository, final Option... options) { |
| final EnumSet<Option> opts = optionSet(options); |
| return RDF4J.createRepositoryDatasetImpl(repository, opts.contains(Option.handleInitAndShutdown), |
| opts.contains(Option.includeInferred)); |
| } |
| |
| /** |
| * Adapt an RDF4J {@link Model} as a Commons RDF {@link Graph}. |
| * <p> |
| * Changes to the graph are reflected in the model, and vice versa. |
| * |
| * @param model |
| * RDF4J {@link Model} to adapt. |
| * @return Adapted {@link Graph}. |
| */ |
| public RDF4JGraph asGraph(final Model model) { |
| return RDF4J.createModelGraphImpl(model, this); |
| } |
| |
| /** |
| * Adapt an RDF4J {@link Repository} as a Commons RDF {@link Graph}. |
| * <p> |
| * The graph will only include triples in the default graph (equivalent to |
| * context <code>new Resource[0]{null})</code> in RDF4J). |
| * <p> |
| * Changes to the graph are reflected in the repository, and vice versa. |
| * <p> |
| * <strong>Note:</strong> Some operations on the {@link RDF4JGraph} requires |
| * the use of try-with-resources to close underlying |
| * {@link RepositoryConnection}s, including {@link RDF4JGraph#iterate()} and |
| * {@link RDF4JGraph#stream()}. |
| * |
| * @param repository |
| * RDF4J {@link Repository} to connect to. |
| * @param options |
| * Zero or more {@link Option} |
| * @return A {@link Graph} backed by the RDF4J repository. |
| */ |
| public RDF4JGraph asGraph(final Repository repository, final Option... options) { |
| final EnumSet<Option> opts = optionSet(options); |
| return RDF4J.createRepositoryGraphImpl(repository, opts.contains(Option.handleInitAndShutdown), |
| opts.contains(Option.includeInferred), new Resource[] { null }); // default |
| // graph |
| } |
| |
| /** |
| * Adapt an RDF4J {@link Repository} as a Commons RDF {@link Graph}. |
| * <p> |
| * The graph will include triples in any contexts (e.g. the union graph). |
| * <p> |
| * Changes to the graph are reflected in the repository, and vice versa. |
| * |
| * @param repository |
| * RDF4J {@link Repository} to connect to. |
| * @param options |
| * Zero or more {@link Option} |
| * @return A union {@link Graph} backed by the RDF4J repository. |
| */ |
| public RDF4JGraph asGraphUnion(final Repository repository, final Option... options) { |
| final EnumSet<Option> opts = optionSet(options); |
| return RDF4J.createRepositoryGraphImpl(repository, opts.contains(Option.handleInitAndShutdown), |
| opts.contains(Option.includeInferred)); // union graph |
| } |
| |
| /** |
| * Adapt an RDF4J {@link Repository} as a Commons RDF {@link Graph}. |
| * <p> |
| * The graph will include triples in the specified contexts. |
| * <p> |
| * Changes to the graph are reflected in the repository, and vice versa. |
| * Triples added/removed to the graph are reflected in all the specified |
| * contexts. |
| * <p> |
| * <strong>Note:</strong> Some operations on the {@link RDF4JGraph} requires |
| * the use of try-with-resources to close underlying |
| * {@link RepositoryConnection}s, including {@link RDF4JGraph#iterate()} and |
| * {@link RDF4JGraph#stream()}. |
| * |
| * @param repository |
| * RDF4J {@link Repository} to connect to. |
| * @param contexts |
| * A {@link Set} of {@link BlankNodeOrIRI} specifying the graph |
| * names to use as a context. The set may include the value |
| * <code>null</code> to indicate the default graph. The empty set |
| * indicates any context, e.g. the <em>union graph</em>. |
| * @param option |
| * Zero or more {@link Option}s |
| * @return A {@link Graph} backed by the RDF4J repository. |
| */ |
| public RDF4JGraph asGraph(final Repository repository, final Set<? extends BlankNodeOrIRI> contexts, final Option... option) { |
| final EnumSet<Option> opts = optionSet(option); |
| /** NOTE: asValue() deliberately CAN handle <code>null</code> */ |
| final Resource[] resources = contexts.stream().map(g -> (Resource) asValue(g)).toArray(Resource[]::new); |
| return RDF4J.createRepositoryGraphImpl(Objects.requireNonNull(repository), |
| opts.contains(Option.handleInitAndShutdown), opts.contains(Option.includeInferred), resources); |
| } |
| |
| /** |
| * Adapt a Commons RDF {@link Triple} or {@link Quad} as a RDF4J |
| * {@link Statement}. |
| * <p> |
| * If the <code>tripleLike</code> argument is an {@link RDF4JTriple} or a |
| * {@link RDF4JQuad}, then its {@link RDF4JTripleLike#asStatement()} is |
| * returned as-is. Note that this means that a {@link RDF4JTriple} would |
| * preserve its {@link Statement#getContext()}, and that any |
| * {@link BlankNode}s would be deemed equivalent in RDF4J if they have the |
| * same {@link BNode#getID()}. |
| * |
| * @param tripleLike |
| * A {@link Triple} or {@link Quad} to adapt |
| * @return A corresponding {@link Statement} |
| */ |
| public Statement asStatement(final TripleLike tripleLike) { |
| if (tripleLike instanceof RDF4JTripleLike) { |
| // Return original statement - this covers both RDF4JQuad and |
| // RDF4JTriple |
| return ((RDF4JTripleLike) tripleLike).asStatement(); |
| } |
| |
| final org.eclipse.rdf4j.model.Resource subject = (org.eclipse.rdf4j.model.Resource) asValue(tripleLike.getSubject()); |
| final org.eclipse.rdf4j.model.IRI predicate = (org.eclipse.rdf4j.model.IRI) asValue(tripleLike.getPredicate()); |
| final Value object = asValue(tripleLike.getObject()); |
| |
| org.eclipse.rdf4j.model.Resource context = null; |
| if (tripleLike instanceof Quad) { |
| final Quad quad = (Quad) tripleLike; |
| context = (org.eclipse.rdf4j.model.Resource) asValue(quad.getGraphName().orElse(null)); |
| } |
| |
| return getValueFactory().createStatement(subject, predicate, object, context); |
| } |
| |
| /** |
| * Adapt a RDF4J {@link Statement} as a Commons RDF {@link Triple}. |
| * <p> |
| * For the purpose of {@link BlankNode} equivalence, this method will use an |
| * internal salt UUID that is unique per instance of {@link RDF4J}. |
| * <p> |
| * <strong>NOTE:</strong> If combining RDF4J statements from multiple |
| * repositories or models, then their {@link BNode}s may have the same |
| * {@link BNode#getID()}, which with this method would become equivalent |
| * according to {@link BlankNode#equals(Object)} and |
| * {@link BlankNode#uniqueReference()}, unless a separate {@link RDF4J} |
| * instance is used per RDF4J repository/model. |
| * |
| * @param statement |
| * The RDF4J {@link Statement} to adapt. |
| * @return A {@link RDF4JTriple} that is equivalent to the statement |
| */ |
| public RDF4JTriple asTriple(final Statement statement) { |
| return RDF4J.createTripleImpl(statement, salt); |
| } |
| |
| /** |
| * Adapt a Commons RDF {@link RDFTerm} as a RDF4J {@link Value}. |
| * <p> |
| * The value will be of the same kind as the term, e.g. a |
| * {@link org.apache.commons.rdf.api.BlankNode} is converted to a |
| * {@link org.eclipse.rdf4j.model.BNode}, a |
| * {@link org.apache.commons.rdf.api.IRI} is converted to a |
| * {@link org.eclipse.rdf4j.model.IRI} and a |
| * {@link org.apache.commons.rdf.api.Literal} is converted to a |
| * {@link org.eclipse.rdf4j.model.Literal}. |
| * <p> |
| * If the provided {@link RDFTerm} is <code>null</code>, then the returned |
| * value is <code>null</code>. |
| * <p> |
| * If the provided term is an instance of {@link RDF4JTerm}, then the |
| * {@link RDF4JTerm#asValue()} is returned without any conversion. Note that |
| * this could mean that a {@link Value} from a different kind of |
| * {@link ValueFactory} could be returned. |
| * |
| * @param term |
| * RDFTerm to adapt to RDF4J Value |
| * @return Adapted RDF4J {@link Value} |
| */ |
| public Value asValue(final RDFTerm term) { |
| if (term == null) { |
| return null; |
| } |
| if (term instanceof RDF4JTerm) { |
| // One of our own - avoid converting again. |
| // (This is crucial to avoid double-escaping in BlankNode) |
| return ((RDF4JTerm) term).asValue(); |
| } |
| if (term instanceof org.apache.commons.rdf.api.IRI) { |
| final org.apache.commons.rdf.api.IRI iri = (org.apache.commons.rdf.api.IRI) term; |
| return getValueFactory().createIRI(iri.getIRIString()); |
| } |
| if (term instanceof org.apache.commons.rdf.api.Literal) { |
| final org.apache.commons.rdf.api.Literal literal = (org.apache.commons.rdf.api.Literal) term; |
| final String label = literal.getLexicalForm(); |
| if (literal.getLanguageTag().isPresent()) { |
| final String lang = literal.getLanguageTag().get(); |
| return getValueFactory().createLiteral(label, lang); |
| } |
| final org.eclipse.rdf4j.model.IRI dataType = (org.eclipse.rdf4j.model.IRI) asValue(literal.getDatatype()); |
| return getValueFactory().createLiteral(label, dataType); |
| } |
| if (term instanceof BlankNode) { |
| // This is where it gets tricky to support round trips! |
| final BlankNode blankNode = (BlankNode) term; |
| // FIXME: The uniqueReference might not be a valid BlankNode |
| // identifier.. |
| // does it have to be in RDF4J? |
| return getValueFactory().createBNode(blankNode.uniqueReference()); |
| } |
| throw new IllegalArgumentException("RDFTerm was not an IRI, Literal or BlankNode: " + term.getClass()); |
| } |
| |
| @Override |
| public RDF4JBlankNode createBlankNode() { |
| final BNode bnode = getValueFactory().createBNode(); |
| return asRDFTerm(bnode); |
| } |
| |
| @Override |
| public RDF4JBlankNode createBlankNode(final String name) { |
| final BNode bnode = getValueFactory().createBNode(name); |
| return asRDFTerm(bnode); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * <strong>Note:</strong> Some operations on the {@link RDF4JDataset} |
| * requires the use of try-with-resources to close underlying |
| * {@link RepositoryConnection}s, including {@link RDF4JDataset#iterate()}, |
| * {@link RDF4JDataset#stream()} and {@link RDF4JDataset#getGraphNames()}. |
| * |
| */ |
| @Override |
| public RDF4JDataset createDataset() { |
| final Sail sail = new MemoryStore(); |
| final Repository repository = new SailRepository(sail); |
| return RDF4J.createRepositoryDatasetImpl(repository, true, false); |
| } |
| |
| @Override |
| public RDF4JGraph createGraph() { |
| return asGraph(new LinkedHashModel()); |
| } |
| |
| @Override |
| public RDF4JIRI createIRI(final String iri) throws IllegalArgumentException { |
| return asRDFTerm(getValueFactory().createIRI(iri)); |
| } |
| |
| @Override |
| public RDF4JLiteral createLiteral(final String lexicalForm) throws IllegalArgumentException { |
| final org.eclipse.rdf4j.model.Literal lit = getValueFactory().createLiteral(lexicalForm); |
| return asRDFTerm(lit); |
| } |
| |
| @Override |
| public org.apache.commons.rdf.api.Literal createLiteral(final String lexicalForm, final org.apache.commons.rdf.api.IRI dataType) |
| throws IllegalArgumentException { |
| final org.eclipse.rdf4j.model.IRI iri = getValueFactory().createIRI(dataType.getIRIString()); |
| final org.eclipse.rdf4j.model.Literal lit = getValueFactory().createLiteral(lexicalForm, iri); |
| return asRDFTerm(lit); |
| } |
| |
| @Override |
| public org.apache.commons.rdf.api.Literal createLiteral(final String lexicalForm, final String languageTag) |
| throws IllegalArgumentException { |
| final org.eclipse.rdf4j.model.Literal lit = getValueFactory().createLiteral(lexicalForm, languageTag); |
| return asRDFTerm(lit); |
| } |
| |
| @Override |
| public RDF4JTriple createTriple(final BlankNodeOrIRI subject, final org.apache.commons.rdf.api.IRI predicate, final RDFTerm object) |
| throws IllegalArgumentException { |
| final Statement statement = getValueFactory().createStatement( |
| (org.eclipse.rdf4j.model.Resource) asValue(subject), (org.eclipse.rdf4j.model.IRI) asValue(predicate), |
| asValue(object)); |
| return asTriple(statement); |
| } |
| |
| @Override |
| public Quad createQuad(final BlankNodeOrIRI graphName, final BlankNodeOrIRI subject, final org.apache.commons.rdf.api.IRI predicate, |
| final RDFTerm object) throws IllegalArgumentException { |
| final Statement statement = getValueFactory().createStatement( |
| (org.eclipse.rdf4j.model.Resource) asValue(subject), (org.eclipse.rdf4j.model.IRI) asValue(predicate), |
| asValue(object), (org.eclipse.rdf4j.model.Resource) asValue(graphName)); |
| return asQuad(statement); |
| } |
| |
| public ValueFactory getValueFactory() { |
| return valueFactory; |
| } |
| |
| private EnumSet<Option> optionSet(final Option... options) { |
| final EnumSet<Option> opts = EnumSet.noneOf(Option.class); |
| opts.addAll(Arrays.asList(options)); |
| return opts; |
| } |
| |
| } |