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         * Constructor.
351         *
352         * @param jsonObject
353         *            a parsed JSON object
354         */
355        public Info(JsonObject jsonObject) {
356            super(jsonObject);
357
358            if (jsonObject.get(JSON_KEY_TARGET) != null) {
359                JsonObject targetObject = jsonObject.get(JSON_KEY_TARGET).asObject();
360                String targetType = targetObject.get(JSON_KEY_TARGET_TYPE).asString();
361                String targetId = targetObject.get(JSON_KEY_TARGET_ID).asString();
362                this.target = new Target(targetType, targetId);
363            }
364
365            if (jsonObject.get(JSON_KEY_TRIGGERS) != null) {
366                this.triggers = new HashSet<Trigger>(
367                        CollectionUtils.map(jsonObject.get(JSON_KEY_TRIGGERS).asArray().values(), JSON_VALUE_TO_TRIGGER)
368                );
369            }
370            if (jsonObject.get(JSON_KEY_ADDRESS) != null) {
371                try {
372                    this.address = new URL(jsonObject.get(JSON_KEY_ADDRESS).asString());
373                } catch (MalformedURLException e) {
374                    throw new RuntimeException(e);
375                }
376            }
377
378            if (jsonObject.get(JSON_KEY_CREATED_BY) != null) {
379                JsonObject userJSON = jsonObject.get(JSON_KEY_CREATED_BY).asObject();
380                if (this.createdBy == null) {
381                    BoxUser user = new BoxUser(getAPI(), userJSON.get(JSON_KEY_TARGET_ID).asString());
382                    this.createdBy = user.new Info(userJSON);
383                } else {
384                    this.createdBy.update(userJSON);
385                }
386            }
387
388            if (jsonObject.get(JSON_KEY_CREATED_AT) != null) {
389                try {
390                    this.createdAt = BoxDateFormat.parse(jsonObject.get(JSON_KEY_CREATED_AT).asString());
391                } catch (ParseException e) {
392                    assert false : "A ParseException indicates a bug in the SDK.";
393                }
394            }
395        }
396
397        /**
398         * {@inheritDoc}
399         */
400        @Override
401        public BoxWebHook getResource() {
402            return BoxWebHook.this;
403        }
404
405        /**
406         * @return WebHook target / {@link BoxResource}.
407         */
408        public Target getTarget() {
409            return this.target;
410        }
411
412        /**
413         * @return {@link URL} where the notification should send to.
414         */
415        public URL getAddress() {
416            return this.address;
417        }
418
419        /**
420         * Setter for {@link #getAddress()}.
421         *
422         * @param address
423         *            {@link #getAddress()}
424         * @return itself
425         */
426        public Info setAddress(URL address) {
427            if (address == null) {
428                throw new IllegalArgumentException("Address cannot be null");
429            }
430            if (this.address == null || !this.address.equals(address)) {
431                this.address = address;
432                this.addPendingChange(JSON_KEY_ADDRESS, address.toExternalForm());
433            }
434
435            return this;
436        }
437
438        /**
439         * @return Events this webhook is interested in.
440         */
441        public Set<Trigger> getTriggers() {
442            return this.triggers;
443        }
444
445        /**
446         * Sets {@link #getTriggers()}.
447         *
448         * @param triggers
449         *            {@link #getTriggers()}
450         * @return itself
451         */
452        public Info setTriggers(BoxWebHook.Trigger... triggers) {
453            return this.setTriggers(new HashSet<Trigger>(Arrays.asList(triggers)));
454        }
455
456        /**
457         * Setter for {@link #getTriggers()}.
458         *
459         * @param triggers
460         *            {@link #getTriggers()}
461         * @return itself
462         */
463        public Info setTriggers(Set<BoxWebHook.Trigger> triggers) {
464            validateTriggers(this.target.getType(), triggers);
465
466            JsonArray oldValue;
467            if (this.triggers != null) {
468                oldValue = toJsonArray(CollectionUtils.map(this.triggers, TRIGGER_TO_VALUE));
469            } else {
470                oldValue = null;
471            }
472            JsonArray newValue = toJsonArray(CollectionUtils.map(triggers, TRIGGER_TO_VALUE));
473
474            if (!newValue.equals(oldValue)) {
475                this.triggers = Collections.unmodifiableSet(triggers);
476                this.addPendingChange(JSON_KEY_TRIGGERS, newValue);
477            }
478
479            return this;
480        }
481
482        /**
483         * @return Info about the user who created this webhook.
484         */
485        public BoxUser.Info getCreatedBy() {
486            return this.createdBy;
487        }
488
489        /**
490         * @return the time this webhook was created.
491         */
492        public Date getCreatedAt() {
493            return this.createdAt;
494        }
495
496        /**
497         * {@inheritDoc}
498         */
499        @Override
500        void parseJSONMember(JsonObject.Member member) {
501            super.parseJSONMember(member);
502            String memberName = member.getName();
503            JsonValue value = member.getValue();
504            try {
505                if (memberName.equals(JSON_KEY_TARGET)) {
506                    String targetType = value.asObject().get(JSON_KEY_TARGET_TYPE).asString();
507                    String targetId = value.asObject().get(JSON_KEY_TARGET_ID).asString();
508                    this.target = new Target(targetType, targetId);
509                } else if (memberName.equals(JSON_KEY_TRIGGERS)) {
510                    this.triggers = new HashSet<Trigger>(
511                            CollectionUtils.map(value.asArray().values(), JSON_VALUE_TO_TRIGGER)
512                    );
513                } else if (memberName.equals(JSON_KEY_ADDRESS)) {
514                    this.address = new URL(value.asString());
515                } else if (memberName.equals(JSON_KEY_CREATED_BY)) {
516                    JsonObject userJSON = value.asObject();
517                    if (this.createdBy == null) {
518                        String userID = userJSON.get(JSON_KEY_ID).asString();
519                        BoxUser user = new BoxUser(getAPI(), userID);
520                        this.createdBy = user.new Info(userJSON);
521                    } else {
522                        this.createdBy.update(userJSON);
523                    }
524                } else if (memberName.equals("created_at")) {
525                    this.createdAt = BoxDateFormat.parse(value.asString());
526                }
527            } catch (ParseException e) {
528                assert false : "A ParseException indicates a bug in the SDK.";
529            } catch (MalformedURLException e) {
530                assert false : "A MalformedURLException indicates a bug in the SDK.";
531            }
532        }
533
534    }
535
536    /**
537     * WebHook target - file or folder.
538     */
539    public static class Target {
540
541        /**
542         * @see #getType()
543         */
544        private final String type;
545
546        /**
547         * @see #getId()
548         */
549        private final String id;
550
551        /**
552         * Constructor.
553         *
554         * @param type
555         *            {@link #getType()}
556         * @param id
557         *            {@link #getId()}
558         */
559        public Target(String type, String id) {
560            this.type = type;
561            this.id = id;
562        }
563
564        /**
565         * @return Type of target.
566         * @see BoxResourceType
567         */
568        public String getType() {
569            return this.type;
570        }
571
572        /**
573         * @return {@link BoxResource#getID()}
574         */
575        public String getId() {
576            return this.id;
577        }
578
579    }
580
581    /**
582     * A Box related triggers.
583     */
584    public enum Trigger {
585
586        // BoxFolder related triggers.
587
588        /**
589         * Triggered when a {@link BoxFolder} gets created.
590         */
591        FOLDER_CREATED("FOLDER.CREATED", BoxResource.getResourceType(BoxFolder.class)),
592
593        /**
594         * Triggered when a {@link BoxFolder} gets copied.
595         */
596        FOLDER_COPIED("FOLDER.COPIED", BoxResource.getResourceType(BoxFolder.class)),
597
598        /**
599         * Triggered when a {@link BoxFolder} gets moved.
600         */
601        FOLDER_MOVED("FOLDER.MOVED", BoxResource.getResourceType(BoxFolder.class)),
602
603        /**
604         * Triggered when a {@link BoxFolder} is downloaded.
605         */
606        FOLDER_DOWNLOADED("FOLDER.DOWNLOADED", BoxResource.getResourceType(BoxFolder.class)),
607
608        /**
609         * Triggered when a {@link BoxFolder} is trashed.
610         */
611        FOLDER_TRASHED("FOLDER.TRASHED", BoxResource.getResourceType(BoxFolder.class)),
612
613        /**
614         * Triggered when a {@link BoxFolder} gets restored.
615         */
616        FOLDER_RESTORED("FOLDER.RESTORED", BoxResource.getResourceType(BoxFolder.class)),
617
618        /**
619         * Triggered when a {@link BoxFolder} gets deleted.
620         */
621        FOLDER_DELETED("FOLDER.DELETED", BoxResource.getResourceType(BoxFolder.class)),
622
623        /**
624         * Triggered when a {@link BoxFolder} is renamed.
625         */
626        FOLDER_RENAMED("FOLDER.RENAMED", BoxResource.getResourceType(BoxFolder.class)),
627
628        // BoxFile related triggers.
629
630        /**
631         * Triggered when a {@link BoxFile} gets uploaded.
632         */
633        FILE_UPLOADED("FILE.UPLOADED", BoxResource.getResourceType(BoxFolder.class)),
634
635        /**
636         * Triggered when a {@link BoxFile} gets copied.
637         */
638        FILE_COPIED("FILE.COPIED",
639                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
640
641        /**
642         * Triggered when a {@link BoxFile} gets copied.
643         */
644        FILE_MOVED("FILE.MOVED",
645                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
646
647        /**
648         * Triggered when a {@link BoxFile} is previewed.
649         */
650        FILE_PREVIEWED("FILE.PREVIEWED",
651                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
652
653        /**
654         * Triggered when a {@link BoxFile} is downloaded.
655         */
656        FILE_DOWNLOADED("FILE.DOWNLOADED",
657                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
658
659        /**
660         * Triggered when a {@link BoxFile} gets locked.
661         */
662        FILE_LOCKED("FILE.LOCKED",
663                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
664
665        /**
666         * Triggered when a {@link BoxFile} gets unlocked.
667         */
668        FILE_UNLOCKED("FILE.UNLOCKED",
669                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
670
671        /**
672         * Triggered when a {@link BoxFile} is trashed. Do not include file versions for now.
673         */
674        FILE_TRASHED("FILE.TRASHED",
675                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
676
677        /**
678         * Triggered when a {@link BoxFile} gets restored.
679         */
680        FILE_RESTORED("FILE.RESTORED",
681                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
682
683        /**
684         * Triggered when a {@link BoxFile} is permanently deleted.
685         */
686        FILE_DELETED("FILE.DELETED",
687                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
688
689        /**
690         * Triggered when a {@link BoxFile} is renamed.
691         */
692        FILE_RENAMED("FILE.RENAMED",
693                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
694
695        /**
696         * Triggered when a {@link BoxComment} was created.
697         */
698        COMMENT_CREATED("COMMENT.CREATED",
699                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
700
701        /**
702         * Triggered when a {@link BoxComment} was updated.
703         */
704        COMMENT_UPDATED("COMMENT.UPDATED",
705                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
706
707        /**
708         * Triggered when a {@link BoxComment} was deleted.
709         */
710        COMMENT_DELETED("COMMENT.DELETED",
711                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
712
713        /**
714         * Triggered when a {@link BoxTaskAssignment} is created.
715         */
716        TASK_ASSIGNMENT_CREATED("TASK_ASSIGNMENT.CREATED",
717                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
718
719        /**
720         * Triggered when a {@link BoxTaskAssignment} is updated.
721         */
722        TASK_ASSIGNMENT_UPDATED("TASK_ASSIGNMENT.UPDATED",
723                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
724
725        /**
726         * Triggered when a metadata template is associated to a {@link BoxFile} or {@link BoxFolder}.
727         */
728        METADATA_INSTANCE_CREATED("METADATA_INSTANCE.CREATED",
729                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
730
731        /**
732         * Triggered when a field is updated in the metadata on a {@link BoxFile} or {@link BoxFolder}.
733         */
734        METADATA_INSTANCE_UPDATED("METADATA_INSTANCE.UPDATED",
735                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
736
737        /**
738         * Triggered when a metadata template is removed from a {@link BoxFile} or {@link BoxFolder}.
739         */
740        METADATA_INSTANCE_DELETED("METADATA_INSTANCE.DELETED",
741                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
742
743        /**
744         * Triggered when a {@link BoxWebHook} is deleted.
745         */
746        WEBHOOK_DELETED("WEBHOOK.DELETED"),
747
748        /**
749         * Triggered when a {@link BoxCollaboration} is created.
750         */
751        COLLABORATION_CREATED("COLLABORATION.CREATED",
752                BoxResource.getResourceType(BoxFolder.class)),
753
754        /**
755         * Triggered when a {@link BoxCollaboration} is accepted.
756         */
757        COLLABORATION_ACCEPTED("COLLABORATION.ACCEPTED",
758                BoxResource.getResourceType(BoxFolder.class)),
759
760        /**
761         * Triggered when a {@link BoxCollaboration} is rejected.
762         */
763        COLLABORATION_REJECTED("COLLABORATION.REJECTED",
764                BoxResource.getResourceType(BoxFolder.class)),
765
766        /**
767         * Triggered when a {@link BoxCollaboration} is removed.
768         */
769        COLLABORATION_REMOVED("COLLABORATION.REMOVED",
770                BoxResource.getResourceType(BoxFolder.class)),
771
772        /**
773         * Triggered when a {@link BoxCollaboration} is updated.
774         */
775        COLLABORATION_UPDATED("COLLABORATION.UPDATED",
776                BoxResource.getResourceType(BoxFolder.class)),
777
778        /**
779         * Triggered when a {@link BoxSharedLink} is created.
780         */
781        SHARED_LINK_CRATED("SHARED_LINK.CREATED",
782                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
783
784        /**
785         * Triggered when a {@link BoxSharedLink} is updated.
786         */
787        SHARED_LINK_UPDATED("SHARED_LINK.UPDATED",
788                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
789
790        /**
791         * Triggered when a {@link BoxSharedLink} is deleted.
792         */
793        SHARED_LINK_DELETED("SHARED_LINK.DELETED",
794                BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class));
795
796
797        /**
798         * @see #getValue()
799         */
800        private final String value;
801
802        /**
803         * @see #getTypes()
804         */
805        private final String[] types;
806
807        /**
808         * Constructor.
809         *
810         * @param value
811         *            {@link #getValue()}
812         * @param types
813         *            {@link #getTypes()}
814         */
815        Trigger(String value, String... types) {
816            this.value = value;
817            this.types = types;
818        }
819
820        /**
821         * @return {@link String} representation for {@link Trigger}.
822         */
823        public String getValue() {
824            return this.value;
825        }
826
827        /**
828         * @param value value to get the Trigger enum value for
829         * @return Trigger for given value
830         */
831        public static Trigger fromValue(String value) {
832            for (Trigger trigger : Trigger.values()) {
833                if (trigger.getValue().equals(value)) {
834                    return trigger;
835                }
836            }
837            throw new IllegalArgumentException("No Trigger for value: " + value);
838        }
839
840        /**
841         * @return Supported types for a web-hook.
842         */
843        public String[] getTypes() {
844            return this.types;
845        }
846
847    }
848
849}