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