001package com.box.sdk; 002 003import com.eclipsesource.json.Json; 004import com.eclipsesource.json.JsonObject; 005import com.eclipsesource.json.JsonValue; 006import java.net.MalformedURLException; 007import java.net.URL; 008import java.util.Date; 009 010/** 011 * Represents a file request on Box. 012 */ 013@BoxResourceType("file_request") 014public class BoxFileRequest extends BoxResource { 015 016 /** 017 * File Request URL Template. 018 */ 019 public static final URLTemplate FILE_REQUEST_URL_TEMPLATE = new URLTemplate("file_requests/%s"); 020 /** 021 * Copy File Request URL Template. 022 */ 023 public static final URLTemplate COPY_FILE_REQUEST_URL_TEMPLATE = new URLTemplate("file_requests/%s/copy"); 024 025 /** 026 * Constructs a BoxFileRequest for a file request with a given ID. 027 * 028 * @param api the API connection to be used by the file request. 029 * @param id the ID of the file request. 030 */ 031 public BoxFileRequest(BoxAPIConnection api, String id) { 032 super(api, id); 033 } 034 035 /** 036 * Gets information about this file request. 037 * 038 * @return info about this file request. 039 */ 040 public BoxFileRequest.Info getInfo() { 041 URL url = FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 042 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 043 BoxJSONResponse response = (BoxJSONResponse) request.send(); 044 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 045 return new Info(responseJSON, this.getAPI().getBaseAppUrl()); 046 } 047 048 /** 049 * Copies this file request that is already present on one folder, and applies it to another folder. 050 * 051 * @param folderId the ID of the folder for the file request. 052 * @return info about the newly copied file request. 053 */ 054 public BoxFileRequest.Info copyInfo(String folderId) { 055 URL url = COPY_FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 056 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 057 JsonObject body = new JsonObject(); 058 JsonObject folderBody = new JsonObject(); 059 folderBody.add("id", folderId); 060 folderBody.add("type", "folder"); 061 body.add("folder", folderBody); 062 request.setBody(body.toString()); 063 BoxJSONResponse response = (BoxJSONResponse) request.send(); 064 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 065 return new Info(jsonObject, this.getAPI().getBaseAppUrl()); 066 } 067 068 /** 069 * Copies this file request that is already present on one folder, and applies it to another folder. 070 * 071 * <p>Info fields that have been modified locally will overwrite the values in the original file request. 072 * 073 * @param info the info. 074 * @param folderId the ID of the folder for the file request. 075 * @return info about the newly copied file request. 076 */ 077 public BoxFileRequest.Info copyInfo(BoxFileRequest.Info info, String folderId) { 078 URL url = COPY_FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 079 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 080 JsonObject body = new JsonObject(); 081 JsonObject pendingChanges = info.getPendingChangesAsJsonObject(); 082 if (pendingChanges != null) { 083 body = pendingChanges; 084 } 085 JsonObject folderBody = new JsonObject(); 086 folderBody.add("id", folderId); 087 folderBody.add("type", "folder"); 088 body.add("folder", folderBody); 089 request.setBody(body.toString()); 090 BoxJSONResponse response = (BoxJSONResponse) request.send(); 091 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 092 info.update(jsonObject); 093 return new Info(jsonObject, this.getAPI().getBaseAppUrl()); 094 } 095 096 /** 097 * Updates the information about this file request with any info fields that have been modified locally. 098 * 099 * <p>The only fields that will be updated are the ones that have been modified locally. For example, the following 100 * code won't update any information (or even send a network request) since none of the info's fields were 101 * changed:</p> 102 * 103 * <pre>BoxFileRequest fileRequest = new BoxFileRequest(api, id); 104 * BoxFileRequest.Info info = fileRequest.getInfo(); 105 * info.updateInfo(info);</pre> 106 * 107 * @param info the updated info. 108 * @return info about the updated file request. 109 */ 110 public BoxFileRequest.Info updateInfo(BoxFileRequest.Info info) { 111 URL url = FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 112 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 113 request.setBody(info.getPendingChanges()); 114 BoxJSONResponse response = (BoxJSONResponse) request.send(); 115 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 116 info.update(jsonObject); 117 return info; 118 } 119 120 /** 121 * Delete this file request. 122 */ 123 public void delete() { 124 URL url = FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 125 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 126 BoxAPIResponse response = request.send(); 127 response.disconnect(); 128 } 129 130 /** 131 * The status of the file request. 132 */ 133 public enum Status { 134 /** 135 * The file request can accept new submissions. 136 */ 137 ACTIVE("active"), 138 139 /** 140 * The file request can't accept new submissions. 141 */ 142 INACTIVE("inactive"); 143 144 private final String jsonValue; 145 146 Status(String jsonValue) { 147 this.jsonValue = jsonValue; 148 } 149 150 static Status fromJSONString(String jsonValue) { 151 return Status.valueOf(jsonValue.toUpperCase()); 152 } 153 154 String toJSONString() { 155 return this.jsonValue; 156 } 157 } 158 159 /** 160 * Contains information about a BoxFileRequest. 161 */ 162 public class Info extends BoxResource.Info { 163 private String type; 164 private Date createdAt; 165 private BoxUser.Info createdBy; 166 private String description; 167 private String etag; 168 private Date expiresAt; 169 private BoxFolder.Info folder; 170 private boolean isDescriptionRequired; 171 private boolean isEmailRequired; 172 private Status status; 173 private String title; 174 private Date updatedAt; 175 private BoxUser.Info updatedBy; 176 private URL url; 177 private String path; 178 private String baseUrl; 179 180 /** 181 * Constructs an empty Info object. 182 */ 183 public Info() { 184 super(); 185 } 186 187 /** 188 * Constructs an Info object by parsing information from a JSON string. 189 * 190 * @param json the JSON string to parse. 191 */ 192 public Info(String json) { 193 super(json); 194 } 195 196 /** 197 * Constructs an Info object using an already parsed JSON object. 198 * 199 * @param jsonObject the parsed JSON object. 200 * @param fileRequestBaseUrl Request base URL 201 */ 202 Info(JsonObject jsonObject, String fileRequestBaseUrl) { 203 super(jsonObject); 204 try { 205 this.baseUrl = fileRequestBaseUrl; 206 this.url = new URL(this.baseUrl + this.path); 207 } catch (MalformedURLException e) { 208 throw new BoxAPIException("Couldn't construct url for file request", e); 209 } 210 } 211 212 @Override 213 public BoxFileRequest getResource() { 214 return BoxFileRequest.this; 215 } 216 217 /** 218 * Gets the file request type. 219 * 220 * @return the file request type. 221 */ 222 public String getType() { 223 return this.type; 224 } 225 226 /** 227 * Gets the date when the file request was created. 228 * 229 * @return the date when the file request was created. 230 */ 231 public Date getCreatedAt() { 232 return this.createdAt; 233 } 234 235 /** 236 * Gets the user who created this file request. 237 * 238 * @return the user who created this file request. 239 */ 240 public BoxUser.Info getCreatedBy() { 241 return this.createdBy; 242 } 243 244 /** 245 * Gets the description of this file request. 246 * 247 * @return the description of this file request. 248 */ 249 public String getDescription() { 250 return this.description; 251 } 252 253 /** 254 * Sets the description of this file request. 255 * 256 * @param description the file request's new description. 257 */ 258 public void setDescription(String description) { 259 this.description = description; 260 this.addPendingChange("description", description); 261 } 262 263 /** 264 * Gets a unique string identifying the version of the item. 265 * 266 * @return a unique string identifying the version of the item. 267 */ 268 public String getEtag() { 269 return this.etag; 270 } 271 272 /** 273 * Gets the date after which a file request will no longer accept new submissions. 274 * 275 * @return the date after which a file request will no longer accept new submissions. 276 */ 277 public Date getExpiresAt() { 278 return this.expiresAt; 279 } 280 281 282 /** 283 * Sets the date after which a file request will no longer accept new submissions. 284 * 285 * @param expiresAt the date after which a file request will no longer accept new submissions. 286 */ 287 public void setExpiresAt(Date expiresAt) { 288 this.expiresAt = expiresAt; 289 this.addPendingChange("expires_at", BoxDateFormat.format(expiresAt)); 290 } 291 292 /** 293 * Gets the folder that this file request is associated with. 294 * 295 * @return the folder that this file request is associated with. 296 */ 297 public BoxFolder.Info getFolder() { 298 return this.folder; 299 } 300 301 /** 302 * Gets whether a file request submitter is required to provide a description of the files they are submitting. 303 * 304 * @return whether a file request submitter is required to provide a description of the files they 305 * are submitting. 306 */ 307 public Boolean getIsDescriptionRequired() { 308 return this.isDescriptionRequired; 309 } 310 311 /** 312 * Sets whether a file request submitter is required to provide a description of the files they are submitting. 313 * 314 * @param isDescriptionRequired whether a file request submitter is required to provide a description of the 315 * files they are submitting. 316 */ 317 public void setIsDescriptionRequired(Boolean isDescriptionRequired) { 318 this.isDescriptionRequired = isDescriptionRequired; 319 this.addPendingChange("is_description_required", isDescriptionRequired); 320 } 321 322 /** 323 * Gets whether a file request submitter is required to provide their email address. 324 * 325 * @return whether a file request submitter is required to provide their email address. 326 */ 327 public Boolean getIsEmailRequired() { 328 return this.isEmailRequired; 329 } 330 331 /** 332 * Sets whether a file request submitter is required to provide their email address. 333 * 334 * @param isEmailRequired whether a file request submitter is required to provide their email address. 335 */ 336 public void setIsEmailRequired(Boolean isEmailRequired) { 337 this.isEmailRequired = isEmailRequired; 338 this.addPendingChange("is_email_required", isEmailRequired); 339 } 340 341 /** 342 * Gets the status of the file request. 343 * 344 * @return the status of the file request 345 */ 346 public Status getStatus() { 347 return this.status; 348 } 349 350 351 /** 352 * Sets the status of the file request. 353 * 354 * @param status the status of the file request 355 */ 356 public void setStatus(Status status) { 357 this.status = status; 358 this.addPendingChange("status", status.toJSONString()); 359 } 360 361 /** 362 * Gets the title of file request. 363 * 364 * @return the title of file request. 365 */ 366 public String getTitle() { 367 return this.title; 368 } 369 370 /** 371 * Sets the title of file request. 372 * 373 * @param title the title of file request. 374 */ 375 public void setTitle(String title) { 376 this.title = title; 377 this.addPendingChange("title", title); 378 } 379 380 /** 381 * Gets the date when the file request was last updated. 382 * 383 * @return the date when the file request was last updated. 384 */ 385 public Date getUpdatedAt() { 386 return this.updatedAt; 387 } 388 389 /** 390 * Gets the user who last modified this file request. 391 * 392 * @return the user who last modified this file request. 393 */ 394 public BoxUser.Info getUpdatedBy() { 395 return this.updatedBy; 396 } 397 398 /** 399 * Gets the URL can be shared with users to let them upload files to the associated folder. 400 * 401 * @return the URL for files upload. 402 */ 403 public URL getUrl() { 404 return this.url; 405 } 406 407 /** 408 * Gets the base URL for the upload files link. 409 * 410 * @return the base url including protocol and hostname. 411 */ 412 public String getBaseUrl() { 413 return this.baseUrl; 414 } 415 416 /** 417 * Sets the base URL for the upload files link. Can throw an exception if format of the URL is invalid. 418 * 419 * @param baseUrl the base url including protocol and hostname. 420 * @throws MalformedURLException when baseUrl format is invalid. 421 */ 422 public void setBaseUrl(String baseUrl) throws MalformedURLException { 423 this.baseUrl = baseUrl; 424 this.url = new URL(this.baseUrl + this.path); 425 } 426 427 /** 428 * Gets the URL containing only the path (e.g. "/f/123456789") shared with users to let 429 * them upload files to the associated folder. 430 * 431 * @return the path of the URL for files upload. 432 */ 433 public String getPath() { 434 return this.path; 435 } 436 437 @Override 438 void parseJSONMember(JsonObject.Member member) { 439 super.parseJSONMember(member); 440 441 String memberName = member.getName(); 442 JsonValue value = member.getValue(); 443 try { 444 if (memberName.equals("type")) { 445 this.type = value.asString(); 446 } else if (memberName.equals("created_at")) { 447 this.createdAt = BoxDateFormat.parse(value.asString()); 448 } else if (memberName.equals("created_by")) { 449 JsonObject userJSON = value.asObject(); 450 String userID = userJSON.get("id").asString(); 451 BoxUser user = new BoxUser(getAPI(), userID); 452 this.createdBy = user.new Info(userJSON); 453 } else if (memberName.equals("description")) { 454 this.description = value.asString(); 455 } else if (memberName.equals("etag")) { 456 this.etag = value.asString(); 457 } else if (memberName.equals("expires_at")) { 458 this.expiresAt = BoxDateFormat.parse(value.asString()); 459 } else if (memberName.equals("folder")) { 460 JsonObject folderJSON = value.asObject(); 461 String folderID = folderJSON.get("id").asString(); 462 BoxFolder folder = new BoxFolder(getAPI(), folderID); 463 this.folder = folder.new Info(folderJSON); 464 } else if (memberName.equals("is_description_required")) { 465 this.isDescriptionRequired = value.asBoolean(); 466 } else if (memberName.equals("is_email_required")) { 467 this.isEmailRequired = value.asBoolean(); 468 } else if (memberName.equals("status")) { 469 this.status = Status.fromJSONString(value.asString()); 470 } else if (memberName.equals("title")) { 471 this.title = value.asString(); 472 } else if (memberName.equals("updated_at")) { 473 this.updatedAt = BoxDateFormat.parse(value.asString()); 474 } else if (memberName.equals("updated_by")) { 475 JsonObject userJSON = value.asObject(); 476 String userID = userJSON.get("id").asString(); 477 BoxUser user = new BoxUser(getAPI(), userID); 478 this.createdBy = user.new Info(userJSON); 479 } else if (memberName.equals("url")) { 480 this.path = value.asString(); 481 } 482 } catch (Exception e) { 483 throw new BoxDeserializationException(memberName, value.toString(), e); 484 } 485 } 486 } 487}