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