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