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