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