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