Skip to content

Commit

Permalink
eclipse-rdf4j#405 Add documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Prince Sachdeva <prince17080@iiitd.ac.in>
  • Loading branch information
prince17080 committed May 23, 2020
1 parent 9369b05 commit d768b86
Showing 1 changed file with 230 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,98 @@
import java.util.regex.Pattern;

/**
* TODO add documentation
* Utilities for working with RDF Containers and converting to/from Java {@link Collection} classes.
* <P>
* RDF Containers are represented using 3 different types of structures:
*
* 1. {@link RDF#BAG} : A Bag (a resource having type rdf:Bag) represents a group of resources or literals, possibly
* including duplicate members, where there is no significance in the order of the members.
*
* 2. {@link RDF#SEQ} : A Sequence or Seq (a resource having type rdf:Seq) represents a group of resources or literals,
* possibly including duplicate members, where the order of the members is significant.
*
* 3. {@link RDF#ALT} : An Alternative or Alt (a resource having type rdf:Alt) represents a group of resources or
* literals that are alternatives (typically for a single value of a property).
*
* So, in each of the above types, the container starts with a first resource node, via the rdf:_1 relation. Similarly,
* the next member is connected via the rdf:_2 relation and so on.
*
* For eg. Bag containing three literal values "A", "B", and "C" looks like this as an RDF Container:
*
* <pre>
* _:n1 -rdf:type--> rdf:Bag
* |
* +---rdf:_1--> "A"
* |
* +---rdf:_2--> "B"
* |
* +---rdf:_3--> "C"
* </pre>
*
* @see <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Schema 1.1 section on Collection
* vocabulary</a>.
*/
public class RDFContainers {

/**
* Converts the supplied {@link Iterable} to an <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF
* Container</a>, using the supplied {@code head} resource as the starting resource of the RDF Containter. The
* statements making up the new RDF Containter will be added to the supplied statement collection.
*
* @param containerType defines the type of RDF Container
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted to
* an RDF Containter. May not be {@code null}. The method attempts to convert each value that is not
* already an instance of {@link Value} to a {@link Literal}. This conversion will fail with a
* {@link LiteralUtilException} if the value's object type is not supported. See
* {@link Literals#createLiteralOrFail(ValueFactory, Object)} for an overview of supported types.
* @param container a {@link Resource} which will be used as the head of the container, that is, the starting
* point of the created RDF Container. May be {@code null}, in which case a new resource is generated
* to represent the container head.
* @param sink a {@link Collection} of {@link Statement} objects (for example a {@link Model}) to which the RDF
* Collection statements will be added. May not be {@code null}.
* @param contexts the context(s) in which to add the RDF Containter. This argument is an optional vararg and can be
* left out.
* @return the supplied sink {@link Collection} of {@link Statement}s, with the new Statements forming the RDF
* Collection added.
* @throws LiteralUtilException if one of the supplied values can not be converted to a Literal.
* @see <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Schema 1.1 section on Collection
* vocabulary</a>.
*/
public static <C extends Collection<Statement>> C asRDF(IRI containerType, Iterable<?> values, Resource container, C sink,
Resource... contexts) {
Resource... contexts) {

Objects.requireNonNull(sink);
consumeContainer(containerType, values, container, st -> sink.add(st), contexts);
return sink;
}

/**
* Converts the supplied {@link Iterable} to an <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF
* Container</a>, using the supplied {@code head} resource as the starting resource of the RDF Containter. The
* statements making up the new RDF Containter will be added to the supplied statement collection.
*
* @param containerType defines the type of RDF Container
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted to
* an RDF Containter. May not be {@code null}. The method attempts to convert each value that is not
* already an instance of {@link Value} to a {@link Literal}. This conversion will fail with a
* {@link LiteralUtilException} if the value's object type is not supported. See
* {@link Literals#createLiteralOrFail(ValueFactory, Object)} for an overview of supported types.
* @param container a {@link Resource} which will be used as the head of the container, that is, the starting
* point of the created RDF Container. May be {@code null}, in which case a new resource is generated
* to represent the container head.
* @param sink a {@link Collection} of {@link Statement} objects (for example a {@link Model}) to which the RDF
* Collection statements will be added. May not be {@code null}.
* @param vf the {@link ValueFactory} to be used for creation of RDF model objects. May not be
* {@code null}.
* @param contexts the context(s) in which to add the RDF Containter. This argument is an optional vararg and can be
* left out.
* @return the supplied sink {@link Collection} of {@link Statement}s, with the new Statements forming the RDF
* Collection added.
* @throws LiteralUtilException if one of the supplied values can not be converted to a Literal.
* @see <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Schema 1.1 section on Collection
* vocabulary</a>.
*/
public static <C extends Collection<Statement>> C asRDF(IRI containerType, Iterable<?> values, Resource container, C sink,
ValueFactory vf, Resource... contexts) {

Expand All @@ -42,6 +122,25 @@ public static <C extends Collection<Statement>> C asRDF(IRI containerType, Itera
return sink;
}

/**
* Converts an RDF Containter to a Java {@link Collection} of {@link Value} objects. The RDF Containter is given by
* the supplied {@link Model} and {@code container}. This method expects the RDF Containter to be well-formed. If the
* collection is not well-formed the method may return part of the collection, or may throw a
* {@link ModelException}.
*
* @param containerType defines the type of RDF Container
* @param m the Model containing the collection to read.
* @param container the {@link Resource} that represents the container head, that is the start resource of the RDF
* Container to be read. May not be {@code null}.
* @param collection the Java {@link Collection} to add the collection items to.
* @param contexts the context(s) from which to read the RDF Containter. This argument is an optional vararg and
* can be left out.
* @return the supplied Java {@link Collection}, filled with the items from the RDF Containter (if any).
* @throws ModelException if a problem occurs reading the RDF Containter, for example if the Collection is not
* well-formed.
* @see <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Schema 1.1 section on Collection
* vocabulary</a>.
*/
public static <C extends Collection<Value>> C asValues(IRI containerType, final Model m, Resource container, C collection,
Resource... contexts) throws ModelException {
Objects.requireNonNull(collection, "collection may not be null");
Expand All @@ -51,13 +150,61 @@ public static <C extends Collection<Value>> C asValues(IRI containerType, final
return collection;
}


/**
* Converts the supplied {@link Iterable} to an <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF
* Container</a>, using the supplied {@code head} resource as the starting resource of the RDF Containter. The
* statements making up the new RDF Containter will be reported to the supplied {@link Consumer} function.
*
* @param containerType defines the type of RDF Container
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted to
* an RDF Containter. May not be {@code null}. The method attempts to convert each value that is not
* already an instance of {@link Value} to a {@link Literal}. This conversion will fail with a
* {@link LiteralUtilException} if the value's object type is not supported. See
* {@link Literals#createLiteralOrFail(ValueFactory, Object)} for an overview of supported types.
* @param container a {@link Resource} which will be used as the head of the container, that is, the starting point of the
* created RDF Containter. May be {@code null}, in which case a new resource is generated to
* represent the containter head.
* @param consumer the {@link Consumer} function for the Statements of the RDF Containter. May not be {@code null}.
* @param contexts the context(s) in which to add the RDF Containter. This argument is an optional vararg and can be
* left out.
* @throws LiteralUtilException if one of the supplied values can not be converted to a Literal.
* @see <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Schema 1.1 section on Collection
* vocabulary</a>.
* @see Literals#createLiteralOrFail(ValueFactory, Object)
*/
public static void consumeContainer(IRI containerType, Iterable<?> values, Resource container, Consumer<Statement> consumer,
Resource... contexts) {
consumeContainer(containerType, values, container, consumer, SimpleValueFactory.getInstance(), contexts);
}

/**
* Converts the supplied {@link Iterable} to an <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF
* Container</a>, using the supplied {@code head} resource as the starting resource of the RDF Container. The
* statements making up the new RDF Container will be reported to the supplied {@link Consumer} function.
*
* @param containerType defines the type of RDF Container
* @param values an {@link Iterable} of objects (such as a Java {@link Collection} ), which will be converted to
* an RDF Container. May not be {@code null}. The method attempts to convert each value that is not
* already an instance of {@link Value} to a {@link Literal}. This conversion will fail with a
* {@link LiteralUtilException} if the value's object type is not supported. See
* {@link Literals#createLiteralOrFail(ValueFactory, Object)} for an overview of supported types.
* @param container a {@link Resource} which will be used as the head of the container, that is, the starting point of the
* created RDF Container. May be {@code null}, in which case a new resource is generated to
* represent the containter head.
* @param consumer the {@link Consumer} function for the Statements of the RDF Container. May not be {@code null}.
* @param vf the {@link ValueFactory} to use for creation of new model objects. May not be {@code null}
* @param contexts the context(s) in which to add the RDF Container. This argument is an optional vararg and can be
* left out.
* @throws LiteralUtilException if one of the supplied values can not be converted to a Literal.
* @see <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Schema 1.1 section on Collection
* vocabulary</a>.
* @see Literals#createLiteralOrFail(ValueFactory, Object)
*
* @since 3.0
*/
public static void consumeContainer(IRI containerType, Iterable<?> values, Resource container, Consumer<Statement> consumer,
ValueFactory vf,
Resource... contexts) {
ValueFactory vf, Resource... contexts) {
Objects.requireNonNull(values, "input collection may not be null");
Objects.requireNonNull(consumer, "consumer may not be null");
Objects.requireNonNull(vf, "injected value factory may not be null");
Expand Down Expand Up @@ -85,11 +232,34 @@ public static void consumeContainer(IRI containerType, Iterable<?> values, Resou
}
}

/**
* Creates the IRI of the element counter predicate in the {@link RDF} namespace, rdf:_nnn
* @param vf the {@link ValueFactory} to use for creation of new model objects. May not be {@code null}
* @param elementCounter the counter varialbe for which IRI has to be created
* @return {@link IRI} of the rdf:_nnn
*/
private static IRI getAnnotatedMemberPredicate(ValueFactory vf, int elementCounter) {
return vf.createIRI(RDF.NAMESPACE, "_" + elementCounter);
}


/**
* Reads an RDF Container starting with the supplied containter head from the supplied {@link Model} and sends each
* collection member {@link Value} to the supplied {@link Consumer} function. This method expects the RDF Container
* to be well-formed. If the collection is not well-formed the method may report only part of the collection, or may
* throw a {@link ModelException}.
*
* @param m the Model containing the collection to read.
* @param container the {@link Resource} that represents the containter head, that is the start resource of the RDF
* Container to be read. May not be {@code null}.
* @param containerType defines the type of RDF Container
* @param consumer the Java {@link Consumer} function to which the collection items are reported.
* @param contexts the context(s) from which to read the RDF Container. This argument is an optional vararg and can
* be left out.
* @throws ModelException if a problem occurs reading the RDF Container, for example if the Collection is not
* well-formed.
* @see <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Schema 1.1 section on Collection
* vocabulary</a>.
*/

public static void consumeValues(final Model m, Resource container, IRI containerType, Consumer<Value> consumer, Resource... contexts)
throws ModelException {
Expand All @@ -112,25 +282,77 @@ public static void consumeValues(final Model m, Resource container, IRI containe
}, exceptionSupplier, contexts);
}

public static <C extends Collection<Statement>> C getContainer(IRI containerType, Model sourceModel, Resource head, C sink,
/**
* Extracts the <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Container</a> starting with the
* supplied {@code head} resource from the supplied source {@link Model}. The statements making up the RDF
* Container will be added to the supplied statement collection, which will also be returned.
*
* @param containerType defines the type of RDF Container
* @param sourceModel the source model, containing the RDF Container to be read.
* @param container the {@link Resource} that represents the container head, that is the start resource of the RDF
* Container to be read. May not be {@code null}. a {@link Collection} of {@link Statement}
* objects (for example a {@link Model}) to which the RDF Container statements will be added.
* May not be {@code null}.
* @param sink a {@link Collection} of {@link Statement} objects (for example a {@link Model}) to which the
* RDF Container statements will be added. May not be {@code null}.
* @param contexts the context(s) from which to read the RDF Container. This argument is an optional vararg and
* can be left out.
* @return the supplied sink {@link Collection} of {@link Statement}s, with the Statements of the RDF Container
* added.
*/
public static <C extends Collection<Statement>> C getContainer(IRI containerType, Model sourceModel, Resource container, C sink,
Resource... contexts) {
Objects.requireNonNull(sourceModel, "input model may not be null");
extract(containerType, sourceModel, head, st -> sink.add(st), contexts);
extract(containerType, sourceModel, container, st -> sink.add(st), contexts);
return sink;
}

/**
* Extracts the <a href="https://www.w3.org/TR/rdf-schema/#ch_container">RDF Container</a> starting with
* supplied {@code head} resource from the supplied source {@link Model} and sends the statements that make up the
* collection to the supplied {@link Consumer}.
*
* @param containerType defines the type of RDF Container
* @param sourceModel the source model, containing the RDF Container to be read.
* @param container the {@link Resource} that represents the container head, that is the start resource of the RDF
* Container to be read. May not be {@code null}. a {@link Collection} of {@link Statement}
* objects (for example a {@link Model}) to which the RDF Container statements will be added.
* May not be {@code null}.
* @param consumer the {@link Consumer} function for the Statements of the RDF Container. May not be
* {@code null}.
* @param contexts the context(s) from which to read the RDF Container. This argument is an optional vararg and
* can be left out.
*/
public static void extract(IRI containerType, Model sourceModel, Resource container, Consumer<Statement> consumer, Resource... contexts) {
Objects.requireNonNull(sourceModel, "source model may not be null");
GetStatementOptional statementSupplier = (s, p, o,
c) -> ((Model) sourceModel).filter(s, p, o, c).stream().findAny();
extract(containerType, statementSupplier, container, consumer, Models::modelException, contexts);
}

/**
* Extracts an RDF Container starting with the supplied container head from the statement supplier and sends all
* statements that make up the collection to the supplied {@link Consumer} function. This method expects the RDF
* Container to be well-formed. If the collection is not well-formed the method may report only part of the
* collection, or may throw an exception.
*
* @param containerType defines the type of RDF Container
* @param statementSupplier the source of the statements from which the RDF Container is to be read, specified as
* a functional interface.
* @param container the {@link Resource} that represents the container head, that is the start resource of the
* RDF Container to be read. May not be {@code null}.
* @param collectionConsumer the Java {@link Consumer} function to which the collection statements are reported.
* @param exceptionSupplier a functional interface that produces the exception type this method will throw when an
* error occurs.
* @param contexts the context(s) from which to read the RDF Container. This argument is an optional
* vararg and can be left out.
* @throws E if a problem occurs reading the RDF Container, for example if it is not well-formed.
*/
public static <E extends RDF4JException> void extract(IRI containerType, GetStatementOptional statementSupplier, Resource container,
Consumer<Statement> collectionConsumer, Function<String, Supplier<E>> exceptionSupplier,
Resource... contexts) throws E {
OpenRDFUtil.verifyContextNotNull(contexts);
Objects.requireNonNull(container, "list head may not be null");
Objects.requireNonNull(container, "containter head may not be null");
Objects.requireNonNull(collectionConsumer, "collection consumer may not be null");

ValueFactory vf = SimpleValueFactory.getInstance();
Expand Down

0 comments on commit d768b86

Please sign in to comment.