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