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