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