001package com.box.sdk;
002
003import com.eclipsesource.json.Json;
004import com.eclipsesource.json.JsonArray;
005import com.eclipsesource.json.JsonObject;
006import com.eclipsesource.json.JsonValue;
007import java.net.URL;
008import java.util.ArrayList;
009import java.util.Date;
010import java.util.List;
011
012/**
013 * Represents a retention policy.
014 * A retention policy blocks permanent deletion of content for a specified amount of time.
015 * Admins can create retention policies and then later assign them to specific folders or their entire enterprise.
016 *
017 * @see <a href="https://developer.box.com/reference/resources/retention-policy/">Box retention policy</a>
018 *
019 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
020 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
021 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p>
022 */
023@BoxResourceType("retention_policy")
024public class BoxRetentionPolicy extends BoxResource {
025    /**
026     * The URL template used for operation with retention policies.
027     */
028    public static final URLTemplate RETENTION_POLICIES_URL_TEMPLATE = new URLTemplate("retention_policies");
029
030    /**
031     * The URL template used for operation with retention policy with given ID.
032     */
033    public static final URLTemplate POLICY_URL_TEMPLATE = new URLTemplate("retention_policies/%s");
034
035    /**
036     * The URL template used for operation with retention policy assignments.
037     */
038    public static final URLTemplate ASSIGNMENTS_URL_TEMPLATE = new URLTemplate("retention_policies/%s/assignments");
039
040    /**
041     * Will cause the content retained by the policy to be permanently deleted.
042     */
043    public static final String ACTION_PERMANENTLY_DELETE = "permanently_delete";
044
045    /**
046     * Will lift the retention policy from the content, allowing it to be deleted by users.
047     */
048    public static final String ACTION_REMOVE_RETENTION = "remove_retention";
049
050    /**
051     * Status corresponding to active retention policy.
052     */
053    public static final String STATUS_ACTIVE = "active";
054
055    /**
056     * Status corresponding to retired retention policy.
057     */
058    public static final String STATUS_RETIRED = "retired";
059
060    /**
061     * The default limit of entries per response.
062     */
063    private static final int DEFAULT_LIMIT = 100;
064
065    /**
066     * Constructs a retention policy for a resource with a given ID.
067     *
068     * @param api the API connection to be used by the resource.
069     * @param id  the ID of the resource.
070     */
071    public BoxRetentionPolicy(BoxAPIConnection api, String id) {
072        super(api, id);
073    }
074
075    /**
076     * Used to create a new indefinite retention policy.
077     *
078     * @param api  the API connection to be used by the created user.
079     * @param name the name of the retention policy.
080     * @return the created retention policy's info.
081     */
082    public static BoxRetentionPolicy.Info createIndefinitePolicy(BoxAPIConnection api, String name) {
083        return createRetentionPolicy(
084            api, name, BoxRetentionPolicyType.Indefinite, 0, BoxRetentionPolicyAction.RemoveRetention
085        );
086    }
087
088    /**
089     * Used to create a new indefinite retention policy with optional parameters.
090     *
091     * @param api            the API connection to be used by the created user.
092     * @param name           the name of the retention policy.
093     * @param optionalParams the optional parameters.
094     * @return the created retention policy's info.
095     */
096    public static BoxRetentionPolicy.Info createIndefinitePolicy(
097        BoxAPIConnection api, String name, RetentionPolicyParams optionalParams
098    ) {
099        return createRetentionPolicy(
100            api, name, BoxRetentionPolicyType.Indefinite, 0, BoxRetentionPolicyAction.RemoveRetention, optionalParams
101        );
102    }
103
104    /**
105     * Used to create a new finite retention policy.
106     *
107     * @param api    the API connection to be used by the created user.
108     * @param name   the name of the retention policy.
109     * @param length the duration in days that the retention policy will be active for after being assigned to content.
110     * @param action the disposition action can be "permanently_delete" or "remove_retention".
111     * @return the created retention policy's info.
112     * @deprecated Use {@link BoxRetentionPolicy#createFinitePolicy(BoxAPIConnection, String, int, BoxRetentionPolicyAction)}
113     */
114    @Deprecated
115    public static BoxRetentionPolicy.Info createFinitePolicy(BoxAPIConnection api,
116                                                             String name,
117                                                             int length,
118                                                             String action) {
119        return createRetentionPolicy(
120            api, name, BoxRetentionPolicyType.Finite, length, BoxRetentionPolicyAction.valueOf(action)
121        );
122    }
123
124    /**
125     * Used to create a new finite retention policy.
126     *
127     * @param api    the API connection to be used by the created user.
128     * @param name   the name of the retention policy.
129     * @param length the duration in days that the retention policy will be active for after being assigned to content.
130     * @param action the disposition action can be "permanently_delete" or "remove_retention".
131     * @return the created retention policy's info.
132     */
133    public static BoxRetentionPolicy.Info createFinitePolicy(BoxAPIConnection api,
134                                                             String name,
135                                                             int length,
136                                                             BoxRetentionPolicyAction action) {
137        return createRetentionPolicy(api, name, BoxRetentionPolicyType.Finite, length, action);
138    }
139
140    /**
141     * Used to create a new finite retention policy with optional parameters.
142     *
143     * @param api            the API connection to be used by the created user.
144     * @param name           the name of the retention policy.
145     * @param length         the duration in days that the retention policy will be active for after being assigned to content.
146     * @param action         the disposition action can be "permanently_delete" or "remove_retention".
147     * @param optionalParams the optional parameters.
148     * @return the created retention policy's info.
149     * @deprecated Use {@link BoxRetentionPolicy#createFinitePolicy(BoxAPIConnection, String, int, BoxRetentionPolicyAction, RetentionPolicyParams)}
150     */
151    @Deprecated
152    public static BoxRetentionPolicy.Info createFinitePolicy(
153        BoxAPIConnection api,
154        String name,
155        int length,
156        String action,
157        RetentionPolicyParams optionalParams
158    ) {
159        return createRetentionPolicy(
160            api, name, BoxRetentionPolicyType.Finite, length, BoxRetentionPolicyAction.valueOf(action), optionalParams
161        );
162    }
163
164    /**
165     * Used to create a new finite retention policy with optional parameters.
166     *
167     * @param api            the API connection to be used by the created user.
168     * @param name           the name of the retention policy.
169     * @param length         the duration in days that the retention policy will be active for after being assigned to content.
170     * @param action         the disposition action can be "permanently_delete" or "remove_retention".
171     * @param optionalParams the optional parameters.
172     * @return the created retention policy's info.
173     */
174    public static BoxRetentionPolicy.Info createFinitePolicy(
175        BoxAPIConnection api,
176        String name,
177        int length,
178        BoxRetentionPolicyAction action,
179        RetentionPolicyParams optionalParams
180    ) {
181        return createRetentionPolicy(api, name, BoxRetentionPolicyType.Finite, length, action, optionalParams);
182    }
183
184    /**
185     * Used to create a new retention policy.
186     *
187     * @param api    the API connection to be used by the created user.
188     * @param name   the name of the retention policy.
189     * @param type   the type of the retention policy. Can be "finite" or "indefinite".
190     * @param length the duration in days that the retention policy will be active for after being assigned to content.
191     * @param action the disposition action can be "permanently_delete" or "remove_retention".
192     * @return the created retention policy's info.
193     */
194    private static BoxRetentionPolicy.Info createRetentionPolicy(BoxAPIConnection api,
195                                                                 String name,
196                                                                 BoxRetentionPolicyType type,
197                                                                 int length,
198                                                                 BoxRetentionPolicyAction action) {
199        return createRetentionPolicy(api, name, type, length, action, null);
200    }
201
202    /**
203     * Used to create a new retention policy with optional parameters.
204     *
205     * @param api            the API connection to be used by the created user.
206     * @param name           the name of the retention policy.
207     * @param type           the type of the retention policy. Can be "finite" or "indefinite".
208     * @param length         the duration in days that the retention policy will be active for after being assigned to content.
209     * @param action         the disposition action can be "permanently_delete" or "remove_retention".
210     * @param optionalParams the optional parameters.
211     * @return the created retention policy's info.
212     */
213    private static BoxRetentionPolicy.Info createRetentionPolicy(
214        BoxAPIConnection api,
215        String name,
216        BoxRetentionPolicyType type,
217        int length,
218        BoxRetentionPolicyAction action,
219        RetentionPolicyParams optionalParams
220    ) {
221        URL url = RETENTION_POLICIES_URL_TEMPLATE.build(api.getBaseURL());
222        BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
223        JsonObject requestJSON = new JsonObject()
224            .add("policy_name", name)
225            .add("policy_type", type.value)
226            .add("disposition_action", action.value);
227        if (type != BoxRetentionPolicyType.Indefinite) {
228            requestJSON.add("retention_length", length);
229        }
230        if (optionalParams != null) {
231            requestJSON.add("can_owner_extend_retention", optionalParams.getCanOwnerExtendRetention());
232            requestJSON.add("are_owners_notified", optionalParams.getAreOwnersNotified());
233            requestJSON.add("description", optionalParams.getDescription());
234            requestJSON.add("retention_type", optionalParams.getRetentionType().toJSONString());
235
236            List<BoxUser.Info> customNotificationRecipients = optionalParams.getCustomNotificationRecipients();
237            if (customNotificationRecipients.size() > 0) {
238                JsonArray users = new JsonArray();
239                for (BoxUser.Info user : customNotificationRecipients) {
240                    JsonObject userJSON = new JsonObject()
241                        .add("type", "user")
242                        .add("id", user.getID());
243                    users.add(userJSON);
244                }
245                requestJSON.add("custom_notification_recipients", users);
246            }
247        }
248        request.setBody(requestJSON.toString());
249        BoxJSONResponse response = (BoxJSONResponse) request.send();
250        JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
251        BoxRetentionPolicy createdPolicy = new BoxRetentionPolicy(api, responseJSON.get("id").asString());
252        return createdPolicy.new Info(responseJSON);
253    }
254
255    /**
256     * Returns all the retention policies.
257     *
258     * @param api    the API connection to be used by the resource.
259     * @param fields the fields to retrieve.
260     * @return an iterable with all the retention policies.
261     */
262    public static Iterable<BoxRetentionPolicy.Info> getAll(final BoxAPIConnection api, String... fields) {
263        return getAll(null, null, null, DEFAULT_LIMIT, api, fields);
264    }
265
266    /**
267     * Returns all the retention policies with specified filters.
268     *
269     * @param name   a name to filter the retention policies by. A trailing partial match search is performed.
270     *               Set to null if no name filtering is required.
271     * @param type   a policy type to filter the retention policies by. Set to null if no type filtering is required.
272     * @param userID a user id to filter the retention policies by. Set to null if no type filtering is required.
273     * @param limit  the limit of items per single response. The default value is 100.
274     * @param api    the API connection to be used by the resource.
275     * @param fields the fields to retrieve.
276     * @return an iterable with all the retention policies met search conditions.
277     */
278    public static Iterable<BoxRetentionPolicy.Info> getAll(
279        String name, String type, String userID, int limit, final BoxAPIConnection api, String... fields) {
280        QueryStringBuilder queryString = new QueryStringBuilder();
281        if (name != null) {
282            queryString.appendParam("policy_name", name);
283        }
284        if (type != null) {
285            queryString.appendParam("policy_type", type);
286        }
287        if (userID != null) {
288            queryString.appendParam("created_by_user_id", userID);
289        }
290        if (fields.length > 0) {
291            queryString.appendParam("fields", fields);
292        }
293        URL url = RETENTION_POLICIES_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), queryString.toString());
294        return new BoxResourceIterable<BoxRetentionPolicy.Info>(api, url, limit) {
295
296            @Override
297            protected BoxRetentionPolicy.Info factory(JsonObject jsonObject) {
298                BoxRetentionPolicy policy = new BoxRetentionPolicy(api, jsonObject.get("id").asString());
299                return policy.new Info(jsonObject);
300            }
301
302        };
303    }
304
305    /**
306     * Returns iterable with all folder assignments of this retention policy.
307     *
308     * @param fields the fields to retrieve.
309     * @return an iterable containing all folder assignments.
310     */
311    public Iterable<BoxRetentionPolicyAssignment.Info> getFolderAssignments(String... fields) {
312        return this.getFolderAssignments(DEFAULT_LIMIT, fields);
313    }
314
315    /**
316     * Returns iterable with all folder assignments of this retention policy.
317     *
318     * @param limit  the limit of entries per response. The default value is 100.
319     * @param fields the fields to retrieve.
320     * @return an iterable containing all folder assignments.
321     */
322    public Iterable<BoxRetentionPolicyAssignment.Info> getFolderAssignments(int limit, String... fields) {
323        return this.getAssignments(BoxRetentionPolicyAssignment.TYPE_FOLDER, limit, fields);
324    }
325
326    /**
327     * Returns iterable with all enterprise assignments of this retention policy.
328     *
329     * @param fields the fields to retrieve.
330     * @return an iterable containing all enterprise assignments.
331     */
332    public Iterable<BoxRetentionPolicyAssignment.Info> getEnterpriseAssignments(String... fields) {
333        return this.getEnterpriseAssignments(DEFAULT_LIMIT, fields);
334    }
335
336    /**
337     * Returns iterable with all enterprise assignments of this retention policy.
338     *
339     * @param limit  the limit of entries per response. The default value is 100.
340     * @param fields the fields to retrieve.
341     * @return an iterable containing all enterprise assignments.
342     */
343    public Iterable<BoxRetentionPolicyAssignment.Info> getEnterpriseAssignments(int limit, String... fields) {
344        return this.getAssignments(BoxRetentionPolicyAssignment.TYPE_ENTERPRISE, limit, fields);
345    }
346
347    /**
348     * Returns iterable with all assignments of this retention policy.
349     *
350     * @param fields the fields to retrieve.
351     * @return an iterable containing all assignments.
352     */
353    public Iterable<BoxRetentionPolicyAssignment.Info> getAllAssignments(String... fields) {
354        return this.getAllAssignments(DEFAULT_LIMIT, fields);
355    }
356
357    /**
358     * Returns iterable with all assignments of this retention policy.
359     *
360     * @param limit  the limit of entries per response. The default value is 100.
361     * @param fields the fields to retrieve.
362     * @return an iterable containing all assignments.
363     */
364    public Iterable<BoxRetentionPolicyAssignment.Info> getAllAssignments(int limit, String... fields) {
365        return this.getAssignments(null, limit, fields);
366    }
367
368    /**
369     * Returns iterable with all assignments of given type of this retention policy.
370     *
371     * @param type   the type of the retention policy assignment to retrieve. Can either be "folder" or "enterprise".
372     * @param limit  the limit of entries per response. The default value is 100.
373     * @param fields the fields to retrieve.
374     * @return an iterable containing all assignments of given type.
375     */
376    private Iterable<BoxRetentionPolicyAssignment.Info> getAssignments(String type, int limit, String... fields) {
377        QueryStringBuilder queryString = new QueryStringBuilder();
378        if (type != null) {
379            queryString.appendParam("type", type);
380        }
381        if (fields.length > 0) {
382            queryString.appendParam("fields", fields);
383        }
384        URL url = ASSIGNMENTS_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(), queryString.toString(), getID());
385        return new BoxResourceIterable<BoxRetentionPolicyAssignment.Info>(getAPI(), url, limit) {
386
387            @Override
388            protected BoxRetentionPolicyAssignment.Info factory(JsonObject jsonObject) {
389                BoxRetentionPolicyAssignment assignment
390                    = new BoxRetentionPolicyAssignment(getAPI(), jsonObject.get("id").asString());
391                return assignment.new Info(jsonObject);
392            }
393
394        };
395    }
396
397    /**
398     * Assigns this retention policy to folder.
399     *
400     * @param folder the folder to assign policy to.
401     * @return info about created assignment.
402     */
403    public BoxRetentionPolicyAssignment.Info assignTo(BoxFolder folder) {
404        return BoxRetentionPolicyAssignment.createAssignmentToFolder(this.getAPI(), this.getID(), folder.getID());
405    }
406
407    /**
408     * Assigns this retention policy to the current enterprise.
409     *
410     * @return info about created assignment.
411     */
412    public BoxRetentionPolicyAssignment.Info assignToEnterprise() {
413        return BoxRetentionPolicyAssignment.createAssignmentToEnterprise(this.getAPI(), this.getID());
414    }
415
416    /**
417     * Assigns this retention policy to a metadata template, optionally with certain field values.
418     *
419     * @param templateID   the ID of the metadata template to apply to.
420     * @param fieldFilters optional field value filters.
421     * @return info about the created assignment.
422     */
423    public BoxRetentionPolicyAssignment.Info assignToMetadataTemplate(String templateID,
424                                                                      MetadataFieldFilter... fieldFilters) {
425        return assignToMetadataTemplate(templateID, null, fieldFilters);
426    }
427
428    /**
429     * Assigns this retention policy to a metadata template, optionally with certain field values.
430     *
431     * @param templateID     the ID of the metadata template to apply to.
432     * @param startDateField the date the retention policy assignment begins. This field can be a date field's metadata attribute key id.
433     * @param fieldFilters   optional field value filters.
434     * @return info about the created assignment.
435     */
436    public BoxRetentionPolicyAssignment.Info assignToMetadataTemplate(String templateID,
437                                                                      String startDateField,
438                                                                      MetadataFieldFilter... fieldFilters) {
439        return BoxRetentionPolicyAssignment.createAssignmentToMetadata(this.getAPI(), this.getID(), templateID,
440            startDateField, fieldFilters);
441    }
442
443    /**
444     * Updates the information about this retention policy with any info fields that have been modified locally.
445     *
446     * @param info the updated info.
447     */
448    public void updateInfo(BoxRetentionPolicy.Info info) {
449        URL url = POLICY_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
450        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
451        request.setBody(info.getPendingChanges());
452        BoxJSONResponse response = (BoxJSONResponse) request.send();
453        JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
454        info.update(responseJSON);
455    }
456
457    /**
458     * Returns information about this retention policy.
459     *
460     * @param fields the fields to retrieve.
461     * @return information about this retention policy.
462     */
463    public BoxRetentionPolicy.Info getInfo(String... fields) {
464        QueryStringBuilder builder = new QueryStringBuilder();
465        if (fields.length > 0) {
466            builder.appendParam("fields", fields);
467        }
468        URL url = POLICY_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID());
469        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
470        BoxJSONResponse response = (BoxJSONResponse) request.send();
471        JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
472        return new Info(responseJSON);
473    }
474
475    /**
476     * Contains information about the retention policy.
477     */
478    public class Info extends BoxResource.Info {
479
480        /**
481         * @see #getPolicyName()
482         */
483        private String policyName;
484
485        /**
486         * @see #getPolicyType()
487         */
488        private String policyType;
489
490        /**
491         * @see #getRetentionLength()
492         */
493        private int retentionLength;
494
495        /**
496         * @see #getDispositionAction()
497         */
498        private String dispositionAction;
499
500        /**
501         * @see #getStatus()
502         */
503        private String status;
504
505        /**
506         * @see #getCreatedBy()
507         */
508        private BoxUser.Info createdBy;
509
510        /**
511         * @see #getCreatedAt()
512         */
513        private Date createdAt;
514
515        /**
516         * @see #getModifiedAt()
517         */
518        private Date modifiedAt;
519
520        /**
521         * @see #getCanOwnerExtendRetention()
522         */
523        private boolean canOwnerExtendRetention;
524
525        /**
526         * @see #getAreOwnersNotified()
527         */
528        private boolean areOwnersNotified;
529
530        /**
531         * @see #getDescription()
532         */
533        private String description;
534
535        /**
536         * @see #getRetentionType()
537         */
538        private RetentionPolicyParams.RetentionType retentionType;
539
540        private List<BoxUser.Info> customNotificationRecipients;
541
542        /**
543         * Constructs an empty Info object.
544         */
545        public Info() {
546            super();
547        }
548
549        /**
550         * Constructs an Info object by parsing information from a JSON string.
551         *
552         * @param json the JSON string to parse.
553         */
554        public Info(String json) {
555            super(json);
556        }
557
558        /**
559         * Constructs an Info object using an already parsed JSON object.
560         *
561         * @param jsonObject the parsed JSON object.
562         */
563        Info(JsonObject jsonObject) {
564            super(jsonObject);
565        }
566
567        /**
568         * {@inheritDoc}
569         */
570        @Override
571        public BoxResource getResource() {
572            return BoxRetentionPolicy.this;
573        }
574
575        /**
576         * Gets the name given to the retention policy.
577         *
578         * @return name given to the retention policy.
579         */
580        public String getPolicyName() {
581            return this.policyName;
582        }
583
584        /**
585         * Update the policy name to a new value.
586         *
587         * @param policyName the new policy name.
588         */
589        public void setPolicyName(String policyName) {
590            this.policyName = policyName;
591            this.addPendingChange("policy_name", policyName);
592        }
593
594        /**
595         * Gets the type of the retention policy.
596         * A retention policy type can either be "finite",
597         * where a specific amount of time to retain the content is known upfront,
598         * or "indefinite", where the amount of time to retain the content is still unknown.
599         *
600         * @return the type of the retention policy.
601         */
602        public String getPolicyType() {
603            return this.policyType;
604        }
605
606        /**
607         * Gets the length of the retention policy. This length specifies the duration
608         * in days that the retention policy will be active for after being assigned to content.
609         *
610         * @return the length of the retention policy.
611         */
612        public int getRetentionLength() {
613            return this.retentionLength;
614        }
615
616        /**
617         *
618         * @param retentionLength The length of the retention policy.
619         */
620        public void setRetentionLength(int retentionLength) {
621            this.retentionLength = retentionLength;
622            this.addPendingChange("retention_length", retentionLength);
623        }
624
625        /**
626         * Gets the disposition action of the retention policy.
627         * This action can be "permanently_delete", or "remove_retention".
628         *
629         * @return the disposition action of the retention policy.
630         */
631        public String getDispositionAction() {
632            return this.dispositionAction;
633        }
634
635        /**
636         * Set the action to take when retention period ends.
637         *
638         * @param dispositionAction the new action.
639         */
640        public void setDispositionAction(String dispositionAction) {
641            this.dispositionAction = dispositionAction;
642            this.addPendingChange("disposition_action", dispositionAction);
643        }
644
645        /**
646         * Gets the status of the retention policy.
647         * The status can be "active" or "retired".
648         *
649         * @return the status of the retention policy.
650         */
651        public String getStatus() {
652            return this.status;
653        }
654
655        /**
656         * Set the policy status.
657         *
658         * @param status the new status value.
659         */
660        public void setStatus(String status) {
661            this.status = status;
662            this.addPendingChange("status", status);
663        }
664
665        /**
666         * Gets info about the user created the retention policy.
667         *
668         * @return info about the user created the retention policy.
669         */
670        public BoxUser.Info getCreatedBy() {
671            return this.createdBy;
672        }
673
674        /**
675         * Gets the time that the retention policy was created.
676         *
677         * @return the time that the retention policy was created.
678         */
679        public Date getCreatedAt() {
680            return this.createdAt;
681        }
682
683        /**
684         * Gets the time that the retention policy was last modified.
685         *
686         * @return the time that the retention policy was last modified.
687         */
688        public Date getModifiedAt() {
689            return this.modifiedAt;
690        }
691
692        /**
693         * Gets the flag to denote that the owner of a retained file can extend the retention when near expiration.
694         *
695         * @return the boolean flag.
696         */
697        public boolean getCanOwnerExtendRetention() {
698            return this.canOwnerExtendRetention;
699        }
700
701        /**
702         * Gets the flag to denote that owners and co-owners of a retained file will get notified when near expiration.
703         *
704         * @return the boolean flag.
705         */
706        public boolean getAreOwnersNotified() {
707            return this.areOwnersNotified;
708        }
709
710        /**
711         * Gets the additional text desription of the retention policy.
712         *
713         * @return the additional text desription of the retention policy
714         */
715        public String getDescription() {
716            return this.description;
717        }
718
719        /**
720         * Set the additional text desription of the retention policy.
721         *
722         * @param description the new text desription of the retention policy
723         */
724        public void setDescription(String description) {
725            this.description = description;
726            this.addPendingChange("description", description);
727        }
728
729        /**
730         *
731         * @return retention type. It can be one of values: `modifiable` or `non-modifiable`.
732         *
733         * `modifiable` means that you can modify the retention policy. For example, you can add or remove folders,
734         *  shorten or lengthen the policy duration, or delete the assignment.
735         *
736         * `non-modifiable` means that can modify the retention policy only in a limited way: add a folder,
737         *  lengthen the duration, retire the policy, change the disposition action or notification settings.
738         *  You cannot perform other actions, such as deleting the assignment or shortening the policy duration.
739         */
740        public RetentionPolicyParams.RetentionType getRetentionType() {
741            return retentionType;
742        }
743
744        /**
745         *
746         * It is not possible to set retention type to `modifiable` once it was set to `non-modifiable`.
747         */
748        public void setRetentionTypeToNonModifiable() {
749            this.retentionType = RetentionPolicyParams.RetentionType.NON_MODIFIABLE;
750            this.addPendingChange("retention_type", retentionType.toJSONString());
751        }
752
753        /**
754         * Gets the list of users to be notified of a retained file when near expiration.
755         *
756         * @return the list of users to be notified.
757         */
758        public List<BoxUser.Info> getCustomNotificationRecipients() {
759            return this.customNotificationRecipients;
760        }
761
762        /**
763         * {@inheritDoc}
764         */
765        @Override
766        void parseJSONMember(JsonObject.Member member) {
767            super.parseJSONMember(member);
768            String memberName = member.getName();
769            JsonValue value = member.getValue();
770            try {
771                if (memberName.equals("policy_name")) {
772                    this.policyName = value.asString();
773                } else if (memberName.equals("policy_type")) {
774                    this.policyType = value.asString();
775                } else if (memberName.equals("retention_length")) {
776                    int intVal;
777                    if (value.asString().equals(BoxRetentionPolicyType.Indefinite.value)) {
778                        intVal = -1;
779                    } else {
780                        intVal = Integer.parseInt(value.asString());
781                    }
782
783                    this.retentionLength = intVal;
784                } else if (memberName.equals("disposition_action")) {
785                    this.dispositionAction = value.asString();
786                } else if (memberName.equals("status")) {
787                    this.status = value.asString();
788                } else if (memberName.equals("created_by")) {
789                    JsonObject userJSON = value.asObject();
790                    if (this.createdBy == null) {
791                        String userID = userJSON.get("id").asString();
792                        BoxUser user = new BoxUser(getAPI(), userID);
793                        this.createdBy = user.new Info(userJSON);
794                    } else {
795                        this.createdBy.update(userJSON);
796                    }
797                } else if (memberName.equals("created_at")) {
798                    this.createdAt = BoxDateFormat.parse(value.asString());
799                } else if (memberName.equals("modified_at")) {
800                    this.modifiedAt = BoxDateFormat.parse(value.asString());
801                } else if (memberName.equals("can_owner_extend_retention")) {
802                    this.canOwnerExtendRetention = value.asBoolean();
803                } else if (memberName.equals("are_owners_notified")) {
804                    this.areOwnersNotified = value.asBoolean();
805                } else if (memberName.equals("description")) {
806                    this.description = value.asString();
807                } else if (memberName.equals("retention_type")) {
808                    this.retentionType = RetentionPolicyParams.RetentionType.fromJSONString(value.asString());
809                } else if (memberName.equals("custom_notification_recipients")) {
810                    List<BoxUser.Info> recipients = new ArrayList<BoxUser.Info>();
811                    for (JsonValue userJSON : value.asArray()) {
812                        String userID = userJSON.asObject().get("id").asString();
813                        BoxUser user = new BoxUser(getAPI(), userID);
814                        recipients.add(user.new Info(userJSON.asObject()));
815                    }
816                    this.customNotificationRecipients = recipients;
817                }
818            } catch (Exception e) {
819                throw new BoxDeserializationException(memberName, value.toString(), e);
820            }
821        }
822    }
823
824    private enum BoxRetentionPolicyType {
825        /**
826         * Type for finite retention policies. Finite retention policies has the duration.
827         */
828        Finite("finite"),
829        /**
830         * Type for indefinite retention policies. Indefinite retention policies can have only
831         * {@link BoxRetentionPolicyAction#RemoveRetention} assigned action.
832         */
833        Indefinite("indefinite");
834
835        private final String value;
836
837        BoxRetentionPolicyType(String value) {
838            this.value = value;
839        }
840    }
841
842    /**
843     * The disposition action of the retention policy.
844     */
845    public enum BoxRetentionPolicyAction {
846        /**
847         * Will cause the content retained by the policy to be permanently deleted.
848         */
849        PermanentlyDelete("permanently_delete"),
850
851        /**
852         * Will lift the retention policy from the content, allowing it to be deleted by users.
853         */
854        RemoveRetention("remove_retention");
855
856        private final String value;
857
858        BoxRetentionPolicyAction(String value) {
859            this.value = value;
860        }
861    }
862}