View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.commons.rdf.api;
19  
20  import java.util.ConcurrentModificationException;
21  import java.util.Iterator;
22  import java.util.Optional;
23  import java.util.stream.Stream;
24  
25  /**
26   * An <a href="http://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset">RDF
27   * 1.1 Dataset</a>, a set of RDF quads, as defined by
28   * <a href="http://www.w3.org/TR/rdf11-concepts/#section-rdf-dataset">RDF-1.1 Concepts and Abstract
29   * Syntax</a>, a W3C Recommendation published on 25 February 2014.
30   *
31   * @since 0.3.0-incubating
32   * @see RDF#createDataset()
33   */
34  public interface Dataset extends AutoCloseable, GraphLike<Quad> {
35  
36      /**
37       * Add a quad to the dataset, possibly mapping any of the components of the
38       * Quad to those supported by this dataset.
39       *
40       * @param quad
41       *            The quad to add
42       */
43      @Override
44      void add(Quad quad);
45  
46      /**
47       * Add a quad to the dataset, possibly mapping any of the components to
48       * those supported by this dataset.
49       *
50       * @param graphName
51       *            The graph the quad belongs to, or <code>null</code> for the
52       *            default graph
53       * @param subject
54       *            The quad subject
55       * @param predicate
56       *            The quad predicate
57       * @param object
58       *            The quad object
59       */
60      void add(BlankNodeOrIRI graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
61  
62      /**
63       * Check if dataset contains quad.
64       *
65       * @param quad
66       *            The quad to check.
67       * @return True if the dataset contains the given Quad.
68       */
69      @Override
70      boolean contains(Quad quad);
71  
72      /**
73       * Check if dataset contains a pattern of quads.
74       *
75       * @param graphName
76       *            The graph the quad belongs to, wrapped as an {@link Optional}
77       *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
78       *            the default graph)
79       * @param subject
80       *            The quad subject (<code>null</code> is a wildcard)
81       * @param predicate
82       *            The quad predicate (<code>null</code> is a wildcard)
83       * @param object
84       *            The quad object (<code>null</code> is a wildcard)
85       * @return True if the dataset contains any quads that match the given
86       *         pattern.
87       */
88      boolean contains(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
89  
90      /**
91       * Close the dataset, relinquishing any underlying resources.
92       * <p>
93       * For example, this would close any open file and network streams and free
94       * database locks held by the dataset implementation.
95       * <p>
96       * The behaviour of the other dataset methods are undefined after closing
97       * the dataset.
98       * <p>
99       * Implementations might not need {@link #close()}, hence the default
100      * implementation does nothing.
101      */
102     @Override
103     default void close() throws Exception {
104     }
105 
106     /**
107      * Get the default graph of this dataset.
108      * <p>
109      * The {@link Triple}s of the default graph are equivalent to the
110      * {@link Quad}s in this Dataset which has the {@link Quad#getGraphName()}
111      * set to {@link Optional#empty()}.
112      * <p>
113      * It is unspecified if modifications to the returned Graph are reflected in
114      * this Dataset.
115      * <p>
116      * The returned graph MAY be empty.
117      *
118      * @see #getGraph(BlankNodeOrIRI)
119      * @return The default graph of this Dataset
120      */
121     Graph getGraph();
122 
123     /**
124      * Get a named graph in this dataset.
125      * <p>
126      * The {@link Triple}s of the named graph are equivalent to the the Quads of
127      * this Dataset which has the {@link Quad#getGraphName()} equal to the
128      * provided <code>graphName</code>, or equal to {@link Optional#empty()} if
129      * the provided <code>graphName</code> is <code>null</code>.
130      * <p>
131      * It is unspecified if modifications to the returned Graph are reflected in
132      * this Dataset.
133      * <p>
134      * It is unspecified if requesting an unknown or empty graph will return
135      * {@link Optional#empty()} or create a new empty {@link Graph}.
136      *
137      * @see #getGraph()
138      * @see #getGraphNames()
139      * @param graphName
140      *            The name of the graph, or <code>null</code> for the default
141      *            graph.
142      * @return The named Graph, or {@link Optional#empty()} if the dataset do
143      *         not contain the named graph.
144      */
145     Optional<Graph> getGraph(BlankNodeOrIRI graphName);
146 
147     /**
148      * Get the graph names in this Dataset.
149      * <p>
150      * The set of returned graph names is equivalent to the set of unique
151      * {@link Quad#getGraphName()} of all the {@link #stream()} of this dataset
152      * (excluding the default graph).
153      * <p>
154      * The returned {@link Stream} SHOULD NOT contain duplicate graph names.
155      * <p>
156      * The graph names can be used with {@link #getGraph(BlankNodeOrIRI)} to
157      * retrieve the corresponding {@link Graph}, however callers should be aware
158      * of any concurrent modifications to the Dataset may cause such calls to
159      * return {@link Optional#empty()}.
160      * <p>
161      * Note that a Dataset always contains a <strong>default graph</strong>
162      * which is not named, and thus is not represented in the returned Stream.
163      * The default graph is accessible via {@link #getGraph()} or by using
164      * {@link Optional#empty()} in the Quad access methods).
165      *
166      * @return A {@link Stream} of the graph names of this Dataset.
167      */
168     Stream<BlankNodeOrIRI> getGraphNames();
169 
170     /**
171      * Remove a concrete quad from the dataset.
172      *
173      * @param quad
174      *            quad to remove
175      */
176     @Override
177     void remove(Quad quad);
178 
179     /**
180      * Remove a concrete pattern of quads from the default graph of the dataset.
181      *
182      * @param graphName
183      *            The graph the quad belongs to, wrapped as an {@link Optional}
184      *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
185      *            the default graph)
186      * @param subject
187      *            The quad subject (<code>null</code> is a wildcard)
188      * @param predicate
189      *            The quad predicate (<code>null</code> is a wildcard)
190      * @param object
191      *            The quad object (<code>null</code> is a wildcard)
192      */
193     void remove(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate, RDFTerm object);
194 
195     /**
196      * Clear the dataset, removing all quads.
197      */
198     @Override
199     void clear();
200 
201     /**
202      * Number of quads contained by the dataset.
203      * <p>
204      * The count of a set does not include duplicates, consistent with the
205      * {@link Quad#equals(Object)} equals method for each {@link Quad}.
206      *
207      * @return The number of quads in the dataset
208      */
209     @Override
210     long size();
211 
212     /**
213      * Get all quads contained by the dataset.<br>
214      * <p>
215      * The iteration does not contain any duplicate quads, as determined by the
216      * {@link Quad#equals(Object)} method for each {@link Quad}.
217      * <p>
218      * The behaviour of the {@link Stream} is not specified if
219      * {@link #add(Quad)}, {@link #remove(Quad)} or {@link #clear()} are called
220      * on the {@link Dataset} before it terminates.
221      * <p>
222      * Implementations may throw {@link ConcurrentModificationException} from
223      * Stream methods if they detect a conflict while the Stream is active.
224      *
225      * @return A {@link Stream} over all of the quads in the dataset
226      */
227     @Override
228     Stream<? extends Quad> stream();
229 
230     /**
231      * Get all quads contained by the dataset matched with the pattern.
232      * <p>
233      * The iteration does not contain any duplicate quads, as determined by the
234      * {@link Quad#equals(Object)} method for each {@link Quad}.
235      * <p>
236      * The behaviour of the {@link Stream} is not specified if
237      * {@link #add(Quad)}, {@link #remove(Quad)} or {@link #clear()} are called
238      * on the {@link Dataset} before it terminates.
239      * <p>
240      * Implementations may throw {@link ConcurrentModificationException} from
241      * Stream methods if they detect a conflict while the Stream is active.
242      *
243      * @param graphName
244      *            The graph the quad belongs to, wrapped as an {@link Optional}
245      *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
246      *            the default graph)
247      * @param subject
248      *            The quad subject (<code>null</code> is a wildcard)
249      * @param predicate
250      *            The quad predicate (<code>null</code> is a wildcard)
251      * @param object
252      *            The quad object (<code>null</code> is a wildcard)
253      * @return A {@link Stream} over the matched quads.
254      */
255     Stream<? extends Quad> stream(Optional<BlankNodeOrIRI> graphName, BlankNodeOrIRI subject, IRI predicate,
256             RDFTerm object);
257 
258     /**
259      * Get an Iterable for iterating over all quads in the dataset.
260      * <p>
261      * This method is meant to be used with a Java for-each loop, e.g.:
262      *
263      * <pre>
264      * for (Quad t : dataset.iterate()) {
265      *     System.out.println(t);
266      * }
267      * </pre>
268      *
269      * The behaviour of the iterator is not specified if {@link #add(Quad)},
270      * {@link #remove(Quad)} or {@link #clear()}, are called on the
271      * {@link Dataset} before it terminates. It is undefined if the returned
272      * {@link Iterator} supports the {@link Iterator#remove()} method.
273      * <p>
274      * Implementations may throw {@link ConcurrentModificationException} from
275      * Iterator methods if they detect a concurrency conflict while the Iterator
276      * is active.
277      * <p>
278      * The {@link Iterable#iterator()} must only be called once, that is the
279      * Iterable must only be iterated over once. A {@link IllegalStateException}
280      * may be thrown on attempt to reuse the Iterable.
281      * <p>
282      * The default implementation of this method will call {@link #stream()} to
283      * return its {@link Stream#iterator()}.
284      *
285      * @return A {@link Iterable} that returns {@link Iterator} over all of the
286      *         quads in the dataset
287      * @throws IllegalStateException
288      *             if the {@link Iterable} has been reused
289      * @throws ConcurrentModificationException
290      *             if a concurrency conflict occurs while the Iterator is
291      *             active.
292      */
293     @Override
294     @SuppressWarnings("unchecked")
295     default Iterable<Quad> iterate() throws ConcurrentModificationException, IllegalStateException {
296         return ((Stream<Quad>) stream())::iterator;
297     }
298 
299     /**
300      * Get an Iterable for iterating over the quads in the dataset that match
301      * the pattern.
302      * <p>
303      * This method is meant to be used with a Java for-each loop, e.g.:
304      *
305      * <pre>
306      * IRI alice = factory.createIRI("http://example.com/alice");
307      * IRI knows = factory.createIRI("http://xmlns.com/foaf/0.1/");
308      * for (Quad t : dataset.iterate(null, alice, knows, null)) {
309      *     System.out.println(t.getGraphName());
310      *     System.out.println(t.getObject());
311      * }
312      * </pre>
313      * <p>
314      * The behaviour of the iterator is not specified if {@link #add(Quad)},
315      * {@link #remove(Quad)} or {@link #clear()}, are called on the
316      * {@link Dataset} before it terminates. It is undefined if the returned
317      * {@link Iterator} supports the {@link Iterator#remove()} method.
318      * <p>
319      * Implementations may throw {@link ConcurrentModificationException} from
320      * Iterator methods if they detect a concurrency conflict while the Iterator
321      * is active.
322      * <p>
323      * The {@link Iterable#iterator()} must only be called once, that is the
324      * Iterable must only be iterated over once. A {@link IllegalStateException}
325      * may be thrown on attempt to reuse the Iterable.
326      * <p>
327      * The default implementation of this method will call
328      * {@link #stream(Optional, BlankNodeOrIRI, IRI, RDFTerm)} to return its
329      * {@link Stream#iterator()}.
330      *
331      * @param graphName
332      *            The graph the quad belongs to, wrapped as an {@link Optional}
333      *            (<code>null</code> is a wildcard, {@link Optional#empty()} is
334      *            the default graph)
335      * @param subject
336      *            The quad subject (<code>null</code> is a wildcard)
337      * @param predicate
338      *            The quad predicate (<code>null</code> is a wildcard)
339      * @param object
340      *            The quad object (<code>null</code> is a wildcard)
341      * @return A {@link Iterable} that returns {@link Iterator} over the
342      *         matching quads in the dataset
343      * @throws IllegalStateException
344      *             if the {@link Iterable} has been reused
345      * @throws ConcurrentModificationException
346      *             if a concurrency conflict occurs while the Iterator is
347      *             active.
348      */
349     @SuppressWarnings("unchecked")
350     default Iterable<Quad> iterate(final Optional<BlankNodeOrIRI> graphName, final BlankNodeOrIRI subject, final IRI predicate,
351             final RDFTerm object) throws ConcurrentModificationException, IllegalStateException {
352         return ((Stream<Quad>) stream(graphName, subject, predicate, object))::iterator;
353     }
354 }