/*
* (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others.
*
* Licensed 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.
*
* Contributors:
* Kevin Leturc
*/
package org.nuxeo.ecm.core.api;
import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator;
/**
* A cursor result which holds a DB cursor and additional information to scroll this DB cursor.
*
* @param <C> The cursor type.
* @param <O> The cursor item type.
* @since 9.1
*/
public class CursorResult<C, O> implements Iterator<O>, Closeable {
protected C cursor;
protected final int batchSize;
protected final int keepAliveSeconds;
protected long lastCallTimestamp;
public CursorResult(C cursor, int batchSize, int keepAliveSeconds) {
this.cursor = cursor;
this.batchSize = batchSize;
this.keepAliveSeconds = keepAliveSeconds;
this.lastCallTimestamp = System.currentTimeMillis();
}
public C getCursor() {
return cursor;
}
public int getBatchSize() {
return batchSize;
}
public void touch() {
lastCallTimestamp = System.currentTimeMillis();
}
public boolean timedOut() {
long now = System.currentTimeMillis();
return now - lastCallTimestamp > keepAliveSeconds * 1000;
}
@Override
public boolean hasNext() {
if (cursor == null) {
return false;
} else if (cursor instanceof Iterator) {
return ((Iterator) cursor).hasNext();
}
throw new IllegalStateException(
"Cursor doesn't implement Iterator interface, you must provide an implementation of #hasNext and #next method");
}
@Override
@SuppressWarnings("unchecked")
public O next() {
if (cursor instanceof Iterator) {
return ((Iterator<O>) cursor).next();
}
throw new IllegalStateException(
"Cursor doesn't implement Iterator interface, you must provide an implementation of #hasNext and #next method");
}
/**
* CAUTION: if your cursor doesn't implement {@link Closeable}, we just set the field to null
*/
@Override
public void close() {
if (cursor instanceof Closeable) {
try {
((Closeable) cursor).close();
} catch (IOException e) {
throw new NuxeoException("Unable to close cursor", e);
}
}
cursor = null;
}
}