001package com.box.sdk;
002
003import com.eclipsesource.json.JsonObject;
004import com.eclipsesource.json.JsonValue;
005import java.util.Date;
006
007/** Represents a link to a file or folder on Box. */
008public class BoxSharedLink extends BoxJSONObject {
009  private String url;
010  private String downloadUrl;
011  private String vanityUrl;
012  private String vanityName;
013  private boolean isPasswordEnabled;
014  private String password;
015  private Date unsharedAt;
016  private long downloadCount;
017  private long previewCount;
018  private Access access;
019  private Access effectiveAccess;
020  private Permissions permissions;
021
022  /** Constructs a BoxSharedLink with default settings. */
023  public BoxSharedLink() {}
024
025  /**
026   * Constructs a BoxSharedLink from a JSON string.
027   *
028   * @param json the JSON encoded shared link.
029   */
030  public BoxSharedLink(String json) {
031    super(json);
032  }
033
034  BoxSharedLink(JsonObject jsonObject) {
035    super(jsonObject);
036  }
037
038  BoxSharedLink(
039      BoxSharedLink.Access access, Date unshareDate, BoxSharedLink.Permissions permissions) {
040    this.setAccess(access);
041    this.setPermissions(permissions);
042
043    if (unshareDate != null) {
044      this.setUnsharedDate(unshareDate);
045    }
046  }
047
048  BoxSharedLink(
049      BoxSharedLink.Access access,
050      Date unshareDate,
051      BoxSharedLink.Permissions permissions,
052      String password) {
053    this.setAccess(access);
054    this.setPermissions(permissions);
055    this.setPassword(password);
056
057    if (unshareDate != null) {
058      this.setUnsharedDate(unshareDate);
059    }
060  }
061
062  /**
063   * Get the URL of this shared link.
064   *
065   * @return the URL of this shared link.
066   */
067  public String getURL() {
068    return this.url;
069  }
070
071  /**
072   * Gets the direct download URL of this shared link.
073   *
074   * @return the direct download URL of this shared link.
075   */
076  public String getDownloadURL() {
077    return this.downloadUrl;
078  }
079
080  /**
081   * Gets the vanity URL of this shared link.
082   *
083   * @return the vanity URL of this shared link.
084   */
085  public String getVanityURL() {
086    return this.vanityUrl;
087  }
088
089  /**
090   * Returns vanity name used to create vanity URL.
091   *
092   * @return Vanity name
093   */
094  public String getVanityName() {
095    return vanityName;
096  }
097
098  /**
099   * Sets vanity name used to create vanity URL. For example: vanityName = myCustomName will produce
100   * vanityUrl as: https://app.box.com/v/myCustomName Custom URLs should not be used when sharing
101   * sensitive content as vanity URLs are a lot easier to guess than regular shared links.
102   *
103   * @param vanityName Vanity name. Vanity name must be at least 12 characters long.
104   */
105  public void setVanityName(String vanityName) {
106    if (vanityName != null && vanityName.length() < 12) {
107      throw new IllegalArgumentException("The vanityName has to be at least 12 characters long.");
108    }
109    this.vanityName = vanityName;
110    this.addPendingChange("vanity_name", vanityName);
111  }
112
113  /**
114   * Gets whether or not a password is enabled on this shared link.
115   *
116   * @return true if there's a password enabled on this shared link; otherwise false.
117   */
118  public boolean getIsPasswordEnabled() {
119    return this.isPasswordEnabled;
120  }
121
122  /**
123   * Gets the time that this shared link will be deactivated.
124   *
125   * @return the time that this shared link will be deactivated.
126   */
127  public Date getUnsharedDate() {
128    return this.unsharedAt;
129  }
130
131  /**
132   * Sets the time that this shared link will be deactivated.
133   *
134   * @param unsharedDate the time that this shared link will be deactivated.
135   */
136  public void setUnsharedDate(Date unsharedDate) {
137    this.unsharedAt = unsharedDate;
138    this.addPendingChange("unshared_at", BoxDateFormat.format(unsharedDate));
139  }
140
141  /**
142   * Gets the number of times that this shared link has been downloaded.
143   *
144   * @return the number of times that this link has been downloaded.
145   */
146  public long getDownloadCount() {
147    return this.downloadCount;
148  }
149
150  /**
151   * Gets the number of times that this shared link has been previewed.
152   *
153   * @return the number of times that this link has been previewed.
154   */
155  public long getPreviewCount() {
156    return this.previewCount;
157  }
158
159  /**
160   * Gets the access level of this shared link.
161   *
162   * @return the access level of this shared link.
163   */
164  public Access getAccess() {
165    return this.access;
166  }
167
168  /**
169   * Sets the access level of this shared link.
170   *
171   * @param access the new access level of this shared link.
172   */
173  public void setAccess(Access access) {
174    this.access = access;
175    this.addPendingChange("access", access.toJSONValue());
176  }
177
178  /**
179   * Sets the password of this shared link.
180   *
181   * @param password the password of this shared link.
182   */
183  public void setPassword(String password) {
184    this.password = password;
185    this.addPendingChange("password", password);
186  }
187
188  /**
189   * Gets the effective access level of this shared link.
190   *
191   * @return the effective access level of this shared link.
192   *     <p>Note there is no setEffectiveAccess metho becaused this cannot be changed via the API
193   */
194  public Access getEffectiveAccess() {
195    return this.effectiveAccess;
196  }
197
198  /**
199   * Gets the permissions associated with this shared link.
200   *
201   * @return the permissions associated with this shared link.
202   */
203  public Permissions getPermissions() {
204    return this.permissions;
205  }
206
207  /**
208   * Sets the permissions associated with this shared link.
209   *
210   * @param permissions the new permissions for this shared link.
211   */
212  public void setPermissions(Permissions permissions) {
213    if (this.permissions != null && this.permissions.equals(permissions)) {
214      return;
215    }
216
217    this.removeChildObject("permissions");
218    this.permissions = permissions;
219    this.addChildObject("permissions", permissions);
220  }
221
222  private Access parseAccessValue(JsonValue value) {
223    String accessString = value.asString().toUpperCase(java.util.Locale.ROOT);
224    return Access.valueOf(accessString);
225  }
226
227  @Override
228  protected JsonObject getPendingJSONObject() {
229    JsonObject result = super.getPendingJSONObject();
230    if (result == null) {
231      result = new JsonObject();
232    }
233    return result;
234  }
235
236  @Override
237  void parseJSONMember(JsonObject.Member member) {
238    JsonValue value = member.getValue();
239    String memberName = member.getName();
240
241    try {
242      if (memberName.equals("url")) {
243        this.url = value.asString();
244      } else if (memberName.equals("download_url")) {
245        this.downloadUrl = value.asString();
246      } else if (memberName.equals("vanity_url")) {
247        this.vanityUrl = value.asString();
248      } else if (memberName.equals("vanity_name")) {
249        this.vanityName = value.asString();
250      } else if (memberName.equals("is_password_enabled")) {
251        this.isPasswordEnabled = value.asBoolean();
252      } else if (memberName.equals("unshared_at")) {
253        this.unsharedAt = BoxDateFormat.parse(value.asString());
254      } else if (memberName.equals("download_count")) {
255        this.downloadCount = Double.valueOf(value.toString()).longValue();
256      } else if (memberName.equals("preview_count")) {
257        this.previewCount = Double.valueOf(value.toString()).longValue();
258      } else if (memberName.equals("access")) {
259        this.access = this.parseAccessValue(value);
260      } else if (memberName.equals("effective_access")) {
261        this.effectiveAccess = this.parseAccessValue(value);
262      } else if (memberName.equals("permissions")) {
263        if (this.permissions == null) {
264          this.setPermissions(new Permissions(value.asObject()));
265        } else {
266          this.permissions.update(value.asObject());
267        }
268      }
269    } catch (Exception e) {
270      throw new BoxDeserializationException(memberName, value.toString(), e);
271    }
272  }
273
274  public static String getSharedLinkHeaderValue(String sharedLink, String password) {
275    String boxAPIValue = "shared_link=" + sharedLink;
276    if (password != null) {
277      boxAPIValue += "&shared_link_password=" + password;
278    }
279    return boxAPIValue;
280  }
281
282  /** Enumerates the possible access levels that can be set on a shared link. */
283  public enum Access {
284    /** The default access level for the user or enterprise. */
285    DEFAULT(null),
286
287    /** The link can be accessed by anyone. */
288    OPEN("open"),
289
290    /** The link can be accessed by other users within the company. */
291    COMPANY("company"),
292
293    /** The link can be accessed by other collaborators. */
294    COLLABORATORS("collaborators");
295
296    private final String jsonValue;
297
298    Access(String jsonValue) {
299      this.jsonValue = jsonValue;
300    }
301
302    String toJSONValue() {
303      return this.jsonValue;
304    }
305  }
306
307  /** Contains permissions fields that can be set on a shared link. */
308  public static class Permissions extends BoxJSONObject {
309    private boolean canDownload;
310    private boolean canPreview;
311    private boolean canEdit;
312
313    /** Constructs a Permissions object with all permissions disabled. */
314    public Permissions() {}
315
316    Permissions(boolean canPreview, boolean canDownload, boolean canEdit) {
317      this.setCanPreview(canPreview);
318      this.setCanDownload(canDownload);
319      this.setCanEdit(canEdit);
320    }
321
322    /**
323     * Constructs a Permissions object from a JSON string.
324     *
325     * @param json the JSON encoded shared link permissions.
326     */
327    public Permissions(String json) {
328      super(json);
329    }
330
331    Permissions(JsonObject jsonObject) {
332      super(jsonObject);
333    }
334
335    /**
336     * Gets whether the shared link can be downloaded.
337     *
338     * @return true if the shared link can be downloaded; otherwise false.
339     */
340    public boolean getCanDownload() {
341      return this.canDownload;
342    }
343
344    /**
345     * Sets whether or not the shared link can be downloaded.
346     *
347     * @param enabled true if the shared link can be downloaded; otherwise false.
348     */
349    public void setCanDownload(boolean enabled) {
350      this.canDownload = enabled;
351      this.addPendingChange("can_download", enabled);
352    }
353
354    /**
355     * Gets whether the shared link can be previewed.
356     *
357     * @return true if the shared link can be previewed; otherwise false.
358     */
359    public boolean getCanPreview() {
360      return this.canPreview;
361    }
362
363    /**
364     * Sets whether the shared link can be previewed.
365     *
366     * @param enabled true if the shared link can be previewed; otherwise false.
367     */
368    public void setCanPreview(boolean enabled) {
369      this.canPreview = enabled;
370      this.addPendingChange("can_preview", enabled);
371    }
372
373    /**
374     * Gets whether the shared link allows for editing of files.
375     *
376     * @return true if the shared link allows for editing of files; otherwise false.
377     */
378    public boolean getCanEdit() {
379      return canEdit;
380    }
381
382    /**
383     * Sets whether the shared link allows for editing of files. For folders this value will always
384     * be set to false.
385     *
386     * @param enabled true if the shared link allows for editing of files; otherwise false.
387     */
388    public void setCanEdit(boolean enabled) {
389      this.canEdit = enabled;
390      this.addPendingChange("can_edit", enabled);
391    }
392
393    @Override
394    void parseJSONMember(JsonObject.Member member) {
395      JsonValue value = member.getValue();
396      String memberName = member.getName();
397      if (memberName.equals("can_download")) {
398        this.canDownload = value.asBoolean();
399      }
400      if (memberName.equals("can_preview")) {
401        this.canPreview = value.asBoolean();
402      }
403      if (memberName.equals("can_edit")) {
404        this.canEdit = value.asBoolean();
405      }
406    }
407
408    @Override
409    public boolean equals(Object o) {
410      if (this == o) {
411        return true;
412      }
413      if (o == null || this.getClass() != o.getClass()) {
414        return false;
415      }
416
417      Permissions that = (Permissions) o;
418
419      return this.canDownload == that.canDownload
420          && this.canPreview == that.canPreview
421          && this.canEdit == that.canEdit;
422    }
423
424    @Override
425    public int hashCode() {
426      int result = (this.canDownload ? 1 : 0);
427      result = 31 * result + (this.canPreview ? 1 : 0);
428      result = 31 * result + (this.canEdit ? 1 : 0);
429      return result;
430    }
431
432    @Override
433    public String toString() {
434      return "Permissions{canDownload="
435          + this.canDownload
436          + ", canPreview="
437          + this.canPreview
438          + ", canEdit="
439          + this.canEdit
440          + '}';
441    }
442  }
443}