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    void parseJSONMember(JsonObject.Member member) {
236        JsonValue value = member.getValue();
237        String memberName = member.getName();
238
239        try {
240            if (memberName.equals("url")) {
241                this.url = value.asString();
242            } else if (memberName.equals("download_url")) {
243                this.downloadUrl = value.asString();
244            } else if (memberName.equals("vanity_url")) {
245                this.vanityUrl = value.asString();
246            } else if (memberName.equals("vanity_name")) {
247                this.vanityName = value.asString();
248            } else if (memberName.equals("is_password_enabled")) {
249                this.isPasswordEnabled = value.asBoolean();
250            } else if (memberName.equals("unshared_at")) {
251                this.unsharedAt = BoxDateFormat.parse(value.asString());
252            } else if (memberName.equals("download_count")) {
253                this.downloadCount = Double.valueOf(value.toString()).longValue();
254            } else if (memberName.equals("preview_count")) {
255                this.previewCount = Double.valueOf(value.toString()).longValue();
256            } else if (memberName.equals("access")) {
257                this.access = this.parseAccessValue(value);
258            } else if (memberName.equals("effective_access")) {
259                this.effectiveAccess = this.parseAccessValue(value);
260            } else if (memberName.equals("permissions")) {
261                if (this.permissions == null) {
262                    this.setPermissions(new Permissions(value.asObject()));
263                } else {
264                    this.permissions.update(value.asObject());
265                }
266            }
267        } catch (Exception e) {
268            throw new BoxDeserializationException(memberName, value.toString(), e);
269        }
270    }
271
272    /**
273     * Enumerates the possible access levels that can be set on a shared link.
274     */
275    public enum Access {
276        /**
277         * The default access level for the user or enterprise.
278         */
279        DEFAULT(null),
280
281        /**
282         * The link can be accessed by anyone.
283         */
284        OPEN("open"),
285
286        /**
287         * The link can be accessed by other users within the company.
288         */
289        COMPANY("company"),
290
291        /**
292         * The link can be accessed by other collaborators.
293         */
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    /**
308     * Contains permissions fields that can be set on a shared link.
309     */
310    public static class Permissions extends BoxJSONObject {
311        private boolean canDownload;
312        private boolean canPreview;
313        private boolean canEdit;
314
315        /**
316         * Constructs a Permissions object with all permissions disabled.
317         */
318        public Permissions() {
319        }
320
321        Permissions(boolean canPreview, boolean canDownload, boolean canEdit) {
322            this.setCanPreview(canPreview);
323            this.setCanDownload(canDownload);
324            this.setCanEdit(canEdit);
325        }
326
327        /**
328         * Constructs a Permissions object from a JSON string.
329         *
330         * @param json the JSON encoded shared link permissions.
331         */
332        public Permissions(String json) {
333            super(json);
334        }
335
336        Permissions(JsonObject jsonObject) {
337            super(jsonObject);
338        }
339
340        /**
341         * Gets whether the shared link can be downloaded.
342         *
343         * @return true if the shared link can be downloaded; otherwise false.
344         */
345        public boolean getCanDownload() {
346            return this.canDownload;
347        }
348
349        /**
350         * Sets whether or not the shared link can be downloaded.
351         *
352         * @param enabled true if the shared link can be downloaded; otherwise false.
353         */
354        public void setCanDownload(boolean enabled) {
355            this.canDownload = enabled;
356            this.addPendingChange("can_download", enabled);
357        }
358
359        /**
360         * Gets whether the shared link can be previewed.
361         *
362         * @return true if the shared link can be previewed; otherwise false.
363         */
364        public boolean getCanPreview() {
365            return this.canPreview;
366        }
367
368        /**
369         * Sets whether the shared link can be previewed.
370         *
371         * @param enabled true if the shared link can be previewed; otherwise false.
372         */
373        public void setCanPreview(boolean enabled) {
374            this.canPreview = enabled;
375            this.addPendingChange("can_preview", enabled);
376        }
377
378        /**
379         * Gets whether the shared link allows for editing of files.
380         *
381         * @return true if the shared link allows for editing of files; otherwise false.
382         */
383        public boolean getCanEdit() {
384            return canEdit;
385        }
386
387        /**
388         * Sets whether the shared link allows for editing of files.
389         * For folders this value will always be set to false.
390         *
391         * @param enabled true if the shared link allows for editing of files; otherwise false.
392         */
393        public void setCanEdit(boolean enabled) {
394            this.canEdit = enabled;
395            this.addPendingChange("can_edit", enabled);
396        }
397
398        @Override
399        void parseJSONMember(JsonObject.Member member) {
400            JsonValue value = member.getValue();
401            String memberName = member.getName();
402            if (memberName.equals("can_download")) {
403                this.canDownload = value.asBoolean();
404            }
405            if (memberName.equals("can_preview")) {
406                this.canPreview = value.asBoolean();
407            }
408            if (memberName.equals("can_edit")) {
409                this.canEdit = value.asBoolean();
410            }
411        }
412
413        @Override
414        public boolean equals(Object o) {
415            if (this == o) {
416                return true;
417            }
418            if (o == null || this.getClass() != o.getClass()) {
419                return false;
420            }
421
422            Permissions that = (Permissions) o;
423
424            return this.canDownload == that.canDownload
425                && this.canPreview == that.canPreview
426                && this.canEdit == that.canEdit;
427        }
428
429        @Override
430        public int hashCode() {
431            int result = (this.canDownload ? 1 : 0);
432            result = 31 * result + (this.canPreview ? 1 : 0);
433            result = 31 * result + (this.canEdit ? 1 : 0);
434            return result;
435        }
436
437        @Override
438        public String toString() {
439            return "Permissions{canDownload=" + this.canDownload
440                + ", canPreview=" + this.canPreview
441                + ", canEdit=" + this.canEdit
442                + '}';
443        }
444    }
445}