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