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 assignment.
014 *
015 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
016 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
017 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p>
018 */
019@BoxResourceType("retention_policy_assignment")
020public class BoxRetentionPolicyAssignment extends BoxResource {
021
022    /**
023     * Type for folder policy assignment.
024     */
025    public static final String TYPE_FOLDER = "folder";
026
027    /**
028     * Type for enterprise policy assignment.
029     */
030    public static final String TYPE_ENTERPRISE = "enterprise";
031
032    /**
033     * Type for metadata policy assignment.
034     */
035    public static final String TYPE_METADATA = "metadata_template";
036
037    /**
038     * The URL template used for operation with retention policy assignments.
039     */
040    public static final URLTemplate ASSIGNMENTS_URL_TEMPLATE = new URLTemplate("retention_policy_assignments");
041
042    /**
043     * The URL template used for operation with retention policy assignment with given ID.
044     */
045    public static final URLTemplate RETENTION_POLICY_ASSIGNMENT_URL_TEMPLATE
046        = new URLTemplate("retention_policy_assignments/%s");
047
048    /**
049     * The URL template used for operation with files under retention with given retention policy assignment ID.
050     */
051    public static final URLTemplate FILES_UNDER_RETENTION_URL_TEMPLATE
052        = new URLTemplate("retention_policy_assignments/%s/files_under_retention");
053
054    /**
055     * The URL template used for operation with file versions under retention with given retention policy assignment ID.
056     */
057    public static final URLTemplate FILE_VERSIONS_UNDER_RETENTION_URL_TEMPLATE
058        = new URLTemplate("retention_policy_assignments/%s/file_versions_under_retention");
059
060    private static final int DEFAULT_LIMIT = 100;
061
062    /**
063     * Constructs a BoxResource for a resource with a given ID.
064     *
065     * @param api the API connection to be used by the resource.
066     * @param id  the ID of the resource.
067     */
068    public BoxRetentionPolicyAssignment(BoxAPIConnection api, String id) {
069        super(api, id);
070    }
071
072    /**
073     * Assigns retention policy with givenID to the enterprise.
074     *
075     * @param api      the API connection to be used by the created assignment.
076     * @param policyID id of the assigned retention policy.
077     * @return info about created assignment.
078     */
079    public static BoxRetentionPolicyAssignment.Info createAssignmentToEnterprise(BoxAPIConnection api,
080                                                                                 String policyID) {
081        return createAssignment(api, policyID, new JsonObject().add("type", TYPE_ENTERPRISE), null, null);
082    }
083
084    /**
085     * Assigns retention policy with givenID to the folder.
086     *
087     * @param api      the API connection to be used by the created assignment.
088     * @param policyID id of the assigned retention policy.
089     * @param folderID id of the folder to assign policy to.
090     * @return info about created assignment.
091     */
092    public static BoxRetentionPolicyAssignment.Info createAssignmentToFolder(BoxAPIConnection api, String policyID,
093                                                                             String folderID) {
094        return createAssignment(
095                api, policyID, new JsonObject().add("type", TYPE_FOLDER).add("id", folderID), null, null);
096    }
097
098    /**
099     * Assigns a retention policy to all items with a given metadata template, optionally matching on fields.
100     *
101     * @param api        the API connection to be used by the created assignment.
102     * @param policyID   id of the assigned retention policy.
103     * @param templateID the ID of the metadata template to assign the policy to.
104     * @param filter     optional fields to match against in the metadata template.
105     * @return info about the created assignment.
106     */
107    public static BoxRetentionPolicyAssignment.Info createAssignmentToMetadata(BoxAPIConnection api,
108                                                                               String policyID,
109                                                                               String templateID,
110                                                                               MetadataFieldFilter... filter) {
111        return createAssignmentToMetadata(api, policyID, templateID, null, filter);
112    }
113
114    /**
115     * Assigns a retention policy to all items with a given metadata template, optionally matching on fields.
116     *
117     * @param api        the API connection to be used by the created assignment.
118     * @param policyID   id of the assigned retention policy.
119     * @param templateID the ID of the metadata template to assign the policy to.
120     * @param startDateField  The date the retention policy assignment begins. This field can be a date field's metadata attribute key id.
121     * @param filter     optional fields to match against in the metadata template.
122     * @return info about the created assignment.
123     */
124    public static BoxRetentionPolicyAssignment.Info createAssignmentToMetadata(BoxAPIConnection api,
125                                                                               String policyID,
126                                                                               String templateID,
127                                                                               String startDateField,
128                                                                               MetadataFieldFilter... filter) {
129        JsonObject assignTo = new JsonObject().add("type", TYPE_METADATA).add("id", templateID);
130        JsonArray filters = null;
131        if (filter.length > 0) {
132            filters = new JsonArray();
133            for (MetadataFieldFilter f : filter) {
134                filters.add(f.getJsonObject());
135            }
136        }
137        return createAssignment(api, policyID, assignTo, startDateField, filters);
138    }
139
140    /**
141     * Assigns retention policy with givenID to folder or enterprise.
142     *
143     * @param api      the API connection to be used by the created assignment.
144     * @param policyID id of the assigned retention policy.
145     * @param assignTo object representing folder or enterprise to assign policy to.
146     * @param filter Filters
147     * @return info about created assignment.
148     */
149    private static BoxRetentionPolicyAssignment.Info createAssignment(BoxAPIConnection api,
150                                                                      String policyID,
151                                                                      JsonObject assignTo,
152                                                                      String startDateField,
153                                                                      JsonArray filter) {
154        URL url = ASSIGNMENTS_URL_TEMPLATE.build(api.getBaseURL());
155        BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
156
157        JsonObject requestJSON = new JsonObject()
158            .add("policy_id", policyID)
159            .add("assign_to", assignTo);
160
161        if (filter != null) {
162            requestJSON.add("filter_fields", filter);
163        }
164        if (startDateField != null) {
165            requestJSON.add("start_date_field", startDateField);
166        }
167
168        request.setBody(requestJSON.toString());
169        BoxJSONResponse response = (BoxJSONResponse) request.send();
170        JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
171        BoxRetentionPolicyAssignment createdAssignment
172            = new BoxRetentionPolicyAssignment(api, responseJSON.get("id").asString());
173        return createdAssignment.new Info(responseJSON);
174    }
175
176    /**
177     * @param fields the fields to retrieve.
178     * @return information about this retention policy assignment.
179     */
180    public BoxRetentionPolicyAssignment.Info getInfo(String... fields) {
181        QueryStringBuilder builder = new QueryStringBuilder();
182        if (fields.length > 0) {
183            builder.appendParam("fields", fields);
184        }
185        URL url = RETENTION_POLICY_ASSIGNMENT_URL_TEMPLATE.buildWithQuery(
186            this.getAPI().getBaseURL(), builder.toString(), this.getID());
187        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
188        BoxJSONResponse response = (BoxJSONResponse) request.send();
189        JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
190        return new Info(responseJSON);
191    }
192
193    /**
194     * Retrieves all files under retention for assignment as Iterable. Default limit is 100
195     *
196     * @param fields the fields to retrieve.
197     * @return an iterable contains information about all files under retentions as Iterable.
198     */
199    public Iterable<BoxFile.Info> getFilesUnderRetention(String... fields) {
200        return this.getFilesUnderRetention(DEFAULT_LIMIT, fields);
201    }
202
203    /**
204     * Retrieves all files under retention for assignment as Iterable.
205     *
206     * @param limit  the limit of retrieved entries per page.
207     * @param fields the fields to retrieve.
208     * @return an iterable contains information about all files under retentions as Iterable.
209     */
210    public Iterable<BoxFile.Info> getFilesUnderRetention(int limit, String... fields) {
211        QueryStringBuilder queryString = new QueryStringBuilder();
212        if (fields.length > 0) {
213            queryString.appendParam("fields", fields);
214        }
215        URL url = FILES_UNDER_RETENTION_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(),
216            queryString.toString(), getID());
217        return new BoxResourceIterable<BoxFile.Info>(getAPI(), url, limit) {
218            @Override
219            protected BoxFile.Info factory(JsonObject jsonObject) {
220                BoxFile boxFile = new BoxFile(getAPI(), jsonObject.get("id").asString());
221                return boxFile.new Info(jsonObject);
222            }
223        };
224    }
225
226    /**
227     * Retrieves all file version under retention for assignment as Iterable. Default limit is 100.
228     *
229     * @param fields the fields to retrieve.
230     * @return an iterable contains information about all file versions under retentions as Iterable.
231     */
232    public Iterable<BoxFile.Info> getFileVersionsUnderRetention(String... fields) {
233        return this.getFileVersionsUnderRetention(DEFAULT_LIMIT, fields);
234    }
235
236    /**
237     * Retrieves all file version under retention for assignment as Iterable.
238     *
239     * @param limit  the limit of retrieved entries per page.
240     * @param fields the fields to retrieve.
241     * @return an iterable contains information about all file versions under retentions as Iterable.
242     */
243    public Iterable<BoxFile.Info> getFileVersionsUnderRetention(int limit, String... fields) {
244        QueryStringBuilder queryString = new QueryStringBuilder();
245        if (fields.length > 0) {
246            queryString.appendParam("fields", fields);
247        }
248        URL url = FILE_VERSIONS_UNDER_RETENTION_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(),
249            queryString.toString(), getID());
250        return new BoxResourceIterable<BoxFile.Info>(getAPI(), url, limit) {
251            @Override
252            protected BoxFile.Info factory(JsonObject jsonObject) {
253                BoxFile boxFile = new BoxFile(getAPI(), jsonObject.get("id").asString());
254                return boxFile.new Info(jsonObject);
255            }
256        };
257    }
258
259    /**
260     * Contains information about the retention policy.
261     */
262    public class Info extends BoxResource.Info {
263
264        /**
265         * @see #getRetentionPolicy()
266         */
267        private BoxRetentionPolicy.Info retentionPolicy;
268
269        /**
270         * @see #getAssignedBy()
271         */
272        private BoxUser.Info assignedBy;
273
274        /**
275         * @see #getAssignedAt()
276         */
277        private Date assignedAt;
278
279        /**
280         * @see #getAssignedToType()
281         */
282        private String assignedToType;
283
284        /**
285         * @see #getAssignedToID()
286         */
287        private String assignedToID;
288
289        /**
290         * @see #getStartDateField()
291         */
292        private String startDateField;
293
294        private List<MetadataFieldFilter> filterFields;
295
296        /**
297         * Constructs an empty Info object.
298         */
299        public Info() {
300            super();
301        }
302
303        /**
304         * Constructs an Info object by parsing information from a JSON string.
305         *
306         * @param json the JSON string to parse.
307         */
308        public Info(String json) {
309            super(json);
310        }
311
312        /**
313         * Constructs an Info object using an already parsed JSON object.
314         *
315         * @param jsonObject the parsed JSON object.
316         */
317        Info(JsonObject jsonObject) {
318            super(jsonObject);
319        }
320
321        /**
322         * {@inheritDoc}
323         */
324        @Override
325        public BoxResource getResource() {
326            return BoxRetentionPolicyAssignment.this;
327        }
328
329        /**
330         * @return the retention policy that has been assigned to this content.
331         */
332        public BoxRetentionPolicy.Info getRetentionPolicy() {
333            return this.retentionPolicy;
334        }
335
336        /**
337         * @return the info about the user that created the retention policy assignment.
338         */
339        public BoxUser.Info getAssignedBy() {
340            return this.assignedBy;
341        }
342
343        /**
344         * @return the time that the retention policy assignment was created.
345         */
346        public Date getAssignedAt() {
347            return this.assignedAt;
348        }
349
350        /**
351         * @return type of the content that is under retention. Can either be "enterprise" or "folder".
352         */
353        public String getAssignedToType() {
354            return this.assignedToType;
355        }
356
357        /**
358         * @return id of the folder that is under retention.
359         */
360        public String getAssignedToID() {
361            return this.assignedToID;
362        }
363
364        /**
365         * @return date the retention policy assignment begins
366         */
367        public String getStartDateField() {
368            return this.startDateField;
369        }
370
371        /**
372         * @return the array of metadata field filters, if present
373         */
374        public List<MetadataFieldFilter> getFilterFields() {
375
376            return this.filterFields;
377        }
378
379        /**
380         * {@inheritDoc}
381         */
382        @Override
383        void parseJSONMember(JsonObject.Member member) {
384            super.parseJSONMember(member);
385            String memberName = member.getName();
386            JsonValue value = member.getValue();
387            try {
388                if (memberName.equals("retention_policy")) {
389                    JsonObject policyJSON = value.asObject();
390                    if (this.retentionPolicy == null) {
391                        String policyID = policyJSON.get("id").asString();
392                        BoxRetentionPolicy policy = new BoxRetentionPolicy(getAPI(), policyID);
393                        this.retentionPolicy = policy.new Info(policyJSON);
394                    } else {
395                        this.retentionPolicy.update(policyJSON);
396                    }
397                } else if (memberName.equals("assigned_to")) {
398                    JsonObject assignmentJSON = value.asObject();
399                    this.assignedToType = assignmentJSON.get("type").asString();
400                    if (this.assignedToType.equals(TYPE_ENTERPRISE)) {
401                        this.assignedToID = null;
402                    } else {
403                        this.assignedToID = assignmentJSON.get("id").asString();
404                    }
405                } else if (memberName.equals("assigned_by")) {
406                    JsonObject userJSON = value.asObject();
407                    if (this.assignedBy == null) {
408                        String userID = userJSON.get("id").asString();
409                        BoxUser user = new BoxUser(getAPI(), userID);
410                        this.assignedBy = user.new Info(userJSON);
411                    } else {
412                        this.assignedBy.update(userJSON);
413                    }
414                } else if (memberName.equals("assigned_at")) {
415                    this.assignedAt = BoxDateFormat.parse(value.asString());
416                } else if (memberName.equals("start_date_field")) {
417                    this.startDateField = value.asString();
418                } else if (memberName.equals("filter_fields")) {
419                    JsonArray jsonFilters = value.asArray();
420                    List<MetadataFieldFilter> filterFields = new ArrayList<>();
421                    for (int i = 0; i < jsonFilters.size(); i++) {
422                        filterFields.add(new MetadataFieldFilter(jsonFilters.get(i).asObject()));
423                    }
424                    this.filterFields = filterFields;
425                }
426            } catch (Exception e) {
427                throw new BoxDeserializationException(memberName, value.toString(), e);
428            }
429        }
430    }
431}