001package com.box.sdk;
002
003import com.eclipsesource.json.Json;
004import com.eclipsesource.json.JsonObject;
005import com.eclipsesource.json.JsonValue;
006import java.net.URL;
007import java.util.Date;
008
009/**
010 * Represents a file version retention.
011 * A retention policy blocks permanent deletion of content for a specified amount of time.
012 * Admins can apply policies to specified folders, or an entire enterprise.
013 * A file version retention is a record for a retained file version.
014 *
015 * @see <a href="https://developer.box.com/reference/resources/file-version-retention/">Box file version retention</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("file_version_retention")
022public class BoxFileVersionRetention extends BoxResource {
023
024    /**
025     * @see #getInfo(String...)
026     */
027    public static final URLTemplate RETENTION_URL_TEMPLATE = new URLTemplate("file_version_retentions/%s");
028
029    /**
030     * The URL template used for operation with file version retentions.
031     */
032    public static final URLTemplate ALL_RETENTIONS_URL_TEMPLATE = new URLTemplate("file_version_retentions");
033
034    /**
035     * The default limit of entries per response.
036     */
037    private static final int DEFAULT_LIMIT = 100;
038
039    /**
040     * Constructs a BoxFileVersionRetention for a resource with a given ID.
041     *
042     * @param api the API connection to be used by the resource.
043     * @param id  the ID of the resource.
044     */
045    public BoxFileVersionRetention(BoxAPIConnection api, String id) {
046        super(api, id);
047    }
048
049    /**
050     * Retrieves all file version retentions.
051     *
052     * @param api    the API connection to be used by the resource.
053     * @param fields the fields to retrieve.
054     * @return an iterable contains information about all file version retentions.
055     */
056    public static Iterable<BoxFileVersionRetention.Info> getAll(BoxAPIConnection api, String... fields) {
057        return getRetentions(api, new QueryFilter(), fields);
058    }
059
060    /**
061     * @param api    the API connection to be used by the resource.
062     * @param filter filters for the query stored in QueryFilter object.
063     * @param fields the fields to retrieve.
064     * @return an iterable contains information about all file version retentions matching given filter.
065     * @deprecated This method will be deprecated in the future. Please use
066     * {@link BoxRetentionPolicyAssignment#getFilesUnderRetention(int, String...)}
067     * and {@link BoxRetentionPolicyAssignment#getFileVersionsUnderRetention(String...)} instead.
068     * Retrieves all file version retentions matching given filters as an Iterable.
069     */
070    public static Iterable<BoxFileVersionRetention.Info> getRetentions(
071        final BoxAPIConnection api, QueryFilter filter, String... fields) {
072        filter.addFields(fields);
073        return new BoxResourceIterable<BoxFileVersionRetention.Info>(api,
074            ALL_RETENTIONS_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), filter.toString()),
075            DEFAULT_LIMIT) {
076
077            @Override
078            protected BoxFileVersionRetention.Info factory(JsonObject jsonObject) {
079                BoxFileVersionRetention retention = new BoxFileVersionRetention(api, jsonObject.get("id").asString());
080                return retention.new Info(jsonObject);
081            }
082        };
083    }
084
085    /**
086     * @param fields the fields to retrieve.
087     * @return information about this retention policy.
088     */
089    public BoxFileVersionRetention.Info getInfo(String... fields) {
090        QueryStringBuilder builder = new QueryStringBuilder();
091        if (fields.length > 0) {
092            builder.appendParam("fields", fields);
093        }
094        URL url = RETENTION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID());
095        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
096        BoxJSONResponse response = (BoxJSONResponse) request.send();
097        JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
098        return new Info(responseJSON);
099    }
100
101    /**
102     * Represents possible query filters for "Get File Version Retentions" function.
103     */
104    public static class QueryFilter extends QueryStringBuilder {
105
106        /**
107         * Param name for the file id to filter the file version retentions by.
108         */
109        private static final String PARAM_FILE_ID = "file_id";
110
111        /**
112         * Param name for the file version id to filter the file version retentions by.
113         */
114        private static final String PARAM_FILE_VERSION_ID = "file_version_id";
115
116        /**
117         * Param name for the policy id to filter the file version retentions by.
118         */
119        private static final String PARAM_POLICY_ID = "policy_id";
120
121        /**
122         * Param name for the disposition action of the retention policy.
123         */
124        private static final String PARAM_DISPOSITION_ACTION = "disposition_action";
125
126        /**
127         * Param name for the datetime to filter file version retentions.
128         */
129        private static final String PARAM_DISPOSITION_BEFORE = "disposition_before";
130
131        /**
132         * Param name for the datetime to filter file version retentions.
133         */
134        private static final String PARAM_DISPOSITION_AFTER = "disposition_after";
135
136        /**
137         * Param name for the the fields to retrieve.
138         */
139        private static final String PARAM_FIELDS = "fields";
140
141        /**
142         * Constructs empty query filter.
143         */
144        public QueryFilter() {
145            super();
146        }
147
148        /**
149         * @param id a file id to filter the file version retentions by.
150         * @return modified query filter.
151         */
152        public QueryFilter addFileID(String id) {
153            this.appendParam(PARAM_FILE_ID, id);
154            return this;
155        }
156
157        /**
158         * @param id a file version id to filter the file version retentions by.
159         * @return modified query filter.
160         */
161        public QueryFilter addFileVersionID(String id) {
162            this.appendParam(PARAM_FILE_VERSION_ID, id);
163            return this;
164        }
165
166        /**
167         * @param id a policy id to filter the file version retentions by.
168         * @return modified query filter.
169         */
170        public QueryFilter addPolicyID(String id) {
171            this.appendParam(PARAM_POLICY_ID, id);
172            return this;
173        }
174
175        /**
176         * The action can be "permanently_delete" or "remove_retention".
177         *
178         * @param action the disposition action of the retention policy.
179         * @return modified query filter.
180         */
181        public QueryFilter addDispositionAction(String action) {
182            this.appendParam(PARAM_DISPOSITION_ACTION, action);
183            return this;
184        }
185
186        /**
187         * @param date the datetime to filter file version retentions.
188         * @return modified query filter.
189         */
190        public QueryFilter addDispositionBefore(Date date) {
191            this.appendParam(PARAM_DISPOSITION_BEFORE, BoxDateFormat.format(date));
192            return this;
193        }
194
195        /**
196         * @param date the datetime to filter file version retentions.
197         * @return modified query filter.
198         */
199        public QueryFilter addDispositionAfter(Date date) {
200            this.appendParam(PARAM_DISPOSITION_AFTER, BoxDateFormat.format(date));
201            return this;
202        }
203
204        /**
205         * @param fields the fields to retrieve.
206         * @return modified query filter.
207         */
208        public QueryFilter addFields(String... fields) {
209            if (fields.length > 0) {
210                this.appendParam(PARAM_FIELDS, fields);
211            }
212            return this;
213        }
214    }
215
216    /**
217     * Contains information about the retention policy.
218     */
219    public class Info extends BoxResource.Info {
220
221        /**
222         * @see #getFileVersion()
223         */
224        private BoxFileVersion fileVersion;
225
226        /**
227         * @see #getFile()
228         */
229        private BoxFile.Info file;
230
231        /**
232         * @see #getAppliedAt()
233         */
234        private Date appliedAt;
235
236        /**
237         * @see #getDispositionAt()
238         */
239        private Date dispositionAt;
240
241        /**
242         * @see #getWinningPolicy()
243         */
244        private BoxRetentionPolicy.Info winningPolicy;
245
246        /**
247         * Constructs an empty Info object.
248         */
249        public Info() {
250            super();
251        }
252
253        /**
254         * Constructs an Info object by parsing information from a JSON string.
255         *
256         * @param json the JSON string to parse.
257         */
258        public Info(String json) {
259            super(json);
260        }
261
262        /**
263         * Constructs an Info object using an already parsed JSON object.
264         *
265         * @param jsonObject the parsed JSON object.
266         */
267        Info(JsonObject jsonObject) {
268            super(jsonObject);
269        }
270
271        /**
272         * {@inheritDoc}
273         */
274        @Override
275        public BoxResource getResource() {
276            return BoxFileVersionRetention.this;
277        }
278
279        /**
280         * @return the file version this file version retention was applied to.
281         */
282        public BoxFileVersion getFileVersion() {
283            return this.fileVersion;
284        }
285
286        /**
287         * @return the file this file version retention was applied to.
288         */
289        public BoxFile.Info getFile() {
290            return this.file;
291        }
292
293        /**
294         * @return the time that this file version retention was created.
295         */
296        public Date getAppliedAt() {
297            return this.appliedAt;
298        }
299
300        /**
301         * @return the time that the retention period expires on this file version retention.
302         */
303        public Date getDispositionAt() {
304            return this.dispositionAt;
305        }
306
307        /**
308         * @return the winning retention policy applied to this file version retention.
309         */
310        public BoxRetentionPolicy.Info getWinningPolicy() {
311            return this.winningPolicy;
312        }
313
314        /**
315         * {@inheritDoc}
316         */
317        @Override
318        void parseJSONMember(JsonObject.Member member) {
319            super.parseJSONMember(member);
320            String memberName = member.getName();
321            JsonValue value = member.getValue();
322            try {
323                if (memberName.equals("winning_retention_policy")) {
324                    JsonObject policyJSON = value.asObject();
325                    if (this.winningPolicy == null) {
326                        String policyID = policyJSON.get("id").asString();
327                        BoxRetentionPolicy policy = new BoxRetentionPolicy(getAPI(), policyID);
328                        this.winningPolicy = policy.new Info(policyJSON);
329                    } else {
330                        this.winningPolicy.update(policyJSON);
331                    }
332                } else if (memberName.equals("file")) {
333                    JsonObject fileJSON = value.asObject();
334                    if (this.file == null) {
335                        String fileID = fileJSON.get("id").asString();
336                        BoxFile file = new BoxFile(getAPI(), fileID);
337                        this.file = file.new Info(fileJSON);
338                    } else {
339                        this.file.update(fileJSON);
340                    }
341                } else if (memberName.equals("file_version")) {
342                    JsonObject versionJSON = value.asObject();
343                    String fileVersionID = versionJSON.get("id").asString();
344                    this.fileVersion = new BoxFileVersion(getAPI(), versionJSON, fileVersionID);
345                } else if (memberName.equals("applied_at")) {
346                    this.appliedAt = BoxDateFormat.parse(value.asString());
347                } else if (memberName.equals("disposition_at")) {
348                    this.dispositionAt = BoxDateFormat.parse(value.asString());
349                }
350            } catch (Exception e) {
351                throw new BoxDeserializationException(memberName, value.toString(), e);
352            }
353        }
354    }
355}