001package com.box.sdk; 002 003import java.io.IOException; 004import java.io.InputStream; 005import java.net.URL; 006import java.util.ArrayList; 007import java.util.Collection; 008import java.util.Date; 009import java.util.EnumSet; 010import java.util.Iterator; 011import java.util.Map; 012import java.util.concurrent.TimeUnit; 013 014import com.box.sdk.internal.utils.Parsers; 015import com.eclipsesource.json.JsonArray; 016import com.eclipsesource.json.JsonObject; 017import com.eclipsesource.json.JsonValue; 018 019/** 020 * Represents a folder on Box. This class can be used to iterate through a folder's contents, collaborate a folder with 021 * another user or group, and perform other common folder operations (move, copy, delete, etc.). 022 * <p> 023 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked 024 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error 025 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p> 026 */ 027@BoxResourceType("folder") 028public class BoxFolder extends BoxItem implements Iterable<BoxItem.Info> { 029 /** 030 * An array of all possible folder fields that can be requested when calling {@link #getInfo()}. 031 */ 032 public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "name", "created_at", "modified_at", 033 "description", "size", "path_collection", "created_by", "modified_by", "trashed_at", "purged_at", 034 "content_created_at", "content_modified_at", "owned_by", "shared_link", "folder_upload_email", "parent", 035 "item_status", "item_collection", "sync_state", "has_collaborations", "permissions", "tags", 036 "can_non_owners_invite", "collections", "watermark_info", "metadata"}; 037 038 /** 039 * Used to specify what direction to sort and display results. 040 */ 041 public enum SortDirection { 042 /** 043 * ASC for ascending order. 044 */ 045 ASC, 046 047 /** 048 * DESC for descending order. 049 */ 050 DESC 051 } 052 053 /** 054 * Create Folder URL Template. 055 */ 056 public static final URLTemplate CREATE_FOLDER_URL = new URLTemplate("folders"); 057 /** 058 * Create Web Link URL Template. 059 */ 060 public static final URLTemplate CREATE_WEB_LINK_URL = new URLTemplate("web_links"); 061 /** 062 * Copy Folder URL Template. 063 */ 064 public static final URLTemplate COPY_FOLDER_URL = new URLTemplate("folders/%s/copy"); 065 /** 066 * Delete Folder URL Template. 067 */ 068 public static final URLTemplate DELETE_FOLDER_URL = new URLTemplate("folders/%s?recursive=%b"); 069 /** 070 * Folder Info URL Template. 071 */ 072 public static final URLTemplate FOLDER_INFO_URL_TEMPLATE = new URLTemplate("folders/%s"); 073 /** 074 * Upload File URL Template. 075 */ 076 public static final URLTemplate UPLOAD_FILE_URL = new URLTemplate("files/content"); 077 /** 078 * Add Collaboration URL Template. 079 */ 080 public static final URLTemplate ADD_COLLABORATION_URL = new URLTemplate("collaborations"); 081 /** 082 * Get Collaborations URL Template. 083 */ 084 public static final URLTemplate GET_COLLABORATIONS_URL = new URLTemplate("folders/%s/collaborations"); 085 /** 086 * Get Items URL Template. 087 */ 088 public static final URLTemplate GET_ITEMS_URL = new URLTemplate("folders/%s/items/"); 089 /** 090 * Search URL Template. 091 */ 092 public static final URLTemplate SEARCH_URL_TEMPLATE = new URLTemplate("search"); 093 /** 094 * Metadata URL Template. 095 */ 096 public static final URLTemplate METADATA_URL_TEMPLATE = new URLTemplate("folders/%s/metadata/%s/%s"); 097 /** 098 * Upload Session URL Template. 099 */ 100 public static final URLTemplate UPLOAD_SESSION_URL_TEMPLATE = new URLTemplate("files/upload_sessions"); 101 102 /** 103 * Constructs a BoxFolder for a folder with a given ID. 104 * 105 * @param api the API connection to be used by the folder. 106 * @param id the ID of the folder. 107 */ 108 public BoxFolder(BoxAPIConnection api, String id) { 109 super(api, id); 110 } 111 112 /** 113 * {@inheritDoc} 114 */ 115 @Override 116 protected URL getItemURL() { 117 return FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 118 } 119 120 /** 121 * Gets the current user's root folder. 122 * 123 * @param api the API connection to be used by the folder. 124 * @return the user's root folder. 125 */ 126 public static BoxFolder getRootFolder(BoxAPIConnection api) { 127 return new BoxFolder(api, "0"); 128 } 129 130 /** 131 * Adds a collaborator to this folder. 132 * 133 * @param collaborator the collaborator to add. 134 * @param role the role of the collaborator. 135 * @return info about the new collaboration. 136 */ 137 public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role) { 138 JsonObject accessibleByField = new JsonObject(); 139 accessibleByField.add("id", collaborator.getID()); 140 141 if (collaborator instanceof BoxUser) { 142 accessibleByField.add("type", "user"); 143 } else if (collaborator instanceof BoxGroup) { 144 accessibleByField.add("type", "group"); 145 } else { 146 throw new IllegalArgumentException("The given collaborator is of an unknown type."); 147 } 148 149 return this.collaborate(accessibleByField, role, null, null); 150 } 151 152 /** 153 * Adds a collaborator to this folder. An email will be sent to the collaborator if they don't already have a Box 154 * account. 155 * 156 * @param email the email address of the collaborator to add. 157 * @param role the role of the collaborator. 158 * @return info about the new collaboration. 159 */ 160 public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role) { 161 JsonObject accessibleByField = new JsonObject(); 162 accessibleByField.add("login", email); 163 accessibleByField.add("type", "user"); 164 165 return this.collaborate(accessibleByField, role, null, null); 166 } 167 168 /** 169 * Adds a collaborator to this folder. 170 * 171 * @param collaborator the collaborator to add. 172 * @param role the role of the collaborator. 173 * @param notify the user/group should receive email notification of the collaboration or not. 174 * @param canViewPath the view path collaboration feature is enabled or not. 175 * View path collaborations allow the invitee to see the entire ancestral path to the associated 176 * folder. The user will not gain privileges in any ancestral folder. 177 * @return info about the new collaboration. 178 */ 179 public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role, 180 Boolean notify, Boolean canViewPath) { 181 JsonObject accessibleByField = new JsonObject(); 182 accessibleByField.add("id", collaborator.getID()); 183 184 if (collaborator instanceof BoxUser) { 185 accessibleByField.add("type", "user"); 186 } else if (collaborator instanceof BoxGroup) { 187 accessibleByField.add("type", "group"); 188 } else { 189 throw new IllegalArgumentException("The given collaborator is of an unknown type."); 190 } 191 192 return this.collaborate(accessibleByField, role, notify, canViewPath); 193 } 194 195 /** 196 * Adds a collaborator to this folder. An email will be sent to the collaborator if they don't already have a Box 197 * account. 198 * 199 * @param email the email address of the collaborator to add. 200 * @param role the role of the collaborator. 201 * @param notify the user/group should receive email notification of the collaboration or not. 202 * @param canViewPath the view path collaboration feature is enabled or not. 203 * View path collaborations allow the invitee to see the entire ancestral path to the associated 204 * folder. The user will not gain privileges in any ancestral folder. 205 * @return info about the new collaboration. 206 */ 207 public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role, 208 Boolean notify, Boolean canViewPath) { 209 JsonObject accessibleByField = new JsonObject(); 210 accessibleByField.add("login", email); 211 accessibleByField.add("type", "user"); 212 213 return this.collaborate(accessibleByField, role, notify, canViewPath); 214 } 215 216 private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxCollaboration.Role role, 217 Boolean notify, Boolean canViewPath) { 218 219 JsonObject itemField = new JsonObject(); 220 itemField.add("id", this.getID()); 221 itemField.add("type", "folder"); 222 223 return BoxCollaboration.create(this.getAPI(), accessibleByField, itemField, role, notify, canViewPath); 224 } 225 226 @Override 227 public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate, 228 BoxSharedLink.Permissions permissions) { 229 230 BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions); 231 Info info = new Info(); 232 info.setSharedLink(sharedLink); 233 234 this.updateInfo(info); 235 return info.getSharedLink(); 236 } 237 238 /** 239 * Creates new SharedLink for a BoxFolder with a password. 240 * 241 * @param access The access level of the shared link. 242 * @param unshareDate A specified date to unshare the Box folder. 243 * @param permissions The permissions to set on the shared link for the Box folder. 244 * @param password Password set on the shared link to give access to the Box folder. 245 * @return information about the newly created shared link. 246 */ 247 public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate, 248 BoxSharedLink.Permissions permissions, String password) { 249 250 BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions, password); 251 Info info = new Info(); 252 info.setSharedLink(sharedLink); 253 254 this.updateInfo(info); 255 return info.getSharedLink(); 256 } 257 258 /** 259 * Gets information about all of the collaborations for this folder. 260 * 261 * @return a collection of information about the collaborations for this folder. 262 */ 263 public Collection<BoxCollaboration.Info> getCollaborations() { 264 BoxAPIConnection api = this.getAPI(); 265 URL url = GET_COLLABORATIONS_URL.build(api.getBaseURL(), this.getID()); 266 267 BoxAPIRequest request = new BoxAPIRequest(api, url, "GET"); 268 BoxJSONResponse response = (BoxJSONResponse) request.send(); 269 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 270 271 int entriesCount = responseJSON.get("total_count").asInt(); 272 Collection<BoxCollaboration.Info> collaborations = new ArrayList<BoxCollaboration.Info>(entriesCount); 273 JsonArray entries = responseJSON.get("entries").asArray(); 274 for (JsonValue entry : entries) { 275 JsonObject entryObject = entry.asObject(); 276 BoxCollaboration collaboration = new BoxCollaboration(api, entryObject.get("id").asString()); 277 BoxCollaboration.Info info = collaboration.new Info(entryObject); 278 collaborations.add(info); 279 } 280 281 return collaborations; 282 } 283 284 @Override 285 public BoxFolder.Info getInfo() { 286 URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 287 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 288 BoxJSONResponse response = (BoxJSONResponse) request.send(); 289 return new Info(response.getJSON()); 290 } 291 292 @Override 293 public BoxFolder.Info getInfo(String... fields) { 294 String queryString = new QueryStringBuilder().appendParam("fields", fields).toString(); 295 URL url = FOLDER_INFO_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID()); 296 297 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 298 BoxJSONResponse response = (BoxJSONResponse) request.send(); 299 return new Info(response.getJSON()); 300 } 301 302 /** 303 * Updates the information about this folder with any info fields that have been modified locally. 304 * 305 * @param info the updated info. 306 */ 307 public void updateInfo(BoxFolder.Info info) { 308 URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 309 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 310 request.setBody(info.getPendingChanges()); 311 BoxJSONResponse response = (BoxJSONResponse) request.send(); 312 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 313 info.update(jsonObject); 314 } 315 316 @Override 317 public BoxFolder.Info copy(BoxFolder destination) { 318 return this.copy(destination, null); 319 } 320 321 @Override 322 public BoxFolder.Info copy(BoxFolder destination, String newName) { 323 URL url = COPY_FOLDER_URL.build(this.getAPI().getBaseURL(), this.getID()); 324 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 325 326 JsonObject parent = new JsonObject(); 327 parent.add("id", destination.getID()); 328 329 JsonObject copyInfo = new JsonObject(); 330 copyInfo.add("parent", parent); 331 if (newName != null) { 332 copyInfo.add("name", newName); 333 } 334 335 request.setBody(copyInfo.toString()); 336 BoxJSONResponse response = (BoxJSONResponse) request.send(); 337 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 338 BoxFolder copiedFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString()); 339 return copiedFolder.new Info(responseJSON); 340 } 341 342 /** 343 * Creates a new child folder inside this folder. 344 * 345 * @param name the new folder's name. 346 * @return the created folder's info. 347 */ 348 public BoxFolder.Info createFolder(String name) { 349 JsonObject parent = new JsonObject(); 350 parent.add("id", this.getID()); 351 352 JsonObject newFolder = new JsonObject(); 353 newFolder.add("name", name); 354 newFolder.add("parent", parent); 355 356 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), CREATE_FOLDER_URL.build(this.getAPI().getBaseURL()), 357 "POST"); 358 request.setBody(newFolder.toString()); 359 BoxJSONResponse response = (BoxJSONResponse) request.send(); 360 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 361 362 BoxFolder createdFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString()); 363 return createdFolder.new Info(responseJSON); 364 } 365 366 /** 367 * Deletes this folder, optionally recursively deleting all of its contents. 368 * 369 * @param recursive true to recursively delete this folder's contents; otherwise false. 370 */ 371 public void delete(boolean recursive) { 372 URL url = DELETE_FOLDER_URL.build(this.getAPI().getBaseURL(), this.getID(), recursive); 373 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 374 BoxAPIResponse response = request.send(); 375 response.disconnect(); 376 } 377 378 @Override 379 public BoxItem.Info move(BoxFolder destination) { 380 return this.move(destination, null); 381 } 382 383 @Override 384 public BoxItem.Info move(BoxFolder destination, String newName) { 385 URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 386 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 387 388 JsonObject parent = new JsonObject(); 389 parent.add("id", destination.getID()); 390 391 JsonObject updateInfo = new JsonObject(); 392 updateInfo.add("parent", parent); 393 if (newName != null) { 394 updateInfo.add("name", newName); 395 } 396 397 request.setBody(updateInfo.toString()); 398 BoxJSONResponse response = (BoxJSONResponse) request.send(); 399 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 400 BoxFolder movedFolder = new BoxFolder(this.getAPI(), responseJSON.get("id").asString()); 401 return movedFolder.new Info(responseJSON); 402 } 403 404 /** 405 * Renames this folder. 406 * 407 * @param newName the new name of the folder. 408 */ 409 public void rename(String newName) { 410 URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 411 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 412 413 JsonObject updateInfo = new JsonObject(); 414 updateInfo.add("name", newName); 415 416 request.setBody(updateInfo.toString()); 417 BoxJSONResponse response = (BoxJSONResponse) request.send(); 418 response.getJSON(); 419 } 420 421 /** 422 * Checks if the file can be successfully uploaded by using the preflight check. 423 * 424 * @param name the name to give the uploaded file. 425 * @param fileSize the size of the file used for account capacity calculations. 426 */ 427 public void canUpload(String name, long fileSize) { 428 URL url = UPLOAD_FILE_URL.build(this.getAPI().getBaseURL()); 429 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "OPTIONS"); 430 431 JsonObject parent = new JsonObject(); 432 parent.add("id", this.getID()); 433 434 JsonObject preflightInfo = new JsonObject(); 435 preflightInfo.add("parent", parent); 436 preflightInfo.add("name", name); 437 438 preflightInfo.add("size", fileSize); 439 440 request.setBody(preflightInfo.toString()); 441 BoxAPIResponse response = request.send(); 442 response.disconnect(); 443 } 444 445 /** 446 * Uploads a new file to this folder. 447 * 448 * @param fileContent a stream containing the contents of the file to upload. 449 * @param name the name to give the uploaded file. 450 * @return the uploaded file's info. 451 */ 452 public BoxFile.Info uploadFile(InputStream fileContent, String name) { 453 FileUploadParams uploadInfo = new FileUploadParams() 454 .setContent(fileContent) 455 .setName(name); 456 return this.uploadFile(uploadInfo); 457 } 458 459 /** 460 * Uploads a new file to this folder. 461 * 462 * @param callback the callback which allows file content to be written on output stream. 463 * @param name the name to give the uploaded file. 464 * @return the uploaded file's info. 465 */ 466 public BoxFile.Info uploadFile(UploadFileCallback callback, String name) { 467 FileUploadParams uploadInfo = new FileUploadParams() 468 .setUploadFileCallback(callback) 469 .setName(name); 470 return this.uploadFile(uploadInfo); 471 } 472 473 /** 474 * Uploads a new file to this folder while reporting the progress to a ProgressListener. 475 * 476 * @param fileContent a stream containing the contents of the file to upload. 477 * @param name the name to give the uploaded file. 478 * @param fileSize the size of the file used for determining the progress of the upload. 479 * @param listener a listener for monitoring the upload's progress. 480 * @return the uploaded file's info. 481 */ 482 public BoxFile.Info uploadFile(InputStream fileContent, String name, long fileSize, ProgressListener listener) { 483 FileUploadParams uploadInfo = new FileUploadParams() 484 .setContent(fileContent) 485 .setName(name) 486 .setSize(fileSize) 487 .setProgressListener(listener); 488 return this.uploadFile(uploadInfo); 489 } 490 491 /** 492 * Uploads a new file to this folder with a specified file description. 493 * 494 * @param fileContent a stream containing the contents of the file to upload. 495 * @param name the name to give the uploaded file. 496 * @param description the description to give the uploaded file. 497 * @return the uploaded file's info. 498 */ 499 public BoxFile.Info uploadFile(InputStream fileContent, String name, String description) { 500 FileUploadParams uploadInfo = new FileUploadParams() 501 .setContent(fileContent) 502 .setName(name) 503 .setDescription(description); 504 return this.uploadFile(uploadInfo); 505 } 506 507 /** 508 * Uploads a new file to this folder with custom upload parameters. 509 * 510 * @param uploadParams the custom upload parameters. 511 * @return the uploaded file's info. 512 */ 513 public BoxFile.Info uploadFile(FileUploadParams uploadParams) { 514 URL uploadURL = UPLOAD_FILE_URL.build(this.getAPI().getBaseUploadURL()); 515 BoxMultipartRequest request = new BoxMultipartRequest(getAPI(), uploadURL); 516 517 JsonObject fieldJSON = new JsonObject(); 518 JsonObject parentIdJSON = new JsonObject(); 519 parentIdJSON.add("id", getID()); 520 fieldJSON.add("name", uploadParams.getName()); 521 fieldJSON.add("parent", parentIdJSON); 522 523 if (uploadParams.getCreated() != null) { 524 fieldJSON.add("content_created_at", BoxDateFormat.format(uploadParams.getCreated())); 525 } 526 527 if (uploadParams.getModified() != null) { 528 fieldJSON.add("content_modified_at", BoxDateFormat.format(uploadParams.getModified())); 529 } 530 531 if (uploadParams.getSHA1() != null && !uploadParams.getSHA1().isEmpty()) { 532 request.setContentSHA1(uploadParams.getSHA1()); 533 } 534 535 if (uploadParams.getDescription() != null) { 536 fieldJSON.add("description", uploadParams.getDescription()); 537 } 538 539 request.putField("attributes", fieldJSON.toString()); 540 541 if (uploadParams.getSize() > 0) { 542 request.setFile(uploadParams.getContent(), uploadParams.getName(), uploadParams.getSize()); 543 } else if (uploadParams.getContent() != null) { 544 request.setFile(uploadParams.getContent(), uploadParams.getName()); 545 } else { 546 request.setUploadFileCallback(uploadParams.getUploadFileCallback(), uploadParams.getName()); 547 } 548 549 BoxJSONResponse response; 550 if (uploadParams.getProgressListener() == null) { 551 response = (BoxJSONResponse) request.send(); 552 } else { 553 response = (BoxJSONResponse) request.send(uploadParams.getProgressListener()); 554 } 555 JsonObject collection = JsonObject.readFrom(response.getJSON()); 556 JsonArray entries = collection.get("entries").asArray(); 557 JsonObject fileInfoJSON = entries.get(0).asObject(); 558 String uploadedFileID = fileInfoJSON.get("id").asString(); 559 560 BoxFile uploadedFile = new BoxFile(getAPI(), uploadedFileID); 561 return uploadedFile.new Info(fileInfoJSON); 562 } 563 564 /** 565 * Uploads a new weblink to this folder. 566 * 567 * @param linkURL the URL the weblink points to. 568 * @return the uploaded weblink's info. 569 */ 570 public BoxWebLink.Info createWebLink(URL linkURL) { 571 return this.createWebLink(null, linkURL, 572 null); 573 } 574 575 /** 576 * Uploads a new weblink to this folder. 577 * 578 * @param name the filename for the weblink. 579 * @param linkURL the URL the weblink points to. 580 * @return the uploaded weblink's info. 581 */ 582 public BoxWebLink.Info createWebLink(String name, URL linkURL) { 583 return this.createWebLink(name, linkURL, 584 null); 585 } 586 587 /** 588 * Uploads a new weblink to this folder. 589 * 590 * @param linkURL the URL the weblink points to. 591 * @param description the weblink's description. 592 * @return the uploaded weblink's info. 593 */ 594 public BoxWebLink.Info createWebLink(URL linkURL, String description) { 595 return this.createWebLink(null, linkURL, description); 596 } 597 598 /** 599 * Uploads a new weblink to this folder. 600 * 601 * @param name the filename for the weblink. 602 * @param linkURL the URL the weblink points to. 603 * @param description the weblink's description. 604 * @return the uploaded weblink's info. 605 */ 606 public BoxWebLink.Info createWebLink(String name, URL linkURL, String description) { 607 JsonObject parent = new JsonObject(); 608 parent.add("id", this.getID()); 609 610 JsonObject newWebLink = new JsonObject(); 611 newWebLink.add("name", name); 612 newWebLink.add("parent", parent); 613 newWebLink.add("url", linkURL.toString()); 614 615 if (description != null) { 616 newWebLink.add("description", description); 617 } 618 619 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), 620 CREATE_WEB_LINK_URL.build(this.getAPI().getBaseURL()), "POST"); 621 request.setBody(newWebLink.toString()); 622 BoxJSONResponse response = (BoxJSONResponse) request.send(); 623 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 624 625 BoxWebLink createdWebLink = new BoxWebLink(this.getAPI(), responseJSON.get("id").asString()); 626 return createdWebLink.new Info(responseJSON); 627 } 628 629 /** 630 * Returns an iterable containing the items in this folder. Iterating over the iterable returned by this method is 631 * equivalent to iterating over this BoxFolder directly. 632 * 633 * @return an iterable containing the items in this folder. 634 */ 635 public Iterable<BoxItem.Info> getChildren() { 636 return this; 637 } 638 639 /** 640 * Returns an iterable containing the items in this folder and specifies which child fields to retrieve from the 641 * API. 642 * 643 * @param fields the fields to retrieve. 644 * @return an iterable containing the items in this folder. 645 */ 646 public Iterable<BoxItem.Info> getChildren(final String... fields) { 647 return new Iterable<BoxItem.Info>() { 648 @Override 649 public Iterator<BoxItem.Info> iterator() { 650 String queryString = new QueryStringBuilder().appendParam("fields", fields).toString(); 651 URL url = GET_ITEMS_URL.buildWithQuery(getAPI().getBaseURL(), queryString, getID()); 652 return new BoxItemIterator(getAPI(), url); 653 } 654 }; 655 } 656 657 /** 658 * Returns an iterable containing the items in this folder sorted by name and direction. 659 * @param sort the field to sort by, can be set as `name`, `id`, and `date`. 660 * @param direction the direction to display the item results. 661 * @param fields the fields to retrieve. 662 * @return an iterable containing the items in this folder. 663 */ 664 public Iterable<BoxItem.Info> getChildren(String sort, SortDirection direction, final String... fields) { 665 QueryStringBuilder builder = new QueryStringBuilder() 666 .appendParam("sort", sort) 667 .appendParam("direction", direction.toString()); 668 669 if (fields.length > 0) { 670 builder.appendParam("fields", fields).toString(); 671 } 672 final String query = builder.toString(); 673 return new Iterable<BoxItem.Info>() { 674 @Override 675 public Iterator<BoxItem.Info> iterator() { 676 URL url = GET_ITEMS_URL.buildWithQuery(getAPI().getBaseURL(), query, getID()); 677 return new BoxItemIterator(getAPI(), url); 678 } 679 }; 680 } 681 682 /** 683 * Retrieves a specific range of child items in this folder. 684 * 685 * @param offset the index of the first child item to retrieve. 686 * @param limit the maximum number of children to retrieve after the offset. 687 * @param fields the fields to retrieve. 688 * @return a partial collection containing the specified range of child items. 689 */ 690 public PartialCollection<BoxItem.Info> getChildrenRange(long offset, long limit, String... fields) { 691 QueryStringBuilder builder = new QueryStringBuilder() 692 .appendParam("limit", limit) 693 .appendParam("offset", offset); 694 695 if (fields.length > 0) { 696 builder.appendParam("fields", fields).toString(); 697 } 698 699 URL url = GET_ITEMS_URL.buildWithQuery(getAPI().getBaseURL(), builder.toString(), getID()); 700 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 701 BoxJSONResponse response = (BoxJSONResponse) request.send(); 702 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 703 704 String totalCountString = responseJSON.get("total_count").toString(); 705 long fullSize = Double.valueOf(totalCountString).longValue(); 706 PartialCollection<BoxItem.Info> children = new PartialCollection<BoxItem.Info>(offset, limit, fullSize); 707 JsonArray jsonArray = responseJSON.get("entries").asArray(); 708 for (JsonValue value : jsonArray) { 709 JsonObject jsonObject = value.asObject(); 710 BoxItem.Info parsedItemInfo = (BoxItem.Info) BoxResource.parseInfo(this.getAPI(), jsonObject); 711 if (parsedItemInfo != null) { 712 children.add(parsedItemInfo); 713 } 714 } 715 return children; 716 } 717 718 /** 719 * Returns an iterator over the items in this folder. 720 * 721 * @return an iterator over the items in this folder. 722 */ 723 @Override 724 public Iterator<BoxItem.Info> iterator() { 725 URL url = GET_ITEMS_URL.build(this.getAPI().getBaseURL(), BoxFolder.this.getID()); 726 return new BoxItemIterator(BoxFolder.this.getAPI(), url); 727 } 728 729 /** 730 * Adds new {@link BoxWebHook} to this {@link BoxFolder}. 731 * 732 * @param address {@link BoxWebHook.Info#getAddress()} 733 * @param triggers {@link BoxWebHook.Info#getTriggers()} 734 * @return created {@link BoxWebHook.Info} 735 */ 736 public BoxWebHook.Info addWebHook(URL address, BoxWebHook.Trigger... triggers) { 737 return BoxWebHook.create(this, address, triggers); 738 } 739 740 /** 741 * Used to retrieve the watermark for the folder. 742 * If the folder does not have a watermark applied to it, a 404 Not Found will be returned by API. 743 * 744 * @param fields the fields to retrieve. 745 * @return the watermark associated with the folder. 746 */ 747 public BoxWatermark getWatermark(String... fields) { 748 return this.getWatermark(FOLDER_INFO_URL_TEMPLATE, fields); 749 } 750 751 /** 752 * Used to apply or update the watermark for the folder. 753 * 754 * @return the watermark associated with the folder. 755 */ 756 public BoxWatermark applyWatermark() { 757 return this.applyWatermark(FOLDER_INFO_URL_TEMPLATE, BoxWatermark.WATERMARK_DEFAULT_IMPRINT); 758 } 759 760 /** 761 * Removes a watermark from the folder. 762 * If the folder did not have a watermark applied to it, a 404 Not Found will be returned by API. 763 */ 764 public void removeWatermark() { 765 this.removeWatermark(FOLDER_INFO_URL_TEMPLATE); 766 } 767 768 /** 769 * Used to retrieve all metadata associated with the folder. 770 * 771 * @param fields the optional fields to retrieve. 772 * @return An iterable of metadata instances associated with the folder 773 */ 774 public Iterable<Metadata> getAllMetadata(String... fields) { 775 return Metadata.getAllMetadata(this, fields); 776 } 777 778 /** 779 * This method is deprecated, please use the {@link BoxSearch} class instead. 780 * Searches this folder and all descendant folders using a given queryPlease use BoxSearch Instead. 781 * 782 * @param query the search query. 783 * @return an Iterable containing the search results. 784 */ 785 @Deprecated 786 public Iterable<BoxItem.Info> search(final String query) { 787 return new Iterable<BoxItem.Info>() { 788 @Override 789 public Iterator<BoxItem.Info> iterator() { 790 QueryStringBuilder builder = new QueryStringBuilder(); 791 builder.appendParam("query", query); 792 builder.appendParam("ancestor_folder_ids", getID()); 793 794 URL url = SEARCH_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(), builder.toString()); 795 return new BoxItemIterator(getAPI(), url); 796 } 797 }; 798 } 799 800 @Override 801 public BoxFolder.Info setCollections(BoxCollection... collections) { 802 JsonArray jsonArray = new JsonArray(); 803 for (BoxCollection collection : collections) { 804 JsonObject collectionJSON = new JsonObject(); 805 collectionJSON.add("id", collection.getID()); 806 jsonArray.add(collectionJSON); 807 } 808 JsonObject infoJSON = new JsonObject(); 809 infoJSON.add("collections", jsonArray); 810 811 String queryString = new QueryStringBuilder().appendParam("fields", ALL_FIELDS).toString(); 812 URL url = FOLDER_INFO_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID()); 813 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 814 request.setBody(infoJSON.toString()); 815 BoxJSONResponse response = (BoxJSONResponse) request.send(); 816 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 817 return new Info(jsonObject); 818 } 819 820 /** 821 * Creates global property metadata on this folder. 822 * 823 * @param metadata the new metadata values. 824 * @return the metadata returned from the server. 825 */ 826 public Metadata createMetadata(Metadata metadata) { 827 return this.createMetadata(Metadata.DEFAULT_METADATA_TYPE, metadata); 828 } 829 830 /** 831 * Creates metadata on this folder using a specified template. 832 * 833 * @param templateName the name of the metadata template. 834 * @param metadata the new metadata values. 835 * @return the metadata returned from the server. 836 */ 837 public Metadata createMetadata(String templateName, Metadata metadata) { 838 String scope = Metadata.scopeBasedOnType(templateName); 839 return this.createMetadata(templateName, scope, metadata); 840 } 841 842 /** 843 * Creates metadata on this folder using a specified scope and template. 844 * 845 * @param templateName the name of the metadata template. 846 * @param scope the scope of the template (usually "global" or "enterprise"). 847 * @param metadata the new metadata values. 848 * @return the metadata returned from the server. 849 */ 850 public Metadata createMetadata(String templateName, String scope, Metadata metadata) { 851 URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), scope, templateName); 852 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "POST"); 853 request.addHeader("Content-Type", "application/json"); 854 request.setBody(metadata.toString()); 855 BoxJSONResponse response = (BoxJSONResponse) request.send(); 856 return new Metadata(JsonObject.readFrom(response.getJSON())); 857 } 858 859 /** 860 * Gets the global properties metadata on this folder. 861 * 862 * @return the metadata returned from the server. 863 */ 864 public Metadata getMetadata() { 865 return this.getMetadata(Metadata.DEFAULT_METADATA_TYPE); 866 } 867 868 /** 869 * Gets the metadata on this folder associated with a specified template. 870 * 871 * @param templateName the metadata template type name. 872 * @return the metadata returned from the server. 873 */ 874 public Metadata getMetadata(String templateName) { 875 String scope = Metadata.scopeBasedOnType(templateName); 876 return this.getMetadata(templateName, scope); 877 } 878 879 /** 880 * Gets the metadata on this folder associated with a specified scope and template. 881 * 882 * @param templateName the metadata template type name. 883 * @param scope the scope of the template (usually "global" or "enterprise"). 884 * @return the metadata returned from the server. 885 */ 886 public Metadata getMetadata(String templateName, String scope) { 887 URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), scope, templateName); 888 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 889 BoxJSONResponse response = (BoxJSONResponse) request.send(); 890 return new Metadata(JsonObject.readFrom(response.getJSON())); 891 } 892 893 /** 894 * Updates the global properties metadata on this folder. 895 * 896 * @param metadata the new metadata values. 897 * @return the metadata returned from the server. 898 */ 899 public Metadata updateMetadata(Metadata metadata) { 900 URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), metadata.getScope(), 901 metadata.getTemplateName()); 902 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "PUT"); 903 request.addHeader("Content-Type", "application/json-patch+json"); 904 request.setBody(metadata.getPatch()); 905 BoxJSONResponse response = (BoxJSONResponse) request.send(); 906 return new Metadata(JsonObject.readFrom(response.getJSON())); 907 } 908 909 /** 910 * Deletes the global properties metadata on this folder. 911 */ 912 public void deleteMetadata() { 913 this.deleteMetadata(Metadata.DEFAULT_METADATA_TYPE); 914 } 915 916 /** 917 * Deletes the metadata on this folder associated with a specified template. 918 * 919 * @param templateName the metadata template type name. 920 */ 921 public void deleteMetadata(String templateName) { 922 String scope = Metadata.scopeBasedOnType(templateName); 923 this.deleteMetadata(templateName, scope); 924 } 925 926 /** 927 * Deletes the metadata on this folder associated with a specified scope and template. 928 * 929 * @param templateName the metadata template type name. 930 * @param scope the scope of the template (usually "global" or "enterprise"). 931 */ 932 public void deleteMetadata(String templateName, String scope) { 933 URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), scope, templateName); 934 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 935 BoxAPIResponse response = request.send(); 936 response.disconnect(); 937 } 938 939 /** 940 * Adds a metadata classification to the specified file. 941 * 942 * @param classificationType the metadata classification type. 943 * @return the metadata classification type added to the file. 944 */ 945 public String addClassification(String classificationType) { 946 Metadata metadata = new Metadata().add(Metadata.CLASSIFICATION_KEY, classificationType); 947 Metadata classification = this.createMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY, 948 "enterprise", metadata); 949 950 return classification.getString(Metadata.CLASSIFICATION_KEY); 951 } 952 953 /** 954 * Updates a metadata classification on the specified file. 955 * 956 * @param classificationType the metadata classification type. 957 * @return the new metadata classification type updated on the file. 958 */ 959 public String updateClassification(String classificationType) { 960 Metadata metadata = new Metadata("enterprise", Metadata.CLASSIFICATION_TEMPLATE_KEY); 961 metadata.replace(Metadata.CLASSIFICATION_KEY, classificationType); 962 Metadata classification = this.updateMetadata(metadata); 963 964 return classification.getString(Metadata.CLASSIFICATION_KEY); 965 } 966 967 /** 968 * Attempts to add classification to a file. If classification already exists then do update. 969 * 970 * @param classificationType the metadata classification type. 971 * @return the metadata classification type on the file. 972 */ 973 public String setClassification(String classificationType) { 974 Metadata metadata = new Metadata().add(Metadata.CLASSIFICATION_KEY, classificationType); 975 Metadata classification = null; 976 977 try { 978 classification = this.createMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY, "enterprise", metadata); 979 } catch (BoxAPIException e) { 980 if (e.getResponseCode() == 409) { 981 metadata = new Metadata("enterprise", Metadata.CLASSIFICATION_TEMPLATE_KEY); 982 metadata.replace(Metadata.CLASSIFICATION_KEY, classificationType); 983 classification = this.updateMetadata(metadata); 984 } else { 985 throw e; 986 } 987 } 988 989 return classification.getString("/Box__Security__Classification__Key"); 990 } 991 992 /** 993 * Gets the classification type for the specified file. 994 * 995 * @return the metadata classification type on the file. 996 */ 997 public String getClassification() { 998 Metadata metadata = this.getMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY); 999 return metadata.getString(Metadata.CLASSIFICATION_KEY); 1000 } 1001 1002 /** 1003 * Deletes the classification on the file. 1004 */ 1005 public void deleteClassification() { 1006 this.deleteMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY, "enterprise"); 1007 } 1008 1009 /** 1010 * Creates an upload session to create a new file in chunks. 1011 * This will first verify that the file can be created and then open a session for uploading pieces of the file. 1012 * 1013 * @param fileName the name of the file to be created 1014 * @param fileSize the size of the file that will be uploaded 1015 * @return the created upload session instance 1016 */ 1017 public BoxFileUploadSession.Info createUploadSession(String fileName, long fileSize) { 1018 1019 URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL()); 1020 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 1021 1022 JsonObject body = new JsonObject(); 1023 body.add("folder_id", this.getID()); 1024 body.add("file_name", fileName); 1025 body.add("file_size", fileSize); 1026 request.setBody(body.toString()); 1027 1028 BoxJSONResponse response = (BoxJSONResponse) request.send(); 1029 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 1030 1031 String sessionId = jsonObject.get("id").asString(); 1032 BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId); 1033 1034 return session.new Info(jsonObject); 1035 } 1036 1037 /** 1038 * Creates a new file. 1039 * 1040 * @param inputStream the stream instance that contains the data. 1041 * @param fileName the name of the file to be created. 1042 * @param fileSize the size of the file that will be uploaded. 1043 * @return the created file instance. 1044 * @throws InterruptedException when a thread execution is interrupted. 1045 * @throws IOException when reading a stream throws exception. 1046 */ 1047 public BoxFile.Info uploadLargeFile(InputStream inputStream, String fileName, long fileSize) 1048 throws InterruptedException, IOException { 1049 URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL()); 1050 return new LargeFileUpload(). 1051 upload(this.getAPI(), this.getID(), inputStream, url, fileName, fileSize); 1052 } 1053 1054 /** 1055 * Creates a new file using specified number of parallel http connections. 1056 * 1057 * @param inputStream the stream instance that contains the data. 1058 * @param fileName the name of the file to be created. 1059 * @param fileSize the size of the file that will be uploaded. 1060 * @param nParallelConnections number of parallel http connections to use 1061 * @param timeOut time to wait before killing the job 1062 * @param unit time unit for the time wait value 1063 * @return the created file instance. 1064 * @throws InterruptedException when a thread execution is interrupted. 1065 * @throws IOException when reading a stream throws exception. 1066 */ 1067 public BoxFile.Info uploadLargeFile(InputStream inputStream, String fileName, long fileSize, 1068 int nParallelConnections, long timeOut, TimeUnit unit) 1069 throws InterruptedException, IOException { 1070 URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL()); 1071 return new LargeFileUpload(nParallelConnections, timeOut, unit). 1072 upload(this.getAPI(), this.getID(), inputStream, url, fileName, fileSize); 1073 } 1074 1075 /** 1076 * Creates a new Metadata Cascade Policy on a folder. 1077 * 1078 * @param scope the scope of the metadata cascade policy. 1079 * @param templateKey the key of the template. 1080 * @return information about the Metadata Cascade Policy. 1081 */ 1082 public BoxMetadataCascadePolicy.Info addMetadataCascadePolicy(String scope, String templateKey) { 1083 1084 return BoxMetadataCascadePolicy.create(this.getAPI(), this.getID(), scope, templateKey); 1085 } 1086 1087 /** 1088 * Retrieves all Metadata Cascade Policies on a folder. 1089 * 1090 * @param fields optional fields to retrieve for cascade policies. 1091 * @return the Iterable of Box Metadata Cascade Policies in your enterprise. 1092 */ 1093 public Iterable<BoxMetadataCascadePolicy.Info> getMetadataCascadePolicies(String... fields) { 1094 Iterable<BoxMetadataCascadePolicy.Info> cascadePoliciesInfo = 1095 BoxMetadataCascadePolicy.getAll(this.getAPI(), this.getID(), fields); 1096 1097 return cascadePoliciesInfo; 1098 } 1099 1100 /** 1101 * Retrieves all Metadata Cascade Policies on a folder. 1102 * 1103 * @param enterpriseID the ID of the enterprise to retrieve cascade policies for. 1104 * @param limit the number of entries of cascade policies to retrieve. 1105 * @param fields optional fields to retrieve for cascade policies. 1106 * @return the Iterable of Box Metadata Cascade Policies in your enterprise. 1107 */ 1108 public Iterable<BoxMetadataCascadePolicy.Info> getMetadataCascadePolicies(String enterpriseID, 1109 int limit, String... fields) { 1110 Iterable<BoxMetadataCascadePolicy.Info> cascadePoliciesInfo = 1111 BoxMetadataCascadePolicy.getAll(this.getAPI(), this.getID(), enterpriseID, limit, fields); 1112 1113 return cascadePoliciesInfo; 1114 } 1115 1116 /** 1117 * Contains information about a BoxFolder. 1118 */ 1119 public class Info extends BoxItem.Info { 1120 private BoxUploadEmail uploadEmail; 1121 private boolean hasCollaborations; 1122 private SyncState syncState; 1123 private EnumSet<Permission> permissions; 1124 private boolean canNonOwnersInvite; 1125 private boolean isWatermarked; 1126 private boolean isCollaborationRestrictedToEnterprise; 1127 private Map<String, Map<String, Metadata>> metadataMap; 1128 1129 /** 1130 * Constructs an empty Info object. 1131 */ 1132 public Info() { 1133 super(); 1134 } 1135 1136 /** 1137 * Constructs an Info object by parsing information from a JSON string. 1138 * 1139 * @param json the JSON string to parse. 1140 */ 1141 public Info(String json) { 1142 super(json); 1143 } 1144 1145 /** 1146 * Constructs an Info object using an already parsed JSON object. 1147 * 1148 * @param jsonObject the parsed JSON object. 1149 */ 1150 public Info(JsonObject jsonObject) { 1151 super(jsonObject); 1152 } 1153 1154 /** 1155 * Gets the upload email for the folder. 1156 * 1157 * @return the upload email for the folder. 1158 */ 1159 public BoxUploadEmail getUploadEmail() { 1160 return this.uploadEmail; 1161 } 1162 1163 /** 1164 * Sets the upload email for the folder. 1165 * 1166 * @param uploadEmail the upload email for the folder. 1167 */ 1168 public void setUploadEmail(BoxUploadEmail uploadEmail) { 1169 if (this.uploadEmail == uploadEmail) { 1170 return; 1171 } 1172 1173 this.removeChildObject("folder_upload_email"); 1174 this.uploadEmail = uploadEmail; 1175 1176 if (uploadEmail == null) { 1177 this.addPendingChange("folder_upload_email", (String) null); 1178 } else { 1179 this.addChildObject("folder_upload_email", uploadEmail); 1180 } 1181 } 1182 1183 /** 1184 * Gets whether or not the folder has any collaborations. 1185 * 1186 * @return true if the folder has collaborations; otherwise false. 1187 */ 1188 public boolean getHasCollaborations() { 1189 return this.hasCollaborations; 1190 } 1191 1192 /** 1193 * Gets the sync state of the folder. 1194 * 1195 * @return the sync state of the folder. 1196 */ 1197 public SyncState getSyncState() { 1198 return this.syncState; 1199 } 1200 1201 /** 1202 * Sets the sync state of the folder. 1203 * 1204 * @param syncState the sync state of the folder. 1205 */ 1206 public void setSyncState(SyncState syncState) { 1207 this.syncState = syncState; 1208 this.addPendingChange("sync_state", syncState.toJSONValue()); 1209 } 1210 1211 /** 1212 * Gets the permissions that the current user has on the folder. 1213 * 1214 * @return the permissions that the current user has on the folder. 1215 */ 1216 public EnumSet<Permission> getPermissions() { 1217 return this.permissions; 1218 } 1219 1220 /** 1221 * Gets whether or not the non-owners can invite collaborators to the folder. 1222 * 1223 * @return [description] 1224 */ 1225 public boolean getCanNonOwnersInvite() { 1226 return this.canNonOwnersInvite; 1227 } 1228 1229 /** 1230 * Gets whether future collaborations should be restricted to within the enterprise only. 1231 * 1232 * @return indicates whether collaboration is restricted to enterprise only. 1233 */ 1234 public boolean getIsCollaborationRestrictedToEnterprise() { 1235 return this.isCollaborationRestrictedToEnterprise; 1236 } 1237 1238 /** 1239 * Sets whether future collaborations should be restricted to within the enterprise only. 1240 * 1241 * @param isRestricted indicates whether there is collaboration restriction within enterprise. 1242 */ 1243 public void setIsCollaborationRestrictedToEnterprise(boolean isRestricted) { 1244 this.isCollaborationRestrictedToEnterprise = isRestricted; 1245 this.addPendingChange("is_collaboration_restricted_to_enterprise", isRestricted); 1246 } 1247 1248 /** 1249 * Gets flag indicating whether this file is Watermarked. 1250 * 1251 * @return whether the file is watermarked or not 1252 */ 1253 public boolean getIsWatermarked() { 1254 return this.isWatermarked; 1255 } 1256 1257 /** 1258 * Gets the metadata on this folder associated with a specified scope and template. 1259 * Makes an attempt to get metadata that was retrieved using getInfo(String ...) method. If no result is found 1260 * then makes an API call to get metadata 1261 * 1262 * @param templateName the metadata template type name. 1263 * @param scope the scope of the template (usually "global" or "enterprise"). 1264 * @return the metadata returned from the server. 1265 */ 1266 public Metadata getMetadata(String templateName, String scope) { 1267 try { 1268 return this.metadataMap.get(scope).get(templateName); 1269 } catch (NullPointerException e) { 1270 return null; 1271 } 1272 } 1273 1274 @Override 1275 public BoxFolder getResource() { 1276 return BoxFolder.this; 1277 } 1278 1279 @Override 1280 protected void parseJSONMember(JsonObject.Member member) { 1281 super.parseJSONMember(member); 1282 1283 String memberName = member.getName(); 1284 JsonValue value = member.getValue(); 1285 if (memberName.equals("folder_upload_email")) { 1286 if (this.uploadEmail == null) { 1287 this.uploadEmail = new BoxUploadEmail(value.asObject()); 1288 } else { 1289 this.uploadEmail.update(value.asObject()); 1290 } 1291 1292 } else if (memberName.equals("has_collaborations")) { 1293 this.hasCollaborations = value.asBoolean(); 1294 1295 } else if (memberName.equals("sync_state")) { 1296 this.syncState = SyncState.fromJSONValue(value.asString()); 1297 1298 } else if (memberName.equals("permissions")) { 1299 this.permissions = this.parsePermissions(value.asObject()); 1300 1301 } else if (memberName.equals("can_non_owners_invite")) { 1302 this.canNonOwnersInvite = value.asBoolean(); 1303 } else if (memberName.equals("is_collaboration_restricted_to_enterprise")) { 1304 this.isCollaborationRestrictedToEnterprise = value.asBoolean(); 1305 1306 } else if (memberName.equals("watermark_info")) { 1307 JsonObject jsonObject = value.asObject(); 1308 this.isWatermarked = jsonObject.get("is_watermarked").asBoolean(); 1309 } else if (memberName.equals("metadata")) { 1310 JsonObject jsonObject = value.asObject(); 1311 this.metadataMap = Parsers.parseAndPopulateMetadataMap(jsonObject); 1312 } 1313 } 1314 1315 private EnumSet<Permission> parsePermissions(JsonObject jsonObject) { 1316 EnumSet<Permission> permissions = EnumSet.noneOf(Permission.class); 1317 for (JsonObject.Member member : jsonObject) { 1318 JsonValue value = member.getValue(); 1319 if (value.isNull() || !value.asBoolean()) { 1320 continue; 1321 } 1322 1323 String memberName = member.getName(); 1324 if (memberName.equals("can_download")) { 1325 permissions.add(Permission.CAN_DOWNLOAD); 1326 } else if (memberName.equals("can_upload")) { 1327 permissions.add(Permission.CAN_UPLOAD); 1328 } else if (memberName.equals("can_rename")) { 1329 permissions.add(Permission.CAN_RENAME); 1330 } else if (memberName.equals("can_delete")) { 1331 permissions.add(Permission.CAN_DELETE); 1332 } else if (memberName.equals("can_share")) { 1333 permissions.add(Permission.CAN_SHARE); 1334 } else if (memberName.equals("can_invite_collaborator")) { 1335 permissions.add(Permission.CAN_INVITE_COLLABORATOR); 1336 } else if (memberName.equals("can_set_share_access")) { 1337 permissions.add(Permission.CAN_SET_SHARE_ACCESS); 1338 } 1339 } 1340 1341 return permissions; 1342 } 1343 } 1344 1345 /** 1346 * Enumerates the possible sync states that a folder can have. 1347 */ 1348 public enum SyncState { 1349 /** 1350 * The folder is synced. 1351 */ 1352 SYNCED("synced"), 1353 1354 /** 1355 * The folder is not synced. 1356 */ 1357 NOT_SYNCED("not_synced"), 1358 1359 /** 1360 * The folder is partially synced. 1361 */ 1362 PARTIALLY_SYNCED("partially_synced"); 1363 1364 private final String jsonValue; 1365 1366 private SyncState(String jsonValue) { 1367 this.jsonValue = jsonValue; 1368 } 1369 1370 static SyncState fromJSONValue(String jsonValue) { 1371 return SyncState.valueOf(jsonValue.toUpperCase()); 1372 } 1373 1374 String toJSONValue() { 1375 return this.jsonValue; 1376 } 1377 } 1378 1379 /** 1380 * Enumerates the possible permissions that a user can have on a folder. 1381 */ 1382 public enum Permission { 1383 /** 1384 * The user can download the folder. 1385 */ 1386 CAN_DOWNLOAD("can_download"), 1387 1388 /** 1389 * The user can upload to the folder. 1390 */ 1391 CAN_UPLOAD("can_upload"), 1392 1393 /** 1394 * The user can rename the folder. 1395 */ 1396 CAN_RENAME("can_rename"), 1397 1398 /** 1399 * The user can delete the folder. 1400 */ 1401 CAN_DELETE("can_delete"), 1402 1403 /** 1404 * The user can share the folder. 1405 */ 1406 CAN_SHARE("can_share"), 1407 1408 /** 1409 * The user can invite collaborators to the folder. 1410 */ 1411 CAN_INVITE_COLLABORATOR("can_invite_collaborator"), 1412 1413 /** 1414 * The user can set the access level for shared links to the folder. 1415 */ 1416 CAN_SET_SHARE_ACCESS("can_set_share_access"); 1417 1418 private final String jsonValue; 1419 1420 private Permission(String jsonValue) { 1421 this.jsonValue = jsonValue; 1422 } 1423 1424 static Permission fromJSONValue(String jsonValue) { 1425 return Permission.valueOf(jsonValue.toUpperCase()); 1426 } 1427 1428 String toJSONValue() { 1429 return this.jsonValue; 1430 } 1431 } 1432}