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 * Sets the provided metadata on the folder, overwriting any existing metadata keys already present. 861 * 862 * @param templateName the name of the metadata template. 863 * @param scope the scope of the template (usually "global" or "enterprise"). 864 * @param metadata the new metadata values. 865 * @return the metadata returned from the server. 866 */ 867 public Metadata setMetadata(String templateName, String scope, Metadata metadata) { 868 Metadata metadataValue = null; 869 870 try { 871 metadataValue = this.createMetadata(templateName, scope, metadata); 872 } catch (BoxAPIException e) { 873 if (e.getResponseCode() == 409) { 874 Metadata metadataToUpdate = new Metadata(scope, templateName); 875 for (JsonValue value : metadata.getOperations()) { 876 if (value.asObject().get("value").isNumber()) { 877 metadataToUpdate.add(value.asObject().get("path").asString(), 878 value.asObject().get("value").asFloat()); 879 } else if (value.asObject().get("value").isString()) { 880 metadataToUpdate.add(value.asObject().get("path").asString(), 881 value.asObject().get("value").asString()); 882 } else if (value.asObject().get("value").isArray()) { 883 ArrayList<String> list = new ArrayList<String>(); 884 for (JsonValue jsonValue : value.asObject().get("value").asArray()) { 885 list.add(jsonValue.asString()); 886 } 887 metadataToUpdate.add(value.asObject().get("path").asString(), list); 888 } 889 } 890 metadataValue = this.updateMetadata(metadataToUpdate); 891 } 892 } 893 894 return metadataValue; 895 } 896 897 /** 898 * Gets the global properties metadata on this folder. 899 * 900 * @return the metadata returned from the server. 901 */ 902 public Metadata getMetadata() { 903 return this.getMetadata(Metadata.DEFAULT_METADATA_TYPE); 904 } 905 906 /** 907 * Gets the metadata on this folder associated with a specified template. 908 * 909 * @param templateName the metadata template type name. 910 * @return the metadata returned from the server. 911 */ 912 public Metadata getMetadata(String templateName) { 913 String scope = Metadata.scopeBasedOnType(templateName); 914 return this.getMetadata(templateName, scope); 915 } 916 917 /** 918 * Gets the metadata on this folder associated with a specified scope and template. 919 * 920 * @param templateName the metadata template type name. 921 * @param scope the scope of the template (usually "global" or "enterprise"). 922 * @return the metadata returned from the server. 923 */ 924 public Metadata getMetadata(String templateName, String scope) { 925 URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), scope, templateName); 926 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 927 BoxJSONResponse response = (BoxJSONResponse) request.send(); 928 return new Metadata(JsonObject.readFrom(response.getJSON())); 929 } 930 931 /** 932 * Updates the global properties metadata on this folder. 933 * 934 * @param metadata the new metadata values. 935 * @return the metadata returned from the server. 936 */ 937 public Metadata updateMetadata(Metadata metadata) { 938 URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), metadata.getScope(), 939 metadata.getTemplateName()); 940 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "PUT"); 941 request.addHeader("Content-Type", "application/json-patch+json"); 942 request.setBody(metadata.getPatch()); 943 BoxJSONResponse response = (BoxJSONResponse) request.send(); 944 return new Metadata(JsonObject.readFrom(response.getJSON())); 945 } 946 947 /** 948 * Deletes the global properties metadata on this folder. 949 */ 950 public void deleteMetadata() { 951 this.deleteMetadata(Metadata.DEFAULT_METADATA_TYPE); 952 } 953 954 /** 955 * Deletes the metadata on this folder associated with a specified template. 956 * 957 * @param templateName the metadata template type name. 958 */ 959 public void deleteMetadata(String templateName) { 960 String scope = Metadata.scopeBasedOnType(templateName); 961 this.deleteMetadata(templateName, scope); 962 } 963 964 /** 965 * Deletes the metadata on this folder associated with a specified scope and template. 966 * 967 * @param templateName the metadata template type name. 968 * @param scope the scope of the template (usually "global" or "enterprise"). 969 */ 970 public void deleteMetadata(String templateName, String scope) { 971 URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), scope, templateName); 972 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 973 BoxAPIResponse response = request.send(); 974 response.disconnect(); 975 } 976 977 /** 978 * Adds a metadata classification to the specified file. 979 * 980 * @param classificationType the metadata classification type. 981 * @return the metadata classification type added to the file. 982 */ 983 public String addClassification(String classificationType) { 984 Metadata metadata = new Metadata().add(Metadata.CLASSIFICATION_KEY, classificationType); 985 Metadata classification = this.createMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY, 986 "enterprise", metadata); 987 988 return classification.getString(Metadata.CLASSIFICATION_KEY); 989 } 990 991 /** 992 * Updates a metadata classification on the specified file. 993 * 994 * @param classificationType the metadata classification type. 995 * @return the new metadata classification type updated on the file. 996 */ 997 public String updateClassification(String classificationType) { 998 Metadata metadata = new Metadata("enterprise", Metadata.CLASSIFICATION_TEMPLATE_KEY); 999 metadata.replace(Metadata.CLASSIFICATION_KEY, classificationType); 1000 Metadata classification = this.updateMetadata(metadata); 1001 1002 return classification.getString(Metadata.CLASSIFICATION_KEY); 1003 } 1004 1005 /** 1006 * Attempts to add classification to a file. If classification already exists then do update. 1007 * 1008 * @param classificationType the metadata classification type. 1009 * @return the metadata classification type on the file. 1010 */ 1011 public String setClassification(String classificationType) { 1012 Metadata metadata = new Metadata().add(Metadata.CLASSIFICATION_KEY, classificationType); 1013 Metadata classification = null; 1014 1015 try { 1016 classification = this.createMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY, "enterprise", metadata); 1017 } catch (BoxAPIException e) { 1018 if (e.getResponseCode() == 409) { 1019 metadata = new Metadata("enterprise", Metadata.CLASSIFICATION_TEMPLATE_KEY); 1020 metadata.replace(Metadata.CLASSIFICATION_KEY, classificationType); 1021 classification = this.updateMetadata(metadata); 1022 } else { 1023 throw e; 1024 } 1025 } 1026 1027 return classification.getString("/Box__Security__Classification__Key"); 1028 } 1029 1030 /** 1031 * Gets the classification type for the specified file. 1032 * 1033 * @return the metadata classification type on the file. 1034 */ 1035 public String getClassification() { 1036 Metadata metadata = this.getMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY); 1037 return metadata.getString(Metadata.CLASSIFICATION_KEY); 1038 } 1039 1040 /** 1041 * Deletes the classification on the file. 1042 */ 1043 public void deleteClassification() { 1044 this.deleteMetadata(Metadata.CLASSIFICATION_TEMPLATE_KEY, "enterprise"); 1045 } 1046 1047 /** 1048 * Creates an upload session to create a new file in chunks. 1049 * This will first verify that the file can be created and then open a session for uploading pieces of the file. 1050 * 1051 * @param fileName the name of the file to be created 1052 * @param fileSize the size of the file that will be uploaded 1053 * @return the created upload session instance 1054 */ 1055 public BoxFileUploadSession.Info createUploadSession(String fileName, long fileSize) { 1056 1057 URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL()); 1058 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 1059 1060 JsonObject body = new JsonObject(); 1061 body.add("folder_id", this.getID()); 1062 body.add("file_name", fileName); 1063 body.add("file_size", fileSize); 1064 request.setBody(body.toString()); 1065 1066 BoxJSONResponse response = (BoxJSONResponse) request.send(); 1067 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 1068 1069 String sessionId = jsonObject.get("id").asString(); 1070 BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId); 1071 1072 return session.new Info(jsonObject); 1073 } 1074 1075 /** 1076 * Creates a new file. 1077 * 1078 * @param inputStream the stream instance that contains the data. 1079 * @param fileName the name of the file to be created. 1080 * @param fileSize the size of the file that will be uploaded. 1081 * @return the created file instance. 1082 * @throws InterruptedException when a thread execution is interrupted. 1083 * @throws IOException when reading a stream throws exception. 1084 */ 1085 public BoxFile.Info uploadLargeFile(InputStream inputStream, String fileName, long fileSize) 1086 throws InterruptedException, IOException { 1087 URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL()); 1088 return new LargeFileUpload(). 1089 upload(this.getAPI(), this.getID(), inputStream, url, fileName, fileSize); 1090 } 1091 1092 /** 1093 * Creates a new file using specified number of parallel http connections. 1094 * 1095 * @param inputStream the stream instance that contains the data. 1096 * @param fileName the name of the file to be created. 1097 * @param fileSize the size of the file that will be uploaded. 1098 * @param nParallelConnections number of parallel http connections to use 1099 * @param timeOut time to wait before killing the job 1100 * @param unit time unit for the time wait value 1101 * @return the created file instance. 1102 * @throws InterruptedException when a thread execution is interrupted. 1103 * @throws IOException when reading a stream throws exception. 1104 */ 1105 public BoxFile.Info uploadLargeFile(InputStream inputStream, String fileName, long fileSize, 1106 int nParallelConnections, long timeOut, TimeUnit unit) 1107 throws InterruptedException, IOException { 1108 URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL()); 1109 return new LargeFileUpload(nParallelConnections, timeOut, unit). 1110 upload(this.getAPI(), this.getID(), inputStream, url, fileName, fileSize); 1111 } 1112 1113 /** 1114 * Creates a new Metadata Cascade Policy on a folder. 1115 * 1116 * @param scope the scope of the metadata cascade policy. 1117 * @param templateKey the key of the template. 1118 * @return information about the Metadata Cascade Policy. 1119 */ 1120 public BoxMetadataCascadePolicy.Info addMetadataCascadePolicy(String scope, String templateKey) { 1121 1122 return BoxMetadataCascadePolicy.create(this.getAPI(), this.getID(), scope, templateKey); 1123 } 1124 1125 /** 1126 * Retrieves all Metadata Cascade Policies on a folder. 1127 * 1128 * @param fields optional fields to retrieve for cascade policies. 1129 * @return the Iterable of Box Metadata Cascade Policies in your enterprise. 1130 */ 1131 public Iterable<BoxMetadataCascadePolicy.Info> getMetadataCascadePolicies(String... fields) { 1132 Iterable<BoxMetadataCascadePolicy.Info> cascadePoliciesInfo = 1133 BoxMetadataCascadePolicy.getAll(this.getAPI(), this.getID(), fields); 1134 1135 return cascadePoliciesInfo; 1136 } 1137 1138 /** 1139 * Retrieves all Metadata Cascade Policies on a folder. 1140 * 1141 * @param enterpriseID the ID of the enterprise to retrieve cascade policies for. 1142 * @param limit the number of entries of cascade policies to retrieve. 1143 * @param fields optional fields to retrieve for cascade policies. 1144 * @return the Iterable of Box Metadata Cascade Policies in your enterprise. 1145 */ 1146 public Iterable<BoxMetadataCascadePolicy.Info> getMetadataCascadePolicies(String enterpriseID, 1147 int limit, String... fields) { 1148 Iterable<BoxMetadataCascadePolicy.Info> cascadePoliciesInfo = 1149 BoxMetadataCascadePolicy.getAll(this.getAPI(), this.getID(), enterpriseID, limit, fields); 1150 1151 return cascadePoliciesInfo; 1152 } 1153 1154 /** 1155 * Contains information about a BoxFolder. 1156 */ 1157 public class Info extends BoxItem.Info { 1158 private BoxUploadEmail uploadEmail; 1159 private boolean hasCollaborations; 1160 private SyncState syncState; 1161 private EnumSet<Permission> permissions; 1162 private boolean canNonOwnersInvite; 1163 private boolean isWatermarked; 1164 private boolean isCollaborationRestrictedToEnterprise; 1165 private Boolean isExternallyOwned; 1166 private Map<String, Map<String, Metadata>> metadataMap; 1167 1168 /** 1169 * Constructs an empty Info object. 1170 */ 1171 public Info() { 1172 super(); 1173 } 1174 1175 /** 1176 * Constructs an Info object by parsing information from a JSON string. 1177 * 1178 * @param json the JSON string to parse. 1179 */ 1180 public Info(String json) { 1181 super(json); 1182 } 1183 1184 /** 1185 * Constructs an Info object using an already parsed JSON object. 1186 * 1187 * @param jsonObject the parsed JSON object. 1188 */ 1189 public Info(JsonObject jsonObject) { 1190 super(jsonObject); 1191 } 1192 1193 /** 1194 * Gets the upload email for the folder. 1195 * 1196 * @return the upload email for the folder. 1197 */ 1198 public BoxUploadEmail getUploadEmail() { 1199 return this.uploadEmail; 1200 } 1201 1202 /** 1203 * Sets the upload email for the folder. 1204 * 1205 * @param uploadEmail the upload email for the folder. 1206 */ 1207 public void setUploadEmail(BoxUploadEmail uploadEmail) { 1208 if (this.uploadEmail == uploadEmail) { 1209 return; 1210 } 1211 1212 this.removeChildObject("folder_upload_email"); 1213 this.uploadEmail = uploadEmail; 1214 1215 if (uploadEmail == null) { 1216 this.addPendingChange("folder_upload_email", (String) null); 1217 } else { 1218 this.addChildObject("folder_upload_email", uploadEmail); 1219 } 1220 } 1221 1222 /** 1223 * Gets whether or not the folder has any collaborations. 1224 * 1225 * @return true if the folder has collaborations; otherwise false. 1226 */ 1227 public boolean getHasCollaborations() { 1228 return this.hasCollaborations; 1229 } 1230 1231 /** 1232 * Gets the sync state of the folder. 1233 * 1234 * @return the sync state of the folder. 1235 */ 1236 public SyncState getSyncState() { 1237 return this.syncState; 1238 } 1239 1240 /** 1241 * Sets the sync state of the folder. 1242 * 1243 * @param syncState the sync state of the folder. 1244 */ 1245 public void setSyncState(SyncState syncState) { 1246 this.syncState = syncState; 1247 this.addPendingChange("sync_state", syncState.toJSONValue()); 1248 } 1249 1250 /** 1251 * Gets the permissions that the current user has on the folder. 1252 * 1253 * @return the permissions that the current user has on the folder. 1254 */ 1255 public EnumSet<Permission> getPermissions() { 1256 return this.permissions; 1257 } 1258 1259 /** 1260 * Gets whether or not the non-owners can invite collaborators to the folder. 1261 * 1262 * @return [description] 1263 */ 1264 public boolean getCanNonOwnersInvite() { 1265 return this.canNonOwnersInvite; 1266 } 1267 1268 /** 1269 * Sets whether or not non-owners can invite collaborators to the folder. 1270 * 1271 * @param canNonOwnersInvite indicates non-owners can invite collaborators to the folder. 1272 */ 1273 public void setCanNonOwnersInvite(boolean canNonOwnersInvite) { 1274 this.canNonOwnersInvite = canNonOwnersInvite; 1275 this.addPendingChange("can_non_owners_invite", canNonOwnersInvite); 1276 } 1277 1278 /** 1279 * Gets whether future collaborations should be restricted to within the enterprise only. 1280 * 1281 * @return indicates whether collaboration is restricted to enterprise only. 1282 */ 1283 public boolean getIsCollaborationRestrictedToEnterprise() { 1284 return this.isCollaborationRestrictedToEnterprise; 1285 } 1286 1287 /** 1288 * Sets whether future collaborations should be restricted to within the enterprise only. 1289 * 1290 * @param isRestricted indicates whether there is collaboration restriction within enterprise. 1291 */ 1292 public void setIsCollaborationRestrictedToEnterprise(boolean isRestricted) { 1293 this.isCollaborationRestrictedToEnterprise = isRestricted; 1294 this.addPendingChange("is_collaboration_restricted_to_enterprise", isRestricted); 1295 } 1296 1297 /** 1298 * Gets flag indicating whether this file is Watermarked. 1299 * 1300 * @return whether the file is watermarked or not 1301 */ 1302 public boolean getIsWatermarked() { 1303 return this.isWatermarked; 1304 } 1305 1306 /** 1307 * Gets the metadata on this folder associated with a specified scope and template. 1308 * Makes an attempt to get metadata that was retrieved using getInfo(String ...) method. If no result is found 1309 * then makes an API call to get metadata 1310 * 1311 * @param templateName the metadata template type name. 1312 * @param scope the scope of the template (usually "global" or "enterprise"). 1313 * @return the metadata returned from the server. 1314 */ 1315 public Metadata getMetadata(String templateName, String scope) { 1316 try { 1317 return this.metadataMap.get(scope).get(templateName); 1318 } catch (NullPointerException e) { 1319 return null; 1320 } 1321 } 1322 1323 /** 1324 * Get the field is_externally_owned determining whether this folder is owned by a user outside of the 1325 * enterprise. 1326 * @return a boolean indicating whether this folder is owned by a user outside the enterprise. 1327 */ 1328 public boolean getIsExternallyOwned() { 1329 return this.isExternallyOwned; 1330 } 1331 1332 @Override 1333 public BoxFolder getResource() { 1334 return BoxFolder.this; 1335 } 1336 1337 @Override 1338 protected void parseJSONMember(JsonObject.Member member) { 1339 super.parseJSONMember(member); 1340 1341 String memberName = member.getName(); 1342 JsonValue value = member.getValue(); 1343 if (memberName.equals("folder_upload_email")) { 1344 if (this.uploadEmail == null) { 1345 this.uploadEmail = new BoxUploadEmail(value.asObject()); 1346 } else { 1347 this.uploadEmail.update(value.asObject()); 1348 } 1349 1350 } else if (memberName.equals("has_collaborations")) { 1351 this.hasCollaborations = value.asBoolean(); 1352 1353 } else if (memberName.equals("sync_state")) { 1354 this.syncState = SyncState.fromJSONValue(value.asString()); 1355 1356 } else if (memberName.equals("permissions")) { 1357 this.permissions = this.parsePermissions(value.asObject()); 1358 1359 } else if (memberName.equals("can_non_owners_invite")) { 1360 this.canNonOwnersInvite = value.asBoolean(); 1361 } else if (memberName.equals("is_collaboration_restricted_to_enterprise")) { 1362 this.isCollaborationRestrictedToEnterprise = value.asBoolean(); 1363 } else if (memberName.equals("is_externally_owned")) { 1364 this.isExternallyOwned = value.asBoolean(); 1365 } else if (memberName.equals("watermark_info")) { 1366 JsonObject jsonObject = value.asObject(); 1367 this.isWatermarked = jsonObject.get("is_watermarked").asBoolean(); 1368 } else if (memberName.equals("metadata")) { 1369 JsonObject jsonObject = value.asObject(); 1370 this.metadataMap = Parsers.parseAndPopulateMetadataMap(jsonObject); 1371 } 1372 } 1373 1374 private EnumSet<Permission> parsePermissions(JsonObject jsonObject) { 1375 EnumSet<Permission> permissions = EnumSet.noneOf(Permission.class); 1376 for (JsonObject.Member member : jsonObject) { 1377 JsonValue value = member.getValue(); 1378 if (value.isNull() || !value.asBoolean()) { 1379 continue; 1380 } 1381 1382 String memberName = member.getName(); 1383 if (memberName.equals("can_download")) { 1384 permissions.add(Permission.CAN_DOWNLOAD); 1385 } else if (memberName.equals("can_upload")) { 1386 permissions.add(Permission.CAN_UPLOAD); 1387 } else if (memberName.equals("can_rename")) { 1388 permissions.add(Permission.CAN_RENAME); 1389 } else if (memberName.equals("can_delete")) { 1390 permissions.add(Permission.CAN_DELETE); 1391 } else if (memberName.equals("can_share")) { 1392 permissions.add(Permission.CAN_SHARE); 1393 } else if (memberName.equals("can_invite_collaborator")) { 1394 permissions.add(Permission.CAN_INVITE_COLLABORATOR); 1395 } else if (memberName.equals("can_set_share_access")) { 1396 permissions.add(Permission.CAN_SET_SHARE_ACCESS); 1397 } 1398 } 1399 1400 return permissions; 1401 } 1402 } 1403 1404 /** 1405 * Enumerates the possible sync states that a folder can have. 1406 */ 1407 public enum SyncState { 1408 /** 1409 * The folder is synced. 1410 */ 1411 SYNCED("synced"), 1412 1413 /** 1414 * The folder is not synced. 1415 */ 1416 NOT_SYNCED("not_synced"), 1417 1418 /** 1419 * The folder is partially synced. 1420 */ 1421 PARTIALLY_SYNCED("partially_synced"); 1422 1423 private final String jsonValue; 1424 1425 private SyncState(String jsonValue) { 1426 this.jsonValue = jsonValue; 1427 } 1428 1429 static SyncState fromJSONValue(String jsonValue) { 1430 return SyncState.valueOf(jsonValue.toUpperCase()); 1431 } 1432 1433 String toJSONValue() { 1434 return this.jsonValue; 1435 } 1436 } 1437 1438 /** 1439 * Enumerates the possible permissions that a user can have on a folder. 1440 */ 1441 public enum Permission { 1442 /** 1443 * The user can download the folder. 1444 */ 1445 CAN_DOWNLOAD("can_download"), 1446 1447 /** 1448 * The user can upload to the folder. 1449 */ 1450 CAN_UPLOAD("can_upload"), 1451 1452 /** 1453 * The user can rename the folder. 1454 */ 1455 CAN_RENAME("can_rename"), 1456 1457 /** 1458 * The user can delete the folder. 1459 */ 1460 CAN_DELETE("can_delete"), 1461 1462 /** 1463 * The user can share the folder. 1464 */ 1465 CAN_SHARE("can_share"), 1466 1467 /** 1468 * The user can invite collaborators to the folder. 1469 */ 1470 CAN_INVITE_COLLABORATOR("can_invite_collaborator"), 1471 1472 /** 1473 * The user can set the access level for shared links to the folder. 1474 */ 1475 CAN_SET_SHARE_ACCESS("can_set_share_access"); 1476 1477 private final String jsonValue; 1478 1479 private Permission(String jsonValue) { 1480 this.jsonValue = jsonValue; 1481 } 1482 1483 static Permission fromJSONValue(String jsonValue) { 1484 return Permission.valueOf(jsonValue.toUpperCase()); 1485 } 1486 1487 String toJSONValue() { 1488 return this.jsonValue; 1489 } 1490 } 1491}