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