nl.topicus.jdbc.shaded.com.google.cloud.PageImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spanner-jdbc Show documentation
Show all versions of spanner-jdbc Show documentation
JDBC Driver for Google Cloud Spanner
/*
* Copyright 2015 Google LLC
*
* 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.
*/
package nl.topicus.jdbc.shaded.com.google.cloud;
import nl.topicus.jdbc.shaded.com.google.api.core.InternalApi;
import nl.topicus.jdbc.shaded.com.google.api.gax.paging.Page;
import nl.topicus.jdbc.shaded.com.google.common.collect.AbstractIterator;
import nl.topicus.jdbc.shaded.com.google.common.collect.ImmutableMap;
import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
/**
* Base implementation for Google Cloud paginated results.
*
* @param the value type that the page holds
*/
@InternalApi
public class PageImpl implements Page, Serializable {
private static final long serialVersionUID = 3914827379823557934L;
private final String cursor;
private final Iterable results;
private final NextPageFetcher pageFetcher;
/**
* Interface for fetching the next page of results from the service.
*
* @param the value type that the page holds
*/
public interface NextPageFetcher extends Serializable {
Page getNextPage();
}
static class PageIterator extends AbstractIterator {
private Iterator currentPageIterator;
private Page currentPage;
PageIterator(Page currentPage) {
this.currentPageIterator = currentPage.getValues().iterator();
this.currentPage = currentPage;
}
@Override
protected T computeNext() {
while (!currentPageIterator.hasNext()) {
currentPage = currentPage.getNextPage();
if (currentPage == null) {
return endOfData();
}
currentPageIterator = currentPage.getValues().iterator();
}
return currentPageIterator.next();
}
}
/**
* Creates a {@code PageImpl} object. In order for the object to be serializable the {@code
* results} parameter must be serializable.
*/
public PageImpl(NextPageFetcher pageFetcher, String cursor, Iterable results) {
this.pageFetcher = pageFetcher;
this.cursor = cursor;
this.results = results;
}
@Override
public Iterable getValues() {
return results == null ? Collections.emptyList() : results;
}
@Override
public Iterable iterateAll() {
return new Iterable() {
@Override
public Iterator iterator() {
return new PageIterator<>(PageImpl.this);
}
};
}
@Override
public boolean hasNextPage() {
return getNextPageToken() != null && !getNextPageToken().equals("");
}
@Override
public String getNextPageToken() {
return cursor;
}
@Override
public Page getNextPage() {
if (cursor == null || pageFetcher == null) {
return null;
}
return pageFetcher.getNextPage();
}
@Override
public int hashCode() {
return Objects.hash(cursor, results);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PageImpl)) {
return false;
}
PageImpl> other = (PageImpl>) obj;
return Objects.equals(cursor, other.cursor)
&& Objects.equals(results, other.results);
}
/**
* Utility method to construct the options map for the next page request.
*
* @param the value type that the page holds. Instances of {@code T} should be
* {@code Serializable}
* @param pageTokenOption the key for the next page cursor option in the options map
* @param cursor the cursor for the next page
* @param optionMap the previous options map
* @return the options map for the next page request
*/
public static Map nextRequestOptions(
T pageTokenOption, String cursor, Map optionMap) {
ImmutableMap.Builder builder = ImmutableMap.builder();
if (cursor != null) {
builder.put(pageTokenOption, cursor);
}
for (Map.Entry option : optionMap.entrySet()) {
if (!Objects.equals(option.getKey(), pageTokenOption)) {
builder.put(option.getKey(), option.getValue());
}
}
return builder.build();
}
}