blob: 3c0e56809150c2f63e2d8b4a079233ce2f633999 [file] [log] [blame]
/**
* 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.api;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Optional;
import java.util.stream.Stream;
/**
* An <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset">RDF
* 1.1 Dataset</a>, a set of RDF quads, as defined by
* <a href="http://www.w3.org/TR/rdf11-concepts/#section-rdf-dataset">RDF-1.1 Concepts and Abstract
* Syntax</a>, a W3C Recommendation published on 25 February 2014.
*
* @since 0.3.0-incubating
* @see RDF#createDataset()
*/
public interface Dataset extends AutoCloseable, GraphLike<Quad> {
/**
* Add a quad to the dataset, possibly mapping any of the components of the
* Quad to those supported by this dataset.
*
* @param quad
* The quad to add
*/
@Override
void add(Quad quad);
/**
* Add a quad to the dataset, possibly mapping any of the components to
* those supported by this dataset.
*
* @param graphName
* The graph the quad belongs to, or <code>null</code> for the
* default graph
* @param subject
* The quad subject
* @param predicate
* The quad predicate
* @param object
* The quad object
*/
void add(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
/**
* Check if dataset contains quad.
*
* @param quad
* The quad to check.
* @return True if the dataset contains the given Quad.
*/
@Override
boolean contains(Quad quad);
/**
* Check if dataset contains a pattern of quads.
*
* @param graphName
* The graph the quad belongs to, wrapped as an {@link Optional}
* (<code>null</code> is a wildcard, {@link Optional#empty()} is
* the default graph)
* @param subject
* The quad subject (<code>null</code> is a wildcard)
* @param predicate
* The quad predicate (<code>null</code> is a wildcard)
* @param object
* The quad object (<code>null</code> is a wildcard)
* @return True if the dataset contains any quads that match the given
* pattern.
*/
boolean contains(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
/**
* Close the dataset, relinquishing any underlying resources.
* <p>
* For example, this would close any open file and network streams and free
* database locks held by the dataset implementation.
* <p>
* The behaviour of the other dataset methods are undefined after closing
* the dataset.
* <p>
* Implementations might not need {@link #close()}, hence the default
* implementation does nothing.
*/
@Override
default void close() throws Exception {
}
/**
* Get the default graph of this dataset.
* <p>
* The {@link Triple}s of the default graph are equivalent to the
* {@link Quad}s in this Dataset which has the {@link Quad#getGraphName()}
* set to {@link Optional#empty()}.
* <p>
* It is unspecified if modifications to the returned Graph are reflected in
* this Dataset.
* <p>
* The returned graph MAY be empty.
*
* @see #getGraph(BlankNodeOrIRI)
* @return The default graph of this Dataset
*/
Graph getGraph();
/**
* Get a named graph in this dataset.
* <p>
* The {@link Triple}s of the named graph are equivalent to the Quads of
* this Dataset which has the {@link Quad#getGraphName()} equal to the
* provided <code>graphName</code>, or equal to {@link Optional#empty()} if
* the provided <code>graphName</code> is <code>null</code>.
* <p>
* It is unspecified if modifications to the returned Graph are reflected in
* this Dataset.
* <p>
* It is unspecified if requesting an unknown or empty graph will return
* {@link Optional#empty()} or create a new empty {@link Graph}.
*
* @see #getGraph()
* @see #getGraphNames()
* @param graphName
* The name of the graph, or <code>null</code> for the default
* graph.
* @return The named Graph, or {@link Optional#empty()} if the dataset do
* not contain the named graph.
*/
Optional<Graph> getGraph(BlankNodeOrIRI graphName);
/**
* Get the graph names in this Dataset.
* <p>
* The set of returned graph names is equivalent to the set of unique
* {@link Quad#getGraphName()} of all the {@link #stream()} of this dataset
* (excluding the default graph).
* <p>
* The returned {@link Stream} SHOULD NOT contain duplicate graph names.
* <p>
* The graph names can be used with {@link #getGraph(BlankNodeOrIRI)} to
* retrieve the corresponding {@link Graph}, however callers should be aware
* of any concurrent modifications to the Dataset may cause such calls to
* return {@link Optional#empty()}.
* <p>
* Note that a Dataset always contains a <strong>default graph</strong>
* which is not named, and thus is not represented in the returned Stream.
* The default graph is accessible via {@link #getGraph()} or by using
* {@link Optional#empty()} in the Quad access methods).
*
* @return A {@link Stream} of the graph names of this Dataset.
*/
Stream<BlankNodeOrIRI> getGraphNames();
/**
* Remove a concrete quad from the dataset.
*
* @param quad
* quad to remove
*/
@Override
void remove(Quad quad);
/**
* Remove a concrete pattern of quads from the default graph of the dataset.
*
* @param graphName
* The graph the quad belongs to, wrapped as an {@link Optional}
* (<code>null</code> is a wildcard, {@link Optional#empty()} is
* the default graph)
* @param subject
* The quad subject (<code>null</code> is a wildcard)
* @param predicate
* The quad predicate (<code>null</code> is a wildcard)
* @param object
* The quad object (<code>null</code> is a wildcard)
*/
void remove(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
/**
* Clear the dataset, removing all quads.
*/
@Override
void clear();
/**
* Number of quads contained by the dataset.
* <p>
* The count of a set does not include duplicates, consistent with the
* {@link Quad#equals(Object)} equals method for each {@link Quad}.
*
* @return The number of quads in the dataset
*/
@Override
long size();
/**
* Get all quads contained by the dataset.<br>
* <p>
* The iteration does not contain any duplicate quads, as determined by the
* {@link Quad#equals(Object)} method for each {@link Quad}.
* <p>
* The behaviour of the {@link Stream} is not specified if
* {@link #add(Quad)}, {@link #remove(Quad)} or {@link #clear()} are called
* on the {@link Dataset} before it terminates.
* <p>
* Implementations may throw {@link ConcurrentModificationException} from
* Stream methods if they detect a conflict while the Stream is active.
*
* @return A {@link Stream} over all of the quads in the dataset
*/
@Override
Stream<? extends Quad> stream();
/**
* Get all quads contained by the dataset matched with the pattern.
* <p>
* The iteration does not contain any duplicate quads, as determined by the
* {@link Quad#equals(Object)} method for each {@link Quad}.
* <p>
* The behaviour of the {@link Stream} is not specified if
* {@link #add(Quad)}, {@link #remove(Quad)} or {@link #clear()} are called
* on the {@link Dataset} before it terminates.
* <p>
* Implementations may throw {@link ConcurrentModificationException} from
* Stream methods if they detect a conflict while the Stream is active.
*
* @param graphName
* The graph the quad belongs to, wrapped as an {@link Optional}
* (<code>null</code> is a wildcard, {@link Optional#empty()} is
* the default graph)
* @param subject
* The quad subject (<code>null</code> is a wildcard)
* @param predicate
* The quad predicate (<code>null</code> is a wildcard)
* @param object
* The quad object (<code>null</code> is a wildcard)
* @return A {@link Stream} over the matched quads.
*/
Stream<? extends Quad> stream(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate,
RDFTerm object);
/**
* Get an Iterable for iterating over all quads in the dataset.
* <p>
* This method is meant to be used with a Java for-each loop, e.g.:
*
* <pre>
* for (Quad t : dataset.iterate()) {
* System.out.println(t);
* }
* </pre>
*
* The behaviour of the iterator is not specified if {@link #add(Quad)},
* {@link #remove(Quad)} or {@link #clear()}, are called on the
* {@link Dataset} before it terminates. It is undefined if the returned
* {@link Iterator} supports the {@link Iterator#remove()} method.
* <p>
* Implementations may throw {@link ConcurrentModificationException} from
* Iterator methods if they detect a concurrency conflict while the Iterator
* is active.
* <p>
* The {@link Iterable#iterator()} must only be called once, that is the
* Iterable must only be iterated over once. A {@link IllegalStateException}
* may be thrown on attempt to reuse the Iterable.
* <p>
* The default implementation of this method will call {@link #stream()} to
* return its {@link Stream#iterator()}.
*
* @return A {@link Iterable} that returns {@link Iterator} over all of the
* quads in the dataset
* @throws IllegalStateException
* if the {@link Iterable} has been reused
* @throws ConcurrentModificationException
* if a concurrency conflict occurs while the Iterator is
* active.
*/
@Override
@SuppressWarnings("unchecked")
default Iterable<Quad> iterate() throws ConcurrentModificationException, IllegalStateException {
return ((Stream<Quad>) stream())::iterator;
}
/**
* Get an Iterable for iterating over the quads in the dataset that match
* the pattern.
* <p>
* This method is meant to be used with a Java for-each loop, e.g.:
*
* <pre>
* IRI alice = factory.createIRI("http://example.com/alice");
* IRI knows = factory.createIRI("http://xmlns.com/foaf/0.1/");
* for (Quad t : dataset.iterate(null, alice, knows, null)) {
* System.out.println(t.getGraphName());
* System.out.println(t.getObject());
* }
* </pre>
* <p>
* The behaviour of the iterator is not specified if {@link #add(Quad)},
* {@link #remove(Quad)} or {@link #clear()}, are called on the
* {@link Dataset} before it terminates. It is undefined if the returned
* {@link Iterator} supports the {@link Iterator#remove()} method.
* <p>
* Implementations may throw {@link ConcurrentModificationException} from
* Iterator methods if they detect a concurrency conflict while the Iterator
* is active.
* <p>
* The {@link Iterable#iterator()} must only be called once, that is the
* Iterable must only be iterated over once. A {@link IllegalStateException}
* may be thrown on attempt to reuse the Iterable.
* <p>
* The default implementation of this method will call
* {@link #stream(Optional, BlankNodeOrIRI, IRI, RDFTerm)} to return its
* {@link Stream#iterator()}.
*
* @param graphName
* The graph the quad belongs to, wrapped as an {@link Optional}
* (<code>null</code> is a wildcard, {@link Optional#empty()} is
* the default graph)
* @param subject
* The quad subject (<code>null</code> is a wildcard)
* @param predicate
* The quad predicate (<code>null</code> is a wildcard)
* @param object
* The quad object (<code>null</code> is a wildcard)
* @return A {@link Iterable} that returns {@link Iterator} over the
* matching quads in the dataset
* @throws IllegalStateException
* if the {@link Iterable} has been reused
* @throws ConcurrentModificationException
* if a concurrency conflict occurs while the Iterator is
* active.
*/
@SuppressWarnings("unchecked")
default Iterable<Quad> iterate(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate,
final RDFTerm object) throws ConcurrentModificationException, IllegalStateException {
return ((Stream<Quad>) stream(graphName, subject, predicate, object))::iterator;
}
}