[ 
https://issues.apache.org/jira/browse/COMMONSRDF-35?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15543898#comment-15543898
 ] 

ASF GitHub Bot commented on COMMONSRDF-35:
------------------------------------------

Github user ansell commented on a diff in the pull request:

    https://github.com/apache/incubator-commonsrdf/pull/24#discussion_r81658617
  
    --- Diff: 
rdf4j/src/main/java/org/apache/commons/rdf/rdf4j/RDF4JTermFactory.java ---
    @@ -0,0 +1,509 @@
    +/**
    + * 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.UUID;
    +
    +// To avoid confusion, avoid importing 
    +// classes that are in both
    +// commons.rdf and openrdf.model (e.g. IRI)
    +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.Quad;
    +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.rdf4j.impl.BlankNodeImpl;
    +import org.apache.commons.rdf.rdf4j.impl.IRIImpl;
    +import org.apache.commons.rdf.rdf4j.impl.LiteralImpl;
    +import org.apache.commons.rdf.rdf4j.impl.ModelGraphImpl;
    +import org.apache.commons.rdf.rdf4j.impl.QuadImpl;
    +import org.apache.commons.rdf.rdf4j.impl.RepositoryDatasetImpl;
    +import org.apache.commons.rdf.rdf4j.impl.RepositoryGraphImpl;
    +import org.apache.commons.rdf.rdf4j.impl.TripleImpl;
    +import org.eclipse.rdf4j.model.BNode;
    +import org.eclipse.rdf4j.model.Model;
    +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;
    +
    +/**
    + * RDF4J implementation of RDFTermFactory
    + * <p>
    + * The {@link #RDF4JTermFactory()} 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 #RDF4JTermFactory(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 RDF4JTermFactory} 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 #asRDFTermGraph(Model)}.
    + * <p>
    + * To adapt a RDF4J {@link Repository} as a {@link Dataset} or {@link 
Graph},
    + * use {@link #asRDFTermDataset(Repository)} or
    + * {@link #asRDFTermGraph(Repository)}.
    + * <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 #asRDFTermDataset(Repository)} and {@link #asRDFTermGraph(Model)}
    + * therefore uses a unique {@link RDF4JTermFactory} internally. An 
alternative
    + * is to use the static methods {@link #asRDFTerm(Value, UUID)},
    + * {@link #asQuad(Statement, UUID)} or {@link #asTriple(Statement, UUID)} 
with
    + * a provided {@link UUID} salt.
    + * 
    + */
    +public class RDF4JTermFactory implements RDFTermFactory {
    +
    +   /**
    +    * 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.
    +    * @param <T>
    +    *            The subclass of {@link Value}, e.g. {@link BNode}
    +    * @return A {@link RDFTerm} that corresponds to the RDF4J value
    +    * @throws IllegalArgumentException
    +    *             if the value is not a BNode, Literal or IRI
    +    */
    +   @SuppressWarnings("unchecked")
    +   public static <T extends Value> RDF4JTerm<T> asRDFTerm(final T value, 
UUID salt) {
    +           if (value instanceof BNode) {
    +                   return (RDF4JTerm<T>) new BlankNodeImpl((BNode) value, 
salt);
    +           }
    +           if (value instanceof org.eclipse.rdf4j.model.Literal) {
    +                   return (RDF4JTerm<T>) new 
LiteralImpl((org.eclipse.rdf4j.model.Literal) value);
    +           }
    +           if (value instanceof org.eclipse.rdf4j.model.IRI) {
    +                   return (RDF4JTerm<T>) new 
IRIImpl((org.eclipse.rdf4j.model.IRI) value);
    +           }
    +           throw new IllegalArgumentException("Value is not a BNode, 
Literal or IRI: " + value.getClass());
    +   }
    +
    +   /**
    +    * Adapt a RDF4J {@link Statement} as a Commons RDF {@link Triple}.
    +    * 
    +    * @param statement
    +    *            The statement 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 Triple} that corresponds to the RDF4J statement
    +    */
    +   public static RDF4JTriple asTriple(final Statement statement, UUID 
salt) {
    +           return new TripleImpl(statement, salt);
    +   }
    +
    +   private UUID salt = UUID.randomUUID();
    +
    +   private final ValueFactory valueFactory;
    +
    +   public RDF4JTermFactory() {
    +           this.valueFactory = SimpleValueFactory.getInstance();
    +   }
    +
    +   public RDF4JTermFactory(ValueFactory valueFactory) {
    +           this.valueFactory = valueFactory;
    +   }
    +
    +   /**
    +    * 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 RDF4JTermFactory}. 
    +    * <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 RDF4JTermFactory}
    +    * instance is used per RDF4J repository/model.  
    +    * 
    +    * @see #asQuad(Statement, UUID)
    +    * @param statement
    +    *            The statement to convert
    +    * @return A {@link RDF4JQuad} that is equivalent to the statement
    +    */
    +   public RDF4JQuad asQuad(final Statement statement) {
    +           return new QuadImpl(statement, salt);
    +   }
    +
    +   /**
    +    * Adapt a RDF4J {@link Statement} as a Commons RDF {@link Quad}.
    +    *
    +    * @see #asQuad(Statement)
    +    * @param statement
    +    *            The statement 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 RDF4JQuad} that is equivalent to the statement
    +    */
    +   public static RDF4JQuad asQuad(final Statement statement, UUID salt) {
    +           return new QuadImpl(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 RDF4JTermFactory}. 
    +    * <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 RDF4JTermFactory}
    +    * instance is used per RDF4J repository/model.  
    +    * 
    +    * @param value The RDF4J {@link Value} to convert.
    +    * @param <T>
    +    *            The subclass of {@link Value}, e.g. {@link BNode}
    +    * @return A {@link RDFTerm} that corresponds to the RDF4J value
    +    * @throws IllegalArgumentException if the value is not a BNode, 
Literal or IRI 
    +    */
    +   public <T extends Value> RDF4JTerm<T> asRDFTerm(T value) {
    +           return asRDFTerm(value, salt);
    +   }
    +
    +   /**
    +    * Adapt an RDF4J {@link Repository} as a Commons RDF {@link Dataset}.
    +    * <p>
    +    * Changes to the dataset are reflected in the repository, and vice 
versa.
    +    * 
    +    * @param repository
    +    *            RDF4J {@link Repository} to connect to.
    +    * @return A {@link Dataset} backed by the RDF4J repository.
    +    */
    +   public RDF4JDataset asRDFTermDataset(Repository repository) {
    +           return new RepositoryDatasetImpl(repository);
    +   }
    +
    +   /**
    +    * Adapt an RDF4J {@link Repository} as a Commons RDF {@link Dataset}.
    +    * <p>
    +    * Changes to the dataset are reflected in the repository, and vice 
versa.
    +    * 
    +    * @param repository
    +    *            RDF4J {@link Repository} to connect to.
    +    * @param includeInferred
    +    *            If true, any inferred quads are included in the dataset
    +    * @return A {@link Dataset} backed by the RDF4J repository.
    +    */
    +   public RDF4JDataset asRDFTermDataset(Repository repository, boolean 
includeInferred) {
    +           return new RepositoryDatasetImpl(repository, 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 asRDFTermGraph(Model model) {
    +           return new ModelGraphImpl(model);
    +   }
    +
    +   /**
    +    * 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.
    +    * @return A {@link Graph} backed by the RDF4J repository.
    +    */
    +   public RDF4JGraph asRDFTermGraph(Repository repository) {
    +           return new RepositoryGraphImpl(repository, false, true);
    +   }
    +
    +   /**
    +    * 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 includeInferred
    +    *            If true, any inferred triples are included in the graph
    +    * @param unionGraph
    +    *            If true, triples from any context is included in the 
graph,
    +    *            otherwise only triples in the default context
    +    *            <code>null</code>.
    +    * @return A {@link Graph} backed by the RDF4J repository.
    +    */
    +   public RDF4JGraph asRDFTermGraph(Repository repository, boolean 
includeInferred, boolean unionGraph) {
    --- End diff --
    
    The biggest issue with naming a boolean is that there are four cases able 
to be supported by the varargs version, and only two cases able to be supported 
by the boolean. The boolean supports 
    
    1. "match regardless of context", and;
    2. "match only default context"
    
    , while the varargs supports 
    
    1. "match regardless of context" (empty Resource array), and;
    2. "match only default context" (Resource array with a single null 
element), and;
    3. "match specific context" (Resource array with a single non-null 
element), and; 
    4. "match specific and possibly default contexts" (Resource array with more 
than one element, one of which can be null to match the default context also)
    
    The name "unionGraph" is fairly clear with its positive case (ie, case 1 
above), but it doesn't indicate immediately what its negative case will be, as 
from an RDF4J user perspective, they are used to having to distinguish between 
case 2 and 3 and it isn't clear which one would be chosen just from the 
signature.


> rdf4j integration
> -----------------
>
>                 Key: COMMONSRDF-35
>                 URL: https://issues.apache.org/jira/browse/COMMONSRDF-35
>             Project: Apache Commons RDF
>          Issue Type: New Feature
>            Reporter: Stian Soiland-Reyes
>            Assignee: Stian Soiland-Reyes
>              Labels: integration, rdf4j, sesame
>             Fix For: 0.3.0
>
>
> Add a new rdf4j module with implementation for Eclipse rdf4j
> See https://github.com/apache/incubator-commonsrdf/tree/rdf4j/rdf4j
> A legacy sesame branch could then be added by mainly copy/paste and change 
> the import



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to