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