[
https://issues.apache.org/jira/browse/COMMONSRDF-33?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15532955#comment-15532955
]
ASF GitHub Bot commented on COMMONSRDF-33:
------------------------------------------
Github user stain commented on a diff in the pull request:
https://github.com/apache/incubator-commonsrdf/pull/23#discussion_r81151848
--- Diff:
jena/src/main/java/org/apache/commons/rdf/jena/JenaRDFTermFactory.java ---
@@ -0,0 +1,874 @@
+/**
+ * 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.jena;
+
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Consumer;
+
+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.IRI;
+import org.apache.commons.rdf.api.Literal;
+import org.apache.commons.rdf.api.Quad;
+import org.apache.commons.rdf.api.QuadLike;
+import org.apache.commons.rdf.api.RDFSyntax;
+import org.apache.commons.rdf.api.RDFTerm;
+import org.apache.commons.rdf.api.RDFTermFactory;
+import org.apache.commons.rdf.api.Triple;
+import org.apache.commons.rdf.api.TripleLike;
+import org.apache.commons.rdf.jena.impl.JenaFactory;
+import org.apache.jena.datatypes.RDFDatatype;
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.RDFLanguages;
+import org.apache.jena.riot.system.StreamRDF;
+import org.apache.jena.riot.system.StreamRDFBase;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.graph.GraphFactory;
+
+/**
+ * RDFTermFactory with Jena-backed objects.
+ * <p>
+ * This factory can also convert existing objects from/to Jena with
methods like
+ * {@link #fromJena(org.apache.jena.graph.Graph)} and {@link
#toJena(Graph)}.
+ * <p>
+ * For the purpose of {@link BlankNode} identity, this factory will use an
internal
+ * {@link UUID} as a salt. See {@link BlankNode#uniqueReference()} for
details.
+ *
+ * @see RDFTermFactory
+ */
+public final class JenaRDFTermFactory implements RDFTermFactory {
+
+ private final UUID salt;
+
+ /**
+ * Create a JenaRDFTermFactory.
+ * <p>
+ * This constructor will use a randomly generated {@link UUID} as a
salt
+ * for the purposes of {@link BlankNode} identity, see {@link
#getSalt()}.
+ */
+ public JenaRDFTermFactory() {
+ this.salt = UUID.randomUUID();
+ }
+
+ /**
+ * Create a JenaRDFTermFactory.
+ * <p>
+ * This constructor will use the specified {@link UUID} as a salt
+ * for the purposes of {@link BlankNode} identity.
+ *
+ * @param salt {@link UUID} to use as salt
+ */
+ public JenaRDFTermFactory(UUID salt) {
+ this.salt = salt;
+ }
+
+ @Override
+ public JenaBlankNode createBlankNode() {
+ return JenaFactory.createBlankNode(getSalt());
+ }
+
+ @Override
+ public JenaBlankNode createBlankNode(String name) {
+ return JenaFactory.createBlankNode(name, getSalt());
+ }
+
+ @Override
+ public JenaDataset createDataset() {
+ return JenaFactory.createDataset(getSalt());
+ }
+
+ @Override
+ public JenaGraph createGraph() {
+ return JenaFactory.createGraph(getSalt());
+ }
+
+ @Override
+ public JenaIRI createIRI(String iri) {
+ validateIRI(iri);
+ return JenaFactory.createIRI(iri);
+ }
+
+ @Override
+ public JenaLiteral createLiteral(String lexicalForm) {
+ return JenaFactory.createLiteral(lexicalForm);
+ }
+
+ @Override
+ public JenaLiteral createLiteral(String lexicalForm, IRI dataType) {
+ return JenaFactory.createLiteralDT(lexicalForm,
dataType.getIRIString());
+ }
+
+ @Override
+ public JenaLiteral createLiteral(String lexicalForm, String
languageTag) {
+ validateLang(languageTag);
+ return JenaFactory.createLiteralLang(lexicalForm, languageTag);
+ }
+
+ @Override
+ public JenaTriple createTriple(BlankNodeOrIRI subject, IRI predicate,
RDFTerm object) {
+ return JenaFactory.createTriple(subject, predicate, object);
+ }
+
+ @Override
+ public JenaQuad createQuad(BlankNodeOrIRI graphName, BlankNodeOrIRI
subject, IRI predicate, RDFTerm object)
+ throws IllegalArgumentException,
UnsupportedOperationException {
+ return JenaFactory.createQuad(subject, predicate, object,
graphName);
+ }
+
+ /**
+ * Adapt a generalized Jena Triple to a CommonsRDF {@link TripleLike}
statement.
+ * <p>
+ * The generalized triple supports any {@link RDFTerm} as its {@link
TripleLike#getSubject()}
+ * {@link TripleLike#getPredicate()} or {@link TripleLike#getObject()}.
+ * <p>
+ * If the Jena triple contains any {@link Node#isBlank()}, then any
corresponding
+ * {@link BlankNode} will use a {@link UUID} salt from this
+ * {@link JenaRDFTermFactory} instance in combination with
+ * {@link Node#getBlankNodeId()} for the purpose of its
+ * {@link BlankNode#uniqueReference()}.
+ *
+ * @see #fromJena(org.apache.jena.graph.Triple, UUID)
+ * @see #fromJena(RDFTermFactory, org.apache.jena.graph.Triple)
+ *
+ * @param subject The subject of the statement
+ * @param predicate The predicate of the statement
+ * @param object The object of the statement
+
+ *
+ * @return Adapted {@link TripleLike}. Note that the generalized triple
does
+ * <strong>not</strong> implement {@link Triple#equals(Object)}
or
+ * {@link Triple#hashCode()}.
+ * @throws ConversionException
+ * if any of the triple's nodes are not concrete
+ */
+ public JenaTripleLike<RDFTerm, RDFTerm, RDFTerm>
createGeneralizedTriple(
+ RDFTerm subject, RDFTerm predicate, RDFTerm object) {
+ return JenaFactory.createGeneralizedTriple(subject, predicate,
object);
+ }
+
+ /**
+ * Adapt an existing Jena Node to CommonsRDF {@link RDFTerm}.
+ * <p>
+ * If {@link Node#isLiteral()}, then the returned value is a {@link
Literal}.
+ * If {@link Node#isURI()}, the returned value is a IRI. If {$@link
Node#isBlank()},
+ * the returned value is a {@link BlankNode}, which will use a {@link
UUID}
+ * salt from this {@link JenaRDFTermFactory} instance in combination
with
+ * {@link Node#getBlankNodeId()} for the purpose of its
+ * {@link BlankNode#uniqueReference()}.
+ *
+ * @see #fromJena(Node, UUID)
+ * @see #fromJena(RDFTermFactory, Node)
+ *
+ * @param node
+ * The Jena Node to adapt. It's {@link Node#isConcrete()}
must be
+ * <code>true</code>.
+ * @return Adapted {@link JenaRDFTerm}
+ * @throws ConversionException
+ * if the node is not concrete.
+ */
+ public JenaRDFTerm fromJena(Node node) throws ConversionException {
+ return JenaFactory.fromJena(node, getSalt());
+ }
+
+ /**
+ * Adapt an existing Jena Node to CommonsRDF {@link RDFTerm}.
+ * <p>
+ * If {@link Node#isLiteral()}, then the returned value is a {@link
Literal}.
+ * If {@link Node#isURI()}, the returned value is a IRI. If {@link
Node#isBlank()},
+ * the returned value is a {@link BlankNode}, which will use the
provided
+ * {@link UUID} salt in combination with {@link Node#getBlankNodeId()}
for
+ * the purpose of its {@link BlankNode#uniqueReference()}.
+ *
+ * @see #fromJena(Node)
+ * @see #fromJena(RDFTermFactory, Node)
+ *
+ * @param node
+ * The Jena Node to adapt. It's {@link Node#isConcrete()}
must be
+ * <code>true</code>.
+ * @param salt
+ * UUID salt for the purpose of
+ * {@link BlankNode#uniqueReference()}
+ * @return Adapted {@link JenaRDFTerm}
+ * @throws ConversionException
+ * if the node is not concrete.
+ */
+ public static JenaRDFTerm fromJena(Node node, UUID salt) {
+ return JenaFactory.fromJena(node, salt);
+ }
+
+ /**
+ * Convert from Jena {@link Node} to any Commons RDF implementation.
+ * <p>
+ * Note that if the {@link Node#isBlank()}, then the factory's
+ * {@link RDFTermFactory#createBlankNode(String)} will be used, meaning
+ * that care should be taken if reusing an {@link RDFTermFactory}
instance
+ * for multiple conversion sessions.
+ *
+ * @see #fromJena(Node)
+ * @see #fromJena(Node, UUID)
+ *
+ * @param factory {@link RDFTermFactory} to use for creating {@link
RDFTerm}.
+ * @param node
+ * The Jena Node to adapt. It's {@link Node#isConcrete()}
must be
+ * <code>true</code>.
+ * @return Adapted {@link RDFTerm}
+ * @throws ConversionException
+ * if the node is not concrete.
+ */
+ public static RDFTerm fromJena(RDFTermFactory factory, Node node) {
+ if (node == null) {
+ return null;
+ }
+ if (factory instanceof JenaRDFTermFactory) {
+ // No need to convert, just wrap
+ return ((JenaRDFTermFactory) factory).fromJena(node);
+ }
+ if (node.isURI())
+ return factory.createIRI(node.getURI());
+ if (node.isLiteral()) {
+ String lang = node.getLiteralLanguage();
+ if (lang != null && !lang.isEmpty())
+ return
factory.createLiteral(node.getLiteralLexicalForm(), lang);
+ if
(node.getLiteralDatatype().equals(XSDDatatype.XSDstring))
+ return
factory.createLiteral(node.getLiteralLexicalForm());
+ IRI dt =
factory.createIRI(node.getLiteralDatatype().getURI());
+ return
factory.createLiteral(node.getLiteralLexicalForm(), dt);
+ }
+ if (node.isBlank())
+ // The factory
+ return
factory.createBlankNode(node.getBlankNodeLabel());
+ throw new ConversionException("Node is not a concrete RDF Term:
" + node);
+ }
+
+ /**
+ * Adapt an existing Jena Triple to CommonsRDF {@link Triple}.
+ * <p>
+ * If the triple contains any {@link Node#isBlank()}, then any
corresponding
+ * {@link BlankNode} will use a {@link UUID} salt from this
+ * {@link JenaRDFTermFactory} instance in combination with
+ * {@link Node#getBlankNodeId()} for the purpose of its
+ * {@link BlankNode#uniqueReference()}.
+ *
+ * @see #fromJena(org.apache.jena.graph.Triple, UUID)
+ * @see #fromJena(RDFTermFactory, org.apache.jena.graph.Triple)
+ *
+ * @param triple
+ * Jena {@link org.apache.jena.graph.Triple} to adapt
+ * @return Adapted {@link JenaTriple}
+ * @throws ConversionException
+ * if any of the triple's nodes are not concrete or the
triple
+ * is a generalized triple
+ */
+ public JenaTriple fromJena(org.apache.jena.graph.Triple triple) throws
ConversionException {
+ return JenaFactory.fromJena(triple, getSalt());
+ }
+
+
+ /**
+ * Adapt a generalized Jena Triple to a CommonsRDF {@link TripleLike}.
+ * <p>
+ * The generalized triple supports any {@link RDFTerm} as its {@link
TripleLike#getSubject()}
+ * {@link TripleLike#getPredicate()} or {@link TripleLike#getObject()}.
+ * <p>
+ * If the Jena triple contains any {@link Node#isBlank()}, then any
corresponding
+ * {@link BlankNode} will use the provided {@link UUID} salt
+ * in combination with
+ * {@link Node#getBlankNodeId()} for the purpose of its
+ * {@link BlankNode#uniqueReference()}.
+ *
+ * @see #fromJena(org.apache.jena.graph.Triple, UUID)
+ * @see #fromJena(RDFTermFactory, org.apache.jena.graph.Triple)
+ *
+ * @param triple
+ * Jena triple
+ * @param salt
+ * UUID salt for the purpose of
+ * {@link BlankNode#uniqueReference()}
+ * @return Adapted {@link TripleLike}. Note that the generalized triple
does
+ * <strong>not</strong> implement {@link Triple#equals(Object)}
or
+ * {@link Triple#hashCode()}.
+ * @throws ConversionException
+ * if any of the triple's nodes are not concrete
+ */
+ public JenaTripleLike<RDFTerm, RDFTerm, RDFTerm>
fromJenaGeneralized(org.apache.jena.graph.Triple triple, UUID salt) throws
ConversionException {
+ return JenaFactory.fromJenaGeneralized(triple, salt);
+ }
+
+ /**
+ * Adapt a generalized Jena {@link org.apache.jena.graph.Triple} to a
CommonsRDF {@link TripleLike}.
+ * <p>
+ * The generalized triple supports any {@link RDFTerm} as its {@link
TripleLike#getSubject()}
+ * {@link TripleLike#getPredicate()} or {@link TripleLike#getObject()},
including
+ * the extensions {@link JenaAny} and {@link JenaVariable}.
+ * <p>
+ * If the Jena triple contains any {@link Node#isBlank()}, then any
corresponding
+ * {@link BlankNode} will use a {@link UUID} salt from this
+ * {@link JenaRDFTermFactory} instance in combination with
+ * {@link Node#getBlankNodeId()} for the purpose of its
+ * {@link BlankNode#uniqueReference()}.
+ *
+ * @see #fromJena(org.apache.jena.graph.Triple, UUID)
+ * @see #fromJena(RDFTermFactory, org.apache.jena.graph.Triple)
+ *
+ * @param triple
+ * Jena triple
+ * @return Adapted {@link TripleLike}. Note that the generalized triple
does
+ * <strong>not</strong> implement {@link Triple#equals(Object)}
or
+ * {@link Triple#hashCode()}.
+ * @throws ConversionException
+ * if any of the triple's nodes are not concrete
+ */
+ public JenaTripleLike<RDFTerm, RDFTerm, RDFTerm>
fromJenaGeneralized(org.apache.jena.graph.Triple triple) throws
ConversionException {
+ return JenaFactory.fromJenaGeneralized(triple, getSalt());
+ }
+
+ /**
+ * Adapt a generalized Jena {@link org.apache.jena.sparql.core.Quad} to
a CommonsRDF {@link QuadLike}.
+ * <p>
+ * The generalized quad supports any {@link RDFTerm} as its
+ * {@link QuadLike#getGraphName()},
+ * {@link QuadLike#getSubject()}
+ * {@link QuadLike#getPredicate()} or
+ * {@link QuadLike#getObject()}, including
+ * the extensions
+ * {@link JenaAny} and {@link JenaVariable}.
+ * <p>
+ * If the Jena quad contains any {@link Node#isBlank()}, then any
corresponding
+ * {@link BlankNode} will use a {@link UUID} salt from this
+ * {@link JenaRDFTermFactory} instance in combination with
+ * {@link Node#getBlankNodeId()} for the purpose of its
+ * {@link BlankNode#uniqueReference()}.
+ *
+ * @see #fromJena(org.apache.jena.sparql.core.Quad)
+ * @see #fromJenaGeneralized(org.apache.jena.graph.Triple)
+ *
+ * @param quad
+ * Jena quad
+ * @return Adapted {@link QuadLike}. Note that the generalized quad does
+ * <strong>not</strong> implement {@link Quad#equals(Object)} or
+ * {@link Quad#hashCode()}.
+ * @throws ConversionException
+ * if any of the quad nodes are not concrete
+ */
+ public JenaQuadLike<RDFTerm, RDFTerm, RDFTerm, RDFTerm>
fromJenaGeneralized(org.apache.jena.sparql.core.Quad quad) throws
ConversionException {
+ return JenaFactory.fromJenaGeneralized(quad, getSalt());
+ }
+
+
+ /**
+ * Adapt an existing Jena Triple to CommonsRDF {@link Triple}.
+ * <p>
+ * If the triple contains any {@link Node#isBlank()}, then any
corresponding
+ * {@link BlankNode} will use the provided a {@link UUID} salt in
+ * combination with {@link Node#getBlankNodeId()} for the purpose of its
+ * {@link BlankNode#uniqueReference()}.
+ *
+ * @param triple
+ * Jena triple
+ * @param salt
+ * A {@link UUID} salt for adapting any {@link BlankNode}s
+ * @return Adapted triple
+ * @throws ConversionException
+ * if any of the triple's nodes are not concrete or the
triple
+ * is a generalized triple
+ */
+ public static JenaTriple fromJena(org.apache.jena.graph.Triple triple,
UUID salt) throws ConversionException {
+ return JenaFactory.fromJena(triple, salt);
+ }
+
+ /**
+ * Convert from Jena {@link org.apache.jena.graph.Triple} to a Commons
RDF
+ * {@link Triple}.
+ * <p>
+ * Note that if any of the triple's nodes {@link Node#isBlank()}, then
the factory's
+ * {@link RDFTermFactory#createBlankNode(String)} will be used, meaning
+ * that care should be taken if reusing an {@link RDFTermFactory}
instance
+ * for multiple conversion sessions.
+ *
+ * @see #fromJena(org.apache.jena.graph.Triple)
+ * @see #fromJena(org.apache.jena.graph.Triple, UUID)
+ *
+ * @param factory {@link RDFTermFactory} to use for creating the {@link
Triple} and its
+ * {@link RDFTerm}s.
+ * @param triple
+ * Jena triple
+ * @return Converted triple
+ * @throws ConversionException
+ * if any of the triple's nodes are not concrete or the
triple
+ * is a generalized triple
+ */
+ public static Triple fromJena(RDFTermFactory factory,
org.apache.jena.graph.Triple triple)
+ throws ConversionException{
+ if (factory instanceof JenaRDFTermFactory) {
+ // No need to convert, just wrap
+ return ((JenaRDFTermFactory) factory).fromJena(triple);
+ }
+ BlankNodeOrIRI subject;
+ IRI predicate;
+ try {
+ subject = (BlankNodeOrIRI) fromJena(factory,
triple.getSubject());
+ predicate = (IRI) fromJena(factory,
triple.getPredicate());
+ } catch (ClassCastException ex) {
+ throw new ConversionException("Can't convert
generalized triple: " + triple, ex);
+ }
+ RDFTerm object = fromJena(factory, triple.getObject());
+ return factory.createTriple(subject, predicate, object);
--- End diff --
I dare to disagree in this instance as `ClassCastException` is unchecked -
- the try-catch should only cover what we want to catch.
Some might argue against a `return` from inside a `try` block, but I don't
see a problem with that side (Java won't let you void through).
We don't expect `fromJena()` or `createTriple()` to throw
ClassCastException. If they do, it should be a proper `RuntimeException`, not a
`ConversionException`.
> Jena integration
> ----------------
>
> Key: COMMONSRDF-33
> URL: https://issues.apache.org/jira/browse/COMMONSRDF-33
> Project: Apache Commons RDF
> Issue Type: New Feature
> Reporter: Stian Soiland-Reyes
> Assignee: Stian Soiland-Reyes
> Fix For: 0.3.0
>
>
> Add a new jena/ module with implementations mapping to Jena 3.x
> Based on JENA-1015, https://github.com/afs/commonsrdf-jena and
> https://github.com/stain/incubator-commonsrdf/tree/jena
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)