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