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