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