package org.gcube.data.streams; import java.net.URI; import java.util.Iterator; import java.util.NoSuchElementException; import org.gcube.data.streams.adapters.IteratorStream; import org.gcube.data.streams.adapters.ResultsetStream; import org.gcube.data.streams.delegates.FoldedStream; import org.gcube.data.streams.delegates.GuardedStream; import org.gcube.data.streams.delegates.MonitoredStream; import org.gcube.data.streams.delegates.PipedStream; import org.gcube.data.streams.delegates.UnfoldedStream; import org.gcube.data.streams.dsl.Faults; import org.gcube.data.streams.dsl.Streams; import org.gcube.data.streams.exceptions.StreamOpenException; import org.gcube.data.streams.handlers.FaultHandler; import org.gcube.data.streams.publishers.RsPublisher; import org.gcube.data.streams.publishers.StreamPublisher; /** * An {@link Iterator} over the elements of a dataset of arbitrary origin, including memory, secondary storage, and * network. *

* *

Properties


* * Streams are: *

* *

* *

Implementations


* * There are predefined implementations that adapt the {@link Stream} interface to existing {@link Iterator}s and remote * gRS2 resultsets (cf. {@link IteratorStream} and {@link ResultsetStream}). *

* * Other predefined implementations transform, fold, and unfold the elements of existing streams (cf. * {@link PipedStream}, {@link FoldedStream}, {@link UnfoldedStream}). *

* * Additional implementations allow modular handling of stream faults and notify interested listeners of stream * iteration events (cf. {@link GuardedStream}, {@link MonitoredStream}). *

* * Finally, streams may be published outside the current runtime by implementations of the {@link StreamPublisher} * interface. A predefined implementation supports publication of streams as gRS2 resultsets (cf. {@link RsPublisher}). * *

* * All the available implementations can be fluently instantiated and configured with an embedded DSL (cf. * {@link Streams}). * *

Fault Handling


* * Clients can implement {@link FaultHandler}s to specify fault handling policies over streams, and then wrap streams in * {@link GuardedStream}s that apply they policies: * *
 * import static ....Streams.*; 
 * ...
 * Stream<T> stream = ...
 * 
 * FaultHandler handler = new FaultHandler() {
 *   public void handle(RuntimeException fault) {
 *    ...
 *   }
 * };
 * 
 * Stream<T> guarded = guard(stream).with(handler);
 * 
* * * {@link FaultHandler}s can ignore faults, rethrow them, rethrow different faults, or use the constant * {@link FaultHandler#iteration} to stop the iteration of the underlying stream (cf. {@link Iteration#stop()}) *

* * * Faults are unchecked exceptions thrown by {@link #next()}, often wrappers around an original cause. * {@link FaultHandler}s can use a fluent API to simplify the task of analysing fault causes (cf. {@link Faults}): * *

 * FaultHandler handler = new FaultHandler() {
 *  	public void handle(RuntimeException fault) {
 *           try {
 *           	throw causeOf(fault).as(SomeException.class,SomeOtherException.class);
 *           }
 *           catch(SomeException e) {...}
 *           catch(SomeOtherException e) {...}
 *        }
 * };
 * 
* *

Consumption


* * Clients may consume streams by explicitly iterating over their elements. Since streams are fallible and closeable, * the recommended idiom is the following: * *
 * Stream<T> stream = ...
 * try {
 *   while (stream.hasNext())
 *     ....stream.next()...
 * }
 * finally {
 *  stream.close();
 * }
 * 
* * Alternatively, clients may provide {@link Callback}s to generic {@link StreamConsumer}s that iterate on * behalf of clients. Using the simplifications of the DSL: * *
 * Stream<T> stream = ...
 * 
 * Callback<T> callback = new Callback<T>() {
 *  	public void consume(T element) {
 *           ...element...
 *        }
 * };
 * 
 * consume(stream).with(callback);
 * 
* * {@link Callback}s can control iteration through the {@link Iteration} constant (cf. {@link Callback#iteration}): * *
 * Callback<T> callback = new Callback<T>() {
 *  	public void consume(T element) {
 *  	    ...iteration.stop()...
 *  		...
 *        }
 * };
 * 
* * * * @param the type of elements iterated over * * @author Fabio Simeoni * */ public interface Stream extends Iterator { boolean hasNext(); /** * @throws NoSuchElementException if the stream has no more elements or it has been closed * @throws StreamOpenException if the stream cannot be opened * @throws RuntimeException if the element cannot be returned */ E next(); /** * Returns the stream locator. * * @return the locator * @throws IllegalStateException if the stream is no longer addressable at the time of invocation. */ URI locator(); /** * Closes the stream unconditionally, releasing any resources that it may be using. *

* Subsequent invocations of this method have no effect.
* Subsequents invocations of {@link #hasNext()} return {@code false}.
* Subsequent invocations of {@link #next()} throw {@link NoSuchElementException}s. *

* Failures are logged by implementations and suppressed otherwise. */ void close(); /** * Returns true if the stream has been closed. * * @return true if the stream has been closed */ boolean isClosed(); }