001package com.box.sdk; 002 003import com.eclipsesource.json.JsonObject; 004import com.eclipsesource.json.JsonValue; 005import java.io.IOException; 006import java.io.InputStream; 007import java.io.OutputStream; 008import java.net.URL; 009import java.text.ParseException; 010import java.util.Date; 011 012/** 013 * Represents a particular version of a file on Box. 014 */ 015@BoxResourceType("file_version") 016public class BoxFileVersion extends BoxResource { 017 /** 018 * Content URL Template. 019 */ 020 public static final URLTemplate CONTENT_URL_TEMPLATE = new URLTemplate("files/%s/content?version=%s"); 021 /** 022 * Version URL Template. 023 */ 024 public static final URLTemplate VERSION_URL_TEMPLATE = new URLTemplate("files/%s/versions/%s"); 025 private static final int BUFFER_SIZE = 8192; 026 027 private String fileID; 028 029 private String versionID; 030 private String sha1; 031 private String name; 032 private long size; 033 private String uploaderDisplayName; 034 private Date createdAt; 035 private Date modifiedAt; 036 private BoxUser.Info modifiedBy; 037 private Date trashedAt; 038 private BoxUser.Info trashedBy; 039 private Date restoredAt; 040 private BoxUser.Info restoredBy; 041 private Date purgedAt; 042 private BoxFileVersion fileVersion; 043 044 /** 045 * Constructs a BoxFileVersion from a JSON string. 046 * 047 * @param api the API connection to be used by the file. 048 * @param json the JSON encoded file version. 049 * @param fileID the ID of the file. 050 */ 051 public BoxFileVersion(BoxAPIConnection api, String json, String fileID) { 052 this(api, JsonObject.readFrom(json), fileID); 053 } 054 055 BoxFileVersion(BoxAPIConnection api, JsonObject jsonObject, String fileID) { 056 super(api, jsonObject.get("id").asString()); 057 058 this.fileID = fileID; 059 this.parseJSON(jsonObject); 060 } 061 062 /** 063 * Method used to update fields with values received from API. 064 * 065 * @param jsonObject JSON-encoded info about File Version object. 066 */ 067 private void parseJSON(JsonObject jsonObject) { 068 for (JsonObject.Member member : jsonObject) { 069 JsonValue value = member.getValue(); 070 if (value.isNull()) { 071 continue; 072 } 073 074 try { 075 String memberName = member.getName(); 076 if (memberName.equals("id")) { 077 this.versionID = value.asString(); 078 } else if (memberName.equals("sha1")) { 079 this.sha1 = value.asString(); 080 } else if (memberName.equals("name")) { 081 this.name = value.asString(); 082 } else if (memberName.equals("size")) { 083 this.size = Double.valueOf(value.toString()).longValue(); 084 } else if (memberName.equals("uploader_display_name")) { 085 this.uploaderDisplayName = value.asString(); 086 } else if (memberName.equals("created_at")) { 087 this.createdAt = BoxDateFormat.parse(value.asString()); 088 } else if (memberName.equals("modified_at")) { 089 this.modifiedAt = BoxDateFormat.parse(value.asString()); 090 } else if (memberName.equals("trashed_at")) { 091 this.trashedAt = BoxDateFormat.parse(value.asString()); 092 } else if (memberName.equals("trashed_by")) { 093 JsonObject userJSON = value.asObject(); 094 String userID = userJSON.get("id").asString(); 095 BoxUser user = new BoxUser(getAPI(), userID); 096 this.trashedBy = user.new Info(userJSON); 097 } else if (memberName.equals("modified_by")) { 098 JsonObject userJSON = value.asObject(); 099 String userID = userJSON.get("id").asString(); 100 BoxUser user = new BoxUser(getAPI(), userID); 101 this.modifiedBy = user.new Info(userJSON); 102 } else if (memberName.equals("restored_at")) { 103 this.restoredAt = BoxDateFormat.parse(value.asString()); 104 } else if (memberName.equals("restored_by")) { 105 JsonObject userJSON = value.asObject(); 106 String userID = userJSON.get("id").asString(); 107 BoxUser user = new BoxUser(getAPI(), userID); 108 this.restoredBy = user.new Info(userJSON); 109 } else if (memberName.equals("purged_at")) { 110 this.purgedAt = BoxDateFormat.parse(value.asString()); 111 } else if (memberName.equals("file_version")) { 112 JsonObject fileVersionJson = value.asObject(); 113 String fileVersionId = fileVersionJson.get("id").asString(); 114 this.fileVersion = new BoxFileVersion(getAPI(), fileVersionJson, fileVersionId); 115 } 116 } catch (ParseException e) { 117 assert false : "A ParseException indicates a bug in the SDK."; 118 } 119 } 120 } 121 122 /** 123 * @return the file id this file version belongs to. 124 */ 125 public String getFileID() { 126 return this.fileID; 127 } 128 129 /** 130 * Used if no or wrong file id was set with constructor. 131 * 132 * @param fileID the file id this file version belongs to. 133 */ 134 public void setFileID(String fileID) { 135 this.fileID = fileID; 136 } 137 138 /** 139 * Gets the version ID of this version of the file. 140 * 141 * @return the version ID of this version of the file. 142 */ 143 public String getVersionID() { 144 return this.versionID; 145 } 146 147 /** 148 * Gets the SHA1 hash of this version of the file. 149 * 150 * @return the SHA1 hash of this version of the file. 151 */ 152 public String getSha1() { 153 return this.sha1; 154 } 155 156 /** 157 * Gets the name of this version of the file. 158 * 159 * @return the name of this version of the file. 160 */ 161 public String getName() { 162 return this.name; 163 } 164 165 /** 166 * Gets the size of this version of the file. 167 * 168 * @return the size of this version of the file. 169 */ 170 public long getSize() { 171 return this.size; 172 } 173 174 /** 175 * Gets the time that this version of the file was created. 176 * 177 * @return the time that this version of the file was created. 178 */ 179 public Date getCreatedAt() { 180 return this.createdAt; 181 } 182 183 /** 184 * Gets the user's name at the time of upload. 185 * 186 * @return the time user's name at the time of upload. 187 */ 188 public String getUploaderDisplayName() { 189 return this.uploaderDisplayName; 190 } 191 192 /** 193 * Gets the time that this version of the file was modified. 194 * 195 * @return the time that this version of the file was modified. 196 */ 197 public Date getModifiedAt() { 198 return this.modifiedAt; 199 } 200 201 /** 202 * Gets the time that this version of the file was deleted. 203 * 204 * @return the time that this version of the file was deleted. 205 */ 206 public Date getTrashedAt() { 207 return this.trashedAt; 208 } 209 210 /** 211 * Gets information about the user who trashed this version of the file. 212 * 213 * @return info about the user who trashed this version of the file. 214 */ 215 public BoxUser.Info getTrashedBy() { 216 return this.trashedBy; 217 } 218 219 /** 220 * Gets information about the user who last modified this version of the file. 221 * 222 * @return info about the user who last modified this version of the file. 223 */ 224 public BoxUser.Info getModifiedBy() { 225 return this.modifiedBy; 226 } 227 228 /** 229 * Gets the time that this version of the file was restored. 230 * 231 * @return the time that this version of the file was restored. 232 */ 233 public Date getRestoredAt() { 234 return this.restoredAt; 235 } 236 237 /** 238 * Gets information about the user who restored this version of the file. 239 * 240 * @return info about the user who restored this version of the file. 241 */ 242 public BoxUser.Info getRestoredBy() { 243 return this.restoredBy; 244 } 245 246 /** 247 * Gets the time that this version of the file was purged. 248 * 249 * @return the time that this version of the file was purged. 250 */ 251 public Date getPurgedAt() { 252 return this.purgedAt; 253 } 254 255 /** 256 * Gets the file version for file version under retention. 257 * 258 * @return the file version for file version under retention. 259 */ 260 public BoxFileVersion getFileVersion() { 261 return this.fileVersion; 262 } 263 264 /** 265 * Deletes this version of the file. 266 */ 267 public void delete() { 268 URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID()); 269 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 270 BoxAPIResponse response = request.send(); 271 response.disconnect(); 272 } 273 274 /** 275 * Downloads this version of the file to a given OutputStream. 276 * 277 * @param output the stream to where the file will be written. 278 */ 279 public void download(OutputStream output) { 280 this.download(output, null); 281 } 282 283 /** 284 * Downloads this version of the file to a given OutputStream while reporting the progress to a ProgressListener. 285 * 286 * @param output the stream to where the file will be written. 287 * @param listener a listener for monitoring the download's progress. 288 */ 289 public void download(OutputStream output, ProgressListener listener) { 290 URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID()); 291 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 292 BoxAPIResponse response = request.send(); 293 InputStream input = response.getBody(listener); 294 295 long totalRead = 0; 296 byte[] buffer = new byte[BUFFER_SIZE]; 297 try { 298 int n = input.read(buffer); 299 totalRead += n; 300 while (n != -1) { 301 output.write(buffer, 0, n); 302 n = input.read(buffer); 303 totalRead += n; 304 } 305 } catch (IOException e) { 306 throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e); 307 } 308 309 response.disconnect(); 310 } 311 312 /** 313 * Promotes this version of the file to be the latest version. 314 */ 315 public void promote() { 316 URL url = VERSION_URL_TEMPLATE.buildAlpha(this.getAPI().getBaseURL(), this.fileID, "current"); 317 318 JsonObject jsonObject = new JsonObject(); 319 jsonObject.add("type", "file_version"); 320 jsonObject.add("id", this.getID()); 321 322 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 323 request.setBody(jsonObject.toString()); 324 BoxJSONResponse response = (BoxJSONResponse) request.send(); 325 this.parseJSON(JsonObject.readFrom(response.getJSON())); 326 } 327}