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