001package com.box.sdk; 002 003import java.io.IOException; 004import java.io.InputStream; 005import java.io.OutputStream; 006import java.net.URL; 007import java.text.ParseException; 008import java.util.Date; 009 010import com.eclipsesource.json.JsonObject; 011import com.eclipsesource.json.JsonValue; 012 013/** 014 * Represents a particular version of a file on Box. 015 */ 016@BoxResourceType("file_version") 017public class BoxFileVersion extends BoxResource { 018 private static final URLTemplate CONTENT_URL_TEMPLATE = new URLTemplate("files/%s/content?version=%s"); 019 private static final URLTemplate VERSION_URL_TEMPLATE = new URLTemplate("files/%s/versions/%s"); 020 private static final int BUFFER_SIZE = 8192; 021 022 private String fileID; 023 024 private String versionID; 025 private String sha1; 026 private String name; 027 private long size; 028 private Date createdAt; 029 private Date modifiedAt; 030 private BoxUser.Info modifiedBy; 031 private Date trashedAt; 032 033 /** 034 * Constructs a BoxFileVersion from a JSON string. 035 * @param api the API connection to be used by the file. 036 * @param json the JSON encoded file version. 037 * @param fileID the ID of the file. 038 */ 039 public BoxFileVersion(BoxAPIConnection api, String json, String fileID) { 040 this(api, JsonObject.readFrom(json), fileID); 041 } 042 043 BoxFileVersion(BoxAPIConnection api, JsonObject jsonObject, String fileID) { 044 super(api, jsonObject.get("id").asString()); 045 046 this.fileID = fileID; 047 this.parseJSON(jsonObject); 048 } 049 050 /** 051 * Method used to update fields with values received from API. 052 * @param jsonObject JSON-encoded info about File Version object. 053 */ 054 private void parseJSON(JsonObject jsonObject) { 055 for (JsonObject.Member member : jsonObject) { 056 JsonValue value = member.getValue(); 057 if (value.isNull()) { 058 continue; 059 } 060 061 try { 062 String memberName = member.getName(); 063 if (memberName.equals("id")) { 064 this.versionID = value.asString(); 065 } else if (memberName.equals("sha1")) { 066 this.sha1 = value.asString(); 067 } else if (memberName.equals("name")) { 068 this.name = value.asString(); 069 } else if (memberName.equals("size")) { 070 this.size = Double.valueOf(value.toString()).longValue(); 071 } else if (memberName.equals("created_at")) { 072 this.createdAt = BoxDateFormat.parse(value.asString()); 073 } else if (memberName.equals("modified_at")) { 074 this.modifiedAt = BoxDateFormat.parse(value.asString()); 075 } else if (memberName.equals("trashed_at")) { 076 this.trashedAt = BoxDateFormat.parse(value.asString()); 077 } else if (memberName.equals("modified_by")) { 078 JsonObject userJSON = value.asObject(); 079 String userID = userJSON.get("id").asString(); 080 BoxUser user = new BoxUser(getAPI(), userID); 081 this.modifiedBy = user.new Info(userJSON); 082 } 083 } catch (ParseException e) { 084 assert false : "A ParseException indicates a bug in the SDK."; 085 } 086 } 087 } 088 089 /** 090 * Used if no or wrong file id was set with constructor. 091 * @param fileID the file id this file version belongs to. 092 */ 093 public void setFileID(String fileID) { 094 this.fileID = fileID; 095 } 096 097 /** 098 * @return the file id this file version belongs to. 099 */ 100 public String getFileID() { 101 return this.fileID; 102 } 103 104 /** 105 * Gets the version ID of this version of the file. 106 * @return the version ID of this version of the file. 107 */ 108 public String getVersionID() { 109 return this.versionID; 110 } 111 112 /** 113 * Gets the SHA1 hash of this version of the file. 114 * @return the SHA1 hash of this version of the file. 115 */ 116 public String getSha1() { 117 return this.sha1; 118 } 119 120 /** 121 * Gets the name of this version of the file. 122 * @return the name of this version of the file. 123 */ 124 public String getName() { 125 return this.name; 126 } 127 128 /** 129 * Gets the size of this version of the file. 130 * @return the size of this version of the file. 131 */ 132 public long getSize() { 133 return this.size; 134 } 135 136 /** 137 * Gets the time that this version of the file was created. 138 * @return the time that this version of the file was created. 139 */ 140 public Date getCreatedAt() { 141 return this.createdAt; 142 } 143 144 /** 145 * Gets the time that this version of the file was modified. 146 * @return the time that this version of the file was modified. 147 */ 148 public Date getModifiedAt() { 149 return this.modifiedAt; 150 } 151 152 /** 153 * Gets the time that this version of the file was deleted. 154 * @return the time that this version of the file was deleted. 155 */ 156 public Date getTrashedAt() { 157 return this.trashedAt; 158 } 159 160 /** 161 * Gets information about the user who last modified this version of the file. 162 * @return info about the user who last modified this version of the file. 163 */ 164 public BoxUser.Info getModifiedBy() { 165 return this.modifiedBy; 166 } 167 168 /** 169 * Deletes this version of the file. 170 */ 171 public void delete() { 172 URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID()); 173 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 174 BoxAPIResponse response = request.send(); 175 response.disconnect(); 176 } 177 178 /** 179 * Downloads this version of the file to a given OutputStream. 180 * @param output the stream to where the file will be written. 181 */ 182 public void download(OutputStream output) { 183 this.download(output, null); 184 } 185 186 /** 187 * Downloads this version of the file to a given OutputStream while reporting the progress to a ProgressListener. 188 * @param output the stream to where the file will be written. 189 * @param listener a listener for monitoring the download's progress. 190 */ 191 public void download(OutputStream output, ProgressListener listener) { 192 URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID()); 193 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 194 BoxAPIResponse response = request.send(); 195 InputStream input = response.getBody(listener); 196 197 long totalRead = 0; 198 byte[] buffer = new byte[BUFFER_SIZE]; 199 try { 200 int n = input.read(buffer); 201 totalRead += n; 202 while (n != -1) { 203 output.write(buffer, 0, n); 204 n = input.read(buffer); 205 totalRead += n; 206 } 207 } catch (IOException e) { 208 throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e); 209 } 210 211 response.disconnect(); 212 } 213 214 /** 215 * Promotes this version of the file to be the latest version. 216 */ 217 public void promote() { 218 URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, "current"); 219 220 JsonObject jsonObject = new JsonObject(); 221 jsonObject.add("type", "file_version"); 222 jsonObject.add("id", this.getID()); 223 224 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 225 request.setBody(jsonObject.toString()); 226 BoxJSONResponse response = (BoxJSONResponse) request.send(); 227 this.parseJSON(JsonObject.readFrom(response.getJSON())); 228 } 229}