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