001package com.box.sdk; 002 003import com.eclipsesource.json.JsonObject; 004import com.eclipsesource.json.JsonValue; 005import java.net.URL; 006import java.util.Date; 007 008/** 009 * Represents a legal hold policy. Legal Hold Policy information describes the basic characteristics of the Policy, such 010 * as name, description, and filter dates. 011 * 012 * @see <a href="https://developer.box.com/reference/resources/legal-hold-policy/">Box legal holds</a> 013 * 014 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked 015 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error 016 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p> 017 */ 018@BoxResourceType("legal_hold") 019public class BoxLegalHoldPolicy extends BoxResource { 020 /** 021 * Legal Hold URL Template. 022 */ 023 public static final URLTemplate LEGAL_HOLD_URL_TEMPLATE = new URLTemplate("legal_hold_policies/%s"); 024 /** 025 * All Legal Hold URL Template. 026 */ 027 public static final URLTemplate ALL_LEGAL_HOLD_URL_TEMPLATE = new URLTemplate("legal_hold_policies"); 028 /** 029 * Legal Hold Assignments URL Template. 030 */ 031 public static final URLTemplate LEGAL_HOLD_ASSIGNMENTS_URL_TEMPLATE 032 = new URLTemplate("legal_hold_policies/%s/assignments"); 033 /** 034 * List of File Version Holds URL Template. 035 */ 036 public static final URLTemplate LIST_OF_FILE_VERSION_HOLDS_URL_TEMPLATE 037 = new URLTemplate("file_version_legal_holds"); 038 private static final int DEFAULT_LIMIT = 100; 039 040 /** 041 * Constructs a BoxLegalHoldPolicy for a resource with a given ID. 042 * 043 * @param api the API connection to be used by the resource. 044 * @param id the ID of the resource. 045 */ 046 public BoxLegalHoldPolicy(BoxAPIConnection api, String id) { 047 super(api, id); 048 } 049 050 /** 051 * Creates a new Legal Hold Policy. 052 * 053 * @param api the API connection to be used by the resource. 054 * @param name the name of Legal Hold Policy. 055 * @return information about the Legal Hold Policy created. 056 */ 057 public static BoxLegalHoldPolicy.Info create(BoxAPIConnection api, String name) { 058 return createOngoing(api, name, null); 059 } 060 061 /** 062 * Creates a new Legal Hold Policy. 063 * 064 * @param api the API connection to be used by the resource. 065 * @param name the name of Legal Hold Policy. 066 * @param description the description of Legal Hold Policy. 067 * @param filterStartedAt optional date filter applies to Custodian assignments only. 068 * @param filterEndedAt optional date filter applies to Custodian assignments only. 069 * @return information about the Legal Hold Policy created. 070 */ 071 public static BoxLegalHoldPolicy.Info create(BoxAPIConnection api, String name, String description, 072 Date filterStartedAt, Date filterEndedAt) { 073 URL url = ALL_LEGAL_HOLD_URL_TEMPLATE.build(api.getBaseURL()); 074 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 075 JsonObject requestJSON = new JsonObject() 076 .add("policy_name", name); 077 if (description != null) { 078 requestJSON.add("description", description); 079 } 080 if (filterStartedAt != null) { 081 requestJSON.add("filter_started_at", BoxDateFormat.format(filterStartedAt)); 082 } 083 if (filterEndedAt != null) { 084 requestJSON.add("filter_ended_at", BoxDateFormat.format(filterEndedAt)); 085 } 086 request.setBody(requestJSON.toString()); 087 BoxJSONResponse response = (BoxJSONResponse) request.send(); 088 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 089 BoxLegalHoldPolicy createdPolicy = new BoxLegalHoldPolicy(api, responseJSON.get("id").asString()); 090 return createdPolicy.new Info(responseJSON); 091 } 092 093 /** 094 * Creates a new ongoing Legal Hold Policy. 095 * 096 * @param api the API connection to be used by the resource. 097 * @param name the name of Legal Hold Policy. 098 * @param description the description of Legal Hold Policy. 099 * @return information about the Legal Hold Policy created. 100 */ 101 public static BoxLegalHoldPolicy.Info createOngoing(BoxAPIConnection api, String name, String description) { 102 URL url = ALL_LEGAL_HOLD_URL_TEMPLATE.build(api.getBaseURL()); 103 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 104 JsonObject requestJSON = new JsonObject() 105 .add("policy_name", name) 106 .add("is_ongoing", true); 107 if (description != null) { 108 requestJSON.add("description", description); 109 } 110 request.setBody(requestJSON.toString()); 111 BoxJSONResponse response = (BoxJSONResponse) request.send(); 112 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 113 BoxLegalHoldPolicy createdPolicy = new BoxLegalHoldPolicy(api, responseJSON.get("id").asString()); 114 return createdPolicy.new Info(responseJSON); 115 } 116 117 /** 118 * Retrieves a list of Legal Hold Policies that belong to your Enterprise as an Iterable. 119 * 120 * @param api api the API connection to be used by the resource. 121 * @return the Iterable of Legal Hold Policies in your Enterprise. 122 */ 123 public static Iterable<BoxLegalHoldPolicy.Info> getAll(final BoxAPIConnection api) { 124 return getAll(api, null, DEFAULT_LIMIT); 125 } 126 127 /** 128 * Retrieves a list of Legal Hold Policies that belong to your Enterprise as an Iterable. 129 * 130 * @param api api the API connection to be used by the resource. 131 * @param policyName case insensitive prefix-match filter on Policy name. 132 * @param limit the limit of retrieved entries per page. 133 * @param fields the optional fields to retrieve. 134 * @return the Iterable of Legal Hold Policies in your Enterprise that match the filter parameters. 135 */ 136 public static Iterable<BoxLegalHoldPolicy.Info> getAll( 137 final BoxAPIConnection api, String policyName, int limit, String... fields) { 138 QueryStringBuilder builder = new QueryStringBuilder(); 139 if (policyName != null) { 140 builder.appendParam("policy_name", policyName); 141 } 142 if (fields.length > 0) { 143 builder.appendParam("fields", fields); 144 } 145 return new BoxResourceIterable<BoxLegalHoldPolicy.Info>(api, 146 ALL_LEGAL_HOLD_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString()), 147 limit) { 148 149 @Override 150 protected BoxLegalHoldPolicy.Info factory(JsonObject jsonObject) { 151 BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, jsonObject.get("id").asString()); 152 return policy.new Info(jsonObject); 153 } 154 }; 155 } 156 157 /** 158 * Gets information about the Legal Hold. 159 * 160 * @param fields the fields to retrieve. 161 * @return information about this legal hold policy. 162 */ 163 public Info getInfo(String... fields) { 164 QueryStringBuilder builder = new QueryStringBuilder(); 165 if (fields.length > 0) { 166 builder.appendParam("fields", fields); 167 } 168 URL url = LEGAL_HOLD_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID()); 169 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 170 BoxJSONResponse response = (BoxJSONResponse) request.send(); 171 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 172 return new Info(responseJSON); 173 } 174 175 /** 176 * Deletes the legal hold policy. 177 */ 178 public void delete() { 179 URL url = LEGAL_HOLD_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 180 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 181 BoxAPIResponse response = request.send(); 182 response.disconnect(); 183 } 184 185 /** 186 * Updates the information about this retention policy with modified locally info. 187 * Only policy_name, description and release_notes can be modified. 188 * 189 * @param info the updated info. 190 */ 191 public void updateInfo(BoxLegalHoldPolicy.Info info) { 192 URL url = LEGAL_HOLD_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 193 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 194 request.setBody(info.getPendingChanges()); 195 BoxJSONResponse response = (BoxJSONResponse) request.send(); 196 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 197 info.update(responseJSON); 198 } 199 200 /** 201 * Assigns this legal holds policy to the given box resource. 202 * Currently only {@link BoxFile}, {@link BoxFileVersion}, {@link BoxFolder} and {@link BoxUser} are supported. 203 * 204 * @param resource the box resource to assign legal hold policy to. 205 * @return info about created legal hold policy assignment. 206 */ 207 public BoxLegalHoldAssignment.Info assignTo(BoxResource resource) { 208 return BoxLegalHoldAssignment.create( 209 this.getAPI(), this.getID(), BoxResource.getResourceType(resource.getClass()), resource.getID()); 210 } 211 212 /** 213 * Returns iterable containing assignments for this single legal hold policy. 214 * 215 * @param fields the fields to retrieve. 216 * @return an iterable containing assignments for this single legal hold policy. 217 */ 218 public Iterable<BoxLegalHoldAssignment.Info> getAssignments(String... fields) { 219 return this.getAssignments(null, null, DEFAULT_LIMIT, fields); 220 } 221 222 /** 223 * Returns iterable containing assignments for this single legal hold policy. 224 * Parameters can be used to filter retrieved assignments. 225 * 226 * @param type filter assignments of this type only. 227 * Can be "file_version", "file", "folder", "user" or null if no type filter is necessary. 228 * @param id filter assignments to this ID only. Can be null if no id filter is necessary. 229 * @param limit the limit of entries per page. Default limit is 100. 230 * @param fields the fields to retrieve. 231 * @return an iterable containing assignments for this single legal hold policy. 232 */ 233 public Iterable<BoxLegalHoldAssignment.Info> getAssignments(String type, String id, int limit, String... fields) { 234 QueryStringBuilder builder = new QueryStringBuilder(); 235 if (type != null) { 236 builder.appendParam("assign_to_type", type); 237 } 238 if (id != null) { 239 builder.appendParam("assign_to_id", id); 240 } 241 if (fields.length > 0) { 242 builder.appendParam("fields", fields); 243 } 244 return new BoxResourceIterable<BoxLegalHoldAssignment.Info>( 245 this.getAPI(), LEGAL_HOLD_ASSIGNMENTS_URL_TEMPLATE.buildWithQuery( 246 this.getAPI().getBaseURL(), builder.toString(), this.getID()), limit) { 247 248 @Override 249 protected BoxLegalHoldAssignment.Info factory(JsonObject jsonObject) { 250 BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment( 251 BoxLegalHoldPolicy.this.getAPI(), jsonObject.get("id").asString()); 252 return assignment.new Info(jsonObject); 253 } 254 }; 255 } 256 257 /** 258 * Returns iterable with all non-deleted file version legal holds for this legal hold policy. 259 * 260 * @param fields the fields to retrieve. 261 * @return an iterable containing file version legal holds info. 262 */ 263 public Iterable<BoxFileVersionLegalHold.Info> getFileVersionHolds(String... fields) { 264 return this.getFileVersionHolds(DEFAULT_LIMIT, fields); 265 } 266 267 /** 268 * Returns iterable with all non-deleted file version legal holds for this legal hold policy. 269 * 270 * @param limit the limit of entries per response. The default value is 100. 271 * @param fields the fields to retrieve. 272 * @return an iterable containing file version legal holds info. 273 */ 274 public Iterable<BoxFileVersionLegalHold.Info> getFileVersionHolds(int limit, String... fields) { 275 QueryStringBuilder queryString = new QueryStringBuilder().appendParam("policy_id", this.getID()); 276 if (fields.length > 0) { 277 queryString.appendParam("fields", fields); 278 } 279 URL url = LIST_OF_FILE_VERSION_HOLDS_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(), queryString.toString()); 280 return new BoxResourceIterable<BoxFileVersionLegalHold.Info>(getAPI(), url, limit) { 281 282 @Override 283 protected BoxFileVersionLegalHold.Info factory(JsonObject jsonObject) { 284 BoxFileVersionLegalHold assignment 285 = new BoxFileVersionLegalHold(getAPI(), jsonObject.get("id").asString()); 286 return assignment.new Info(jsonObject); 287 } 288 289 }; 290 } 291 292 /** 293 * Contains information about the legal hold policy. 294 */ 295 public class Info extends BoxResource.Info { 296 297 /** 298 * @see #getPolicyName() 299 */ 300 private String policyName; 301 302 /** 303 * @see #getDescription() 304 */ 305 private String description; 306 307 /** 308 * @see #getStatus() 309 */ 310 private String status; 311 312 /** 313 * @see #getAssignmentCountUser() 314 */ 315 private int assignmentCountUser; 316 317 /** 318 * @see #getAssignmentCountFolder() 319 */ 320 private int assignmentCountFolder; 321 322 /** 323 * @see #getAssignmentCountFile() 324 */ 325 private int assignmentCountFile; 326 327 /** 328 * @see #getAssignmentCountFileVersion() 329 */ 330 private int assignmentCountFileVersion; 331 332 /** 333 * @see #getCreatedAt() 334 */ 335 private BoxUser.Info createdBy; 336 337 /** 338 * @see #getCreatedAt() 339 */ 340 private Date createdAt; 341 342 /** 343 * @see #getModifiedAt() 344 */ 345 private Date modifiedAt; 346 347 /** 348 * @see #getDeletedAt() 349 */ 350 private Date deletedAt; 351 352 /** 353 * @see #getFilterStartedAt() 354 */ 355 private Date filterStartedAt; 356 357 /** 358 * @see #getFilterEndedAt() 359 */ 360 private Date filterEndedAt; 361 362 /** 363 * @see #getReleaseNotes() 364 */ 365 private String releaseNotes; 366 367 /** 368 * @see #getIsOngoing() 369 */ 370 private Boolean isOngoing; 371 372 /** 373 * Constructs an empty Info object. 374 */ 375 public Info() { 376 super(); 377 } 378 379 /** 380 * Constructs an Info object by parsing information from a JSON string. 381 * 382 * @param json the JSON string to parse. 383 */ 384 public Info(String json) { 385 super(json); 386 } 387 388 /** 389 * Constructs an Info object using an already parsed JSON object. 390 * 391 * @param jsonObject the parsed JSON object. 392 */ 393 Info(JsonObject jsonObject) { 394 super(jsonObject); 395 } 396 397 /** 398 * {@inheritDoc} 399 */ 400 @Override 401 public BoxResource getResource() { 402 return BoxLegalHoldPolicy.this; 403 } 404 405 /** 406 * @return the name of the policy. 407 */ 408 public String getPolicyName() { 409 return this.policyName; 410 } 411 412 /** 413 * Sets the policy's name. 414 * 415 * @param policyName the policy's new name. 416 */ 417 public void setPolicyName(String policyName) { 418 this.policyName = policyName; 419 this.addPendingChange("policy_name", policyName); 420 } 421 422 /** 423 * @return the description of the policy. 424 */ 425 public String getDescription() { 426 return this.description; 427 } 428 429 /** 430 * Sets the policy's description. 431 * 432 * @param description the policy's new description. 433 */ 434 public void setDescription(String description) { 435 this.description = description; 436 this.addPendingChange("description", description); 437 } 438 439 /** 440 * Status can be "active", "applying", "releasing" or "released". 441 * 442 * @return the status of the policy. 443 */ 444 public String getStatus() { 445 return this.status; 446 } 447 448 /** 449 * @return count of users this policy assigned to. 450 */ 451 public int getAssignmentCountUser() { 452 return this.assignmentCountUser; 453 } 454 455 /** 456 * @return count of folders this policy assigned to. 457 */ 458 public int getAssignmentCountFolder() { 459 return this.assignmentCountFolder; 460 } 461 462 /** 463 * @return count of files this policy assigned to. 464 */ 465 public int getAssignmentCountFile() { 466 return this.assignmentCountFile; 467 } 468 469 /** 470 * @return count of file versions this policy assigned to. 471 */ 472 public int getAssignmentCountFileVersion() { 473 return this.assignmentCountFileVersion; 474 } 475 476 /** 477 * @return info about the user who created this policy. 478 */ 479 public BoxUser.Info getCreatedBy() { 480 return this.createdBy; 481 } 482 483 /** 484 * @return time the policy was created. 485 */ 486 public Date getCreatedAt() { 487 return this.createdAt; 488 } 489 490 /** 491 * @return time the policy was modified. 492 */ 493 public Date getModifiedAt() { 494 return this.modifiedAt; 495 } 496 497 /** 498 * @return time that the policy release request was sent. 499 */ 500 public Date getDeletedAt() { 501 return this.deletedAt; 502 } 503 504 /** 505 * @return optional date filter applies to Custodian assignments only. 506 */ 507 public Date getFilterStartedAt() { 508 return this.filterStartedAt; 509 } 510 511 /** 512 * @return optional date filter applies to Custodian assignments only. 513 */ 514 public Date getFilterEndedAt() { 515 return this.filterEndedAt; 516 } 517 518 /** 519 * @return notes around why the policy was released. 520 */ 521 public String getReleaseNotes() { 522 return this.releaseNotes; 523 } 524 525 /** 526 * Sets the policy's release notes. 527 * 528 * @param releaseNotes the policy's new release notes. 529 */ 530 public void setReleaseNotes(String releaseNotes) { 531 this.releaseNotes = releaseNotes; 532 this.addPendingChange("release_notes", releaseNotes); 533 } 534 535 /** 536 * @return boolean indicating whether the policy will continue applying to files based on events, indefinitely. 537 */ 538 public Boolean getIsOngoing() { 539 return this.isOngoing; 540 } 541 542 /** 543 * {@inheritDoc} 544 */ 545 @Override 546 void parseJSONMember(JsonObject.Member member) { 547 super.parseJSONMember(member); 548 String memberName = member.getName(); 549 JsonValue value = member.getValue(); 550 try { 551 if (memberName.equals("policy_name")) { 552 this.policyName = value.asString(); 553 } else if (memberName.equals("description")) { 554 this.description = value.asString(); 555 } else if (memberName.equals("status")) { 556 this.status = value.asString(); 557 } else if (memberName.equals("release_notes")) { 558 this.releaseNotes = value.asString(); 559 } else if (memberName.equals("assignment_counts")) { 560 JsonObject countsJSON = value.asObject(); 561 this.assignmentCountUser = countsJSON.get("user").asInt(); 562 this.assignmentCountFolder = countsJSON.get("folder").asInt(); 563 this.assignmentCountFile = countsJSON.get("file").asInt(); 564 this.assignmentCountFileVersion = countsJSON.get("file_version").asInt(); 565 } else if (memberName.equals("created_by")) { 566 JsonObject userJSON = value.asObject(); 567 if (this.createdBy == null) { 568 String userID = userJSON.get("id").asString(); 569 BoxUser user = new BoxUser(getAPI(), userID); 570 this.createdBy = user.new Info(userJSON); 571 } else { 572 this.createdBy.update(userJSON); 573 } 574 } else if (memberName.equals("created_at")) { 575 this.createdAt = BoxDateFormat.parse(value.asString()); 576 } else if (memberName.equals("modified_at")) { 577 this.modifiedAt = BoxDateFormat.parse(value.asString()); 578 } else if (memberName.equals("deleted_at")) { 579 this.deletedAt = BoxDateFormat.parse(value.asString()); 580 } else if (memberName.equals("filter_started_at")) { 581 this.filterStartedAt = BoxDateFormat.parse(value.asString()); 582 } else if (memberName.equals("filter_ended_at")) { 583 this.filterEndedAt = BoxDateFormat.parse(value.asString()); 584 } else if (memberName.equals("is_ongoing")) { 585 this.isOngoing = value.asBoolean(); 586 } 587 } catch (Exception e) { 588 throw new BoxDeserializationException(memberName, value.toString(), e); 589 } 590 } 591 } 592}