170 lines
3.8 KiB
Java
170 lines
3.8 KiB
Java
package org.gcube.data.streams.adapters;
|
|
|
|
import gr.uoa.di.madgik.grs.buffer.IBuffer.Status;
|
|
import gr.uoa.di.madgik.grs.reader.ForwardReader;
|
|
import gr.uoa.di.madgik.grs.reader.GRS2ReaderException;
|
|
import gr.uoa.di.madgik.grs.record.Record;
|
|
import gr.uoa.di.madgik.grs.record.exception.GRS2UncheckedException;
|
|
|
|
import java.net.URI;
|
|
import java.util.Iterator;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import org.gcube.data.streams.LookAheadStream;
|
|
import org.gcube.data.streams.Stream;
|
|
import org.gcube.data.streams.exceptions.StreamException;
|
|
import org.gcube.data.streams.exceptions.StreamOpenException;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
/**
|
|
* A {@link Stream} adapter for gRS2 resultsets.
|
|
* <p>
|
|
* This implementation is not thread safe.
|
|
*
|
|
* @author Fabio Simeoni
|
|
*
|
|
*/
|
|
public class ResultsetStream<E extends Record> extends LookAheadStream<E> {
|
|
|
|
private static Logger log =LoggerFactory.getLogger(ResultsetStream.class);
|
|
|
|
public static final int default_timeout = 30;
|
|
public static final TimeUnit default_timeout_unit=TimeUnit.SECONDS;
|
|
|
|
private final URI locator;
|
|
|
|
private long timeout = default_timeout;
|
|
private TimeUnit timeoutUnit = default_timeout_unit;
|
|
|
|
private boolean open=false;
|
|
private boolean closed=false;
|
|
private RuntimeException lookAheadFailure;
|
|
|
|
private ForwardReader<E> reader;
|
|
private Iterator<E> iterator;
|
|
|
|
|
|
/**
|
|
* Creates a new instance with a result set locator.
|
|
* @param locator the locator.
|
|
* @throws IllegalArgumentException if the locator is <code>null</code>.
|
|
* */
|
|
public ResultsetStream(URI locator) throws IllegalArgumentException {
|
|
|
|
if (locator==null)
|
|
throw new IllegalArgumentException("invalid or null locator");
|
|
|
|
this.locator=locator;
|
|
|
|
}
|
|
|
|
public void setTimeout(long timeout, TimeUnit unit) throws IllegalArgumentException {
|
|
|
|
if (timeout<=0 || timeoutUnit==null)
|
|
throw new IllegalArgumentException("invalid timeout or null timeout unit");
|
|
|
|
this.timeout = timeout;
|
|
this.timeoutUnit = unit;
|
|
}
|
|
|
|
@Override
|
|
protected E delegateNext() {
|
|
|
|
try {
|
|
if (lookAheadFailure!=null)
|
|
throw lookAheadFailure;
|
|
else
|
|
try {
|
|
return iterator.next();
|
|
}
|
|
catch(GRS2UncheckedException e) {
|
|
|
|
//get underlying cause
|
|
Throwable cause = e.getCause();
|
|
|
|
//rewrap checked cause as appropriate to this layer
|
|
if (cause instanceof RuntimeException)
|
|
throw (RuntimeException) cause;
|
|
else
|
|
throw new StreamException(cause);
|
|
}
|
|
}
|
|
finally {
|
|
lookAheadFailure=null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected boolean delegateHasNext() {
|
|
|
|
if (closed)
|
|
return false;
|
|
|
|
if (!open) {
|
|
|
|
try {
|
|
reader = new ForwardReader<E>(locator);
|
|
reader.setIteratorTimeout(timeout);
|
|
reader.setIteratorTimeUnit(timeoutUnit);
|
|
}
|
|
catch (Throwable t) {
|
|
lookAheadFailure= new StreamOpenException("cannot open resultset "+locator,t);
|
|
return true;
|
|
}
|
|
|
|
iterator = reader.iterator();
|
|
|
|
log.info("initialised resultset at "+locator);
|
|
|
|
open=true;
|
|
}
|
|
|
|
//infer outage if reader has been dismissed remotely
|
|
if (reader.getStatus()==Status.Dispose && !closed)
|
|
lookAheadFailure= new RuntimeException("unrecoverable failure in resultset ");
|
|
|
|
boolean hasNext = iterator.hasNext();
|
|
|
|
return hasNext;
|
|
}
|
|
|
|
|
|
@Override
|
|
public void close() {
|
|
|
|
if (open) {
|
|
try {
|
|
reader.close();
|
|
log.info("closed resultset at "+locator);
|
|
}
|
|
catch(GRS2ReaderException e) {
|
|
log.error("could not close resultset",e);
|
|
}
|
|
open=false;
|
|
}
|
|
closed=true;
|
|
}
|
|
|
|
@Override
|
|
public URI locator() throws IllegalStateException {
|
|
|
|
if (open)
|
|
throw new IllegalStateException("locator is invalid as result set has already been opened");
|
|
else
|
|
return locator;
|
|
|
|
}
|
|
|
|
@Override
|
|
public void remove() {
|
|
iterator.remove();
|
|
}
|
|
|
|
@Override
|
|
public boolean isClosed() {
|
|
return closed;
|
|
}
|
|
}
|