001package com.box.sdk; 002 003import java.net.URL; 004import java.text.ParseException; 005import java.util.ArrayList; 006import java.util.Date; 007import java.util.List; 008 009import com.eclipsesource.json.JsonArray; 010import com.eclipsesource.json.JsonObject; 011import com.eclipsesource.json.JsonValue; 012 013/** 014 * The abstract base class for items in a user's file tree (files, folders, etc.). 015 */ 016public abstract class BoxItem extends BoxResource { 017 /** 018 * An array of all possible file fields that can be requested when calling {@link #getInfo()}. 019 */ 020 public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "sha1", "name", "description", 021 "size", "path_collection", "created_at", "modified_at", "trashed_at", "purged_at", "content_created_at", 022 "content_modified_at", "created_by", "modified_by", "owned_by", "shared_link", "parent", "item_status", 023 "version_number", "comment_count", "permissions", "tags", "lock", "extension", "is_package", 024 "folder_upload_email", "item_collection", "sync_state", "has_collaborations", "can_non_owners_invite"}; 025 026 private static final URLTemplate SHARED_ITEM_URL_TEMPLATE = new URLTemplate("shared_items"); 027 028 /** 029 * Constructs a BoxItem for an item with a given ID. 030 * @param api the API connection to be used by the item. 031 * @param id the ID of the item. 032 */ 033 public BoxItem(BoxAPIConnection api, String id) { 034 super(api, id); 035 } 036 037 /** 038 * Gets an item that was shared with a shared link. 039 * @param api the API connection to be used by the shared item. 040 * @param sharedLink the shared link to the item. 041 * @return info about the shared item. 042 */ 043 public static BoxItem.Info getSharedItem(BoxAPIConnection api, String sharedLink) { 044 return getSharedItem(api, sharedLink, null); 045 } 046 047 /** 048 * Gets an item that was shared with a password-protected shared link. 049 * @param api the API connection to be used by the shared item. 050 * @param sharedLink the shared link to the item. 051 * @param password the password for the shared link. 052 * @return info about the shared item. 053 */ 054 public static BoxItem.Info getSharedItem(BoxAPIConnection api, String sharedLink, String password) { 055 BoxAPIConnection newAPI = new SharedLinkAPIConnection(api, sharedLink, password); 056 URL url = SHARED_ITEM_URL_TEMPLATE.build(newAPI.getBaseURL()); 057 BoxAPIRequest request = new BoxAPIRequest(newAPI, url, "GET"); 058 BoxJSONResponse response = (BoxJSONResponse) request.send(); 059 JsonObject json = JsonObject.readFrom(response.getJSON()); 060 return (BoxItem.Info) BoxResource.parseInfo(newAPI, json); 061 } 062 063 /** 064 * Copies this item to another folder. 065 * @param destination the destination folder. 066 * @return info about the copied item. 067 */ 068 public abstract BoxItem.Info copy(BoxFolder destination); 069 070 /** 071 * Copies this item to another folder and gives it a new name. If the destination is the same folder as the item's 072 * current parent, then newName must be a new, unique name. 073 * @param destination the destination folder. 074 * @param newName a new name for the copied item. 075 * @return info about the copied item. 076 */ 077 public abstract BoxItem.Info copy(BoxFolder destination, String newName); 078 079 /** 080 * Moves this item to another folder. 081 * @param destination the destination folder. 082 * @return info about the moved item. 083 */ 084 public abstract BoxItem.Info move(BoxFolder destination); 085 086 /** 087 * Moves this item to another folder and gives it a new name. 088 * @param destination the destination folder. 089 * @param newName a new name for the moved item. 090 * @return info about the moved item. 091 */ 092 public abstract BoxItem.Info move(BoxFolder destination, String newName); 093 094 /** 095 * Creates a new shared link for this item. 096 * 097 * <p>This method is a convenience method for manually creating a new shared link and applying it to this item with 098 * {@link Info#setSharedLink}. You may want to create the shared link manually so that it can be updated along with 099 * other changes to the item's info in a single network request, giving a boost to performance.</p> 100 * 101 * @param access the access level of the shared link. 102 * @param unshareDate the date and time at which the link will expire. Can be null to create a non-expiring link. 103 * @param permissions the permissions of the shared link. Can be null to use the default permissions. 104 * @return the created shared link. 105 */ 106 public abstract BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate, 107 BoxSharedLink.Permissions permissions); 108 109 /** 110 * Gets information about this item. 111 * @return info about this item. 112 */ 113 public abstract BoxItem.Info getInfo(); 114 115 /** 116 * Gets information about this item that's limited to a list of specified fields. 117 * @param fields the fields to retrieve. 118 * @return info about this item containing only the specified fields. 119 */ 120 public abstract BoxItem.Info getInfo(String... fields); 121 122 /** 123 * Contains information about a BoxItem. 124 */ 125 public abstract class Info extends BoxResource.Info { 126 private String sequenceID; 127 private String etag; 128 private String name; 129 private Date createdAt; 130 private Date modifiedAt; 131 private String description; 132 private long size; 133 private List<BoxFolder> pathCollection; 134 private BoxUser.Info createdBy; 135 private BoxUser.Info modifiedBy; 136 private Date trashedAt; 137 private Date purgedAt; 138 private Date contentCreatedAt; 139 private Date contentModifiedAt; 140 private BoxUser.Info ownedBy; 141 private BoxSharedLink sharedLink; 142 private List<String> tags; 143 private BoxFolder.Info parent; 144 private String itemStatus; 145 146 /** 147 * Constructs an empty Info object. 148 */ 149 public Info() { 150 super(); 151 } 152 153 /** 154 * Constructs an Info object by parsing information from a JSON string. 155 * @param json the JSON string to parse. 156 */ 157 public Info(String json) { 158 super(json); 159 } 160 161 /** 162 * Constructs an Info object using an already parsed JSON object. 163 * @param jsonObject the parsed JSON object. 164 */ 165 Info(JsonObject jsonObject) { 166 super(jsonObject); 167 } 168 169 /** 170 * Gets a unique string identifying the version of the item. 171 * @return a unique string identifying the version of the item. 172 */ 173 public String getEtag() { 174 return this.etag; 175 } 176 177 /** 178 * Gets the name of the item. 179 * @return the name of the item. 180 */ 181 public String getName() { 182 return this.name; 183 } 184 185 /** 186 * Sets the name of the item. 187 * @param name the new name of the item. 188 */ 189 public void setName(String name) { 190 this.name = name; 191 this.addPendingChange("name", name); 192 } 193 194 /** 195 * Gets the time the item was created. 196 * @return the time the item was created. 197 */ 198 public Date getCreatedAt() { 199 return this.createdAt; 200 } 201 202 /** 203 * Gets the time the item was last modified. 204 * @return the time the item was last modified. 205 */ 206 public Date getModifiedAt() { 207 return this.modifiedAt; 208 } 209 210 /** 211 * Gets the description of the item. 212 * @return the description of the item. 213 */ 214 public String getDescription() { 215 return this.description; 216 } 217 218 /** 219 * Sets the description of the item. 220 * @param description the new description of the item. 221 */ 222 public void setDescription(String description) { 223 this.description = description; 224 this.addPendingChange("description", description); 225 } 226 227 /** 228 * Gets the size of the item in bytes. 229 * @return the size of the item in bytes. 230 */ 231 public long getSize() { 232 return this.size; 233 } 234 235 /** 236 * Gets the path of folders to the item, starting at the root. 237 * @return the path of folders to the item. 238 */ 239 public List<BoxFolder> getPathCollection() { 240 return this.pathCollection; 241 } 242 243 /** 244 * Gets info about the user who created the item. 245 * @return info about the user who created the item. 246 */ 247 public BoxUser.Info getCreatedBy() { 248 return this.createdBy; 249 } 250 251 /** 252 * Gets info about the user who last modified the item. 253 * @return info about the user who last modified the item. 254 */ 255 public BoxUser.Info getModifiedBy() { 256 return this.modifiedBy; 257 } 258 259 /** 260 * Gets the time that the item was trashed. 261 * @return the time that the item was trashed. 262 */ 263 public Date getTrashedAt() { 264 return this.trashedAt; 265 } 266 267 /** 268 * Gets the time that the item was purged from the trash. 269 * @return the time that the item was purged from the trash. 270 */ 271 public Date getPurgedAt() { 272 return this.purgedAt; 273 } 274 275 /** 276 * Gets the time that the item was created according to the uploader. 277 * @return the time that the item was created according to the uploader. 278 */ 279 public Date getContentCreatedAt() { 280 return this.contentCreatedAt; 281 } 282 283 /** 284 * Gets the time that the item was last modified according to the uploader. 285 * @return the time that the item was last modified according to the uploader. 286 */ 287 public Date getContentModifiedAt() { 288 return this.contentModifiedAt; 289 } 290 291 /** 292 * Gets info about the user who owns the item. 293 * @return info about the user who owns the item. 294 */ 295 public BoxUser.Info getOwnedBy() { 296 return this.ownedBy; 297 } 298 299 /** 300 * Gets the shared link for the item. 301 * @return the shared link for the item. 302 */ 303 public BoxSharedLink getSharedLink() { 304 return this.sharedLink; 305 } 306 307 /** 308 * Sets a shared link for the item. 309 * @param sharedLink the shared link for the item. 310 */ 311 public void setSharedLink(BoxSharedLink sharedLink) { 312 if (this.sharedLink == sharedLink) { 313 return; 314 } 315 316 this.removeChildObject("shared_link"); 317 this.sharedLink = sharedLink; 318 this.addChildObject("shared_link", sharedLink); 319 } 320 321 /** 322 * Gets a unique ID for use with the {@link EventStream}. 323 * @return a unique ID for use with the EventStream. 324 */ 325 public String getSequenceID() { 326 return this.sequenceID; 327 } 328 329 /** 330 * Gets a list of all the tags applied to the item. 331 * 332 * <p>Note that this field isn't populated by default and must be specified as a field parameter when getting 333 * Info about the item.</p> 334 * 335 * @return a list of all the tags applied to the item. 336 */ 337 public List<String> getTags() { 338 return this.tags; 339 } 340 341 /** 342 * Gets info about the parent folder of the item. 343 * @return info abou thte parent folder of the item. 344 */ 345 public BoxFolder.Info getParent() { 346 return this.parent; 347 } 348 349 /** 350 * Gets the status of the item. 351 * @return the status of the item. 352 */ 353 public String getItemStatus() { 354 return this.itemStatus; 355 } 356 357 @Override 358 protected void parseJSONMember(JsonObject.Member member) { 359 super.parseJSONMember(member); 360 361 try { 362 JsonValue value = member.getValue(); 363 switch (member.getName()) { 364 case "sequence_id": 365 this.sequenceID = value.asString(); 366 break; 367 case "etag": 368 this.etag = value.asString(); 369 break; 370 case "name": 371 this.name = value.asString(); 372 break; 373 case "created_at": 374 this.createdAt = BoxDateFormat.parse(value.asString()); 375 break; 376 case "modified_at": 377 this.modifiedAt = BoxDateFormat.parse(value.asString()); 378 break; 379 case "description": 380 this.description = value.asString(); 381 break; 382 case "size": 383 this.size = Double.valueOf(value.toString()).longValue(); 384 break; 385 case "trashed_at": 386 this.trashedAt = BoxDateFormat.parse(value.asString()); 387 break; 388 case "purged_at": 389 this.purgedAt = BoxDateFormat.parse(value.asString()); 390 break; 391 case "content_created_at": 392 this.contentCreatedAt = BoxDateFormat.parse(value.asString()); 393 break; 394 case "content_modified_at": 395 this.contentModifiedAt = BoxDateFormat.parse(value.asString()); 396 break; 397 case "path_collection": 398 this.pathCollection = this.parsePathCollection(value.asObject()); 399 break; 400 case "created_by": 401 this.createdBy = this.parseUserInfo(value.asObject()); 402 break; 403 case "modified_by": 404 this.modifiedBy = this.parseUserInfo(value.asObject()); 405 break; 406 case "owned_by": 407 this.ownedBy = this.parseUserInfo(value.asObject()); 408 break; 409 case "shared_link": 410 if (this.sharedLink == null) { 411 this.setSharedLink(new BoxSharedLink(value.asObject())); 412 } else { 413 this.sharedLink.update(value.asObject()); 414 } 415 break; 416 case "tags": 417 this.tags = this.parseTags(value.asArray()); 418 break; 419 case "parent": 420 JsonObject jsonObject = value.asObject(); 421 if (this.parent == null) { 422 String id = jsonObject.get("id").asString(); 423 BoxFolder parentFolder = new BoxFolder(getAPI(), id); 424 this.parent = parentFolder.new Info(jsonObject); 425 } else { 426 this.parent.update(jsonObject); 427 } 428 break; 429 case "item_status": 430 this.itemStatus = value.asString(); 431 break; 432 default: 433 break; 434 } 435 } catch (ParseException e) { 436 assert false : "A ParseException indicates a bug in the SDK."; 437 } 438 } 439 440 private List<BoxFolder> parsePathCollection(JsonObject jsonObject) { 441 int count = jsonObject.get("total_count").asInt(); 442 List<BoxFolder> pathCollection = new ArrayList<BoxFolder>(count); 443 JsonArray entries = jsonObject.get("entries").asArray(); 444 for (JsonValue value : entries) { 445 JsonObject entry = value.asObject(); 446 String id = entry.get("id").asString(); 447 pathCollection.add(new BoxFolder(getAPI(), id)); 448 } 449 450 return pathCollection; 451 } 452 453 private BoxUser.Info parseUserInfo(JsonObject jsonObject) { 454 String userID = jsonObject.get("id").asString(); 455 BoxUser user = new BoxUser(getAPI(), userID); 456 return user.new Info(jsonObject); 457 } 458 459 private List<String> parseTags(JsonArray jsonArray) { 460 List<String> tags = new ArrayList<String>(jsonArray.size()); 461 for (JsonValue value : jsonArray) { 462 tags.add(value.asString()); 463 } 464 465 return tags; 466 } 467 } 468}