All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kohsuke.github.GraphQLPageIterator Maven / Gradle / Ivy

package org.kohsuke.github;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Function;

/**
 * Used for any GraphQL resource that has pagination information.
 * 

* This class is not thread-safe. Any one instance should only be called from a single thread. * * @param the type parameter * @author Hiroyuki Wada */ public class GraphQLPageIterator, U> implements Iterator { private static final ObjectMapper mapper = new ObjectMapper(); private final GitHubClient client; private final Class type; private final GraphQLSearchVariables variables; private Function, GraphQLPageInfo> findNext; private T next; private GitHubRequest nextRequest; private GitHubResponse finalResponse = null; private GraphQLPageIterator(GitHubClient client, Class type, GitHubRequest request, GraphQLSearchVariables variables, Function, GraphQLPageInfo> nextFinder) { if (!"POST".equals(request.method())) { throw new IllegalStateException("Request method \"POST\" is required for GraphQL page iterator."); } this.client = client; this.type = type; this.nextRequest = request; this.variables = variables; this.findNext = nextFinder; } static , U> GraphQLPageIterator create(GitHubClient client, Class type, GitHubRequest request, GraphQLSearchVariables variables, Function, GraphQLPageInfo> nextFinder) { try { GitHubRequest.Builder builder = request.toBuilder().set("variables", mapper.writeValueAsString(variables)); request = builder.build(); return new GraphQLPageIterator<>(client, type, request, variables, nextFinder); } catch (MalformedURLException | JsonProcessingException e) { throw new GHException("Unable to build GitHub GraphQL API URL", e); } } public boolean hasNext() { fetch(); return next != null; } public T next() { fetch(); T result = next; if (result == null) throw new NoSuchElementException(); // If this is the last page, keep the response next = null; return result; } public GitHubResponse finalResponse() { if (hasNext()) { throw new GHException("Final response is not available until after iterator is done."); } return finalResponse; } private void fetch() { if (next != null) return; // already fetched if (nextRequest == null) return; // no more data to fetch URL url = nextRequest.url(); try { GitHubResponse nextResponse = client.sendRequest(nextRequest, (responseInfo) -> GitHubResponse.parseBody(responseInfo, type)); assert nextResponse.body() != null; next = nextResponse.body(); if (next == null) { throw new GHException("GraphQL API returns error"); } GraphQLPageInfo pageInfo = findNext.apply(nextResponse.body()); if (pageInfo == null || !pageInfo.hasNextPage) { finalResponse = nextResponse; nextRequest = null; return; } GraphQLSearchVariables nextVariables = variables.next(pageInfo); nextRequest = nextResponse.request().toBuilder() .set("variables", mapper.writeValueAsString(nextVariables)) .build(); } catch (IOException e) { // Iterators do not throw IOExceptions, so we wrap any IOException // in a runtime GHException to bubble out if needed. throw new GHException("Failed to retrieve " + url, e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy