001package com.box.sdk;
002
003import java.net.URL;
004import java.util.ArrayList;
005import java.util.Date;
006import java.util.List;
007
008import com.eclipsesource.json.JsonArray;
009import com.eclipsesource.json.JsonObject;
010import com.eclipsesource.json.JsonValue;
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     * @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     * @param api the API connection to be used by the created assignment.
086     * @param policyID id of the assigned retention policy.
087     * @param folderID id of the folder to assign policy to.
088     * @return info about created assignment.
089     */
090    public static BoxRetentionPolicyAssignment.Info createAssignmentToFolder(BoxAPIConnection api, String policyID,
091                                                                             String folderID) {
092        return createAssignment(api, policyID, new JsonObject().add("type", TYPE_FOLDER).add("id", folderID), null);
093    }
094
095    /**
096     * Assigns a retention policy to all items with a given metadata template, optionally matching on fields.
097     * @param api the API connection to be used by the created assignment.
098     * @param policyID id of the assigned retention policy.
099     * @param templateID the ID of the metadata template to assign the policy to.
100     * @param filter optional fields to match against in the metadata template.
101     * @return info about the created assignment.
102     */
103    public static BoxRetentionPolicyAssignment.Info createAssignmentToMetadata(BoxAPIConnection api,
104                                                                               String policyID,
105                                                                               String templateID,
106                                                                               MetadataFieldFilter... filter) {
107        JsonObject assignTo = new JsonObject().add("type", TYPE_METADATA).add("id", templateID);
108        JsonArray filters = null;
109        if (filter.length > 0) {
110            filters = new JsonArray();
111            for (MetadataFieldFilter f : filter) {
112                filters.add(f.getJsonObject());
113            }
114        }
115        return createAssignment(api, policyID, assignTo, filters);
116    }
117
118    /**
119     * Assigns retention policy with givenID to folder or enterprise.
120     * @param api the API connection to be used by the created assignment.
121     * @param policyID id of the assigned retention policy.
122     * @param assignTo object representing folder or enterprise to assign policy to.
123     * @return info about created assignment.
124     */
125    private static BoxRetentionPolicyAssignment.Info createAssignment(BoxAPIConnection api, String policyID,
126                                                                      JsonObject assignTo, JsonArray filter) {
127        URL url = ASSIGNMENTS_URL_TEMPLATE.build(api.getBaseURL());
128        BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
129
130        JsonObject requestJSON = new JsonObject()
131                .add("policy_id", policyID)
132                .add("assign_to", assignTo);
133
134        if (filter != null) {
135            requestJSON.add("filter_fields", filter);
136        }
137
138        request.setBody(requestJSON.toString());
139        BoxJSONResponse response = (BoxJSONResponse) request.send();
140        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
141        BoxRetentionPolicyAssignment createdAssignment
142            = new BoxRetentionPolicyAssignment(api, responseJSON.get("id").asString());
143        return createdAssignment.new Info(responseJSON);
144    }
145
146    /**
147     * @param fields the fields to retrieve.
148     * @return information about this retention policy assignment.
149     */
150    public BoxRetentionPolicyAssignment.Info getInfo(String ... fields) {
151        QueryStringBuilder builder = new QueryStringBuilder();
152        if (fields.length > 0) {
153            builder.appendParam("fields", fields);
154        }
155        URL url = RETENTION_POLICY_ASSIGNMENT_URL_TEMPLATE.buildWithQuery(
156                this.getAPI().getBaseURL(), builder.toString(), this.getID());
157        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
158        BoxJSONResponse response = (BoxJSONResponse) request.send();
159        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
160        return new Info(responseJSON);
161    }
162
163    /**
164     * Retrieves all files under retention for assignment as Iterable. Default limit is 100
165     * @param fields the fields to retrieve.
166     * @return an iterable contains information about all files under retentions as Iterable.
167     */
168    public Iterable<BoxFile.Info> getFilesUnderRetention(String ... fields) {
169        return this.getFilesUnderRetention(DEFAULT_LIMIT, fields);
170    }
171
172    /**
173     * Retrieves all files under retention for assignment as Iterable.
174     * @param limit the limit of retrieved entries per page.
175     * @param fields the fields to retrieve.
176     * @return an iterable contains information about all files under retentions as Iterable.
177     */
178    public Iterable<BoxFile.Info> getFilesUnderRetention(int limit, String ... fields) {
179        QueryStringBuilder queryString = new QueryStringBuilder();
180        if (fields.length > 0) {
181            queryString.appendParam("fields", fields);
182        }
183        URL url = FILES_UNDER_RETENTION_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(),
184                queryString.toString(), getID());
185        return new BoxResourceIterable<BoxFile.Info>(getAPI(), url, limit) {
186            @Override
187            protected BoxFile.Info factory(JsonObject jsonObject) {
188                BoxFile boxFile
189                        = new BoxFile(getAPI(), jsonObject.get("id").asString());
190                return boxFile.new Info(jsonObject);
191            }
192        };
193    }
194
195    /**
196     * Retrieves all file version under retention for assignment as Iterable. Default limit is 100.
197     * @param fields the fields to retrieve.
198     * @return an iterable contains information about all file versions under retentions as Iterable.
199     */
200    public Iterable<BoxFileVersion> getFileVersionsUnderRetention(String ... fields) {
201        return this.getFileVersionsUnderRetention(DEFAULT_LIMIT, fields);
202    }
203
204    /**
205     * Retrieves all file version under retention for assignment as Iterable.
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 file versions under retentions as Iterable.
209     */
210    public Iterable<BoxFileVersion> getFileVersionsUnderRetention(int limit, String ... fields) {
211        QueryStringBuilder queryString = new QueryStringBuilder();
212        if (fields.length > 0) {
213            queryString.appendParam("fields", fields);
214        }
215        URL url = FILE_VERSIONS_UNDER_RETENTION_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(),
216                queryString.toString(), getID());
217        return new BoxResourceIterable<BoxFileVersion>(getAPI(), url, limit) {
218            @Override
219            protected BoxFileVersion factory(JsonObject jsonObject) {
220                return new BoxFileVersion(getAPI(), jsonObject, jsonObject.get("id").asString());
221            }
222        };
223    }
224
225    /**
226     * Contains information about the retention policy.
227     */
228    public class Info extends BoxResource.Info {
229
230        /**
231         * @see #getRetentionPolicy()
232         */
233        private BoxRetentionPolicy.Info retentionPolicy;
234
235        /**
236         * @see #getAssignedBy()
237         */
238        private BoxUser.Info assignedBy;
239
240        /**
241         * @see #getAssignedAt()
242         */
243        private Date assignedAt;
244
245        /**
246         * @see #getAssignedToType()
247         */
248        private String assignedToType;
249
250        /**
251         * @see #getAssignedToID()
252         */
253        private String assignedToID;
254
255        private List<MetadataFieldFilter> filterFields;
256
257        /**
258         * Constructs an empty Info object.
259         */
260        public Info() {
261            super();
262        }
263
264        /**
265         * Constructs an Info object by parsing information from a JSON string.
266         * @param  json the JSON string to parse.
267         */
268        public Info(String json) {
269            super(json);
270        }
271
272        /**
273         * Constructs an Info object using an already parsed JSON object.
274         * @param  jsonObject the parsed JSON object.
275         */
276        Info(JsonObject jsonObject) {
277            super(jsonObject);
278        }
279
280        /**
281         * {@inheritDoc}
282         */
283        @Override
284        public BoxResource getResource() {
285            return BoxRetentionPolicyAssignment.this;
286        }
287
288        /**
289         * @return the retention policy that has been assigned to this content.
290         */
291        public BoxRetentionPolicy.Info getRetentionPolicy() {
292            return this.retentionPolicy;
293        }
294
295        /**
296         * @return the info about the user that created the retention policy assignment.
297         */
298        public BoxUser.Info getAssignedBy() {
299            return this.assignedBy;
300        }
301
302        /**
303         * @return the time that the retention policy assignment was created.
304         */
305        public Date getAssignedAt() {
306            return this.assignedAt;
307        }
308
309        /**
310         * @return type of the content that is under retention. Can either be "enterprise" or "folder".
311         */
312        public String getAssignedToType() {
313            return this.assignedToType;
314        }
315
316        /**
317         * @return id of the folder that is under retention.
318         */
319        public String getAssignedToID() {
320            return this.assignedToID;
321        }
322
323        /**
324         * @return the array of metadata field filters, if present
325         */
326        public List<MetadataFieldFilter> getFilterFields() {
327
328            return this.filterFields;
329        }
330
331        /**
332         * {@inheritDoc}
333         */
334        @Override
335        void parseJSONMember(JsonObject.Member member) {
336            super.parseJSONMember(member);
337            String memberName = member.getName();
338            JsonValue value = member.getValue();
339            try {
340                if (memberName.equals("retention_policy")) {
341                    JsonObject policyJSON = value.asObject();
342                    if (this.retentionPolicy == null) {
343                        String policyID = policyJSON.get("id").asString();
344                        BoxRetentionPolicy policy = new BoxRetentionPolicy(getAPI(), policyID);
345                        this.retentionPolicy = policy.new Info(policyJSON);
346                    } else {
347                        this.retentionPolicy.update(policyJSON);
348                    }
349                } else if (memberName.equals("assigned_to")) {
350                    JsonObject assignmentJSON = value.asObject();
351                    this.assignedToType = assignmentJSON.get("type").asString();
352                    if (this.assignedToType.equals(TYPE_ENTERPRISE)) {
353                        this.assignedToID = null;
354                    } else {
355                        this.assignedToID = assignmentJSON.get("id").asString();
356                    }
357                } else if (memberName.equals("assigned_by")) {
358                    JsonObject userJSON = value.asObject();
359                    if (this.assignedBy == null) {
360                        String userID = userJSON.get("id").asString();
361                        BoxUser user = new BoxUser(getAPI(), userID);
362                        this.assignedBy = user.new Info(userJSON);
363                    } else {
364                        this.assignedBy.update(userJSON);
365                    }
366                } else if (memberName.equals("assigned_at")) {
367                    this.assignedAt = BoxDateFormat.parse(value.asString());
368                } else if (memberName.equals("filter_fields")) {
369                    JsonArray jsonFilters = value.asArray();
370                    List<MetadataFieldFilter> filterFields = new ArrayList<MetadataFieldFilter>();
371                    for (int i = 0; i < jsonFilters.size(); i++) {
372                        filterFields.add(new MetadataFieldFilter(jsonFilters.get(i).asObject()));
373                    }
374                    this.filterFields = filterFields;
375                }
376            } catch (Exception e) {
377                throw new BoxDeserializationException(memberName, value.toString(), e);
378            }
379        }
380    }
381}