001package com.box.sdk;
002
003import static com.box.sdk.BinaryBodyUtils.writeStream;
004
005import com.eclipsesource.json.Json;
006import com.eclipsesource.json.JsonArray;
007import com.eclipsesource.json.JsonObject;
008import java.io.OutputStream;
009import java.net.URL;
010import java.util.List;
011
012/**
013 * Provides methods to allow users to download multiple files and folders as a single zip file.
014 * Users can download up to either 32GB or 10,000 files in one batch (whichever limitation is hit
015 * first) as a single zip file.
016 */
017public class BoxZip {
018  /** Zip URL Template. */
019  public static final URLTemplate ZIP_URL_TEMPLATE = new URLTemplate("zip_downloads");
020
021  private final BoxAPIConnection api;
022
023  /**
024   * Constructs a Zip to be used by everything.
025   *
026   * @param api the API connection to be used by the Zip.
027   */
028  public BoxZip(BoxAPIConnection api) {
029    this.api = api;
030  }
031
032  /**
033   * Creates a zip of multiple files and folders.
034   *
035   * @param name the name of the zip file to be created
036   * @param items list of files or folders to be part of the created zip
037   * @return information about the created zip file
038   */
039  public BoxZipInfo create(String name, List<BoxZipItem> items) {
040    JsonArray itemsArray = new JsonArray();
041    for (BoxZipItem item : items) {
042      itemsArray.add(item.getJSONObject());
043    }
044    JsonObject requestJSON = new JsonObject();
045    requestJSON.add("items", itemsArray);
046    requestJSON.add("download_file_name", name);
047
048    URL url = ZIP_URL_TEMPLATE.build(this.getAPI().getBaseURL());
049    BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
050    request.setBody(requestJSON.toString());
051    try (BoxJSONResponse response = request.send()) {
052      JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
053      return new BoxZipInfo(responseJSON);
054    }
055  }
056
057  /**
058   * Creates a zip and downloads it to a given OutputStream.
059   *
060   * @param name the name of the zip file to be created
061   * @param items list of files or folders to be part of the created zip
062   * @param output the stream to where the zip file will be written.
063   * @return information about status of the download
064   */
065  public BoxZipDownloadStatus download(String name, List<BoxZipItem> items, OutputStream output) {
066    return this.download(name, items, output, null);
067  }
068
069  /**
070   * Creates a zip and downloads its contents its to a given OutputStream.
071   *
072   * @param name the name of the zip file to be created
073   * @param items list of files or folders to be part of the created zip
074   * @param output the stream to where the zip file will be written.
075   * @param listener a listener for monitoring the download's progress.
076   * @return information about status of the download
077   */
078  public BoxZipDownloadStatus download(
079      String name, List<BoxZipItem> items, OutputStream output, ProgressListener listener) {
080    BoxZipInfo zipInfo = this.create(name, items);
081    BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), zipInfo.getDownloadURL(), "GET");
082    BoxAPIResponse response = request.send();
083    writeStream(response, output, listener);
084    BoxJSONRequest statusRequest = new BoxJSONRequest(this.getAPI(), zipInfo.getStatusURL(), "GET");
085    try (BoxJSONResponse statusResponse = statusRequest.send()) {
086      JsonObject statusResponseJSON = Json.parse(statusResponse.getJSON()).asObject();
087      return new BoxZipDownloadStatus(statusResponseJSON);
088    }
089  }
090
091  /**
092   * Gets the API connection used by this resource.
093   *
094   * @return the API connection used by this resource.
095   */
096  public BoxAPIConnection getAPI() {
097    return this.api;
098  }
099}