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