001package com.box.sdk; 002 003import com.eclipsesource.json.Json; 004import com.eclipsesource.json.JsonArray; 005import com.eclipsesource.json.JsonObject; 006import com.eclipsesource.json.JsonValue; 007import java.net.URL; 008import java.util.ArrayList; 009import java.util.Date; 010import java.util.List; 011 012/** 013 * Represents a retention policy. 014 * A retention policy blocks permanent deletion of content for a specified amount of time. 015 * Admins can create retention policies and then later assign them to specific folders or their entire enterprise. 016 * 017 * @see <a href="https://developer.box.com/reference/resources/retention-policy/">Box retention policy</a> 018 * 019 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked 020 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error 021 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p> 022 */ 023@BoxResourceType("retention_policy") 024public class BoxRetentionPolicy extends BoxResource { 025 /** 026 * The URL template used for operation with retention policies. 027 */ 028 public static final URLTemplate RETENTION_POLICIES_URL_TEMPLATE = new URLTemplate("retention_policies"); 029 030 /** 031 * The URL template used for operation with retention policy with given ID. 032 */ 033 public static final URLTemplate POLICY_URL_TEMPLATE = new URLTemplate("retention_policies/%s"); 034 035 /** 036 * The URL template used for operation with retention policy assignments. 037 */ 038 public static final URLTemplate ASSIGNMENTS_URL_TEMPLATE = new URLTemplate("retention_policies/%s/assignments"); 039 040 /** 041 * Will cause the content retained by the policy to be permanently deleted. 042 */ 043 public static final String ACTION_PERMANENTLY_DELETE = "permanently_delete"; 044 045 /** 046 * Will lift the retention policy from the content, allowing it to be deleted by users. 047 */ 048 public static final String ACTION_REMOVE_RETENTION = "remove_retention"; 049 050 /** 051 * Status corresponding to active retention policy. 052 */ 053 public static final String STATUS_ACTIVE = "active"; 054 055 /** 056 * Status corresponding to retired retention policy. 057 */ 058 public static final String STATUS_RETIRED = "retired"; 059 060 /** 061 * Type for finite retention policies. Finite retention policies has the duration. 062 */ 063 private static final String TYPE_FINITE = "finite"; 064 065 /** 066 * Type for indefinite retention policies. Indefinite retention policies can have only "remove_retention" 067 * assigned action. 068 */ 069 private static final String TYPE_INDEFINITE = "indefinite"; 070 071 /** 072 * The default limit of entries per response. 073 */ 074 private static final int DEFAULT_LIMIT = 100; 075 076 /** 077 * Constructs a retention policy for a resource with a given ID. 078 * 079 * @param api the API connection to be used by the resource. 080 * @param id the ID of the resource. 081 */ 082 public BoxRetentionPolicy(BoxAPIConnection api, String id) { 083 super(api, id); 084 } 085 086 /** 087 * Used to create a new indefinite retention policy. 088 * 089 * @param api the API connection to be used by the created user. 090 * @param name the name of the retention policy. 091 * @return the created retention policy's info. 092 */ 093 public static BoxRetentionPolicy.Info createIndefinitePolicy(BoxAPIConnection api, String name) { 094 return createRetentionPolicy(api, name, TYPE_INDEFINITE, 0, ACTION_REMOVE_RETENTION); 095 } 096 097 /** 098 * Used to create a new indefinite retention policy with optional parameters. 099 * 100 * @param api the API connection to be used by the created user. 101 * @param name the name of the retention policy. 102 * @param optionalParams the optional parameters. 103 * @return the created retention policy's info. 104 */ 105 public static BoxRetentionPolicy.Info createIndefinitePolicy(BoxAPIConnection api, String name, 106 RetentionPolicyParams optionalParams) { 107 return createRetentionPolicy(api, name, TYPE_INDEFINITE, 0, ACTION_REMOVE_RETENTION, optionalParams); 108 } 109 110 /** 111 * Used to create a new finite retention policy. 112 * 113 * @param api the API connection to be used by the created user. 114 * @param name the name of the retention policy. 115 * @param length the duration in days that the retention policy will be active for after being assigned to content. 116 * @param action the disposition action can be "permanently_delete" or "remove_retention". 117 * @return the created retention policy's info. 118 */ 119 public static BoxRetentionPolicy.Info createFinitePolicy(BoxAPIConnection api, String name, int length, 120 String action) { 121 return createRetentionPolicy(api, name, TYPE_FINITE, length, action); 122 } 123 124 /** 125 * Used to create a new finite retention policy with optional parameters. 126 * 127 * @param api the API connection to be used by the created user. 128 * @param name the name of the retention policy. 129 * @param length the duration in days that the retention policy will be active for after being assigned to content. 130 * @param action the disposition action can be "permanently_delete" or "remove_retention". 131 * @param optionalParams the optional parameters. 132 * @return the created retention policy's info. 133 */ 134 public static BoxRetentionPolicy.Info createFinitePolicy( 135 BoxAPIConnection api, 136 String name, 137 int length, 138 String action, 139 RetentionPolicyParams optionalParams 140 ) { 141 return createRetentionPolicy(api, name, TYPE_FINITE, length, action, optionalParams); 142 } 143 144 /** 145 * Used to create a new retention policy. 146 * 147 * @param api the API connection to be used by the created user. 148 * @param name the name of the retention policy. 149 * @param type the type of the retention policy. Can be "finite" or "indefinite". 150 * @param length the duration in days that the retention policy will be active for after being assigned to content. 151 * @param action the disposition action can be "permanently_delete" or "remove_retention". 152 * @return the created retention policy's info. 153 */ 154 private static BoxRetentionPolicy.Info createRetentionPolicy(BoxAPIConnection api, String name, String type, 155 int length, String action) { 156 return createRetentionPolicy(api, name, type, length, action, null); 157 } 158 159 /** 160 * Used to create a new retention policy with optional parameters. 161 * 162 * @param api the API connection to be used by the created user. 163 * @param name the name of the retention policy. 164 * @param type the type of the retention policy. Can be "finite" or "indefinite". 165 * @param length the duration in days that the retention policy will be active for after being assigned to content. 166 * @param action the disposition action can be "permanently_delete" or "remove_retention". 167 * @param optionalParams the optional parameters. 168 * @return the created retention policy's info. 169 */ 170 private static BoxRetentionPolicy.Info createRetentionPolicy( 171 BoxAPIConnection api, 172 String name, 173 String type, 174 int length, 175 String action, 176 RetentionPolicyParams optionalParams 177 ) { 178 URL url = RETENTION_POLICIES_URL_TEMPLATE.build(api.getBaseURL()); 179 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 180 JsonObject requestJSON = new JsonObject() 181 .add("policy_name", name) 182 .add("policy_type", type) 183 .add("disposition_action", action); 184 if (!type.equals(TYPE_INDEFINITE)) { 185 requestJSON.add("retention_length", length); 186 } 187 if (optionalParams != null) { 188 requestJSON.add("can_owner_extend_retention", optionalParams.getCanOwnerExtendRetention()); 189 requestJSON.add("are_owners_notified", optionalParams.getAreOwnersNotified()); 190 191 List<BoxUser.Info> customNotificationRecipients = optionalParams.getCustomNotificationRecipients(); 192 if (customNotificationRecipients.size() > 0) { 193 JsonArray users = new JsonArray(); 194 for (BoxUser.Info user : customNotificationRecipients) { 195 JsonObject userJSON = new JsonObject() 196 .add("type", "user") 197 .add("id", user.getID()); 198 users.add(userJSON); 199 } 200 requestJSON.add("custom_notification_recipients", users); 201 } 202 } 203 request.setBody(requestJSON.toString()); 204 BoxJSONResponse response = (BoxJSONResponse) request.send(); 205 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 206 BoxRetentionPolicy createdPolicy = new BoxRetentionPolicy(api, responseJSON.get("id").asString()); 207 return createdPolicy.new Info(responseJSON); 208 } 209 210 /** 211 * Returns all the retention policies. 212 * 213 * @param api the API connection to be used by the resource. 214 * @param fields the fields to retrieve. 215 * @return an iterable with all the retention policies. 216 */ 217 public static Iterable<BoxRetentionPolicy.Info> getAll(final BoxAPIConnection api, String... fields) { 218 return getAll(null, null, null, DEFAULT_LIMIT, api, fields); 219 } 220 221 /** 222 * Returns all the retention policies with specified filters. 223 * 224 * @param name a name to filter the retention policies by. A trailing partial match search is performed. 225 * Set to null if no name filtering is required. 226 * @param type a policy type to filter the retention policies by. Set to null if no type filtering is required. 227 * @param userID a user id to filter the retention policies by. Set to null if no type filtering is required. 228 * @param limit the limit of items per single response. The default value is 100. 229 * @param api the API connection to be used by the resource. 230 * @param fields the fields to retrieve. 231 * @return an iterable with all the retention policies met search conditions. 232 */ 233 public static Iterable<BoxRetentionPolicy.Info> getAll( 234 String name, String type, String userID, int limit, final BoxAPIConnection api, String... fields) { 235 QueryStringBuilder queryString = new QueryStringBuilder(); 236 if (name != null) { 237 queryString.appendParam("policy_name", name); 238 } 239 if (type != null) { 240 queryString.appendParam("policy_type", type); 241 } 242 if (userID != null) { 243 queryString.appendParam("created_by_user_id", userID); 244 } 245 if (fields.length > 0) { 246 queryString.appendParam("fields", fields); 247 } 248 URL url = RETENTION_POLICIES_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), queryString.toString()); 249 return new BoxResourceIterable<BoxRetentionPolicy.Info>(api, url, limit) { 250 251 @Override 252 protected BoxRetentionPolicy.Info factory(JsonObject jsonObject) { 253 BoxRetentionPolicy policy = new BoxRetentionPolicy(api, jsonObject.get("id").asString()); 254 return policy.new Info(jsonObject); 255 } 256 257 }; 258 } 259 260 /** 261 * Returns iterable with all folder assignments of this retention policy. 262 * 263 * @param fields the fields to retrieve. 264 * @return an iterable containing all folder assignments. 265 */ 266 public Iterable<BoxRetentionPolicyAssignment.Info> getFolderAssignments(String... fields) { 267 return this.getFolderAssignments(DEFAULT_LIMIT, fields); 268 } 269 270 /** 271 * Returns iterable with all folder assignments of this retention policy. 272 * 273 * @param limit the limit of entries per response. The default value is 100. 274 * @param fields the fields to retrieve. 275 * @return an iterable containing all folder assignments. 276 */ 277 public Iterable<BoxRetentionPolicyAssignment.Info> getFolderAssignments(int limit, String... fields) { 278 return this.getAssignments(BoxRetentionPolicyAssignment.TYPE_FOLDER, limit, fields); 279 } 280 281 /** 282 * Returns iterable with all enterprise assignments of this retention policy. 283 * 284 * @param fields the fields to retrieve. 285 * @return an iterable containing all enterprise assignments. 286 */ 287 public Iterable<BoxRetentionPolicyAssignment.Info> getEnterpriseAssignments(String... fields) { 288 return this.getEnterpriseAssignments(DEFAULT_LIMIT, fields); 289 } 290 291 /** 292 * Returns iterable with all enterprise assignments of this retention policy. 293 * 294 * @param limit the limit of entries per response. The default value is 100. 295 * @param fields the fields to retrieve. 296 * @return an iterable containing all enterprise assignments. 297 */ 298 public Iterable<BoxRetentionPolicyAssignment.Info> getEnterpriseAssignments(int limit, String... fields) { 299 return this.getAssignments(BoxRetentionPolicyAssignment.TYPE_ENTERPRISE, limit, fields); 300 } 301 302 /** 303 * Returns iterable with all assignments of this retention policy. 304 * 305 * @param fields the fields to retrieve. 306 * @return an iterable containing all assignments. 307 */ 308 public Iterable<BoxRetentionPolicyAssignment.Info> getAllAssignments(String... fields) { 309 return this.getAllAssignments(DEFAULT_LIMIT, fields); 310 } 311 312 /** 313 * Returns iterable with all assignments of this retention policy. 314 * 315 * @param limit the limit of entries per response. The default value is 100. 316 * @param fields the fields to retrieve. 317 * @return an iterable containing all assignments. 318 */ 319 public Iterable<BoxRetentionPolicyAssignment.Info> getAllAssignments(int limit, String... fields) { 320 return this.getAssignments(null, limit, fields); 321 } 322 323 /** 324 * Returns iterable with all assignments of given type of this retention policy. 325 * 326 * @param type the type of the retention policy assignment to retrieve. Can either be "folder" or "enterprise". 327 * @param limit the limit of entries per response. The default value is 100. 328 * @param fields the fields to retrieve. 329 * @return an iterable containing all assignments of given type. 330 */ 331 private Iterable<BoxRetentionPolicyAssignment.Info> getAssignments(String type, int limit, String... fields) { 332 QueryStringBuilder queryString = new QueryStringBuilder(); 333 if (type != null) { 334 queryString.appendParam("type", type); 335 } 336 if (fields.length > 0) { 337 queryString.appendParam("fields", fields); 338 } 339 URL url = ASSIGNMENTS_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(), queryString.toString(), getID()); 340 return new BoxResourceIterable<BoxRetentionPolicyAssignment.Info>(getAPI(), url, limit) { 341 342 @Override 343 protected BoxRetentionPolicyAssignment.Info factory(JsonObject jsonObject) { 344 BoxRetentionPolicyAssignment assignment 345 = new BoxRetentionPolicyAssignment(getAPI(), jsonObject.get("id").asString()); 346 return assignment.new Info(jsonObject); 347 } 348 349 }; 350 } 351 352 /** 353 * Assigns this retention policy to folder. 354 * 355 * @param folder the folder to assign policy to. 356 * @return info about created assignment. 357 */ 358 public BoxRetentionPolicyAssignment.Info assignTo(BoxFolder folder) { 359 return BoxRetentionPolicyAssignment.createAssignmentToFolder(this.getAPI(), this.getID(), folder.getID()); 360 } 361 362 /** 363 * Assigns this retention policy to the current enterprise. 364 * 365 * @return info about created assignment. 366 */ 367 public BoxRetentionPolicyAssignment.Info assignToEnterprise() { 368 return BoxRetentionPolicyAssignment.createAssignmentToEnterprise(this.getAPI(), this.getID()); 369 } 370 371 /** 372 * Assigns this retention policy to a metadata template, optionally with certain field values. 373 * 374 * @param templateID the ID of the metadata template to apply to. 375 * @param fieldFilters optional field value filters. 376 * @return info about the created assignment. 377 */ 378 public BoxRetentionPolicyAssignment.Info assignToMetadataTemplate(String templateID, 379 MetadataFieldFilter... fieldFilters) { 380 return BoxRetentionPolicyAssignment.createAssignmentToMetadata(this.getAPI(), this.getID(), templateID, 381 fieldFilters); 382 } 383 384 /** 385 * Updates the information about this retention policy with any info fields that have been modified locally. 386 * 387 * @param info the updated info. 388 */ 389 public void updateInfo(BoxRetentionPolicy.Info info) { 390 URL url = POLICY_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 391 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 392 request.setBody(info.getPendingChanges()); 393 BoxJSONResponse response = (BoxJSONResponse) request.send(); 394 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 395 info.update(responseJSON); 396 } 397 398 /** 399 * Returns information about this retention policy. 400 * 401 * @param fields the fields to retrieve. 402 * @return information about this retention policy. 403 */ 404 public BoxRetentionPolicy.Info getInfo(String... fields) { 405 QueryStringBuilder builder = new QueryStringBuilder(); 406 if (fields.length > 0) { 407 builder.appendParam("fields", fields); 408 } 409 URL url = POLICY_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID()); 410 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 411 BoxJSONResponse response = (BoxJSONResponse) request.send(); 412 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 413 return new Info(responseJSON); 414 } 415 416 /** 417 * Contains information about the retention policy. 418 */ 419 public class Info extends BoxResource.Info { 420 421 /** 422 * @see #getPolicyName() 423 */ 424 private String policyName; 425 426 /** 427 * @see #getPolicyType() 428 */ 429 private String policyType; 430 431 /** 432 * @see #getRetentionLength() 433 */ 434 private int retentionLength; 435 436 /** 437 * @see #getDispositionAction() 438 */ 439 private String dispositionAction; 440 441 /** 442 * @see #getStatus() 443 */ 444 private String status; 445 446 /** 447 * @see #getCreatedBy() 448 */ 449 private BoxUser.Info createdBy; 450 451 /** 452 * @see #getCreatedAt() 453 */ 454 private Date createdAt; 455 456 /** 457 * @see #getModifiedAt() 458 */ 459 private Date modifiedAt; 460 461 /** 462 * @see #getCanOwnerExtendRetention() 463 */ 464 private boolean canOwnerExtendRetention; 465 466 /** 467 * @see #getAreOwnersNotified() 468 */ 469 private boolean areOwnersNotified; 470 471 private List<BoxUser.Info> customNotificationRecipients; 472 473 /** 474 * Constructs an empty Info object. 475 */ 476 public Info() { 477 super(); 478 } 479 480 /** 481 * Constructs an Info object by parsing information from a JSON string. 482 * 483 * @param json the JSON string to parse. 484 */ 485 public Info(String json) { 486 super(json); 487 } 488 489 /** 490 * Constructs an Info object using an already parsed JSON object. 491 * 492 * @param jsonObject the parsed JSON object. 493 */ 494 Info(JsonObject jsonObject) { 495 super(jsonObject); 496 } 497 498 /** 499 * {@inheritDoc} 500 */ 501 @Override 502 public BoxResource getResource() { 503 return BoxRetentionPolicy.this; 504 } 505 506 /** 507 * Gets the name given to the retention policy. 508 * 509 * @return name given to the retention policy. 510 */ 511 public String getPolicyName() { 512 return this.policyName; 513 } 514 515 /** 516 * Update the policy name to a new value. 517 * 518 * @param policyName the new policy name. 519 */ 520 public void setPolicyName(String policyName) { 521 this.policyName = policyName; 522 this.addPendingChange("policy_name", policyName); 523 } 524 525 /** 526 * Gets the type of the retention policy. 527 * A retention policy type can either be "finite", 528 * where a specific amount of time to retain the content is known upfront, 529 * or "indefinite", where the amount of time to retain the content is still unknown. 530 * 531 * @return the type of the retention policy. 532 */ 533 public String getPolicyType() { 534 return this.policyType; 535 } 536 537 /** 538 * Gets the length of the retention policy. This length specifies the duration 539 * in days that the retention policy will be active for after being assigned to content. 540 * 541 * @return the length of the retention policy. 542 */ 543 public int getRetentionLength() { 544 return this.retentionLength; 545 } 546 547 /** 548 * Gets the disposition action of the retention policy. 549 * This action can be "permanently_delete", or "remove_retention". 550 * 551 * @return the disposition action of the retention policy. 552 */ 553 public String getDispositionAction() { 554 return this.dispositionAction; 555 } 556 557 /** 558 * Set the action to take when retention period ends. 559 * 560 * @param dispositionAction the new action. 561 */ 562 public void setDispositionAction(String dispositionAction) { 563 this.dispositionAction = dispositionAction; 564 this.addPendingChange("disposition_action", dispositionAction); 565 } 566 567 /** 568 * Gets the status of the retention policy. 569 * The status can be "active" or "retired". 570 * 571 * @return the status of the retention policy. 572 */ 573 public String getStatus() { 574 return this.status; 575 } 576 577 /** 578 * Set the policy status. 579 * 580 * @param status the new status value. 581 */ 582 public void setStatus(String status) { 583 this.status = status; 584 this.addPendingChange("status", status); 585 } 586 587 /** 588 * Gets info about the user created the retention policy. 589 * 590 * @return info about the user created the retention policy. 591 */ 592 public BoxUser.Info getCreatedBy() { 593 return this.createdBy; 594 } 595 596 /** 597 * Gets the time that the retention policy was created. 598 * 599 * @return the time that the retention policy was created. 600 */ 601 public Date getCreatedAt() { 602 return this.createdAt; 603 } 604 605 /** 606 * Gets the time that the retention policy was last modified. 607 * 608 * @return the time that the retention policy was last modified. 609 */ 610 public Date getModifiedAt() { 611 return this.modifiedAt; 612 } 613 614 /** 615 * Gets the flag to denote that the owner of a retained file can extend the retention when near expiration. 616 * 617 * @return the boolean flag. 618 */ 619 public boolean getCanOwnerExtendRetention() { 620 return this.canOwnerExtendRetention; 621 } 622 623 /** 624 * Gets the flag to denote that owners and co-owners of a retained file will get notified when near expiration. 625 * 626 * @return the boolean flag. 627 */ 628 public boolean getAreOwnersNotified() { 629 return this.areOwnersNotified; 630 } 631 632 /** 633 * Gets the list of users to be notified of a retained file when near expiration. 634 * 635 * @return the list of users to be notified. 636 */ 637 public List<BoxUser.Info> getCustomNotificationRecipients() { 638 return this.customNotificationRecipients; 639 } 640 641 /** 642 * {@inheritDoc} 643 */ 644 @Override 645 void parseJSONMember(JsonObject.Member member) { 646 super.parseJSONMember(member); 647 String memberName = member.getName(); 648 JsonValue value = member.getValue(); 649 try { 650 if (memberName.equals("policy_name")) { 651 this.policyName = value.asString(); 652 } else if (memberName.equals("policy_type")) { 653 this.policyType = value.asString(); 654 } else if (memberName.equals("retention_length")) { 655 int intVal; 656 if (value.asString().equals(TYPE_INDEFINITE)) { 657 intVal = -1; 658 } else { 659 intVal = Integer.parseInt(value.asString()); 660 } 661 662 this.retentionLength = intVal; 663 } else if (memberName.equals("disposition_action")) { 664 this.dispositionAction = value.asString(); 665 } else if (memberName.equals("status")) { 666 this.status = value.asString(); 667 } else if (memberName.equals("created_by")) { 668 JsonObject userJSON = value.asObject(); 669 if (this.createdBy == null) { 670 String userID = userJSON.get("id").asString(); 671 BoxUser user = new BoxUser(getAPI(), userID); 672 this.createdBy = user.new Info(userJSON); 673 } else { 674 this.createdBy.update(userJSON); 675 } 676 } else if (memberName.equals("created_at")) { 677 this.createdAt = BoxDateFormat.parse(value.asString()); 678 } else if (memberName.equals("modified_at")) { 679 this.modifiedAt = BoxDateFormat.parse(value.asString()); 680 } else if (memberName.equals("can_owner_extend_retention")) { 681 this.canOwnerExtendRetention = value.asBoolean(); 682 } else if (memberName.equals("are_owners_notified")) { 683 this.areOwnersNotified = value.asBoolean(); 684 } else if (memberName.equals("custom_notification_recipients")) { 685 List<BoxUser.Info> recipients = new ArrayList<BoxUser.Info>(); 686 for (JsonValue userJSON : value.asArray()) { 687 String userID = userJSON.asObject().get("id").asString(); 688 BoxUser user = new BoxUser(getAPI(), userID); 689 recipients.add(user.new Info(userJSON.asObject())); 690 } 691 this.customNotificationRecipients = recipients; 692 } 693 } catch (Exception e) { 694 throw new BoxDeserializationException(memberName, value.toString(), e); 695 } 696 } 697 } 698}