/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.runtime.module.extension.internal.runtime.streaming;
import static java.util.Optional.empty;
import static org.apache.commons.collections.CollectionUtils.isEmpty;
import static org.slf4j.LoggerFactory.getLogger;
import org.mule.runtime.extension.api.runtime.streaming.PagingProvider;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
/**
* This implementation of {@link PagingProvider} takes care of enforcing some basic behaviour of the delegate contract so that
* users don't have to. Concerns such as logging, auto closing the delegate if the consumer has been fully consumed are addressed
* here
*
* @param <C> connection type expected to handle the operations.
* @param <T> the type of the elements in the returned pages.
* @since 3.5.0
*/
final class PagingProviderWrapper<C, T> implements PagingProvider<C, T> {
private static final Logger LOGGER = getLogger(PagingProviderWrapper.class);
private final PagingProvider<C, T> delegate;
private boolean closed = false;
public PagingProviderWrapper(PagingProvider<C, T> delegate) {
this.delegate = delegate;
}
/**
* {@inheritDoc} Sets the closed flag to true and then delegates into the wrapped instance
*/
@Override
public void close() throws IOException {
closed = true;
delegate.close();
}
private void handleCloseException(Throwable t) {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("Exception was found trying to close paging delegate. Execution will continue", t);
}
}
/**
* {@inheritDoc} This implementation already takes care of returning <code>null</code> if the delegate is closed or if the
* obtained page is <code>null</code> or empty. It delegates into the wrapped instance to actually obtain the page.
*/
@Override
public List<T> getPage(C connection) {
if (closed) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("paging delegate is closed. Returning null");
}
return null;
}
List<T> page = delegate.getPage(connection);
if (isEmpty(page)) {
try {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Empty page was obtained. Closing delegate since this means that the data source has been consumed");
}
close();
} catch (Exception e) {
handleCloseException(e);
}
}
return page;
}
@Override
public Optional<Integer> getTotalResults(C connection) {
Optional<Integer> size = delegate.getTotalResults(connection);
return size != null ? size : empty();
}
@Override
public boolean useStickyConnections() {
return delegate.useStickyConnections();
}
}