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     * Constructs a BoxResource for a resource with a given ID.
050     *
051     * @param api the API connection to be used by the resource.
052     * @param id  the ID of the resource.
053     */
054    public BoxRetentionPolicyAssignment(BoxAPIConnection api, String id) {
055        super(api, id);
056    }
057
058    /**
059     * Assigns retention policy with givenID to the enterprise.
060     * @param api the API connection to be used by the created assignment.
061     * @param policyID id of the assigned retention policy.
062     * @return info about created assignment.
063     */
064    public static BoxRetentionPolicyAssignment.Info createAssignmentToEnterprise(BoxAPIConnection api,
065                                                                                 String policyID) {
066        return createAssignment(api, policyID, new JsonObject().add("type", TYPE_ENTERPRISE), null);
067    }
068
069    /**
070     * Assigns retention policy with givenID to the folder.
071     * @param api the API connection to be used by the created assignment.
072     * @param policyID id of the assigned retention policy.
073     * @param folderID id of the folder to assign policy to.
074     * @return info about created assignment.
075     */
076    public static BoxRetentionPolicyAssignment.Info createAssignmentToFolder(BoxAPIConnection api, String policyID,
077                                                                             String folderID) {
078        return createAssignment(api, policyID, new JsonObject().add("type", TYPE_FOLDER).add("id", folderID), null);
079    }
080
081    /**
082     * Assigns a retention policy to all items with a given metadata template, optionally matching on fields.
083     * @param api the API connection to be used by the created assignment.
084     * @param policyID id of the assigned retention policy.
085     * @param templateID the ID of the metadata template to assign the policy to.
086     * @param filter optional fields to match against in the metadata template.
087     * @return info about the created assignment.
088     */
089    public static BoxRetentionPolicyAssignment.Info createAssignmentToMetadata(BoxAPIConnection api,
090                                                                               String policyID,
091                                                                               String templateID,
092                                                                               MetadataFieldFilter... filter) {
093        JsonObject assignTo = new JsonObject().add("type", TYPE_METADATA).add("id", templateID);
094        JsonArray filters = null;
095        if (filter.length > 0) {
096            filters = new JsonArray();
097            for (MetadataFieldFilter f : filter) {
098                filters.add(f.getJsonObject());
099            }
100        }
101        return createAssignment(api, policyID, assignTo, filters);
102    }
103
104    /**
105     * Assigns retention policy with givenID to folder or enterprise.
106     * @param api the API connection to be used by the created assignment.
107     * @param policyID id of the assigned retention policy.
108     * @param assignTo object representing folder or enterprise to assign policy to.
109     * @return info about created assignment.
110     */
111    private static BoxRetentionPolicyAssignment.Info createAssignment(BoxAPIConnection api, String policyID,
112                                                                      JsonObject assignTo, JsonArray filter) {
113        URL url = ASSIGNMENTS_URL_TEMPLATE.build(api.getBaseURL());
114        BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
115
116        JsonObject requestJSON = new JsonObject()
117                .add("policy_id", policyID)
118                .add("assign_to", assignTo);
119
120        if (filter != null) {
121            requestJSON.add("filter_fields", filter);
122        }
123
124        request.setBody(requestJSON.toString());
125        BoxJSONResponse response = (BoxJSONResponse) request.send();
126        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
127        BoxRetentionPolicyAssignment createdAssignment
128            = new BoxRetentionPolicyAssignment(api, responseJSON.get("id").asString());
129        return createdAssignment.new Info(responseJSON);
130    }
131
132    /**
133     * @param fields the fields to retrieve.
134     * @return information about this retention policy assignment.
135     */
136    public BoxRetentionPolicyAssignment.Info getInfo(String ... fields) {
137        QueryStringBuilder builder = new QueryStringBuilder();
138        if (fields.length > 0) {
139            builder.appendParam("fields", fields);
140        }
141        URL url = RETENTION_POLICY_ASSIGNMENT_URL_TEMPLATE.buildWithQuery(
142                this.getAPI().getBaseURL(), builder.toString(), this.getID());
143        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
144        BoxJSONResponse response = (BoxJSONResponse) request.send();
145        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
146        return new Info(responseJSON);
147    }
148
149    /**
150     * Contains information about the retention policy.
151     */
152    public class Info extends BoxResource.Info {
153
154        /**
155         * @see #getRetentionPolicy()
156         */
157        private BoxRetentionPolicy.Info retentionPolicy;
158
159        /**
160         * @see #getAssignedBy()
161         */
162        private BoxUser.Info assignedBy;
163
164        /**
165         * @see #getAssignedAt()
166         */
167        private Date assignedAt;
168
169        /**
170         * @see #getAssignedToType()
171         */
172        private String assignedToType;
173
174        /**
175         * @see #getAssignedToID()
176         */
177        private String assignedToID;
178
179        private List<MetadataFieldFilter> filterFields;
180
181        /**
182         * Constructs an empty Info object.
183         */
184        public Info() {
185            super();
186        }
187
188        /**
189         * Constructs an Info object by parsing information from a JSON string.
190         * @param  json the JSON string to parse.
191         */
192        public Info(String json) {
193            super(json);
194        }
195
196        /**
197         * Constructs an Info object using an already parsed JSON object.
198         * @param  jsonObject the parsed JSON object.
199         */
200        Info(JsonObject jsonObject) {
201            super(jsonObject);
202        }
203
204        /**
205         * {@inheritDoc}
206         */
207        @Override
208        public BoxResource getResource() {
209            return BoxRetentionPolicyAssignment.this;
210        }
211
212        /**
213         * @return the retention policy that has been assigned to this content.
214         */
215        public BoxRetentionPolicy.Info getRetentionPolicy() {
216            return this.retentionPolicy;
217        }
218
219        /**
220         * @return the info about the user that created the retention policy assignment.
221         */
222        public BoxUser.Info getAssignedBy() {
223            return this.assignedBy;
224        }
225
226        /**
227         * @return the time that the retention policy assignment was created.
228         */
229        public Date getAssignedAt() {
230            return this.assignedAt;
231        }
232
233        /**
234         * @return type of the content that is under retention. Can either be "enterprise" or "folder".
235         */
236        public String getAssignedToType() {
237            return this.assignedToType;
238        }
239
240        /**
241         * @return id of the folder that is under retention.
242         */
243        public String getAssignedToID() {
244            return this.assignedToID;
245        }
246
247        /**
248         * @return the array of metadata field filters, if present
249         */
250        public List<MetadataFieldFilter> getFilterFields() {
251
252            return this.filterFields;
253        }
254
255        /**
256         * {@inheritDoc}
257         */
258        @Override
259        void parseJSONMember(JsonObject.Member member) {
260            super.parseJSONMember(member);
261            String memberName = member.getName();
262            JsonValue value = member.getValue();
263            try {
264                if (memberName.equals("retention_policy")) {
265                    JsonObject policyJSON = value.asObject();
266                    if (this.retentionPolicy == null) {
267                        String policyID = policyJSON.get("id").asString();
268                        BoxRetentionPolicy policy = new BoxRetentionPolicy(getAPI(), policyID);
269                        this.retentionPolicy = policy.new Info(policyJSON);
270                    } else {
271                        this.retentionPolicy.update(policyJSON);
272                    }
273                } else if (memberName.equals("assigned_to")) {
274                    JsonObject assignmentJSON = value.asObject();
275                    this.assignedToType = assignmentJSON.get("type").asString();
276                    if (this.assignedToType.equals(TYPE_ENTERPRISE)) {
277                        this.assignedToID = null;
278                    } else {
279                        this.assignedToID = assignmentJSON.get("id").asString();
280                    }
281                } else if (memberName.equals("assigned_by")) {
282                    JsonObject userJSON = value.asObject();
283                    if (this.assignedBy == null) {
284                        String userID = userJSON.get("id").asString();
285                        BoxUser user = new BoxUser(getAPI(), userID);
286                        this.assignedBy = user.new Info(userJSON);
287                    } else {
288                        this.assignedBy.update(userJSON);
289                    }
290                } else if (memberName.equals("assigned_at")) {
291                    this.assignedAt = BoxDateFormat.parse(value.asString());
292                } else if (memberName.equals("filter_fields")) {
293                    JsonArray jsonFilters = value.asArray();
294                    List<MetadataFieldFilter> filterFields = new ArrayList<MetadataFieldFilter>();
295                    for (int i = 0; i < jsonFilters.size(); i++) {
296                        filterFields.add(new MetadataFieldFilter(jsonFilters.get(i).asObject()));
297                    }
298                    this.filterFields = filterFields;
299                }
300            } catch (Exception e) {
301                throw new BoxDeserializationException(memberName, value.toString(), e);
302            }
303        }
304    }
305}