001package com.box.sdk; 002 003import com.box.sdk.internal.utils.CollectionUtils; 004import com.box.sdk.internal.utils.CollectionUtils.Mapper; 005import com.eclipsesource.json.Json; 006import com.eclipsesource.json.JsonArray; 007import com.eclipsesource.json.JsonObject; 008import com.eclipsesource.json.JsonValue; 009import java.net.MalformedURLException; 010import java.net.URL; 011import java.text.ParseException; 012import java.util.Arrays; 013import java.util.Collection; 014import java.util.Collections; 015import java.util.Date; 016import java.util.HashSet; 017import java.util.Set; 018 019/** 020 * Box WebHook resource. 021 * 022 * @since 2.2.1 023 */ 024@BoxResourceType("webhook") 025public class BoxWebHook extends BoxResource { 026 027 /** 028 * {@link URLTemplate} for {@link BoxWebHook}s resource. 029 */ 030 public static final URLTemplate WEBHOOKS_URL_TEMPLATE = new URLTemplate("webhooks"); 031 /** 032 * {@link URLTemplate} for single {@link BoxWebHook} resource. 033 */ 034 public static final URLTemplate WEBHOOK_URL_TEMPLATE = new URLTemplate("webhooks/%s"); 035 036 /** 037 * JSON Key for {@link BoxWebHook} {@link #getID()}. 038 */ 039 private static final String JSON_KEY_ID = "id"; 040 041 /** 042 * JSON Key for {@link BoxWebHook.Info#getTarget()}. 043 */ 044 private static final String JSON_KEY_TARGET = "target"; 045 046 /** 047 * JSON Key for {@link BoxWebHook.Target#getType()}. 048 */ 049 private static final String JSON_KEY_TARGET_TYPE = "type"; 050 051 /** 052 * JSON Key for {@link BoxWebHook.Target#getId()}. 053 */ 054 private static final String JSON_KEY_TARGET_ID = "id"; 055 056 /** 057 * JSON Key for {@link BoxWebHook.Info#getAddress()}. 058 */ 059 private static final String JSON_KEY_ADDRESS = "address"; 060 061 /** 062 * JSON Key for {@link BoxWebHook.Info#getTriggers()}. 063 */ 064 private static final String JSON_KEY_TRIGGERS = "triggers"; 065 066 /** 067 * JSON Key for {@link BoxWebHook.Info#getCreatedBy()}. 068 */ 069 private static final String JSON_KEY_CREATED_BY = "created_by"; 070 071 /** 072 * JSON Key for {@link BoxWebHook.Info#getCreatedAt()}. 073 */ 074 private static final String JSON_KEY_CREATED_AT = "created_at"; 075 076 /** 077 * Maps a {@link Trigger} to its {@link Trigger#getValue()}. 078 */ 079 private static final Mapper<String, BoxWebHook.Trigger> TRIGGER_TO_VALUE = Trigger::getValue; 080 081 private static final Mapper<Trigger, JsonValue> JSON_VALUE_TO_TRIGGER = 082 value -> Trigger.fromValue(value.asString()); 083 084 /** 085 * Constructor. 086 * 087 * @param api {@link #getAPI()} 088 * @param id {@link #getID()} 089 */ 090 public BoxWebHook(BoxAPIConnection api, String id) { 091 super(api, id); 092 } 093 094 /** 095 * Adds a {@link BoxWebHook} to a provided {@link BoxResource}. 096 * 097 * @param target {@link BoxResource} web resource 098 * @param address {@link URL} where the notification should send to 099 * @param triggers events this {@link BoxWebHook} is interested in 100 * @return created {@link BoxWebHook} 101 * @see #create(BoxResource, URL, Set) 102 */ 103 public static BoxWebHook.Info create(BoxResource target, URL address, BoxWebHook.Trigger... triggers) { 104 return create(target, address, new HashSet<>(Arrays.asList(triggers))); 105 } 106 107 /** 108 * Adds a {@link BoxWebHook} to a provided {@link BoxResource}. 109 * 110 * @param target {@link BoxResource} web resource 111 * @param address {@link URL} where the notification should send to 112 * @param triggers events this {@link BoxWebHook} is interested in 113 * @return created {@link BoxWebHook} 114 * @see #create(BoxResource, URL, Trigger...) 115 */ 116 public static BoxWebHook.Info create(BoxResource target, URL address, Set<BoxWebHook.Trigger> triggers) { 117 BoxAPIConnection api = target.getAPI(); 118 119 String type = BoxResource.getResourceType(target.getClass()); 120 validateTriggers(type, triggers); 121 122 JsonObject targetJSON = new JsonObject() 123 .add(JSON_KEY_TARGET_TYPE, type) 124 .add(JSON_KEY_TARGET_ID, target.getID()); 125 126 JsonObject requestJSON = new JsonObject() 127 .add(JSON_KEY_TARGET, targetJSON) 128 .add(JSON_KEY_ADDRESS, address.toExternalForm()) 129 .add(JSON_KEY_TRIGGERS, toJsonArray(CollectionUtils.map(triggers, TRIGGER_TO_VALUE))); 130 131 URL url = WEBHOOKS_URL_TEMPLATE.build(api.getBaseURL()); 132 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 133 request.setBody(requestJSON.toString()); 134 135 try (BoxJSONResponse response = request.send()) { 136 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 137 138 BoxWebHook webHook = new BoxWebHook(api, responseJSON.get(JSON_KEY_ID).asString()); 139 return webHook.new Info(responseJSON); 140 } 141 } 142 143 /** 144 * Helper function to create JsonArray from collection. 145 * 146 * @param values collection of values to convert to JsonArray 147 * @return JsonArray with collection values 148 */ 149 private static JsonArray toJsonArray(Collection<String> values) { 150 JsonArray array = new JsonArray(); 151 for (String value : values) { 152 array.add(value); 153 } 154 return array; 155 156 } 157 158 /** 159 * Returns iterator over all {@link BoxWebHook}-s. 160 * 161 * @param api the API connection to be used by the resource 162 * @return existing {@link BoxWebHook.Info}-s 163 */ 164 public static Iterable<BoxWebHook.Info> all(final BoxAPIConnection api) { 165 return new BoxResourceIterable<BoxWebHook.Info>(api, WEBHOOKS_URL_TEMPLATE.build(api.getBaseURL()), 64) { 166 167 @Override 168 protected BoxWebHook.Info factory(JsonObject jsonObject) { 169 BoxWebHook webHook = new BoxWebHook(api, jsonObject.get("id").asString()); 170 return webHook.new Info(jsonObject); 171 } 172 173 }; 174 } 175 176 /** 177 * Returns iterator over all {@link BoxWebHook}-s. 178 * 179 * @param api the API connection to be used by the resource 180 * @param fields the fields to retrieve. 181 * @return existing {@link BoxWebHook.Info}-s 182 */ 183 public static Iterable<BoxWebHook.Info> all(final BoxAPIConnection api, String... fields) { 184 QueryStringBuilder builder = new QueryStringBuilder(); 185 if (fields.length > 0) { 186 builder.appendParam("fields", fields); 187 } 188 return new BoxResourceIterable<BoxWebHook.Info>( 189 api, WEBHOOKS_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString()), 64) { 190 191 @Override 192 protected BoxWebHook.Info factory(JsonObject jsonObject) { 193 BoxWebHook webHook = new BoxWebHook(api, jsonObject.get("id").asString()); 194 return webHook.new Info(jsonObject); 195 } 196 197 }; 198 } 199 200 /** 201 * Validates that provided {@link BoxWebHook.Trigger}-s can be applied on the provided {@link BoxResourceType}. 202 * 203 * @param targetType on which target the triggers should be applied to 204 * @param triggers for check 205 * @see #validateTrigger(String, Trigger) 206 */ 207 public static void validateTriggers(String targetType, Collection<BoxWebHook.Trigger> triggers) { 208 for (BoxWebHook.Trigger trigger : triggers) { 209 validateTrigger(targetType, trigger); 210 } 211 } 212 213 /** 214 * Validates that provided {@link BoxWebHook.Trigger} can be applied on the provided {@link BoxResourceType}. 215 * 216 * @param targetType on which targets the trigger should be applied to 217 * @param trigger for check 218 * @see #validateTriggers(String, Collection) 219 */ 220 private static void validateTrigger(String targetType, BoxWebHook.Trigger trigger) { 221 for (String type : trigger.getTypes()) { 222 if (targetType.equals(type)) { 223 return; 224 } 225 } 226 throw new IllegalArgumentException(String.format( 227 "Provided trigger '%s' is not supported on provided target '%s'.", trigger.name(), targetType)); 228 } 229 230 /** 231 * @param fields the fields to retrieve. 232 * @return Gets information about this {@link BoxWebHook}. 233 */ 234 public BoxWebHook.Info getInfo(String... fields) { 235 URL url = WEBHOOK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 236 if (fields.length > 0) { 237 QueryStringBuilder builder = new QueryStringBuilder().appendParam("fields", fields); 238 url = WEBHOOK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID()); 239 } 240 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET"); 241 try (BoxJSONResponse response = request.send()) { 242 return new Info(Json.parse(response.getJSON()).asObject()); 243 } 244 } 245 246 /** 247 * Updates {@link BoxWebHook} information. 248 * 249 * @param info new state 250 */ 251 public void updateInfo(BoxWebHook.Info info) { 252 URL url = WEBHOOK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 253 BoxJSONRequest request = new BoxJSONRequest(getAPI(), url, "PUT"); 254 request.setBody(info.getPendingChanges()); 255 256 try (BoxJSONResponse response = request.send()) { 257 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 258 info.update(jsonObject); 259 } 260 } 261 262 /** 263 * Deletes this webhook. 264 */ 265 public void delete() { 266 URL url = WEBHOOK_URL_TEMPLATE.build(getAPI().getBaseURL(), this.getID()); 267 BoxAPIRequest request = new BoxAPIRequest(getAPI(), url, "DELETE"); 268 request.send().close(); 269 } 270 271 /** 272 * A Box related triggers. 273 */ 274 public enum Trigger { 275 276 // BoxFolder related triggers. 277 278 /** 279 * Triggered when a {@link BoxFolder} gets created. 280 */ 281 FOLDER_CREATED("FOLDER.CREATED", BoxResource.getResourceType(BoxFolder.class)), 282 283 /** 284 * Triggered when a {@link BoxFolder} gets copied. 285 */ 286 FOLDER_COPIED("FOLDER.COPIED", BoxResource.getResourceType(BoxFolder.class)), 287 288 /** 289 * Triggered when a {@link BoxFolder} gets moved. 290 */ 291 FOLDER_MOVED("FOLDER.MOVED", BoxResource.getResourceType(BoxFolder.class)), 292 293 /** 294 * Triggered when a {@link BoxFolder} is downloaded. 295 */ 296 FOLDER_DOWNLOADED("FOLDER.DOWNLOADED", BoxResource.getResourceType(BoxFolder.class)), 297 298 /** 299 * Triggered when a {@link BoxFolder} is trashed. 300 */ 301 FOLDER_TRASHED("FOLDER.TRASHED", BoxResource.getResourceType(BoxFolder.class)), 302 303 /** 304 * Triggered when a {@link BoxFolder} gets restored. 305 */ 306 FOLDER_RESTORED("FOLDER.RESTORED", BoxResource.getResourceType(BoxFolder.class)), 307 308 /** 309 * Triggered when a {@link BoxFolder} gets deleted. 310 */ 311 FOLDER_DELETED("FOLDER.DELETED", BoxResource.getResourceType(BoxFolder.class)), 312 313 /** 314 * Triggered when a {@link BoxFolder} is renamed. 315 */ 316 FOLDER_RENAMED("FOLDER.RENAMED", BoxResource.getResourceType(BoxFolder.class)), 317 318 // BoxFile related triggers. 319 320 /** 321 * Triggered when a {@link BoxFile} gets uploaded. 322 */ 323 FILE_UPLOADED("FILE.UPLOADED", BoxResource.getResourceType(BoxFolder.class)), 324 325 /** 326 * Triggered when a {@link BoxFile} gets copied. 327 */ 328 FILE_COPIED("FILE.COPIED", 329 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 330 331 /** 332 * Triggered when a {@link BoxFile} gets copied. 333 */ 334 FILE_MOVED("FILE.MOVED", 335 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 336 337 /** 338 * Triggered when a {@link BoxFile} is previewed. 339 */ 340 FILE_PREVIEWED("FILE.PREVIEWED", 341 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 342 343 /** 344 * Triggered when a {@link BoxFile} is downloaded. 345 */ 346 FILE_DOWNLOADED("FILE.DOWNLOADED", 347 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 348 349 /** 350 * Triggered when a {@link BoxFile} gets locked. 351 */ 352 FILE_LOCKED("FILE.LOCKED", 353 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 354 355 /** 356 * Triggered when a {@link BoxFile} gets unlocked. 357 */ 358 FILE_UNLOCKED("FILE.UNLOCKED", 359 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 360 361 /** 362 * Triggered when a {@link BoxFile} is trashed. Do not include file versions for now. 363 */ 364 FILE_TRASHED("FILE.TRASHED", 365 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 366 367 /** 368 * Triggered when a {@link BoxFile} gets restored. 369 */ 370 FILE_RESTORED("FILE.RESTORED", 371 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 372 373 /** 374 * Triggered when a {@link BoxFile} is permanently deleted. 375 */ 376 FILE_DELETED("FILE.DELETED", 377 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 378 379 /** 380 * Triggered when a {@link BoxFile} is renamed. 381 */ 382 FILE_RENAMED("FILE.RENAMED", 383 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 384 385 /** 386 * Triggered when a {@link BoxComment} was created. 387 */ 388 COMMENT_CREATED("COMMENT.CREATED", 389 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 390 391 /** 392 * Triggered when a {@link BoxComment} was updated. 393 */ 394 COMMENT_UPDATED("COMMENT.UPDATED", 395 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 396 397 /** 398 * Triggered when a {@link BoxComment} was deleted. 399 */ 400 COMMENT_DELETED("COMMENT.DELETED", 401 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 402 403 /** 404 * Triggered when a {@link BoxTaskAssignment} is created. 405 */ 406 TASK_ASSIGNMENT_CREATED("TASK_ASSIGNMENT.CREATED", 407 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 408 409 /** 410 * Triggered when a {@link BoxTaskAssignment} is updated. 411 */ 412 TASK_ASSIGNMENT_UPDATED("TASK_ASSIGNMENT.UPDATED", 413 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 414 415 /** 416 * Triggered when a metadata template is associated to a {@link BoxFile} or {@link BoxFolder}. 417 */ 418 METADATA_INSTANCE_CREATED("METADATA_INSTANCE.CREATED", 419 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 420 421 /** 422 * Triggered when a field is updated in the metadata on a {@link BoxFile} or {@link BoxFolder}. 423 */ 424 METADATA_INSTANCE_UPDATED("METADATA_INSTANCE.UPDATED", 425 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 426 427 /** 428 * Triggered when a metadata template is removed from a {@link BoxFile} or {@link BoxFolder}. 429 */ 430 METADATA_INSTANCE_DELETED("METADATA_INSTANCE.DELETED", 431 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 432 433 /** 434 * Triggered when a {@link BoxWebHook} is deleted. 435 */ 436 WEBHOOK_DELETED("WEBHOOK.DELETED"), 437 438 /** 439 * Triggered when a {@link BoxCollaboration} is created. 440 */ 441 COLLABORATION_CREATED("COLLABORATION.CREATED", 442 BoxResource.getResourceType(BoxFolder.class)), 443 444 /** 445 * Triggered when a {@link BoxCollaboration} is accepted. 446 */ 447 COLLABORATION_ACCEPTED("COLLABORATION.ACCEPTED", 448 BoxResource.getResourceType(BoxFolder.class)), 449 450 /** 451 * Triggered when a {@link BoxCollaboration} is rejected. 452 */ 453 COLLABORATION_REJECTED("COLLABORATION.REJECTED", 454 BoxResource.getResourceType(BoxFolder.class)), 455 456 /** 457 * Triggered when a {@link BoxCollaboration} is removed. 458 */ 459 COLLABORATION_REMOVED("COLLABORATION.REMOVED", 460 BoxResource.getResourceType(BoxFolder.class)), 461 462 /** 463 * Triggered when a {@link BoxCollaboration} is updated. 464 */ 465 COLLABORATION_UPDATED("COLLABORATION.UPDATED", 466 BoxResource.getResourceType(BoxFolder.class)), 467 468 /** 469 * Triggered when a {@link BoxSharedLink} is created. 470 */ 471 SHARED_LINK_CRATED("SHARED_LINK.CREATED", 472 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 473 474 /** 475 * Triggered when a {@link BoxSharedLink} is updated. 476 */ 477 SHARED_LINK_UPDATED("SHARED_LINK.UPDATED", 478 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 479 480 /** 481 * Triggered when a {@link BoxSharedLink} is deleted. 482 */ 483 SHARED_LINK_DELETED("SHARED_LINK.DELETED", 484 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 485 486 /** 487 * Triggered when {@link BoxSignRequest} is completed. 488 */ 489 SIGN_REQUEST_COMPLETED("SIGN_REQUEST.COMPLETED", 490 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 491 /** 492 * Triggered when {@link BoxFile} is declined. 493 */ 494 SIGN_REQUEST_DECLINED("SIGN_REQUEST.DECLINED", 495 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 496 /** 497 * Triggered when {@link BoxFile} is expired. 498 */ 499 SIGN_REQUEST_EXPIRED("SIGN_REQUEST.EXPIRED", 500 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 501 /** 502 * Triggered when a signer's email is bounced. 503 */ 504 SIGN_REQUEST_SIGNER_EMAIL_BOUNCED("SIGN_REQUEST.SIGNER_EMAIL_BOUNCED", 505 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 506 /** 507 * Triggered when the signature request is signed. 508 */ 509 SIGN_REQUEST_SIGNER_SIGNED("SIGN_REQUEST.SIGNER_SIGNED", 510 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 511 /** 512 * Triggered when the signature is requested from the signer. 513 */ 514 SIGN_REQUEST_SIGNATURE_REQUESTED("SIGN_REQUEST.SIGNATURE_REQUESTED", 515 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), 516 /** 517 * Triggered when the signature request could not be processed. 518 */ 519 SIGN_REQUEST_ERROR_FINALIZING("SIGN_REQUEST.ERROR_FINALIZING", 520 BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)); 521 522 /** 523 * @see #getValue() 524 */ 525 private final String value; 526 527 /** 528 * @see #getTypes() 529 */ 530 private final String[] types; 531 532 /** 533 * Constructor. 534 * 535 * @param value {@link #getValue()} 536 * @param types {@link #getTypes()} 537 */ 538 Trigger(String value, String... types) { 539 this.value = value; 540 this.types = types; 541 } 542 543 /** 544 * @param value value to get the Trigger enum value for 545 * @return Trigger for given value 546 */ 547 public static Trigger fromValue(String value) { 548 for (Trigger trigger : Trigger.values()) { 549 if (trigger.getValue().equals(value)) { 550 return trigger; 551 } 552 } 553 throw new IllegalArgumentException("No Trigger for value: " + value); 554 } 555 556 /** 557 * @return {@link String} representation for {@link Trigger}. 558 */ 559 public String getValue() { 560 return this.value; 561 } 562 563 /** 564 * @return Supported types for a web-hook. 565 */ 566 public String[] getTypes() { 567 return this.types; 568 } 569 570 } 571 572 /** 573 * WebHook target - file or folder. 574 */ 575 public static class Target { 576 577 /** 578 * @see #getType() 579 */ 580 private final String type; 581 582 /** 583 * @see #getId() 584 */ 585 private final String id; 586 587 /** 588 * Constructor. 589 * 590 * @param type {@link #getType()} 591 * @param id {@link #getId()} 592 */ 593 public Target(String type, String id) { 594 this.type = type; 595 this.id = id; 596 } 597 598 /** 599 * @return Type of target. 600 * @see BoxResourceType 601 */ 602 public String getType() { 603 return this.type; 604 } 605 606 /** 607 * @return {@link BoxResource#getID()} 608 */ 609 public String getId() { 610 return this.id; 611 } 612 613 } 614 615 /** 616 * Contains information for a {@link BoxWebHook} instance. 617 */ 618 public class Info extends BoxResource.Info { 619 620 /** 621 * @see #getTarget() 622 */ 623 private Target target; 624 625 /** 626 * @see #getAddress() 627 */ 628 private URL address; 629 630 /** 631 * @see #getTriggers() 632 */ 633 private Set<Trigger> triggers; 634 635 /** 636 * @see #getCreatedBy() 637 */ 638 private BoxUser.Info createdBy; 639 640 /** 641 * @see #getCreatedAt() 642 */ 643 private Date createdAt; 644 645 /** 646 * Constructs an Info object with current target. 647 */ 648 public Info() { 649 super(); 650 this.target = BoxWebHook.this.getInfo().getTarget(); 651 } 652 653 /** 654 * Constructs an Info object by parsing information from a JSON string. 655 * 656 * @param json the JSON string to parse. 657 */ 658 public Info(String json) { 659 this(Json.parse(json).asObject()); 660 } 661 662 /** 663 * Constructor. 664 * 665 * @param jsonObject a parsed JSON object 666 */ 667 public Info(JsonObject jsonObject) { 668 super(jsonObject); 669 670 if (jsonObject.get(JSON_KEY_TARGET) != null) { 671 JsonObject targetObject = jsonObject.get(JSON_KEY_TARGET).asObject(); 672 String targetType = targetObject.get(JSON_KEY_TARGET_TYPE).asString(); 673 String targetId = targetObject.get(JSON_KEY_TARGET_ID).asString(); 674 this.target = new Target(targetType, targetId); 675 } 676 677 if (jsonObject.get(JSON_KEY_TRIGGERS) != null) { 678 this.triggers = new HashSet<>( 679 CollectionUtils.map(jsonObject.get(JSON_KEY_TRIGGERS).asArray().values(), JSON_VALUE_TO_TRIGGER) 680 ); 681 } 682 if (jsonObject.get(JSON_KEY_ADDRESS) != null) { 683 try { 684 this.address = new URL(jsonObject.get(JSON_KEY_ADDRESS).asString()); 685 } catch (MalformedURLException e) { 686 throw new RuntimeException(e); 687 } 688 } 689 690 if (jsonObject.get(JSON_KEY_CREATED_BY) != null) { 691 JsonObject userJSON = jsonObject.get(JSON_KEY_CREATED_BY).asObject(); 692 if (this.createdBy == null) { 693 BoxUser user = new BoxUser(getAPI(), userJSON.get(JSON_KEY_TARGET_ID).asString()); 694 this.createdBy = user.new Info(userJSON); 695 } else { 696 this.createdBy.update(userJSON); 697 } 698 } 699 700 if (jsonObject.get(JSON_KEY_CREATED_AT) != null) { 701 try { 702 this.createdAt = BoxDateFormat.parse(jsonObject.get(JSON_KEY_CREATED_AT).asString()); 703 } catch (ParseException e) { 704 assert false : "A ParseException indicates a bug in the SDK."; 705 } 706 } 707 } 708 709 /** 710 * {@inheritDoc} 711 */ 712 @Override 713 public BoxWebHook getResource() { 714 return BoxWebHook.this; 715 } 716 717 /** 718 * @return WebHook target / {@link BoxResource}. 719 */ 720 public Target getTarget() { 721 return this.target; 722 } 723 724 /** 725 * @return {@link URL} where the notification should send to. 726 */ 727 public URL getAddress() { 728 return this.address; 729 } 730 731 /** 732 * Setter for {@link #getAddress()}. 733 * 734 * @param address {@link #getAddress()} 735 * @return itself 736 */ 737 public Info setAddress(URL address) { 738 if (address == null) { 739 throw new IllegalArgumentException("Address cannot be null"); 740 } 741 if (this.address == null || !this.address.equals(address)) { 742 this.address = address; 743 this.addPendingChange(JSON_KEY_ADDRESS, address.toExternalForm()); 744 } 745 746 return this; 747 } 748 749 /** 750 * @return Events this webhook is interested in. 751 */ 752 public Set<Trigger> getTriggers() { 753 return this.triggers; 754 } 755 756 /** 757 * Sets {@link #getTriggers()}. 758 * 759 * @param triggers {@link #getTriggers()} 760 * @return itself 761 */ 762 public Info setTriggers(BoxWebHook.Trigger... triggers) { 763 return this.setTriggers(new HashSet<>(Arrays.asList(triggers))); 764 } 765 766 /** 767 * Setter for {@link #getTriggers()}. 768 * 769 * @param triggers {@link #getTriggers()} 770 * @return itself 771 */ 772 public Info setTriggers(Set<BoxWebHook.Trigger> triggers) { 773 validateTriggers(this.target.getType(), triggers); 774 775 JsonArray oldValue; 776 if (this.triggers != null) { 777 oldValue = toJsonArray(CollectionUtils.map(this.triggers, TRIGGER_TO_VALUE)); 778 } else { 779 oldValue = null; 780 } 781 JsonArray newValue = toJsonArray(CollectionUtils.map(triggers, TRIGGER_TO_VALUE)); 782 783 if (!newValue.equals(oldValue)) { 784 this.triggers = Collections.unmodifiableSet(triggers); 785 this.addPendingChange(JSON_KEY_TRIGGERS, newValue); 786 } 787 788 return this; 789 } 790 791 /** 792 * @return Info about the user who created this webhook. 793 */ 794 public BoxUser.Info getCreatedBy() { 795 return this.createdBy; 796 } 797 798 /** 799 * @return the time this webhook was created. 800 */ 801 public Date getCreatedAt() { 802 return this.createdAt; 803 } 804 805 /** 806 * {@inheritDoc} 807 */ 808 @Override 809 void parseJSONMember(JsonObject.Member member) { 810 super.parseJSONMember(member); 811 String memberName = member.getName(); 812 JsonValue value = member.getValue(); 813 try { 814 if (memberName.equals(JSON_KEY_TARGET)) { 815 String targetType = value.asObject().get(JSON_KEY_TARGET_TYPE).asString(); 816 String targetId = value.asObject().get(JSON_KEY_TARGET_ID).asString(); 817 this.target = new Target(targetType, targetId); 818 } else if (memberName.equals(JSON_KEY_TRIGGERS)) { 819 this.triggers = new HashSet<>( 820 CollectionUtils.map(value.asArray().values(), JSON_VALUE_TO_TRIGGER) 821 ); 822 } else if (memberName.equals(JSON_KEY_ADDRESS)) { 823 this.address = new URL(value.asString()); 824 } else if (memberName.equals(JSON_KEY_CREATED_BY)) { 825 JsonObject userJSON = value.asObject(); 826 if (this.createdBy == null) { 827 String userID = userJSON.get(JSON_KEY_ID).asString(); 828 BoxUser user = new BoxUser(getAPI(), userID); 829 this.createdBy = user.new Info(userJSON); 830 } else { 831 this.createdBy.update(userJSON); 832 } 833 } else if (memberName.equals("created_at")) { 834 this.createdAt = BoxDateFormat.parse(value.asString()); 835 } 836 } catch (Exception e) { 837 throw new BoxDeserializationException(memberName, value.toString(), e); 838 } 839 } 840 841 } 842 843}