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}