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

io.gdcc.xoai.dataprovider.repository.ResultsPage Maven / Gradle / Ivy

package io.gdcc.xoai.dataprovider.repository;

import io.gdcc.xoai.dataprovider.exceptions.InternalOAIException;
import io.gdcc.xoai.model.oaipmh.ResumptionToken;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * A mapping POJO carrying a list of elements returned from application repositories. Contains also
 * information about the total number of results. Represents a page of results only - indicates the
 * presence of more data via a boolean flag.
 *
 * 

This item or sections of it might be used to create a cache of results within the application. * * @param The type of results. See {@link io.gdcc.xoai.dataprovider.model.Item}, {@link * io.gdcc.xoai.dataprovider.model.ItemIdentifier} and {@link * io.gdcc.xoai.dataprovider.model.Set} */ public final class ResultsPage { private final boolean hasMore; private final List resultsList; private final int totalResults; private final ResumptionToken.Value requestToken; /** * Create a page of results. Will verify nonsense combinations of parameters. * * @param requestToken The token a client (would) send in a request (might be precalculated to * cache pages) * @param hasMoreResults A flag to indicate if a client may ask for more results by sending the * response token value * @param resultsList The actual results for this page * @param totalResults The number of all results (sum of pages) * @throws NullPointerException when token or results are null * @throws InternalOAIException when semantic values of parameters don't make sense */ public ResultsPage( ResumptionToken.Value requestToken, boolean hasMoreResults, List resultsList, int totalResults) { Objects.requireNonNull(resultsList, "List of result may be empty but not null"); if (totalResults < 0) { throw new InternalOAIException("Number of results may not be negative " + totalResults); } if (resultsList.size() > totalResults) { throw new InternalOAIException( "Number of results (" + totalResults + ") may not be smaller than the list size " + resultsList.size()); } if (resultsList.isEmpty() && totalResults > 0) { throw new InternalOAIException( "Number of results (" + totalResults + ") may not be larger 0 with an empty result list"); } if (resultsList.isEmpty() && hasMoreResults) { throw new InternalOAIException( "Cannot indicate more results and have an empty result list"); } Objects.requireNonNull(requestToken, "Resumption token may not be null"); if (requestToken.isEmpty()) { throw new InternalOAIException("Result may not contain an empty resumption token"); } this.requestToken = requestToken; this.hasMore = hasMoreResults; this.resultsList = Collections.unmodifiableList(resultsList); this.totalResults = totalResults; } public boolean hasMore() { return hasMore; } public List getList() { return resultsList; } public int getTotal() { return this.totalResults; } /** * Access the resumption token of this request (this is the token the client sent us) * * @return The token the client sent us before */ public ResumptionToken.Value getRequestTokenValue() { return this.requestToken; } /** * Create a new resumption token value from this result. Will either carry the details and have * the offset shifted with the number of results or be empty to indicate this is the last page * of results. * *

The token value is independent of whether this was an initial request (offset would be 0). * Case 1) No more results: return empty token value Case 2) More results: return token value * with number of results in this page added to former offset * * @return The resumption token value to be sent to the client */ public ResumptionToken.Value getResponseTokenValue() { return hasMore() ? requestToken.next(resultsList.size()) : new ResumptionToken.ValueBuilder().build(); } /** * Create a new OAI-PMH response token model instance, already adding the cursor and * totalResults attributes and the appropriate token value, encoding this pages state of data * retrieval. * *

The token is independent of whether this was an initial request, see {@link * #getResponseTokenValue()} We simply add the cursor attribute (which is the offset encoded in * the request token value) and the total number of results attribute (given during page * creation). * * @return A <resumptionToken> to return to the harvesting client. */ public Optional getResponseToken(int maxResponseLength) { return totalResults > maxResponseLength ? Optional.of( new ResumptionToken(getResponseTokenValue()) .withCompleteListSize(totalResults) .withCursor(requestToken.getOffset())) : Optional.empty(); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ResultsPage)) return false; ResultsPage that = (ResultsPage) o; return hasMore == that.hasMore && totalResults == that.totalResults && resultsList.equals(that.resultsList) && requestToken.equals(that.requestToken); } @Override public int hashCode() { return Objects.hash(hasMore, resultsList, totalResults, requestToken); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy