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