Skip to content
36 changes: 22 additions & 14 deletions src/main/java/com/twilio/base/Page.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
import java.util.List;

public class Page<T> {
private final List<T> records;
private final String firstPageUrl;
private final String firstPageUri;
private final String nextPageUrl;
private final String nextPageUri;
private final String previousPageUrl;
private final String previousPageUri;
private final String url;
private final String uri;
private final int pageSize;

private Page(Builder<T> b) {
protected final List<T> records;
protected final String firstPageUrl;
protected final String firstPageUri;
protected final String nextPageUrl;
protected final String nextPageUri;
protected final String previousPageUrl;
protected final String previousPageUri;
protected final String url;
protected final String uri;
protected final int pageSize;

protected Page(Builder<T> b) {
this.records = b.records;
this.firstPageUri = b.firstPageUri;
this.firstPageUrl = b.firstPageUrl;
Expand All @@ -33,7 +33,7 @@ private Page(Builder<T> b) {
this.pageSize = b.pageSize;
}

private String urlFromUri(String domain, String uri) {
protected String urlFromUri(String domain, String uri) {
return "https://" + domain + ".twilio.com" + uri;
}

Expand Down Expand Up @@ -101,6 +101,14 @@ public String getUrl(String domain) {
return urlFromUri(domain, uri);
}

public String previousQueryString() {
return "";
}

public String nextQueryString() {
return "";
}

public boolean hasNextPage() {
return (nextPageUri != null && !nextPageUri.isEmpty()) || (nextPageUrl != null && !nextPageUrl.isEmpty());
}
Expand Down Expand Up @@ -198,7 +206,7 @@ private static <T> Page<T> buildNextGenPage(JsonNode root, List<T> results) {
return builder.records(results).build();
}

private static class Builder<T> {
protected static class Builder<T> {
private List<T> records;
private String firstPageUrl;
private String firstPageUri;
Expand Down
172 changes: 172 additions & 0 deletions src/main/java/com/twilio/base/TokenPaginationPage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package com.twilio.base;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.twilio.exception.ApiConnectionException;
import com.twilio.exception.ApiException;
import lombok.Getter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class TokenPaginationPage<T> extends Page<T> {
@Getter
private final String key;
private final String nextToken;
private final String previousToken;

private TokenPaginationPage(Builder<T> b) {
super(b);
this.key = b.key;
this.nextToken = b.nextToken;
this.previousToken = b.previousToken;
}

// adding custom getter and not using lombok to handle null token
// when token is null, lombok getter returns "null" not a null object
public String getNextToken() {
return nextToken;
}

public String getPreviousToken() {
return previousToken;
}

@Override
public String previousQueryString() {
return getQueryString(previousToken);
}

@Override
public String nextQueryString() {
return getQueryString(nextToken);
}

private void addQueryOperators(StringBuilder query) {
if(query.length() == 0) {
query.append("?");
} else {
query.append("&");
}
}

private String getQueryString(String pageToken) {
StringBuilder query = new StringBuilder();
if (pageSize > 0) {
addQueryOperators(query);
query.append("pageSize=").append(pageSize);
}
if(pageToken != null && !pageToken.isEmpty()) {
addQueryOperators(query);
query.append("pageToken=").append(pageToken);
}
return query.toString();
}

/**
* Checks if there is a next page of records available.
*
* @return true if a next page is available, false otherwise
*/
@Override
public boolean hasNextPage() {
return (nextToken != null && !nextToken.isEmpty());
}


/**
* Create a new page of data from a json blob.
*
* @param recordKey key which holds the records
* @param json json blob
* @param recordType resource type
* @param mapper json parser
* @param <T> record class type
* @return a page of records of type T
*/
public static <T> TokenPaginationPage<T> fromJson(String recordKey, String json, Class<T> recordType, ObjectMapper mapper) {

Check warning on line 88 in src/main/java/com/twilio/base/TokenPaginationPage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused method parameter "recordKey".

See more on https://sonarcloud.io/project/issues?id=twilio_twilio-java&issues=AZpTg0Q3LxTehwL5A5b-&open=AZpTg0Q3LxTehwL5A5b-&pullRequest=917
try {
List<T> results = new ArrayList<>();
JsonNode root = mapper.readTree(json);
try {

Check warning on line 92 in src/main/java/com/twilio/base/TokenPaginationPage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested try block into a separate method.

See more on https://sonarcloud.io/project/issues?id=twilio_twilio-java&issues=AZpYp3E5L8C5IfvBzOjT&open=AZpYp3E5L8C5IfvBzOjT&pullRequest=917
JsonNode meta = root.get("meta");
String key = meta.get("key").asText();
JsonNode records = root.get(key);
for (final JsonNode record : records) {

Check warning on line 96 in src/main/java/com/twilio/base/TokenPaginationPage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this variable to not match a restricted identifier.

See more on https://sonarcloud.io/project/issues?id=twilio_twilio-java&issues=AZpOX1dLlbo70Nvtetl2&open=AZpOX1dLlbo70Nvtetl2&pullRequest=917
results.add(mapper.readValue(record.toString(), recordType));
}

return buildPage(meta, results);
} catch (NullPointerException e) {
throw new ApiException("Key not found", e);
}

} catch (final IOException e) {
throw new ApiConnectionException(
"Unable to deserialize response: " + e.getMessage() + "\nJSON: " + json, e
);
}
}

private static <T> TokenPaginationPage<T> buildPage(JsonNode meta, List<T> results) {
try {
Builder<T> builder = new Builder<T>()
.key(meta.get("key").asText());

JsonNode nextTokenNode = meta.get("nextToken");
if (nextTokenNode != null && !nextTokenNode.isNull()) {
builder.nextToken(nextTokenNode.asText());
}

JsonNode previousTokenNode = meta.get("previousToken");
if (previousTokenNode != null && !previousTokenNode.isNull()) {
builder.previousToken(previousTokenNode.asText());
}

JsonNode pageSizeNode = meta.get("pageSize");
builder.pageSize(pageSizeNode.asInt());

return builder.records(results).build();
} catch (NullPointerException e) {
throw new ApiException("Key not found", e);
}
}

protected static class Builder<T> extends Page.Builder<T> {
private String key;
private String nextToken;
private String previousToken;

@Override
public Builder<T> records(List<T> records) {
super.records(records);
return this;
}

@Override
public Builder<T> pageSize(int pageSize) {
super.pageSize(pageSize);
return this;
}

public Builder<T> key(String key) {
this.key = key;
return this;
}

public Builder<T> nextToken(String nextToken) {
this.nextToken = nextToken;
return this;
}

public Builder<T> previousToken(String previousToken) {
this.previousToken = previousToken;
return this;
}

public TokenPaginationPage<T> build() {

Check warning on line 168 in src/main/java/com/twilio/base/TokenPaginationPage.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add the "@Override" annotation above this method signature

See more on https://sonarcloud.io/project/issues?id=twilio_twilio-java&issues=AZpTg0Q3LxTehwL5A5b_&open=AZpTg0Q3LxTehwL5A5b_&pullRequest=917
return new TokenPaginationPage<>(this);
}
}
}
Loading