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        try (BoxJSONResponse response = 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    /**
178     * @param fields the fields to retrieve.
179     * @return information about this retention policy assignment.
180     */
181    public BoxRetentionPolicyAssignment.Info getInfo(String... fields) {
182        QueryStringBuilder builder = new QueryStringBuilder();
183        if (fields.length > 0) {
184            builder.appendParam("fields", fields);
185        }
186        URL url = RETENTION_POLICY_ASSIGNMENT_URL_TEMPLATE.buildWithQuery(
187            this.getAPI().getBaseURL(), builder.toString(), this.getID());
188        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
189        try (BoxJSONResponse response = request.send()) {
190            JsonObject responseJSON = Json.parse(response.getJSON()).asObject();
191            return new Info(responseJSON);
192        }
193    }
194
195    /**
196     * Retrieves all files under retention for assignment as Iterable. Default limit is 100
197     *
198     * @param fields the fields to retrieve.
199     * @return an iterable contains information about all files under retentions as Iterable.
200     */
201    public Iterable<BoxFile.Info> getFilesUnderRetention(String... fields) {
202        return this.getFilesUnderRetention(DEFAULT_LIMIT, fields);
203    }
204
205    /**
206     * Retrieves all files under retention for assignment as Iterable.
207     *
208     * @param limit  the limit of retrieved entries per page.
209     * @param fields the fields to retrieve.
210     * @return an iterable contains information about all files under retentions as Iterable.
211     */
212    public Iterable<BoxFile.Info> getFilesUnderRetention(int limit, String... fields) {
213        QueryStringBuilder queryString = new QueryStringBuilder();
214        if (fields.length > 0) {
215            queryString.appendParam("fields", fields);
216        }
217        URL url = FILES_UNDER_RETENTION_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(),
218            queryString.toString(), getID());
219        return new BoxResourceIterable<BoxFile.Info>(getAPI(), url, limit) {
220            @Override
221            protected BoxFile.Info factory(JsonObject jsonObject) {
222                BoxFile boxFile = new BoxFile(getAPI(), jsonObject.get("id").asString());
223                return boxFile.new Info(jsonObject);
224            }
225        };
226    }
227
228    /**
229     * Retrieves all file version under retention for assignment as Iterable. Default limit is 100.
230     *
231     * @param fields the fields to retrieve.
232     * @return an iterable contains information about all file versions under retentions as Iterable.
233     */
234    public Iterable<BoxFile.Info> getFileVersionsUnderRetention(String... fields) {
235        return this.getFileVersionsUnderRetention(DEFAULT_LIMIT, fields);
236    }
237
238    /**
239     * Retrieves all file version under retention for assignment as Iterable.
240     *
241     * @param limit  the limit of retrieved entries per page.
242     * @param fields the fields to retrieve.
243     * @return an iterable contains information about all file versions under retentions as Iterable.
244     */
245    public Iterable<BoxFile.Info> getFileVersionsUnderRetention(int limit, String... fields) {
246        QueryStringBuilder queryString = new QueryStringBuilder();
247        if (fields.length > 0) {
248            queryString.appendParam("fields", fields);
249        }
250        URL url = FILE_VERSIONS_UNDER_RETENTION_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(),
251            queryString.toString(), getID());
252        return new BoxResourceIterable<BoxFile.Info>(getAPI(), url, limit) {
253            @Override
254            protected BoxFile.Info factory(JsonObject jsonObject) {
255                BoxFile boxFile = new BoxFile(getAPI(), jsonObject.get("id").asString());
256                return boxFile.new Info(jsonObject);
257            }
258        };
259    }
260
261    /**
262     * Deletes retention policy assignment.
263     */
264    public void delete() {
265        URL url = RETENTION_POLICY_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
266        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
267        request.send().close();
268    }
269
270    /**
271     * Contains information about the retention policy.
272     */
273    public class Info extends BoxResource.Info {
274
275        /**
276         * @see #getRetentionPolicy()
277         */
278        private BoxRetentionPolicy.Info retentionPolicy;
279
280        /**
281         * @see #getAssignedBy()
282         */
283        private BoxUser.Info assignedBy;
284
285        /**
286         * @see #getAssignedAt()
287         */
288        private Date assignedAt;
289
290        /**
291         * @see #getAssignedToType()
292         */
293        private String assignedToType;
294
295        /**
296         * @see #getAssignedToID()
297         */
298        private String assignedToID;
299
300        /**
301         * @see #getStartDateField()
302         */
303        private String startDateField;
304
305        private List<MetadataFieldFilter> filterFields;
306
307        /**
308         * Constructs an empty Info object.
309         */
310        public Info() {
311            super();
312        }
313
314        /**
315         * Constructs an Info object by parsing information from a JSON string.
316         *
317         * @param json the JSON string to parse.
318         */
319        public Info(String json) {
320            super(json);
321        }
322
323        /**
324         * Constructs an Info object using an already parsed JSON object.
325         *
326         * @param jsonObject the parsed JSON object.
327         */
328        Info(JsonObject jsonObject) {
329            super(jsonObject);
330        }
331
332        /**
333         * {@inheritDoc}
334         */
335        @Override
336        public BoxResource getResource() {
337            return BoxRetentionPolicyAssignment.this;
338        }
339
340        /**
341         * @return the retention policy that has been assigned to this content.
342         */
343        public BoxRetentionPolicy.Info getRetentionPolicy() {
344            return this.retentionPolicy;
345        }
346
347        /**
348         * @return the info about the user that created the retention policy assignment.
349         */
350        public BoxUser.Info getAssignedBy() {
351            return this.assignedBy;
352        }
353
354        /**
355         * @return the time that the retention policy assignment was created.
356         */
357        public Date getAssignedAt() {
358            return this.assignedAt;
359        }
360
361        /**
362         * @return type of the content that is under retention. Can either be "enterprise" or "folder".
363         */
364        public String getAssignedToType() {
365            return this.assignedToType;
366        }
367
368        /**
369         * @return id of the folder that is under retention.
370         */
371        public String getAssignedToID() {
372            return this.assignedToID;
373        }
374
375        /**
376         * @return date the retention policy assignment begins
377         */
378        public String getStartDateField() {
379            return this.startDateField;
380        }
381
382        /**
383         * @return the array of metadata field filters, if present
384         */
385        public List<MetadataFieldFilter> getFilterFields() {
386
387            return this.filterFields;
388        }
389
390        /**
391         * {@inheritDoc}
392         */
393        @Override
394        void parseJSONMember(JsonObject.Member member) {
395            super.parseJSONMember(member);
396            String memberName = member.getName();
397            JsonValue value = member.getValue();
398            try {
399                if (memberName.equals("retention_policy")) {
400                    JsonObject policyJSON = value.asObject();
401                    if (this.retentionPolicy == null) {
402                        String policyID = policyJSON.get("id").asString();
403                        BoxRetentionPolicy policy = new BoxRetentionPolicy(getAPI(), policyID);
404                        this.retentionPolicy = policy.new Info(policyJSON);
405                    } else {
406                        this.retentionPolicy.update(policyJSON);
407                    }
408                } else if (memberName.equals("assigned_to")) {
409                    JsonObject assignmentJSON = value.asObject();
410                    this.assignedToType = assignmentJSON.get("type").asString();
411                    if (this.assignedToType.equals(TYPE_ENTERPRISE)) {
412                        this.assignedToID = null;
413                    } else {
414                        this.assignedToID = assignmentJSON.get("id").asString();
415                    }
416                } else if (memberName.equals("assigned_by")) {
417                    JsonObject userJSON = value.asObject();
418                    if (this.assignedBy == null) {
419                        String userID = userJSON.get("id").asString();
420                        BoxUser user = new BoxUser(getAPI(), userID);
421                        this.assignedBy = user.new Info(userJSON);
422                    } else {
423                        this.assignedBy.update(userJSON);
424                    }
425                } else if (memberName.equals("assigned_at")) {
426                    this.assignedAt = BoxDateFormat.parse(value.asString());
427                } else if (memberName.equals("start_date_field")) {
428                    this.startDateField = value.asString();
429                } else if (memberName.equals("filter_fields")) {
430                    JsonArray jsonFilters = value.asArray();
431                    List<MetadataFieldFilter> filterFields = new ArrayList<>();
432                    for (int i = 0; i < jsonFilters.size(); i++) {
433                        filterFields.add(new MetadataFieldFilter(jsonFilters.get(i).asObject()));
434                    }
435                    this.filterFields = filterFields;
436                }
437            } catch (Exception e) {
438                throw new BoxDeserializationException(memberName, value.toString(), e);
439            }
440        }
441    }
442}