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