edu.byu.hbll.box.client.AbstractHttpBoxClient Maven / Gradle / Ivy
The newest version!
package edu.byu.hbll.box.client;
import edu.byu.hbll.box.BoxDocument;
import edu.byu.hbll.box.BoxQuery;
import edu.byu.hbll.box.QueryResult;
import edu.byu.hbll.box.internal.core.DocumentIterable;
import edu.byu.hbll.box.internal.util.BoxUriBuilder;
import edu.byu.hbll.json.ObjectMapperFactory;
import edu.byu.hbll.json.UncheckedObjectMapper;
import edu.byu.hbll.misc.BatchIterable.Batch;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URI;
import java.util.List;
import java.util.Objects;
import lombok.Data;
/**
* A client for communicating with Box through it's web api.
*
* @author Charles Draper
*/
public abstract class AbstractHttpBoxClient implements BoxClient {
private static final UncheckedObjectMapper mapper = ObjectMapperFactory.newUnchecked();
private static final int MAX_URI_LENGTH = 2048;
private static final int ID_PARAM_OVERHEAD = "&id=".length();
private URI uri;
/**
* Creates a new client.
*
* @param uri the base uri of the box source (eg, http://localhost:8080/app/box)
*/
public AbstractHttpBoxClient(URI uri) {
this.uri = Objects.requireNonNull(uri);
}
@Override
public QueryResult collect(BoxQuery query) {
if (query.isIdQuery()) {
BoxQuery batchQuery = new BoxQuery(query).clearIds();
QueryResult result = new QueryResult();
for (List batch :
Batch.of(query.getIds())
.capacity(MAX_URI_LENGTH - getBaseUriLength(batchQuery))
.scale(i -> i.length() + ID_PARAM_OVERHEAD)) {
batchQuery.clearIds().addIds(batch);
result.addAll(retrieve(batchQuery));
}
return result;
} else {
return retrieve(query);
}
}
@Override
public Iterable find(BoxQuery query) {
return new DocumentIterable(query, q -> retrieve(q));
}
/**
* Returns the base uri for the box.
*
* @return the uri
*/
public URI getUri() {
return uri;
}
/**
* Queries the upstream box client for documents.
*
* @param query the query to run
* @return the result of the query
*/
private QueryResult retrieve(BoxQuery query) {
URI uri = BoxUriBuilder.buildQuery(this.uri, query);
try (InputStream input = send(uri)) {
QueryResponse response = mapper.readValue(input, QueryResponse.class);
QueryResult result = new QueryResult(response.documents);
result.setNextCursor(response.nextCursor);
return result;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
/**
* Returns the length of the uri based on the given id query, but without ids. Note this is
* designed for id type queries.
*
* @param query the original box query
* @return the length of the resulting uri for the box query
*/
private int getBaseUriLength(BoxQuery query) {
BoxQuery lengthQuery = new BoxQuery(query).clearIds().addId("");
return BoxUriBuilder.buildQuery(this.uri, lengthQuery).toString().length() - ID_PARAM_OVERHEAD;
}
/**
* Sends the request to the Box server and returns the response as an input stream. This can be
* overridden by subclasses that require different HTTP clients. The input stream will be closed
* here.
*
* @param uri the full uri to send to box for the query
* @return the response body as an {@link InputStream}
*/
protected abstract InputStream send(URI uri);
/** Represents an http response from a box documents enpoint. */
@Data
public static class QueryResponse {
private List documents;
private long nextCursor;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy