001package com.box.sdk;
002
003import java.net.URL;
004import java.text.ParseException;
005import java.util.Date;
006
007import com.eclipsesource.json.JsonObject;
008import com.eclipsesource.json.JsonValue;
009
010/**
011 * Represents a retention policy.
012 * A retention policy blocks permanent deletion of content for a specified amount of time.
013 * Admins can create retention policies and then later assign them to specific folders or their entire enterprise.
014 *
015 * @see <a href="https://docs.box.com/reference#retention-policy-object">Box retention policy</a>
016 *
017 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
018 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
019 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p>
020 */
021@BoxResourceType("retention_policy")
022public class BoxRetentionPolicy extends BoxResource {
023    /**
024     * The URL template used for operation with retention policies.
025     */
026    public static final URLTemplate RETENTION_POLICIES_URL_TEMPLATE = new URLTemplate("retention_policies");
027
028    /**
029     * The URL template used for operation with retention policy with given ID.
030     */
031    public static final URLTemplate POLICY_URL_TEMPLATE = new URLTemplate("retention_policies/%s");
032
033    /**
034     * The URL template used for operation with retention policy assignments.
035     */
036    public static final URLTemplate ASSIGNMENTS_URL_TEMPLATE = new URLTemplate("retention_policies/%s/assignments");
037
038    /**
039     *  Will cause the content retained by the policy to be permanently deleted.
040     */
041    public static final String ACTION_PERMANENTLY_DELETE = "permanently_delete";
042
043    /**
044     * Will lift the retention policy from the content, allowing it to be deleted by users.
045     */
046    public static final String ACTION_REMOVE_RETENTION = "remove_retention";
047
048    /**
049     * Status corresponding to active retention policy.
050     */
051    public static final String STATUS_ACTIVE = "active";
052
053    /**
054     * Status corresponding to retired retention policy.
055     */
056    public static final String STATUS_RETIRED = "retired";
057
058    /**
059     * Type for finite retention policies. Finite retention policies has the duration.
060     */
061    private static final String TYPE_FINITE = "finite";
062
063    /**
064     * Type for indefinite retention policies. Indefinite retention policies can have only "remove_retention"
065     * assigned action.
066     */
067    private static final String TYPE_INDEFINITE = "indefinite";
068
069    /**
070     * The default limit of entries per response.
071     */
072    private static final int DEFAULT_LIMIT = 100;
073
074    /**
075     * Constructs a retention policy for a resource with a given ID.
076     *
077     * @param api the API connection to be used by the resource.
078     * @param id  the ID of the resource.
079     */
080    public BoxRetentionPolicy(BoxAPIConnection api, String id) {
081        super(api, id);
082    }
083
084    /**
085     * Used to create a new indefinite retention policy.
086     * @param api the API connection to be used by the created user.
087     * @param name the name of the retention policy.
088     * @return the created retention policy's info.
089     */
090    public static BoxRetentionPolicy.Info createIndefinitePolicy(BoxAPIConnection api, String name) {
091        return createRetentionPolicy(api, name, TYPE_INDEFINITE, 0, ACTION_REMOVE_RETENTION);
092    }
093
094    /**
095     * Used to create a new finite retention policy.
096     * @param api the API connection to be used by the created user.
097     * @param name the name of the retention policy.
098     * @param length the duration in days that the retention policy will be active for after being assigned to content.
099     * @param action the disposition action can be "permanently_delete" or "remove_retention".
100     * @return the created retention policy's info.
101     */
102    public static BoxRetentionPolicy.Info createFinitePolicy(BoxAPIConnection api, String name, int length,
103                                                                      String action) {
104        return createRetentionPolicy(api, name, TYPE_FINITE, length, action);
105    }
106
107    /**
108     * Used to create a new retention policy.
109     * @param api the API connection to be used by the created user.
110     * @param name the name of the retention policy.
111     * @param type the type of the retention policy. Can be "finite" or "indefinite".
112     * @param length the duration in days that the retention policy will be active for after being assigned to content.
113     * @param action the disposition action can be "permanently_delete" or "remove_retention".
114     * @return the created retention policy's info.
115     */
116    private static BoxRetentionPolicy.Info createRetentionPolicy(BoxAPIConnection api, String name, String type,
117                                                                int length, String action) {
118        URL url = RETENTION_POLICIES_URL_TEMPLATE.build(api.getBaseURL());
119        BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
120        JsonObject requestJSON = new JsonObject()
121                .add("policy_name", name)
122                .add("policy_type", type)
123                .add("disposition_action", action);
124        if (!type.equals(TYPE_INDEFINITE)) {
125            requestJSON.add("retention_length", length);
126        }
127        request.setBody(requestJSON.toString());
128        BoxJSONResponse response = (BoxJSONResponse) request.send();
129        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
130        BoxRetentionPolicy createdPolicy = new BoxRetentionPolicy(api, responseJSON.get("id").asString());
131        return createdPolicy.new Info(responseJSON);
132    }
133
134    /**
135     * Returns iterable with all folder assignments of this retention policy.
136     * @param fields the fields to retrieve.
137     * @return an iterable containing all folder assignments.
138     */
139    public Iterable<BoxRetentionPolicyAssignment.Info> getFolderAssignments(String ... fields) {
140        return this.getFolderAssignments(DEFAULT_LIMIT, fields);
141    }
142
143    /**
144     * Returns iterable with all folder assignments of this retention policy.
145     * @param limit the limit of entries per response. The default value is 100.
146     * @param fields the fields to retrieve.
147     * @return an iterable containing all folder assignments.
148     */
149    public Iterable<BoxRetentionPolicyAssignment.Info> getFolderAssignments(int limit, String ... fields) {
150        return this.getAssignments(BoxRetentionPolicyAssignment.TYPE_FOLDER, limit, fields);
151    }
152
153    /**
154     * Returns iterable with all enterprise assignments of this retention policy.
155     * @param fields the fields to retrieve.
156     * @return an iterable containing all enterprise assignments.
157     */
158    public Iterable<BoxRetentionPolicyAssignment.Info> getEnterpriseAssignments(String ... fields) {
159        return this.getEnterpriseAssignments(DEFAULT_LIMIT, fields);
160    }
161
162    /**
163     * Returns iterable with all enterprise assignments of this retention policy.
164     * @param limit the limit of entries per response. The default value is 100.
165     * @param fields the fields to retrieve.
166     * @return an iterable containing all enterprise assignments.
167     */
168    public Iterable<BoxRetentionPolicyAssignment.Info> getEnterpriseAssignments(int limit, String ... fields) {
169        return this.getAssignments(BoxRetentionPolicyAssignment.TYPE_ENTERPRISE, limit, fields);
170    }
171
172    /**
173     * Returns iterable with all assignments of this retention policy.
174     * @param fields the fields to retrieve.
175     * @return an iterable containing all assignments.
176     */
177    public Iterable<BoxRetentionPolicyAssignment.Info> getAllAssignments(String ... fields) {
178        return this.getAllAssignments(DEFAULT_LIMIT, fields);
179    }
180
181    /**
182     * Returns iterable with all assignments of this retention policy.
183     * @param limit the limit of entries per response. The default value is 100.
184     * @param fields the fields to retrieve.
185     * @return an iterable containing all assignments.
186     */
187    public Iterable<BoxRetentionPolicyAssignment.Info> getAllAssignments(int limit, String ... fields) {
188        return this.getAssignments(null, limit, fields);
189    }
190
191    /**
192     * Returns iterable with all assignments of given type of this retention policy.
193     * @param type the type of the retention policy assignment to retrieve. Can either be "folder" or "enterprise".
194     * @param limit the limit of entries per response. The default value is 100.
195     * @param fields the fields to retrieve.
196     * @return an iterable containing all assignments of given type.
197     */
198    private Iterable<BoxRetentionPolicyAssignment.Info> getAssignments(String type, int limit, String ... fields) {
199        QueryStringBuilder queryString = new QueryStringBuilder();
200        if (type != null) {
201            queryString.appendParam("type", type);
202        }
203        if (fields.length > 0) {
204            queryString.appendParam("fields", fields);
205        }
206        URL url = ASSIGNMENTS_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(), queryString.toString(), getID());
207        return new BoxResourceIterable<BoxRetentionPolicyAssignment.Info>(getAPI(), url, limit) {
208
209            @Override
210            protected BoxRetentionPolicyAssignment.Info factory(JsonObject jsonObject) {
211                BoxRetentionPolicyAssignment assignment
212                    = new BoxRetentionPolicyAssignment(getAPI(), jsonObject.get("id").asString());
213                return assignment.new Info(jsonObject);
214            }
215
216        };
217    }
218
219    /**
220     * Assigns this retention policy to folder.
221     * @param folder the folder to assign policy to.
222     * @return info about created assignment.
223     */
224    public BoxRetentionPolicyAssignment.Info assignTo(BoxFolder folder) {
225        return BoxRetentionPolicyAssignment.createAssignmentToFolder(this.getAPI(), this.getID(), folder.getID());
226    }
227
228    /**
229     * Assigns this retention policy to the current enterprise.
230     * @return info about created assignment.
231     */
232    public BoxRetentionPolicyAssignment.Info assignToEnterprise() {
233        return BoxRetentionPolicyAssignment.createAssignmentToEnterprise(this.getAPI(), this.getID());
234    }
235
236    /**
237     * Updates the information about this retention policy with any info fields that have been modified locally.
238     * @param info the updated info.
239     */
240    public void updateInfo(BoxRetentionPolicy.Info info) {
241        URL url = POLICY_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
242        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
243        request.setBody(info.getPendingChanges());
244        BoxJSONResponse response = (BoxJSONResponse) request.send();
245        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
246        info.update(responseJSON);
247    }
248
249    /**
250     * Returns information about this retention policy.
251     * @param fields the fields to retrieve.
252     * @return information about this retention policy.
253     */
254    public BoxRetentionPolicy.Info getInfo(String ... fields) {
255        QueryStringBuilder builder = new QueryStringBuilder();
256        if (fields.length > 0) {
257            builder.appendParam("fields", fields);
258        }
259        URL url = POLICY_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID());
260        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
261        BoxJSONResponse response = (BoxJSONResponse) request.send();
262        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
263        return new Info(responseJSON);
264    }
265
266
267    /**
268     * Returns all the retention policies.
269     * @param api the API connection to be used by the resource.
270     * @param fields the fields to retrieve.
271     * @return an iterable with all the retention policies.
272     */
273    public static Iterable<BoxRetentionPolicy.Info> getAll(final BoxAPIConnection api, String ... fields) {
274        return getAll(null, null, null, DEFAULT_LIMIT, api, fields);
275    }
276
277    /**
278     * Returns all the retention policies with specified filters.
279     * @param name a name to filter the retention policies by. A trailing partial match search is performed.
280     *             Set to null if no name filtering is required.
281     * @param type a policy type to filter the retention policies by. Set to null if no type filtering is required.
282     * @param userID a user id to filter the retention policies by. Set to null if no type filtering is required.
283     * @param limit the limit of items per single response. The default value is 100.
284     * @param api the API connection to be used by the resource.
285     * @param fields the fields to retrieve.
286     * @return an iterable with all the retention policies met search conditions.
287     */
288    public static Iterable<BoxRetentionPolicy.Info> getAll(
289            String name, String type, String userID, int limit, final BoxAPIConnection api, String ... fields) {
290        QueryStringBuilder queryString = new QueryStringBuilder();
291        if (name != null) {
292            queryString.appendParam("policy_name", name);
293        }
294        if (type != null) {
295            queryString.appendParam("policy_type", type);
296        }
297        if (userID != null) {
298            queryString.appendParam("created_by_user_id", userID);
299        }
300        if (fields.length > 0) {
301            queryString.appendParam("fields", fields);
302        }
303        URL url = RETENTION_POLICIES_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), queryString.toString());
304        return new BoxResourceIterable<BoxRetentionPolicy.Info>(api, url, limit) {
305
306            @Override
307            protected BoxRetentionPolicy.Info factory(JsonObject jsonObject) {
308                BoxRetentionPolicy policy = new BoxRetentionPolicy(api, jsonObject.get("id").asString());
309                return policy.new Info(jsonObject);
310            }
311
312        };
313    }
314
315    /**
316     * Contains information about the retention policy.
317     */
318    public class Info extends BoxResource.Info {
319
320        /**
321         * @see #getPolicyName()
322         */
323        private String policyName;
324
325        /**
326         * @see #getPolicyType()
327         */
328        private String policyType;
329
330        /**
331         * @see #getRetentionLength()
332         */
333        private int retentionLength;
334
335        /**
336         * @see #getDispositionAction()
337         */
338        private String dispositionAction;
339
340        /**
341         * @see #getStatus()
342         */
343        private String status;
344
345        /**
346         * @see #getCreatedBy()
347         */
348        private BoxUser.Info createdBy;
349
350        /**
351         * @see #getCreatedAt()
352         */
353        private Date createdAt;
354
355        /**
356         * @see #getModifiedAt()
357         */
358        private Date modifiedAt;
359
360        /**
361         * Constructs an empty Info object.
362         */
363        public Info() {
364            super();
365        }
366
367        /**
368         * Constructs an Info object by parsing information from a JSON string.
369         * @param  json the JSON string to parse.
370         */
371        public Info(String json) {
372            super(json);
373        }
374
375        /**
376         * Constructs an Info object using an already parsed JSON object.
377         * @param  jsonObject the parsed JSON object.
378         */
379        Info(JsonObject jsonObject) {
380            super(jsonObject);
381        }
382
383        /**
384         * {@inheritDoc}
385         */
386        @Override
387        public BoxResource getResource() {
388            return BoxRetentionPolicy.this;
389        }
390
391        /**
392         * Gets the name given to the retention policy.
393         * @return name given to the retention policy.
394         */
395        public String getPolicyName() {
396            return this.policyName;
397        }
398
399        /**
400         * Gets the type of the retention policy.
401         * A retention policy type can either be "finite",
402         * where a specific amount of time to retain the content is known upfront,
403         * or "indefinite", where the amount of time to retain the content is still unknown.
404         * @return the type of the retention policy.
405         */
406        public String getPolicyType() {
407            return this.policyType;
408        }
409
410        /**
411         * Gets the length of the retention policy. This length specifies the duration
412         * in days that the retention policy will be active for after being assigned to content.
413         * @return the length of the retention policy.
414         */
415        public int getRetentionLength() {
416            return this.retentionLength;
417        }
418
419        /**
420         * Gets the disposition action of the retention policy.
421         * This action can be "permanently_delete", or "remove_retention".
422         * @return the disposition action of the retention policy.
423         */
424        public String getDispositionAction() {
425            return this.dispositionAction;
426        }
427
428        /**
429         * Gets the status of the retention policy.
430         * The status can be "active" or "retired".
431         * @return the status of the retention policy.
432         */
433        public String getStatus() {
434            return this.status;
435        }
436
437        /**
438         * Gets info about the user created the retention policy.
439         * @return info about the user created the retention policy.
440         */
441        public BoxUser.Info getCreatedBy() {
442            return this.createdBy;
443        }
444
445        /**
446         * Gets the time that the retention policy was created.
447         * @return the time that the retention policy was created.
448         */
449        public Date getCreatedAt() {
450            return this.createdAt;
451        }
452
453        /**
454         * Gets the time that the retention policy was last modified.
455         * @return the time that the retention policy was last modified.
456         */
457        public Date getModifiedAt() {
458            return this.modifiedAt;
459        }
460
461        /**
462         * {@inheritDoc}
463         */
464        @Override
465        void parseJSONMember(JsonObject.Member member) {
466            super.parseJSONMember(member);
467            String memberName = member.getName();
468            JsonValue value = member.getValue();
469            try {
470                if (memberName.equals("policy_name")) {
471                    this.policyName = value.asString();
472                } else if (memberName.equals("policy_type")) {
473                    this.policyType = value.asString();
474                } else if (memberName.equals("retention_length")) {
475                    this.retentionLength = value.asInt();
476                } else if (memberName.equals("disposition_action")) {
477                    this.dispositionAction = value.asString();
478                } else if (memberName.equals("status")) {
479                    this.status = value.asString();
480                } else if (memberName.equals("created_by")) {
481                    JsonObject userJSON = value.asObject();
482                    if (this.createdBy == null) {
483                        String userID = userJSON.get("id").asString();
484                        BoxUser user = new BoxUser(getAPI(), userID);
485                        this.createdBy = user.new Info(userJSON);
486                    } else {
487                        this.createdBy.update(userJSON);
488                    }
489                } else if (memberName.equals("created_at")) {
490                    this.createdAt = BoxDateFormat.parse(value.asString());
491                } else if (memberName.equals("modified_at")) {
492                    this.modifiedAt = BoxDateFormat.parse(value.asString());
493                }
494            } catch (ParseException e) {
495                assert false : "A ParseException indicates a bug in the SDK.";
496            }
497        }
498    }
499}