From a954994935094b82a4f4b9752da030a5d35cdb7b Mon Sep 17 00:00:00 2001
From: Dor Fire
Date: Wed, 19 Oct 2016 10:25:18 +0300
Subject: [PATCH 001/119] Fixed #325
---
src/main/java/com/box/sdk/BoxSharedLink.java | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxSharedLink.java b/src/main/java/com/box/sdk/BoxSharedLink.java
index c031eca53..4a3075a3b 100644
--- a/src/main/java/com/box/sdk/BoxSharedLink.java
+++ b/src/main/java/com/box/sdk/BoxSharedLink.java
@@ -18,6 +18,7 @@ public class BoxSharedLink extends BoxJSONObject {
private long downloadCount;
private long previewCount;
private Access access;
+ private Access effectiveAccess;
private Permissions permissions;
/**
@@ -150,6 +151,11 @@ public void setPermissions(Permissions permissions) {
this.addChildObject("permissions", permissions);
}
+ private Access parseAccessValue(JsonValue value) {
+ String accessString = value.asString().toUpperCase();
+ return Access.valueOf(accessString);
+ }
+
@Override
void parseJSONMember(JsonObject.Member member) {
JsonValue value = member.getValue();
@@ -170,8 +176,9 @@ void parseJSONMember(JsonObject.Member member) {
} else if (memberName.equals("preview_count")) {
this.previewCount = Double.valueOf(value.toString()).longValue();
} else if (memberName.equals("access")) {
- String accessString = value.asString().toUpperCase();
- this.access = Access.valueOf(accessString);
+ this.access = parseAccessValue(value);
+ } else if (memberName.equals("effective_access")) {
+ this.effectiveAccess = parseAccessValue(value);
} else if (memberName.equals("permissions")) {
if (this.permissions == null) {
this.setPermissions(new Permissions(value.asObject()));
From 1d13ec6e544f3f3666bd5904de0339773f76d394 Mon Sep 17 00:00:00 2001
From: Dor Fire
Date: Wed, 19 Oct 2016 10:34:43 +0300
Subject: [PATCH 002/119] Fixed CheckStyle errors
---
src/main/java/com/box/sdk/BoxSharedLink.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxSharedLink.java b/src/main/java/com/box/sdk/BoxSharedLink.java
index 4a3075a3b..4c6b63894 100644
--- a/src/main/java/com/box/sdk/BoxSharedLink.java
+++ b/src/main/java/com/box/sdk/BoxSharedLink.java
@@ -176,9 +176,9 @@ void parseJSONMember(JsonObject.Member member) {
} else if (memberName.equals("preview_count")) {
this.previewCount = Double.valueOf(value.toString()).longValue();
} else if (memberName.equals("access")) {
- this.access = parseAccessValue(value);
+ this.access = this.parseAccessValue(value);
} else if (memberName.equals("effective_access")) {
- this.effectiveAccess = parseAccessValue(value);
+ this.effectiveAccess = this.parseAccessValue(value);
} else if (memberName.equals("permissions")) {
if (this.permissions == null) {
this.setPermissions(new Permissions(value.asObject()));
From 8a168599e070cd4cea20db56a63ccd44efc08bef Mon Sep 17 00:00:00 2001
From: Dor Fire
Date: Wed, 19 Oct 2016 11:11:07 +0300
Subject: [PATCH 003/119] Added a getter + setter for the new property
---
src/main/java/com/box/sdk/BoxSharedLink.java | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxSharedLink.java b/src/main/java/com/box/sdk/BoxSharedLink.java
index 4c6b63894..437efd23b 100644
--- a/src/main/java/com/box/sdk/BoxSharedLink.java
+++ b/src/main/java/com/box/sdk/BoxSharedLink.java
@@ -122,13 +122,30 @@ public Access getAccess() {
/**
* Sets the access level of this shared link.
- * @param access the new acccess level of this shared link.
+ * @param access the new access level of this shared link.
*/
public void setAccess(Access access) {
this.access = access;
this.addPendingChange("access", access.toJSONValue());
}
+ /**
+ * Gets the effective access level of this shared link.
+ * @return the effective access level of this shared link.
+ */
+ public Access getEffectiveAccess() {
+ return this.effectiveAccess;
+ }
+
+ /**
+ * Sets the effective access level of this shared link.
+ * @param access the new effective access level of this shared link.
+ */
+ public void setEffectiveAccess(Access access) {
+ this.effectiveAccess = access;
+ this.addPendingChange("access", access.toJSONValue());
+ }
+
/**
* Gets the permissions associated with this shared link.
* @return the permissions associated with this shared link.
From a5ca6b091cd61edeace23bbf62f506ab2d7a47ee Mon Sep 17 00:00:00 2001
From: Dor Fire
Date: Wed, 19 Oct 2016 11:32:15 +0300
Subject: [PATCH 004/119] Added a verification test
---
src/test/java/com/box/sdk/BoxFolderTest.java | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index 51ea9ec16..9e4697ef5 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -554,4 +554,21 @@ public void createWebLinkNoNameOrDescriptionSucceeds() throws MalformedURLExcept
createdWebLink.delete();
assertThat(rootFolder, not(hasItem(Matchers.hasProperty("ID", equalTo(createdWebLink.getID())))));
}
+
+ /**
+ * Verifies the fix for issue #325
+ */
+ @Test
+ @Category(IntegrationTest.class)
+ public void sharedLinkInfoHasEffectiveAccess() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ BoxFolder folder = rootFolder.createFolder("[sharedLinkInfoHasEffectiveAccess] Test Folder").getResource();
+ BoxSharedLink sharedLink = folder.createSharedLink(BoxSharedLink.Access.OPEN, null, null);
+
+ assertThat(sharedLink, Matchers.hasProperty("effectiveAccess"));
+ assertThat(sharedLink.getEffectiveAccess(), equalTo(BoxSharedLink.Access.OPEN));
+
+ folder.delete(true);
+ }
}
From 3bdab34d1e2a994d07660e74352b17175f387567 Mon Sep 17 00:00:00 2001
From: Dor Fire
Date: Thu, 20 Oct 2016 10:03:58 +0300
Subject: [PATCH 005/119] Added method BoxMultipartRequest.setContentSHA1
---
src/main/java/com/box/sdk/BoxMultipartRequest.java | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/main/java/com/box/sdk/BoxMultipartRequest.java b/src/main/java/com/box/sdk/BoxMultipartRequest.java
index e04ad9a95..fa5cdae0c 100644
--- a/src/main/java/com/box/sdk/BoxMultipartRequest.java
+++ b/src/main/java/com/box/sdk/BoxMultipartRequest.java
@@ -87,6 +87,15 @@ public void setFile(InputStream inputStream, String filename, long fileSize) {
this.fileSize = fileSize;
}
+ /**
+ * Sets the SHA1 hash of the file contents of this request.
+ * If set, it will ensure that the file is not corrupted in transit.
+ * @param sha1 a string containing the SHA1 hash of the file contents.
+ */
+ public void setContentSHA1(String sha1) {
+ this.addHeader("Content-MD5", sha1);
+ }
+
/**
* This method is unsupported in BoxMultipartRequest. Instead, the body should be modified via the {@code putField}
* and {@code setFile} methods.
From e64091ada36b724173ff600a5d64e27632785068 Mon Sep 17 00:00:00 2001
From: Dor Fire
Date: Thu, 20 Oct 2016 10:29:16 +0300
Subject: [PATCH 006/119] Added SHA1 parameter to BoxFile.uploadVersion
variants
---
src/main/java/com/box/sdk/BoxFile.java | 48 +++++++++++++++++++++-----
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index e28409185..986f16bef 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -447,31 +447,63 @@ public void uploadVersion(InputStream fileContent) {
/**
* Uploads a new version of this file, replacing the current version. Note that only users with premium accounts
* will be able to view and recover previous versions of the file.
- * @param fileContent a stream containing the new file contents.
- * @param modified the date that the new version was modified.
+ * @param fileContent a stream containing the new file contents.
+ * @param fileContentSHA1 a string containing the SHA1 hash of the new file contents.
+ *
+ */
+ public void uploadVersion(InputStream fileContent, String fileContentSHA1) {
+ this.uploadVersion(fileContent, null, null);
+ }
+
+ /**
+ * Uploads a new version of this file, replacing the current version. Note that only users with premium accounts
+ * will be able to view and recover previous versions of the file.
+ * @param fileContent a stream containing the new file contents.
+ * @param fileContentSHA1 a string containing the SHA1 hash of the new file contents.
+ * @param modified the date that the new version was modified.
*/
- public void uploadVersion(InputStream fileContent, Date modified) {
- this.uploadVersion(fileContent, modified, 0, null);
+ public void uploadVersion(InputStream fileContent, String fileContentSHA1, Date modified) {
+ this.uploadVersion(fileContent, fileContentSHA1, modified, 0, null);
}
/**
* Uploads a new version of this file, replacing the current version, while reporting the progress to a
* ProgressListener. Note that only users with premium accounts will be able to view and recover previous versions
* of the file.
- * @param fileContent a stream containing the new file contents.
- * @param modified the date that the new version was modified.
- * @param fileSize the size of the file used for determining the progress of the upload.
- * @param listener a listener for monitoring the upload's progress.
+ * @param fileContent a stream containing the new file contents.
+ * @param modified the date that the new version was modified.
+ * @param fileSize the size of the file used for determining the progress of the upload.
+ * @param listener a listener for monitoring the upload's progress.
*/
public void uploadVersion(InputStream fileContent, Date modified, long fileSize, ProgressListener listener) {
+ this.uploadVersion(fileContent, null, modified, fileSize, listener);
+ }
+
+ /**
+ * Uploads a new version of this file, replacing the current version, while reporting the progress to a
+ * ProgressListener. Note that only users with premium accounts will be able to view and recover previous versions
+ * of the file.
+ * @param fileContent a stream containing the new file contents.
+ * @param fileContentSHA1 the SHA1 hash of the file contents. will be sent along in the Content-MD5 header
+ * @param modified the date that the new version was modified.
+ * @param fileSize the size of the file used for determining the progress of the upload.
+ * @param listener a listener for monitoring the upload's progress.
+ */
+ public void uploadVersion(InputStream fileContent, String fileContentSHA1, Date modified, long fileSize,
+ ProgressListener listener) {
URL uploadURL = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseUploadURL(), this.getID());
BoxMultipartRequest request = new BoxMultipartRequest(getAPI(), uploadURL);
+
if (fileSize > 0) {
request.setFile(fileContent, "", fileSize);
} else {
request.setFile(fileContent, "");
}
+ if (fileContentSHA1 != null) {
+ request.setContentSHA1(fileContentSHA1);
+ }
+
if (modified != null) {
request.putField("content_modified_at", modified);
}
From bd58270ad3a785d5786606737d99467072971117 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Tue, 25 Oct 2016 14:13:54 +0200
Subject: [PATCH 007/119] paging and fields support implementation, tests and
javadocs for groups and memberships
---
doc/groups.md | 94 ++++-
src/main/java/com/box/sdk/BoxGroup.java | 101 ++++++
.../java/com/box/sdk/BoxGroupMembership.java | 51 +++
.../box/sdk/BoxGroupMembershipIterator.java | 35 +-
src/main/java/com/box/sdk/BoxUser.java | 20 ++
.../com/box/sdk/BoxGroupMembershipTest.java | 105 +++++-
src/test/java/com/box/sdk/BoxGroupTest.java | 335 +++++++++++++++++-
src/test/java/com/box/sdk/BoxUserTest.java | 119 +++++++
8 files changed, 851 insertions(+), 9 deletions(-)
diff --git a/doc/groups.md b/doc/groups.md
index b99f85bf3..9ae5857aa 100644
--- a/doc/groups.md
+++ b/doc/groups.md
@@ -7,6 +7,12 @@ Groups are sets of users that can be used in collaborations.
* [Create a Group](#create-a-group)
* [Delete a Group](#delete-a-group)
* [Get a Groups collaborations](#get-a-groups-collaborations)
+* [Create Membership](#create-membership)
+* [Get Membership](#get-membership)
+* [Update Membership](#update-membership)
+* [Delete Membership](#delete-membership)
+* [Get Memberships for Group](#get-memberships-for-group)
+* [Get Memberships for User](#get-memberships-for-user)
Get All Groups
--------------
@@ -50,11 +56,95 @@ group.delete();
Get a Groups collaborations
---------------------------
-A groups collaborations can be retrieved by calling the [`getCollaborations()`[get-collaborations] method.
+A groups collaborations can be retrieved by calling the [`getCollaborations()`][get-collaborations] method.
```java
BoxGroup group = new BoxGroup(api, "id");
group.getCollaborations();
```
-[get-collaborations]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#getCollaborations()
\ No newline at end of file
+[get-collaborations]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#getCollaborations()
+
+Create Membership
+---------------
+
+Membership for the group can be created by calling [`addMembership(BoxUser)`][add-membership] and [`addMembership(BoxUser, Role)`][add-membership2] methods.
+
+```java
+BoxGroup group = new BoxGroup(api, "groupID");
+BoxUser user = new BoxUser(api, "userID");
+BoxGroupMembership.Info groupMembershipInfo = group.addMembership(user);
+```
+
+[add-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#addMembership(com.box.sdk.BoxUser)
+[add-membership2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#addMembership(com.box.sdk.BoxUser,%20com.box.sdk.BoxGroupMembership.Role)
+
+Get Membership
+---------------
+
+A groups membership can be retrieved by calling the [`BoxGroupMembership.getInfo()`][get-membership] method.
+
+```java
+BoxGroupMembership membership = new BoxGroupMembership(api, id);
+BoxGroupMembership.Info groupMembershipInfo = membership.getInfo();
+```
+
+[get-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroupMembership.html#getInfo()
+
+Update Membership
+---------------
+
+A groups membership can be updated by calling the [`BoxGroupMembership.updateInfo(BoxGroupMembership.Info)`][update-membership] method.
+
+```java
+BoxGroupMembership membership = new BoxGroupMembership(api, id);
+BoxGroupMembership.Info info = membership.new Info();
+info.addPendingChange("role", role);
+membership.updateInfo(info);
+```
+
+[update-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroupMembership.html#updateInfo(com.box.sdk.BoxGroupMembership.Info)
+
+Delete Membership
+---------------
+
+A group can be deleted by calling the [`BoxGroupMembership.delete()`][delete-membership] method.
+
+```java
+BoxGroupMembership membership = new BoxGroupMembership(api, id);
+membership.delete();
+```
+
+[delete-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroupMembership.html#delete()
+
+Get Memberships for Group
+---------------
+
+Calling the [`getAllMemberships(String...)`][get-memberships-for-group] will return an iterable that will page through all of the group's memberships.
+Optional parameters can be used to retrieve specific fields of the Group Membership object.
+
+```java
+BoxGroup group = new BoxGroup(api, id);
+Iterable memberships = group.getAllMemberships();
+for (BoxGroupMembership.Info membershipInfo : memberships) {
+ // Do something with the membership.
+}
+```
+
+[get-memberships-for-group]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#getAllMemberships(java.lang.String...)
+
+Get Memberships for User
+---------------
+
+Calling the [`BoxUser.getAllMemberships(String...)`][get-memberships-for-user] will return an iterable that will page through all of the user's memberships.
+Optional parameters can be used to retrieve specific fields of the Group Membership object.
+
+```java
+BoxUser user = new BoxUser(api, id);
+Iterable memberships = user.getAllMemberships();
+for (BoxGroupMembership.Info membershipInfo : memberships) {
+ // Do something with the membership.
+}
+```
+
+[get-memberships-for-user]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#getAllMemberships(java.lang.String...)
\ No newline at end of file
diff --git a/src/main/java/com/box/sdk/BoxGroup.java b/src/main/java/com/box/sdk/BoxGroup.java
index 07f8e7cd9..2c447fd64 100644
--- a/src/main/java/com/box/sdk/BoxGroup.java
+++ b/src/main/java/com/box/sdk/BoxGroup.java
@@ -19,10 +19,30 @@
*/
@BoxResourceType("group")
public class BoxGroup extends BoxCollaborator {
+
+ /**
+ * @see #getAllGroups(BoxAPIConnection, String...)
+ */
private static final URLTemplate GROUPS_URL_TEMPLATE = new URLTemplate("groups");
+
+ /**
+ * @see #getInfo()
+ */
private static final URLTemplate GROUP_URL_TEMPLATE = new URLTemplate("groups/%s");
+
+ /**
+ * @see #getMemberships()
+ */
private static final URLTemplate MEMBERSHIPS_URL_TEMPLATE = new URLTemplate("groups/%s/memberships");
+
+ /**
+ * @see #addMembership(BoxUser)
+ */
private static final URLTemplate ADD_MEMBERSHIP_URL_TEMPLATE = new URLTemplate("group_memberships");
+
+ /**
+ * @see #getCollaborations()
+ */
private static final URLTemplate COLLABORATIONS_URL_TEMPLATE = new URLTemplate("groups/%s/collaborations");
/**
@@ -101,6 +121,25 @@ public Iterator iterator() {
};
}
+ /**
+ * Gets an iterable of all the groups in the enterprise.
+ * @param api the API connection to be used when retrieving the groups.
+ * @param fields the fields to retrieve.
+ * @return an iterable containing info about all the groups.
+ */
+ public static Iterable getAllGroups(final BoxAPIConnection api, String ... fields) {
+ final QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new Iterable() {
+ public Iterator iterator() {
+ URL url = GROUPS_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString());
+ return new BoxGroupIterator(api, url);
+ }
+ };
+ }
+
/**
* Gets information about this group.
* @return info about this group.
@@ -113,8 +152,26 @@ public Info getInfo() {
return new Info(responseJSON);
}
+ /**
+ * Gets information about this group.
+ * @param fields the fields to retrieve.
+ * @return info about this group.
+ */
+ public Info getInfo(String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = GROUP_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+ return new Info(responseJSON);
+ }
+
/**
* Gets information about all of the group memberships for this group.
+ * Does not support paging.
* @return a collection of information about the group memberships for this group.
*/
public Collection getMemberships() {
@@ -137,6 +194,25 @@ public Iterator iterator() {
return memberships;
}
+ /**
+ * Gets information about all of the group memberships for this group as iterable with paging support.
+ * @param fields the fields to retrieve.
+ * @return an iterable with information about the group memberships for this group.
+ */
+ public Iterable getAllMemberships(String ... fields) {
+ final QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new Iterable() {
+ public Iterator iterator() {
+ URL url = MEMBERSHIPS_URL_TEMPLATE.buildWithQuery(
+ BoxGroup.this.getAPI().getBaseURL(), builder.toString(), BoxGroup.this.getID());
+ return new BoxGroupMembershipIterator(BoxGroup.this.getAPI(), url);
+ }
+ };
+ }
+
/**
* Adds a member to this group with the default role.
* @param user the member to be added to this group.
@@ -212,10 +288,29 @@ public void delete() {
*/
public class Info extends BoxCollaborator.Info {
+ /**
+ * @see #getProvenance()
+ */
private String provenance;
+
+ /**
+ * @see #getExternalSyncIdentifier()
+ */
private String externalSyncIdentifier;
+
+ /**
+ * @see #getDescription()
+ */
private String description;
+
+ /**
+ * @see #getInvitabilityLevel()
+ */
private String invitabilityLevel;
+
+ /**
+ * @see #getMemberViewabilityLevel()
+ */
private String memberViewabilityLevel;
/**
@@ -241,11 +336,17 @@ public Info(String json) {
super(jsonObject);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public BoxGroup getResource() {
return BoxGroup.this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void parseJSONMember(JsonObject.Member member) {
super.parseJSONMember(member);
diff --git a/src/main/java/com/box/sdk/BoxGroupMembership.java b/src/main/java/com/box/sdk/BoxGroupMembership.java
index 2439a3d00..8d4781867 100644
--- a/src/main/java/com/box/sdk/BoxGroupMembership.java
+++ b/src/main/java/com/box/sdk/BoxGroupMembership.java
@@ -16,6 +16,11 @@
*/
@BoxResourceType("group_membership")
public class BoxGroupMembership extends BoxResource {
+
+ /**
+ * The URL template for all group membership requests.
+ * @see #getInfo()
+ */
private static final URLTemplate MEMBERSHIP_URL_TEMPLATE = new URLTemplate("group_memberships/%s");
/**
@@ -72,10 +77,30 @@ public void delete() {
* Contains information about a BoxGroupMembership.
*/
public class Info extends BoxResource.Info {
+
+ /**
+ * @see #getUser()
+ */
private BoxUser.Info user;
+
+ /**
+ * @see #getGroup()
+ */
private BoxGroup.Info group;
+
+ /**
+ * @see #getRole()
+ */
private Role role;
+
+ /**
+ * @see #getCreatedAt()
+ */
private Date createdAt;
+
+ /**
+ * @see #getModifiedAt()
+ */
private Date modifiedAt;
/**
@@ -157,11 +182,17 @@ public Date getModifiedAt() {
return this.modifiedAt;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public BoxGroupMembership getResource() {
return BoxGroupMembership.this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void parseJSONMember(JsonObject.Member member) {
super.parseJSONMember(member);
@@ -215,21 +246,41 @@ public enum Role {
*/
ADMIN ("admin"),
+ /**
+ * The user is a submaster in the group.
+ */
+ SUBMASTER ("submaster"),
+
/**
* The user is a regular member in the group.
*/
MEMBER ("member");
+ /**
+ * String representation of the role.
+ */
private final String jsonValue;
+ /**
+ * Constructor.
+ * @param jsonValue srting representation of the role.
+ */
private Role(String jsonValue) {
this.jsonValue = jsonValue;
}
+ /**
+ * Creates the role from given string.
+ * @param jsonValue string to be converted to role.
+ * @return the role, created from string value.
+ */
static Role fromJSONString(String jsonValue) {
return Role.valueOf(jsonValue.toUpperCase());
}
+ /**
+ * @return string representation of the role.
+ */
String toJSONString() {
return this.jsonValue;
}
diff --git a/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java b/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java
index 8fe077978..998b1f185 100644
--- a/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java
+++ b/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java
@@ -5,29 +5,58 @@
import com.eclipsesource.json.JsonObject;
+/**
+ * An iterator object for {@link BoxGroupMembership} object.
+ * Supports offset-based paging.
+ */
class BoxGroupMembershipIterator implements Iterator {
- private static final long LIMIT = 1000;
+ /**
+ * The limit of entries per response.
+ */
+ private static final long LIMIT = 100;
+
+ /**
+ * The API connection to be used.
+ */
private final BoxAPIConnection api;
+
+ /**
+ * Iterator object with paging support.
+ */
private final JSONIterator jsonIterator;
+ /**
+ * Creates new BoxGroupMembership iterator.
+ * @param api The API connection to be used by the iterator.
+ * @param url The endpoint url.
+ */
BoxGroupMembershipIterator(BoxAPIConnection api, URL url) {
this.api = api;
this.jsonIterator = new JSONIterator(api, url, LIMIT);
}
+ /**
+ * @return false if current element is the last.
+ */
public boolean hasNext() {
return this.jsonIterator.hasNext();
}
+ /**
+ * @return next BoxGroupMembeship object in the list.
+ */
public BoxGroupMembership.Info next() {
JsonObject nextJSONObject = this.jsonIterator.next();
String id = nextJSONObject.get("id").asString();
- BoxGroupMembership group = new BoxGroupMembership(this.api, id);
- return group.new Info(nextJSONObject);
+ BoxGroupMembership membership = new BoxGroupMembership(this.api, id);
+ return membership.new Info(nextJSONObject);
}
+ /**
+ * Remove operation is not supported.
+ */
public void remove() {
throw new UnsupportedOperationException();
}
diff --git a/src/main/java/com/box/sdk/BoxUser.java b/src/main/java/com/box/sdk/BoxUser.java
index 369b49a16..c5fa0f64d 100644
--- a/src/main/java/com/box/sdk/BoxUser.java
+++ b/src/main/java/com/box/sdk/BoxUser.java
@@ -247,6 +247,7 @@ public BoxUser.Info getInfo(String... fields) {
/**
* Gets information about all of the group memberships for this user.
+ * Does not support paging.
*
* Note: This method is only available to enterprise admins.
*
@@ -273,6 +274,25 @@ public Collection getMemberships() {
return memberships;
}
+ /**
+ * Gets information about all of the group memberships for this user as iterable with paging support.
+ * @param fields the fields to retrieve.
+ * @return an iterable with information about the group memberships for this user.
+ */
+ public Iterable getAllMemberships(String ... fields) {
+ final QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new Iterable() {
+ public Iterator iterator() {
+ URL url = USER_MEMBERSHIPS_URL_TEMPLATE.buildWithQuery(
+ BoxUser.this.getAPI().getBaseURL(), builder.toString(), BoxUser.this.getID());
+ return new BoxGroupMembershipIterator(BoxUser.this.getAPI(), url);
+ }
+ };
+ }
+
/**
* Adds a new email alias to this user's account.
* @param email the email address to add as an alias.
diff --git a/src/test/java/com/box/sdk/BoxGroupMembershipTest.java b/src/test/java/com/box/sdk/BoxGroupMembershipTest.java
index f6886d42c..f55ca10c9 100644
--- a/src/test/java/com/box/sdk/BoxGroupMembershipTest.java
+++ b/src/test/java/com/box/sdk/BoxGroupMembershipTest.java
@@ -1,26 +1,45 @@
package com.box.sdk;
import java.text.ParseException;
+import java.util.Date;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.delete;
+import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import com.box.sdk.BoxGroupMembership.Role;
import com.eclipsesource.json.JsonObject;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
+/**
+ * {@link BoxGroupMembership} related tests.
+ */
public class BoxGroupMembershipTest {
+
+ /**
+ * Wiremock
+ */
@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);
+ /**
+ * Unit test for {@link BoxGroupMembership#getInfo()}.
+ */
@Test
@Category(UnitTest.class)
public void getInfoSendsCorrectRequestAndParsesResponseCorrectly() throws ParseException {
@@ -78,6 +97,9 @@ public void getInfoSendsCorrectRequestAndParsesResponseCorrectly() throws ParseE
.withRequestBody(WireMock.equalTo("")));
}
+ /**
+ * Unit test for {@link BoxGroupMembership#delete()}.
+ */
@Test
@Category(UnitTest.class)
public void deleteMembershipSendsCorrectRequest() {
@@ -98,6 +120,87 @@ public void deleteMembershipSendsCorrectRequest() {
.withRequestBody(WireMock.equalTo("")));
}
+ /**
+ * Unit test for {@link BoxGroupMembership#updateInfo(BoxGroupMembership.Info)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoSendsCorrectJson() {
+ final String role = "submaster";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/group_memberships/0", request.getUrl().toString());
+ Assert.assertEquals(role, json.get("role").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ BoxGroupMembership membership = new BoxGroupMembership(api, "0");
+ BoxGroupMembership.Info info = membership.new Info();
+ info.addPendingChange("role", role);
+ membership.updateInfo(info);
+ }
+
+ /**
+ * Unit test for {@link BoxGroupMembership#updateInfo(BoxGroupMembership.Info)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "1560354";
+ final String userID = "13130406";
+ final String userName = "Alison Wonderland";
+ final String userLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final Role role = Role.SUBMASTER;
+ final Date createdAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130406\",\n"
+ + " \"name\": \"Alison Wonderland\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"submaster\",\n"
+ + " \"created_at\": \"2013-05-16T15:27:57-07:00\",\n"
+ + " \"modified_at\": \"2013-05-16T15:27:57-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxGroupMembership membership = new BoxGroupMembership(api, id);
+ BoxGroupMembership.Info info = membership.new Info();
+ info.addPendingChange("role", "non-empty");
+ membership.updateInfo(info);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(userID, info.getUser().getID());
+ Assert.assertEquals(userName, info.getUser().getName());
+ Assert.assertEquals(userLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ }
+
@Test
@Category(IntegrationTest.class)
public void getInfoSucceeds() {
diff --git a/src/test/java/com/box/sdk/BoxGroupTest.java b/src/test/java/com/box/sdk/BoxGroupTest.java
index c74fea72d..4860dc351 100644
--- a/src/test/java/com/box/sdk/BoxGroupTest.java
+++ b/src/test/java/com/box/sdk/BoxGroupTest.java
@@ -2,29 +2,352 @@
import java.text.ParseException;
import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
-import static org.skyscreamer.jsonassert.JSONCompareMode.*;
+import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
-
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.delete;
+import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
+
+import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
+/**
+ * {@link BoxGroup} related tests.
+ */
public class BoxGroupTest {
+
+ /**
+ * Wiremock
+ */
@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);
+ /**
+ * Unit test for {@link BoxGroup#getInfo(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequestWithParams() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/groups/0?fields=name%2Ccreated_at", request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, "0");
+ group.getInfo("name", "created_at");
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getInfo()}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/groups/0", request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, "0");
+ group.getInfo();
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getInfo()}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "119720";
+ final String name = "Box Employees";
+ final Date createdAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"Box Employees\",\n"
+ + " \"created_at\": \"2013-05-16T15:27:57-07:00\",\n"
+ + " \"modified_at\": \"2013-05-16T15:27:57-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxGroup group = new BoxGroup(api, id);
+ BoxGroup.Info info = group.getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(name, info.getName());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#addMembership(BoxUser)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddMembershipSendsCorrectJson() {
+ final String userID = "1992432";
+ final String groupID = "1992433";
+
+ final JsonObject fakeJSONResponse = new JsonObject().add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/group_memberships", request.getUrl().toString());
+ Assert.assertEquals(userID, json.get("user").asObject().get("id").asString());
+ Assert.assertEquals(groupID, json.get("group").asObject().get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, groupID);
+ group.addMembership(new BoxUser(api, userID));
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#addMembership(BoxUser)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddMembershipParseAllFieldscorrectly() {
+ final String id = "1560354";
+ final String userID = "13130406";
+ final String userName = "Alison Wonderland";
+ final String userLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final BoxGroupMembership.Role role = BoxGroupMembership.Role.MEMBER;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130406\",\n"
+ + " \"name\": \"Alison Wonderland\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " }");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxGroup group = new BoxGroup(api, id);
+ BoxGroupMembership.Info info = group.addMembership(new BoxUser(api, "0"));
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(userID, info.getUser().getID());
+ Assert.assertEquals(userName, info.getUser().getName());
+ Assert.assertEquals(userLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMembershipsParseAllFieldsCorrectly() {
+ final String firstMembershipID = "1560354";
+ final String firstMembershipUserID = "13130906";
+ final String firstMembershipUserName = "Alice";
+ final String firstMembershipUserLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final BoxGroupMembership.Role role = BoxGroupMembership.Role.MEMBER;
+ final String secondMembershipID = "1560356";
+ final String secondMembershipUserID = "192633962";
+ final String secondMembershipUserName = "rabbit";
+ final String secondMembershipUserLogin = "rabbit@gmail.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"total_count\": 2,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130906\",\n"
+ + " \"name\": \"Alice\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560356\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"192633962\",\n"
+ + " \"name\": \"rabbit\",\n"
+ + " \"login\": \"rabbit@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"offset\": 0,\n"
+ + " \"limit\": 100\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxGroup group = new BoxGroup(api, "0");
+ Iterator iterator = group.getAllMemberships().iterator();
+ BoxGroupMembership.Info info = iterator.next();
+ Assert.assertEquals(firstMembershipID, info.getID());
+ Assert.assertEquals(firstMembershipUserID, info.getUser().getID());
+ Assert.assertEquals(firstMembershipUserName, info.getUser().getName());
+ Assert.assertEquals(firstMembershipUserLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ info = iterator.next();
+ Assert.assertEquals(secondMembershipID, info.getID());
+ Assert.assertEquals(secondMembershipUserID, info.getUser().getID());
+ Assert.assertEquals(secondMembershipUserName, info.getUser().getName());
+ Assert.assertEquals(secondMembershipUserLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ Assert.assertEquals(false, iterator.hasNext());
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMembershipsSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("total_count", 0)
+ .add("offset", 0)
+ .add("entries", new JsonArray());
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/groups/0/memberships?fields=user%2Cgroup&limit=100&offset=0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, "0");
+ Iterator iterator = group.getAllMemberships("user", "group").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getAllGroups(BoxAPIConnection, String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllGroupsSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("total_count", 0)
+ .add("offset", 0)
+ .add("entries", new JsonArray());
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/groups?fields=name%2Ccreated_at&limit=1000&offset=0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ Iterator iterator = BoxGroup.getAllGroups(api, "name", "created_at").iterator();
+ iterator.hasNext();
+ }
+
@Test
@Category(IntegrationTest.class)
public void createAndDeleteGroupSucceeds() {
@@ -74,6 +397,9 @@ public void getInfoSucceeds() {
createdGroupInfo.getResource().delete();
}
+ /**
+ * Unit test for {@link BoxGroup#createGroup(BoxAPIConnection, String, String, String, String, String, String)}.
+ */
@Test
@Category(UnitTest.class)
public void createGroupSendsCorrectRequestAndParsesResponseCorrectly() throws ParseException {
@@ -131,6 +457,9 @@ public void createGroupSendsCorrectRequestAndParsesResponseCorrectly() throws Pa
.withRequestBody(equalToJson(expectedJSON.toString(), LENIENT)));
}
+ /**
+ * Unit test for {@link BoxGroup#delete()}.
+ */
@Test
@Category(UnitTest.class)
public void deleteGroupSendsCorrectRequest() {
diff --git a/src/test/java/com/box/sdk/BoxUserTest.java b/src/test/java/com/box/sdk/BoxUserTest.java
index 84cf83c1f..c30d0d188 100644
--- a/src/test/java/com/box/sdk/BoxUserTest.java
+++ b/src/test/java/com/box/sdk/BoxUserTest.java
@@ -3,6 +3,7 @@
import java.text.ParseException;
import java.util.Collection;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
@@ -33,10 +34,20 @@
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.google.common.collect.Lists;
+/**
+ * {@link BoxUser} related tests.
+ */
public class BoxUserTest {
+
+ /**
+ * Wiremock
+ */
@Rule
public final WireMockRule wireMockRule = new WireMockRule(8080);
+ /**
+ * Unit test for {@link BoxUser#getAllEnterpriseUsers(BoxAPIConnection, String, String...)}.
+ */
@Test
@Category(UnitTest.class)
public void getAllEnterpriseUsersRequestsCorrectFilterAndFields() {
@@ -62,6 +73,9 @@ public void getAllEnterpriseUsersRequestsCorrectFilterAndFields() {
assertThat(usersList.get(0).getName(), is(equalTo(name)));
}
+ /**
+ * Unit test for {@link BoxUser#getExternalUsers(BoxAPIConnection, String, String...)}.
+ */
@Test
@Category(UnitTest.class)
public void getExternalUsersRequestsCorrectFilterAndFields() {
@@ -88,6 +102,9 @@ public void getExternalUsersRequestsCorrectFilterAndFields() {
assertThat(usersList.get(0).getName(), is(equalTo(name)));
}
+ /**
+ * Unit test for {@link BoxUser#getAllEnterpriseOrExternalUsers(BoxAPIConnection, String, String...)}.
+ */
@Test
@Category(UnitTest.class)
public void getAllEnterpriseOrExternalUsersRequestsCorrectFilterAndFields() {
@@ -114,6 +131,9 @@ public void getAllEnterpriseOrExternalUsersRequestsCorrectFilterAndFields() {
assertThat(usersList.get(0).getName(), is(equalTo(name)));
}
+ /**
+ * Unit test for {@link BoxUser#createEnterpriseUser(BoxAPIConnection, String, String)}.
+ */
@Test
@Category(UnitTest.class)
public void createEnterpriseUserSendsJSONWithLoginAndName() {
@@ -143,6 +163,9 @@ public String getJSON() {
BoxUser.Info createdUserInfo = BoxUser.createEnterpriseUser(api, login, name);
}
+ /**
+ * Unit test for {@link BoxUser#createEnterpriseUser(BoxAPIConnection, String, String, CreateUserParams)}.
+ */
@Test
@Category(UnitTest.class)
public void createEnterpriseUserSendsJSONWithAdditionalParams() {
@@ -211,6 +234,9 @@ public String getJSON() {
BoxUser.Info createdUserInfo = BoxUser.createEnterpriseUser(api, login, name, params);
}
+ /**
+ * Unit test for {@link BoxUser#createEnterpriseUser(BoxAPIConnection, String, String)}.
+ */
@Test
@Category(UnitTest.class)
public void createEnterpriseUserParsesAllFieldsCorrectly() throws ParseException {
@@ -272,6 +298,9 @@ public void createEnterpriseUserParsesAllFieldsCorrectly() throws ParseException
assertEquals(avatarURL, createdUserInfo.getAvatarURL());
}
+ /**
+ * Unit test for {@link BoxUser#updateInfo(BoxUser.Info)}.
+ */
@Test
@Category(UnitTest.class)
public void updateInfoSendsCorrectJSON() {
@@ -346,6 +375,9 @@ public String getJSON() {
user.updateInfo(info);
}
+ /**
+ * Unit test for {@link BoxUser#getEmailAliases()}.
+ */
@Test
@Category(UnitTest.class)
public void getEmailAliasesParsesAllFieldsCorrectly() {
@@ -392,6 +424,9 @@ public void getEmailAliasesParsesAllFieldsCorrectly() {
}
}
+ /**
+ * Unit test for {@link BoxUser#addEmailAlias(String)}.
+ */
@Test
@Category(UnitTest.class)
public void addEmailAliasSendsCorrectJSON() {
@@ -416,6 +451,90 @@ public String getJSON() {
user.addEmailAlias(email);
}
+ /**
+ * Unit test for {@link BoxUser#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMembershipsSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("total_count", 0)
+ .add("offset", 0)
+ .add("entries", new JsonArray());
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ assertEquals("https://api.box.com/2.0/users/0/memberships?fields=user%2Cgroup&limit=100&offset=0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, "0");
+ Iterator iterator = user.getAllMemberships("user", "group").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxUser#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetMembershipsParseAllFieldsCorrectly() throws ParseException {
+ final String id = "1560354";
+ final String userID = "13130406";
+ final String userName = "Alison Wonderland";
+ final String userLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final BoxGroupMembership.Role role = BoxGroupMembership.Role.MEMBER;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"total_count\": 1,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130406\",\n"
+ + " \"name\": \"Alison Wonderland\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"limit\": 100,\n"
+ + " \"offset\": 0\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxUser user = new BoxUser(api, "0");
+ Iterator iterator = user.getAllMemberships().iterator();
+ BoxGroupMembership.Info info = iterator.next();
+ assertEquals(id, info.getID());
+ assertEquals(userID, info.getUser().getID());
+ assertEquals(userName, info.getUser().getName());
+ assertEquals(userLogin, info.getUser().getLogin());
+ assertEquals(groupID, info.getGroup().getID());
+ assertEquals(groupName, info.getGroup().getName());
+ assertEquals(role, info.getRole());
+ assertEquals(false, iterator.hasNext());
+ }
+
@Test
@Category(IntegrationTest.class)
public void getCurrentUserInfoIsCorrect() throws InterruptedException {
From 6d3b05a9ee6071a3572a87d0823d8c94c2a7d1b0 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Mon, 14 Nov 2016 11:17:23 +0100
Subject: [PATCH 008/119] update group feature implemented
---
doc/groups.md | 111 ++++-
src/main/java/com/box/sdk/BoxGroup.java | 114 +++++
.../java/com/box/sdk/BoxGroupMembership.java | 51 +++
.../box/sdk/BoxGroupMembershipIterator.java | 33 +-
src/main/java/com/box/sdk/BoxUser.java | 20 +
.../com/box/sdk/BoxGroupMembershipTest.java | 105 ++++-
src/test/java/com/box/sdk/BoxGroupTest.java | 411 +++++++++++++++++-
src/test/java/com/box/sdk/BoxUserTest.java | 119 +++++
8 files changed, 956 insertions(+), 8 deletions(-)
diff --git a/doc/groups.md b/doc/groups.md
index b99f85bf3..5dd66aa4a 100644
--- a/doc/groups.md
+++ b/doc/groups.md
@@ -5,8 +5,15 @@ Groups are sets of users that can be used in collaborations.
* [Get All Groups](#get-all-groups)
* [Create a Group](#create-a-group)
+* [Update a Group](#update-a-group)
* [Delete a Group](#delete-a-group)
* [Get a Groups collaborations](#get-a-groups-collaborations)
+* [Create Membership](#create-membership)
+* [Get Membership](#get-membership)
+* [Update Membership](#update-membership)
+* [Delete Membership](#delete-membership)
+* [Get Memberships for Group](#get-memberships-for-group)
+* [Get Memberships for User](#get-memberships-for-user)
Get All Groups
--------------
@@ -35,6 +42,22 @@ BoxGroup.Info groupInfo = BoxGroup.createGroup(api, "My Group");
[create-group]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#createGroup(com.box.sdk.BoxAPIConnection,%20java.lang.String)
+
+Update a Group
+--------------
+
+To update a group, call [`updateInfo(BoxGroup.Info)`][update-group] method.
+
+```java
+BoxGroup group = new BoxGroup(api, id);
+BoxGroup.Info groupInfo = group.getInfo();
+groupInfo.addPendingChange("name", "New name for My Group");
+group.updateInfo(groupInfo);
+```
+
+[update-group]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#updateInfo(com.box.sdk.BoxGroup.Info)
+
+
Delete a Group
--------------
@@ -50,11 +73,95 @@ group.delete();
Get a Groups collaborations
---------------------------
-A groups collaborations can be retrieved by calling the [`getCollaborations()`[get-collaborations] method.
+A groups collaborations can be retrieved by calling the [`getCollaborations()`][get-collaborations] method.
```java
BoxGroup group = new BoxGroup(api, "id");
group.getCollaborations();
```
-[get-collaborations]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#getCollaborations()
\ No newline at end of file
+[get-collaborations]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#getCollaborations()
+
+Create Membership
+---------------
+
+Membership for the group can be created by calling [`addMembership(BoxUser)`][add-membership] and [`addMembership(BoxUser, Role)`][add-membership2] methods.
+
+```java
+BoxGroup group = new BoxGroup(api, "groupID");
+BoxUser user = new BoxUser(api, "userID");
+BoxGroupMembership.Info groupMembershipInfo = group.addMembership(user);
+```
+
+[add-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#addMembership(com.box.sdk.BoxUser)
+[add-membership2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#addMembership(com.box.sdk.BoxUser,%20com.box.sdk.BoxGroupMembership.Role)
+
+Get Membership
+---------------
+
+A groups membership can be retrieved by calling the [`BoxGroupMembership.getInfo()`][get-membership] method.
+
+```java
+BoxGroupMembership membership = new BoxGroupMembership(api, id);
+BoxGroupMembership.Info groupMembershipInfo = membership.getInfo();
+```
+
+[get-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroupMembership.html#getInfo()
+
+Update Membership
+---------------
+
+A groups membership can be updated by calling the [`BoxGroupMembership.updateInfo(BoxGroupMembership.Info)`][update-membership] method.
+
+```java
+BoxGroupMembership membership = new BoxGroupMembership(api, id);
+BoxGroupMembership.Info info = membership.new Info();
+info.addPendingChange("role", role);
+membership.updateInfo(info);
+```
+
+[update-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroupMembership.html#updateInfo(com.box.sdk.BoxGroupMembership.Info)
+
+Delete Membership
+---------------
+
+A group can be deleted by calling the [`BoxGroupMembership.delete()`][delete-membership] method.
+
+```java
+BoxGroupMembership membership = new BoxGroupMembership(api, id);
+membership.delete();
+```
+
+[delete-membership]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroupMembership.html#delete()
+
+Get Memberships for Group
+---------------
+
+Calling the [`getAllMemberships(String...)`][get-memberships-for-group] will return an iterable that will page through all of the group's memberships.
+Optional parameters can be used to retrieve specific fields of the Group Membership object.
+
+```java
+BoxGroup group = new BoxGroup(api, id);
+Iterable memberships = group.getAllMemberships();
+for (BoxGroupMembership.Info membershipInfo : memberships) {
+ // Do something with the membership.
+}
+```
+
+[get-memberships-for-group]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxGroup.html#getAllMemberships(java.lang.String...)
+
+Get Memberships for User
+---------------
+
+Calling the [`BoxUser.getAllMemberships(String...)`][get-memberships-for-user] will return an iterable that will page through all of the user's memberships.
+Optional parameters can be used to retrieve specific fields of the Group Membership object.
+
+```java
+BoxUser user = new BoxUser(api, id);
+Iterable memberships = user.getAllMemberships();
+for (BoxGroupMembership.Info membershipInfo : memberships) {
+ // Do something with the membership.
+}
+```
+
+[get-memberships-for-user]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#getAllMemberships(java.lang.String...)
\ No newline at end of file
diff --git a/src/main/java/com/box/sdk/BoxGroup.java b/src/main/java/com/box/sdk/BoxGroup.java
index 07f8e7cd9..82e259e0b 100644
--- a/src/main/java/com/box/sdk/BoxGroup.java
+++ b/src/main/java/com/box/sdk/BoxGroup.java
@@ -19,10 +19,30 @@
*/
@BoxResourceType("group")
public class BoxGroup extends BoxCollaborator {
+
+ /**
+ * @see #getAllGroups(BoxAPIConnection, String...)
+ */
private static final URLTemplate GROUPS_URL_TEMPLATE = new URLTemplate("groups");
+
+ /**
+ * @see #getInfo()
+ */
private static final URLTemplate GROUP_URL_TEMPLATE = new URLTemplate("groups/%s");
+
+ /**
+ * @see #getMemberships()
+ */
private static final URLTemplate MEMBERSHIPS_URL_TEMPLATE = new URLTemplate("groups/%s/memberships");
+
+ /**
+ * @see #addMembership(BoxUser)
+ */
private static final URLTemplate ADD_MEMBERSHIP_URL_TEMPLATE = new URLTemplate("group_memberships");
+
+ /**
+ * @see #getCollaborations()
+ */
private static final URLTemplate COLLABORATIONS_URL_TEMPLATE = new URLTemplate("groups/%s/collaborations");
/**
@@ -101,6 +121,25 @@ public Iterator iterator() {
};
}
+ /**
+ * Gets an iterable of all the groups in the enterprise.
+ * @param api the API connection to be used when retrieving the groups.
+ * @param fields the fields to retrieve.
+ * @return an iterable containing info about all the groups.
+ */
+ public static Iterable getAllGroups(final BoxAPIConnection api, String ... fields) {
+ final QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new Iterable() {
+ public Iterator iterator() {
+ URL url = GROUPS_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString());
+ return new BoxGroupIterator(api, url);
+ }
+ };
+ }
+
/**
* Gets information about this group.
* @return info about this group.
@@ -113,8 +152,26 @@ public Info getInfo() {
return new Info(responseJSON);
}
+ /**
+ * Gets information about this group.
+ * @param fields the fields to retrieve.
+ * @return info about this group.
+ */
+ public Info getInfo(String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = GROUP_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+ return new Info(responseJSON);
+ }
+
/**
* Gets information about all of the group memberships for this group.
+ * Does not support paging.
* @return a collection of information about the group memberships for this group.
*/
public Collection getMemberships() {
@@ -137,6 +194,25 @@ public Iterator iterator() {
return memberships;
}
+ /**
+ * Gets information about all of the group memberships for this group as iterable with paging support.
+ * @param fields the fields to retrieve.
+ * @return an iterable with information about the group memberships for this group.
+ */
+ public Iterable getAllMemberships(String ... fields) {
+ final QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new Iterable() {
+ public Iterator iterator() {
+ URL url = MEMBERSHIPS_URL_TEMPLATE.buildWithQuery(
+ BoxGroup.this.getAPI().getBaseURL(), builder.toString(), BoxGroup.this.getID());
+ return new BoxGroupMembershipIterator(BoxGroup.this.getAPI(), url);
+ }
+ };
+ }
+
/**
* Adds a member to this group with the default role.
* @param user the member to be added to this group.
@@ -207,15 +283,47 @@ public void delete() {
response.disconnect();
}
+ /**
+ * Updates the information about this group with any info fields that have been modified locally.
+ * @param info the updated info.
+ */
+ public void updateInfo(BoxGroup.Info info) {
+ URL url = GROUP_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
+ request.setBody(info.getPendingChanges());
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ info.update(jsonObject);
+ }
+
/**
* Contains information about a BoxGroup.
*/
public class Info extends BoxCollaborator.Info {
+ /**
+ * @see #getProvenance()
+ */
private String provenance;
+
+ /**
+ * @see #getExternalSyncIdentifier()
+ */
private String externalSyncIdentifier;
+
+ /**
+ * @see #getDescription()
+ */
private String description;
+
+ /**
+ * @see #getInvitabilityLevel()
+ */
private String invitabilityLevel;
+
+ /**
+ * @see #getMemberViewabilityLevel()
+ */
private String memberViewabilityLevel;
/**
@@ -241,11 +349,17 @@ public Info(String json) {
super(jsonObject);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public BoxGroup getResource() {
return BoxGroup.this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void parseJSONMember(JsonObject.Member member) {
super.parseJSONMember(member);
diff --git a/src/main/java/com/box/sdk/BoxGroupMembership.java b/src/main/java/com/box/sdk/BoxGroupMembership.java
index 2439a3d00..8d4781867 100644
--- a/src/main/java/com/box/sdk/BoxGroupMembership.java
+++ b/src/main/java/com/box/sdk/BoxGroupMembership.java
@@ -16,6 +16,11 @@
*/
@BoxResourceType("group_membership")
public class BoxGroupMembership extends BoxResource {
+
+ /**
+ * The URL template for all group membership requests.
+ * @see #getInfo()
+ */
private static final URLTemplate MEMBERSHIP_URL_TEMPLATE = new URLTemplate("group_memberships/%s");
/**
@@ -72,10 +77,30 @@ public void delete() {
* Contains information about a BoxGroupMembership.
*/
public class Info extends BoxResource.Info {
+
+ /**
+ * @see #getUser()
+ */
private BoxUser.Info user;
+
+ /**
+ * @see #getGroup()
+ */
private BoxGroup.Info group;
+
+ /**
+ * @see #getRole()
+ */
private Role role;
+
+ /**
+ * @see #getCreatedAt()
+ */
private Date createdAt;
+
+ /**
+ * @see #getModifiedAt()
+ */
private Date modifiedAt;
/**
@@ -157,11 +182,17 @@ public Date getModifiedAt() {
return this.modifiedAt;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public BoxGroupMembership getResource() {
return BoxGroupMembership.this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void parseJSONMember(JsonObject.Member member) {
super.parseJSONMember(member);
@@ -215,21 +246,41 @@ public enum Role {
*/
ADMIN ("admin"),
+ /**
+ * The user is a submaster in the group.
+ */
+ SUBMASTER ("submaster"),
+
/**
* The user is a regular member in the group.
*/
MEMBER ("member");
+ /**
+ * String representation of the role.
+ */
private final String jsonValue;
+ /**
+ * Constructor.
+ * @param jsonValue srting representation of the role.
+ */
private Role(String jsonValue) {
this.jsonValue = jsonValue;
}
+ /**
+ * Creates the role from given string.
+ * @param jsonValue string to be converted to role.
+ * @return the role, created from string value.
+ */
static Role fromJSONString(String jsonValue) {
return Role.valueOf(jsonValue.toUpperCase());
}
+ /**
+ * @return string representation of the role.
+ */
String toJSONString() {
return this.jsonValue;
}
diff --git a/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java b/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java
index 8fe077978..bb135ecc7 100644
--- a/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java
+++ b/src/main/java/com/box/sdk/BoxGroupMembershipIterator.java
@@ -5,29 +5,58 @@
import com.eclipsesource.json.JsonObject;
+/**
+ * An iterator object for {@link BoxGroupMembership} object.
+ * Supports offset-based paging.
+ */
class BoxGroupMembershipIterator implements Iterator {
+
+ /**
+ * The limit of entries per response.
+ */
private static final long LIMIT = 1000;
+ /**
+ * The API connection to be used.
+ */
private final BoxAPIConnection api;
+
+ /**
+ * Iterator object with paging support.
+ */
private final JSONIterator jsonIterator;
+ /**
+ * Creates new BoxGroupMembership iterator.
+ * @param api The API connection to be used by the iterator.
+ * @param url The endpoint url.
+ */
BoxGroupMembershipIterator(BoxAPIConnection api, URL url) {
this.api = api;
this.jsonIterator = new JSONIterator(api, url, LIMIT);
}
+ /**
+ * @return false if current element is the last.
+ */
public boolean hasNext() {
return this.jsonIterator.hasNext();
}
+ /**
+ * @return next BoxGroupMembeship object in the list.
+ */
public BoxGroupMembership.Info next() {
JsonObject nextJSONObject = this.jsonIterator.next();
String id = nextJSONObject.get("id").asString();
- BoxGroupMembership group = new BoxGroupMembership(this.api, id);
- return group.new Info(nextJSONObject);
+ BoxGroupMembership membership = new BoxGroupMembership(this.api, id);
+ return membership.new Info(nextJSONObject);
}
+ /**
+ * Remove operation is not supported.
+ */
public void remove() {
throw new UnsupportedOperationException();
}
diff --git a/src/main/java/com/box/sdk/BoxUser.java b/src/main/java/com/box/sdk/BoxUser.java
index 369b49a16..c5fa0f64d 100644
--- a/src/main/java/com/box/sdk/BoxUser.java
+++ b/src/main/java/com/box/sdk/BoxUser.java
@@ -247,6 +247,7 @@ public BoxUser.Info getInfo(String... fields) {
/**
* Gets information about all of the group memberships for this user.
+ * Does not support paging.
*
* Note: This method is only available to enterprise admins.
*
@@ -273,6 +274,25 @@ public Collection getMemberships() {
return memberships;
}
+ /**
+ * Gets information about all of the group memberships for this user as iterable with paging support.
+ * @param fields the fields to retrieve.
+ * @return an iterable with information about the group memberships for this user.
+ */
+ public Iterable getAllMemberships(String ... fields) {
+ final QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new Iterable() {
+ public Iterator iterator() {
+ URL url = USER_MEMBERSHIPS_URL_TEMPLATE.buildWithQuery(
+ BoxUser.this.getAPI().getBaseURL(), builder.toString(), BoxUser.this.getID());
+ return new BoxGroupMembershipIterator(BoxUser.this.getAPI(), url);
+ }
+ };
+ }
+
/**
* Adds a new email alias to this user's account.
* @param email the email address to add as an alias.
diff --git a/src/test/java/com/box/sdk/BoxGroupMembershipTest.java b/src/test/java/com/box/sdk/BoxGroupMembershipTest.java
index f6886d42c..f55ca10c9 100644
--- a/src/test/java/com/box/sdk/BoxGroupMembershipTest.java
+++ b/src/test/java/com/box/sdk/BoxGroupMembershipTest.java
@@ -1,26 +1,45 @@
package com.box.sdk;
import java.text.ParseException;
+import java.util.Date;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.delete;
+import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import com.box.sdk.BoxGroupMembership.Role;
import com.eclipsesource.json.JsonObject;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
+/**
+ * {@link BoxGroupMembership} related tests.
+ */
public class BoxGroupMembershipTest {
+
+ /**
+ * Wiremock
+ */
@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);
+ /**
+ * Unit test for {@link BoxGroupMembership#getInfo()}.
+ */
@Test
@Category(UnitTest.class)
public void getInfoSendsCorrectRequestAndParsesResponseCorrectly() throws ParseException {
@@ -78,6 +97,9 @@ public void getInfoSendsCorrectRequestAndParsesResponseCorrectly() throws ParseE
.withRequestBody(WireMock.equalTo("")));
}
+ /**
+ * Unit test for {@link BoxGroupMembership#delete()}.
+ */
@Test
@Category(UnitTest.class)
public void deleteMembershipSendsCorrectRequest() {
@@ -98,6 +120,87 @@ public void deleteMembershipSendsCorrectRequest() {
.withRequestBody(WireMock.equalTo("")));
}
+ /**
+ * Unit test for {@link BoxGroupMembership#updateInfo(BoxGroupMembership.Info)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoSendsCorrectJson() {
+ final String role = "submaster";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/group_memberships/0", request.getUrl().toString());
+ Assert.assertEquals(role, json.get("role").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ BoxGroupMembership membership = new BoxGroupMembership(api, "0");
+ BoxGroupMembership.Info info = membership.new Info();
+ info.addPendingChange("role", role);
+ membership.updateInfo(info);
+ }
+
+ /**
+ * Unit test for {@link BoxGroupMembership#updateInfo(BoxGroupMembership.Info)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "1560354";
+ final String userID = "13130406";
+ final String userName = "Alison Wonderland";
+ final String userLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final Role role = Role.SUBMASTER;
+ final Date createdAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130406\",\n"
+ + " \"name\": \"Alison Wonderland\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"submaster\",\n"
+ + " \"created_at\": \"2013-05-16T15:27:57-07:00\",\n"
+ + " \"modified_at\": \"2013-05-16T15:27:57-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxGroupMembership membership = new BoxGroupMembership(api, id);
+ BoxGroupMembership.Info info = membership.new Info();
+ info.addPendingChange("role", "non-empty");
+ membership.updateInfo(info);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(userID, info.getUser().getID());
+ Assert.assertEquals(userName, info.getUser().getName());
+ Assert.assertEquals(userLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ }
+
@Test
@Category(IntegrationTest.class)
public void getInfoSucceeds() {
diff --git a/src/test/java/com/box/sdk/BoxGroupTest.java b/src/test/java/com/box/sdk/BoxGroupTest.java
index c74fea72d..b1cfe9986 100644
--- a/src/test/java/com/box/sdk/BoxGroupTest.java
+++ b/src/test/java/com/box/sdk/BoxGroupTest.java
@@ -2,29 +2,428 @@
import java.text.ParseException;
import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
-import static org.skyscreamer.jsonassert.JSONCompareMode.*;
+import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
-
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.delete;
+import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.verify;
+
+import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
+/**
+ * {@link BoxGroup} related tests.
+ */
public class BoxGroupTest {
+
+ /**
+ * Wiremock
+ */
@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);
+ /**
+ * Unit test for {@link BoxGroup#getInfo(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequestWithParams() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/groups/0?fields=name%2Ccreated_at", request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, "0");
+ group.getInfo("name", "created_at");
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getInfo()}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/groups/0", request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, "0");
+ group.getInfo();
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getInfo()}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "119720";
+ final String name = "Box Employees";
+ final Date createdAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"Box Employees\",\n"
+ + " \"created_at\": \"2013-05-16T15:27:57-07:00\",\n"
+ + " \"modified_at\": \"2013-05-16T15:27:57-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxGroup group = new BoxGroup(api, id);
+ BoxGroup.Info info = group.getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(name, info.getName());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#addMembership(BoxUser)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddMembershipSendsCorrectJson() {
+ final String userID = "1992432";
+ final String groupID = "1992433";
+
+ final JsonObject fakeJSONResponse = new JsonObject().add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/group_memberships", request.getUrl().toString());
+ Assert.assertEquals(userID, json.get("user").asObject().get("id").asString());
+ Assert.assertEquals(groupID, json.get("group").asObject().get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, groupID);
+ group.addMembership(new BoxUser(api, userID));
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#addMembership(BoxUser)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddMembershipParseAllFieldscorrectly() {
+ final String id = "1560354";
+ final String userID = "13130406";
+ final String userName = "Alison Wonderland";
+ final String userLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final BoxGroupMembership.Role role = BoxGroupMembership.Role.MEMBER;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130406\",\n"
+ + " \"name\": \"Alison Wonderland\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " }");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxGroup group = new BoxGroup(api, id);
+ BoxGroupMembership.Info info = group.addMembership(new BoxUser(api, "0"));
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(userID, info.getUser().getID());
+ Assert.assertEquals(userName, info.getUser().getName());
+ Assert.assertEquals(userLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMembershipsParseAllFieldsCorrectly() {
+ final String firstMembershipID = "1560354";
+ final String firstMembershipUserID = "13130906";
+ final String firstMembershipUserName = "Alice";
+ final String firstMembershipUserLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final BoxGroupMembership.Role role = BoxGroupMembership.Role.MEMBER;
+ final String secondMembershipID = "1560356";
+ final String secondMembershipUserID = "192633962";
+ final String secondMembershipUserName = "rabbit";
+ final String secondMembershipUserLogin = "rabbit@gmail.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"total_count\": 2,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130906\",\n"
+ + " \"name\": \"Alice\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560356\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"192633962\",\n"
+ + " \"name\": \"rabbit\",\n"
+ + " \"login\": \"rabbit@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"offset\": 0,\n"
+ + " \"limit\": 100\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxGroup group = new BoxGroup(api, "0");
+ Iterator iterator = group.getAllMemberships().iterator();
+ BoxGroupMembership.Info info = iterator.next();
+ Assert.assertEquals(firstMembershipID, info.getID());
+ Assert.assertEquals(firstMembershipUserID, info.getUser().getID());
+ Assert.assertEquals(firstMembershipUserName, info.getUser().getName());
+ Assert.assertEquals(firstMembershipUserLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ info = iterator.next();
+ Assert.assertEquals(secondMembershipID, info.getID());
+ Assert.assertEquals(secondMembershipUserID, info.getUser().getID());
+ Assert.assertEquals(secondMembershipUserName, info.getUser().getName());
+ Assert.assertEquals(secondMembershipUserLogin, info.getUser().getLogin());
+ Assert.assertEquals(groupID, info.getGroup().getID());
+ Assert.assertEquals(groupName, info.getGroup().getName());
+ Assert.assertEquals(role, info.getRole());
+ Assert.assertEquals(false, iterator.hasNext());
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMembershipsSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("total_count", 0)
+ .add("offset", 0)
+ .add("entries", new JsonArray());
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/groups/0/memberships?fields=user%2Cgroup&limit=1000&offset=0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, "0");
+ Iterator iterator = group.getAllMemberships("user", "group").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#getAllGroups(BoxAPIConnection, String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllGroupsSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("total_count", 0)
+ .add("offset", 0)
+ .add("entries", new JsonArray());
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/groups?fields=name%2Ccreated_at&limit=1000&offset=0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ Iterator iterator = BoxGroup.getAllGroups(api, "name", "created_at").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#updateInfo(BoxGroup.Info)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoSendsCorrectJSON() {
+ final String name = "family";
+ final String provenance = "non-empty provenance";
+ final String externalSyncIdentifier = "non-empty identifier";
+ final String description = "non-empty description";
+ final String invitabilityLevel = "non-empty level";
+ final String memberViewabilityLevel = "another non-empty level";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/groups/0", request.getUrl().toString());
+ Assert.assertEquals(name, json.get("name").asString());
+ Assert.assertEquals(provenance, json.get("provenance").asString());
+ Assert.assertEquals(externalSyncIdentifier, json.get("external_sync_identifier").asString());
+ Assert.assertEquals(description, json.get("description").asString());
+ Assert.assertEquals(invitabilityLevel, json.get("invitability_level").asString());
+ Assert.assertEquals(memberViewabilityLevel, json.get("member_viewability_level").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ BoxGroup group = new BoxGroup(api, "0");
+ BoxGroup.Info info = group.new Info();
+ info.addPendingChange("name", name);
+ info.addPendingChange("provenance", provenance);
+ info.addPendingChange("external_sync_identifier", externalSyncIdentifier);
+ info.addPendingChange("description", description);
+ info.addPendingChange("invitability_level", invitabilityLevel);
+ info.addPendingChange("member_viewability_level", memberViewabilityLevel);
+ group.updateInfo(info);
+ }
+
+ /**
+ * Unit test for {@link BoxGroup#updateInfo(BoxGroup.Info)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "119720";
+ final String name = "family";
+ final Date createdAt = BoxDateFormat.parse("2013-05-16T15:27:57-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2013-05-17T15:27:57-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\",\n"
+ + " \"created_at\": \"2013-05-16T15:27:57-07:00\",\n"
+ + " \"modified_at\": \"2013-05-17T15:27:57-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxGroup group = new BoxGroup(api, id);
+ BoxGroup.Info info = group.new Info();
+ info.addPendingChange("name", name);
+ group.updateInfo(info);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(name, info.getName());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ }
+
@Test
@Category(IntegrationTest.class)
public void createAndDeleteGroupSucceeds() {
@@ -74,6 +473,9 @@ public void getInfoSucceeds() {
createdGroupInfo.getResource().delete();
}
+ /**
+ * Unit test for {@link BoxGroup#createGroup(BoxAPIConnection, String, String, String, String, String, String)}.
+ */
@Test
@Category(UnitTest.class)
public void createGroupSendsCorrectRequestAndParsesResponseCorrectly() throws ParseException {
@@ -131,6 +533,9 @@ public void createGroupSendsCorrectRequestAndParsesResponseCorrectly() throws Pa
.withRequestBody(equalToJson(expectedJSON.toString(), LENIENT)));
}
+ /**
+ * Unit test for {@link BoxGroup#delete()}.
+ */
@Test
@Category(UnitTest.class)
public void deleteGroupSendsCorrectRequest() {
diff --git a/src/test/java/com/box/sdk/BoxUserTest.java b/src/test/java/com/box/sdk/BoxUserTest.java
index 84cf83c1f..7aef4ccea 100644
--- a/src/test/java/com/box/sdk/BoxUserTest.java
+++ b/src/test/java/com/box/sdk/BoxUserTest.java
@@ -3,6 +3,7 @@
import java.text.ParseException;
import java.util.Collection;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
@@ -33,10 +34,20 @@
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.google.common.collect.Lists;
+/**
+ * {@link BoxUser} related tests.
+ */
public class BoxUserTest {
+
+ /**
+ * Wiremock
+ */
@Rule
public final WireMockRule wireMockRule = new WireMockRule(8080);
+ /**
+ * Unit test for {@link BoxUser#getAllEnterpriseUsers(BoxAPIConnection, String, String...)}.
+ */
@Test
@Category(UnitTest.class)
public void getAllEnterpriseUsersRequestsCorrectFilterAndFields() {
@@ -62,6 +73,9 @@ public void getAllEnterpriseUsersRequestsCorrectFilterAndFields() {
assertThat(usersList.get(0).getName(), is(equalTo(name)));
}
+ /**
+ * Unit test for {@link BoxUser#getExternalUsers(BoxAPIConnection, String, String...)}.
+ */
@Test
@Category(UnitTest.class)
public void getExternalUsersRequestsCorrectFilterAndFields() {
@@ -88,6 +102,9 @@ public void getExternalUsersRequestsCorrectFilterAndFields() {
assertThat(usersList.get(0).getName(), is(equalTo(name)));
}
+ /**
+ * Unit test for {@link BoxUser#getAllEnterpriseOrExternalUsers(BoxAPIConnection, String, String...)}.
+ */
@Test
@Category(UnitTest.class)
public void getAllEnterpriseOrExternalUsersRequestsCorrectFilterAndFields() {
@@ -114,6 +131,9 @@ public void getAllEnterpriseOrExternalUsersRequestsCorrectFilterAndFields() {
assertThat(usersList.get(0).getName(), is(equalTo(name)));
}
+ /**
+ * Unit test for {@link BoxUser#createEnterpriseUser(BoxAPIConnection, String, String)}.
+ */
@Test
@Category(UnitTest.class)
public void createEnterpriseUserSendsJSONWithLoginAndName() {
@@ -143,6 +163,9 @@ public String getJSON() {
BoxUser.Info createdUserInfo = BoxUser.createEnterpriseUser(api, login, name);
}
+ /**
+ * Unit test for {@link BoxUser#createEnterpriseUser(BoxAPIConnection, String, String, CreateUserParams)}.
+ */
@Test
@Category(UnitTest.class)
public void createEnterpriseUserSendsJSONWithAdditionalParams() {
@@ -211,6 +234,9 @@ public String getJSON() {
BoxUser.Info createdUserInfo = BoxUser.createEnterpriseUser(api, login, name, params);
}
+ /**
+ * Unit test for {@link BoxUser#createEnterpriseUser(BoxAPIConnection, String, String)}.
+ */
@Test
@Category(UnitTest.class)
public void createEnterpriseUserParsesAllFieldsCorrectly() throws ParseException {
@@ -272,6 +298,9 @@ public void createEnterpriseUserParsesAllFieldsCorrectly() throws ParseException
assertEquals(avatarURL, createdUserInfo.getAvatarURL());
}
+ /**
+ * Unit test for {@link BoxUser#updateInfo(BoxUser.Info)}.
+ */
@Test
@Category(UnitTest.class)
public void updateInfoSendsCorrectJSON() {
@@ -346,6 +375,9 @@ public String getJSON() {
user.updateInfo(info);
}
+ /**
+ * Unit test for {@link BoxUser#getEmailAliases()}.
+ */
@Test
@Category(UnitTest.class)
public void getEmailAliasesParsesAllFieldsCorrectly() {
@@ -392,6 +424,9 @@ public void getEmailAliasesParsesAllFieldsCorrectly() {
}
}
+ /**
+ * Unit test for {@link BoxUser#addEmailAlias(String)}.
+ */
@Test
@Category(UnitTest.class)
public void addEmailAliasSendsCorrectJSON() {
@@ -416,6 +451,90 @@ public String getJSON() {
user.addEmailAlias(email);
}
+ /**
+ * Unit test for {@link BoxUser#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMembershipsSendsCorrectRequest() {
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("total_count", 0)
+ .add("offset", 0)
+ .add("entries", new JsonArray());
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ assertEquals("https://api.box.com/2.0/users/0/memberships?fields=user%2Cgroup&limit=1000&offset=0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, "0");
+ Iterator iterator = user.getAllMemberships("user", "group").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxUser#getAllMemberships(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetMembershipsParseAllFieldsCorrectly() throws ParseException {
+ final String id = "1560354";
+ final String userID = "13130406";
+ final String userName = "Alison Wonderland";
+ final String userLogin = "alice@gmail.com";
+ final String groupID = "119720";
+ final String groupName = "family";
+ final BoxGroupMembership.Role role = BoxGroupMembership.Role.MEMBER;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"total_count\": 1,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"group_membership\",\n"
+ + " \"id\": \"1560354\",\n"
+ + " \"user\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13130406\",\n"
+ + " \"name\": \"Alison Wonderland\",\n"
+ + " \"login\": \"alice@gmail.com\"\n"
+ + " },\n"
+ + " \"group\": {\n"
+ + " \"type\": \"group\",\n"
+ + " \"id\": \"119720\",\n"
+ + " \"name\": \"family\"\n"
+ + " },\n"
+ + " \"role\": \"member\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"limit\": 100,\n"
+ + " \"offset\": 0\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxUser user = new BoxUser(api, "0");
+ Iterator iterator = user.getAllMemberships().iterator();
+ BoxGroupMembership.Info info = iterator.next();
+ assertEquals(id, info.getID());
+ assertEquals(userID, info.getUser().getID());
+ assertEquals(userName, info.getUser().getName());
+ assertEquals(userLogin, info.getUser().getLogin());
+ assertEquals(groupID, info.getGroup().getID());
+ assertEquals(groupName, info.getGroup().getName());
+ assertEquals(role, info.getRole());
+ assertEquals(false, iterator.hasNext());
+ }
+
@Test
@Category(IntegrationTest.class)
public void getCurrentUserInfoIsCorrect() throws InterruptedException {
From 0b354f9c02f1b2fcb5c97e9b280414d2ceffb60f Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Fri, 11 Nov 2016 17:48:09 +0100
Subject: [PATCH 009/119] get all metadata on file feature implementation and
testing
---
doc/files.md | 15 +++
src/main/java/com/box/sdk/BoxFile.java | 17 +++
src/main/java/com/box/sdk/BoxItem.java | 7 ++
src/main/java/com/box/sdk/Metadata.java | 41 +++++++
src/test/java/com/box/sdk/BoxFileTest.java | 128 ++++++++++++++++++++-
5 files changed, 206 insertions(+), 2 deletions(-)
diff --git a/doc/files.md b/doc/files.md
index 24f959a87..6b7113c74 100644
--- a/doc/files.md
+++ b/doc/files.md
@@ -25,6 +25,7 @@ file's contents, upload new versions, and perform other common file operations
* [Get Metadata](#get-metadata)
* [Update Metadata](#update-metadata)
* [Delete Metadata](#delete-metadata)
+* [Get All Metadata on File](#get-all-metadata-on-file)
Get a File's Information
------------------------
@@ -357,3 +358,17 @@ file.deleteMetadata();
[delete-metadata-2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#deleteMetadata(java.lang.String)
[delete-metadata-3]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#deleteMetadata(java.lang.String,%20java.lang.String)
+Get All Metadata on File
+--------------
+
+[`getAllMetadata(String...)`][get-all-metadata] method will return an iterable that will page through all of the metadata associated with the file.
+
+```java
+BoxFile file = new BoxFile(api, "id");
+Iterable metadataList = file.getAllMetadata("name", "description");
+for (Metadata metadata : metadataList) {
+ // Do something with the metadata.
+}
+```
+
+[get-all-metadata]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#getAllMetadata(java.lang.String...)
\ No newline at end of file
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 8530ac0ae..29efcd4dc 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -75,6 +75,14 @@ public BoxFile(BoxAPIConnection api, String id) {
super(api, id);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected URL getItemURL() {
+ return FILE_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
+ }
+
@Override
public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
BoxSharedLink.Permissions permissions) {
@@ -678,6 +686,15 @@ public void unlock() {
request.send();
}
+ /**
+ * Used to retrieve all metadata associated with the file.
+ * @param fields the optional fields to retrieve.
+ * @return An iterable of metadata instances associated with the file.
+ */
+ public Iterable getAllMetadata(String ... fields) {
+ return Metadata.getAllMetadata(this, fields);
+ }
+
/**
* Gets the file properties metadata.
* @return the metadata returned from the server.
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index 7248b1a32..073f13890 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -37,6 +37,13 @@ public BoxItem(BoxAPIConnection api, String id) {
super(api, id);
}
+ /**
+ * @return URL for the current object, constructed as base URL pus an item specifier.
+ */
+ protected URL getItemURL() {
+ return new URLTemplate("").build(this.getAPI().getBaseURL());
+ }
+
/**
* Gets an item that was shared with a shared link.
* @param api the API connection to be used by the shared item.
diff --git a/src/main/java/com/box/sdk/Metadata.java b/src/main/java/com/box/sdk/Metadata.java
index 40a87bf81..02f446450 100644
--- a/src/main/java/com/box/sdk/Metadata.java
+++ b/src/main/java/com/box/sdk/Metadata.java
@@ -30,7 +30,24 @@ public class Metadata {
*/
public static final String ENTERPRISE_METADATA_SCOPE = "enterprise";
+ /**
+ * The default limit of entries per response.
+ */
+ public static final int DEFAULT_LIMIT = 100;
+
+ /**
+ * URL template for all metadata associated with item.
+ */
+ private static final URLTemplate GET_ALL_METADATA_URL_TEMPLATE = new URLTemplate("/metadata");
+
+ /**
+ * Values contained by the metadata object.
+ */
private final JsonObject values;
+
+ /**
+ * Operations to be applied to the metadata object.
+ */
private JsonArray operations;
/**
@@ -56,6 +73,30 @@ public Metadata(Metadata other) {
this.values = new JsonObject(other.values);
}
+ /**
+ * Used to retrieve all metadata associated with the item.
+ * @param item item to get metadata for.
+ * @param fields the optional fields to retrieve.
+ * @return An iterable of metadata instances associated with the item.
+ */
+ public static Iterable getAllMetadata(BoxItem item, String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new BoxResourceIterable(
+ item.getAPI(),
+ GET_ALL_METADATA_URL_TEMPLATE.buildWithQuery(item.getItemURL().toString(), builder.toString()),
+ DEFAULT_LIMIT) {
+
+ @Override
+ protected Metadata factory(JsonObject jsonObject) {
+ return new Metadata(jsonObject);
+ }
+
+ };
+ }
+
/**
* Returns the 36 character UUID to identify the metadata object.
* @return the metadata ID.
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 85a039286..1434faf1d 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -15,8 +15,17 @@
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
-
-import static org.hamcrest.Matchers.*;
+import java.util.Iterator;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyLong;
@@ -30,7 +39,122 @@
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxFile} related unit tests.
+ */
public class BoxFileTest {
+
+ /**
+ * Unit test for {@link BoxFile#getAllMetadata(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMetadataSendsCorrectRequest() {
+ final BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/files/5010739061/metadata?fields=name%2Cdescription&limit=100",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ BoxFile file = new BoxFile(api, "5010739061");
+ Iterator iterator = file.getAllMetadata("name", "description").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxFile#getAllMetadata(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMetadateParseAllFieldsCorrectly() {
+ final String firstEntrycurrentDocumentStage = "Init";
+ final String firstEntryType = "documentFlow-452b4c9d-c3ad-4ac7-b1ad-9d5192f2fc5f";
+ final String firstEntryParent = "file_5010739061";
+ final String firstEntryID = "50ba0dba-0f89-4395-b867-3e057c1f6ed9";
+ final int firstEntryVersion = 4;
+ final int firstEntryTypeVersion = 2;
+ final String firstEntryNeedApprovalFrom = "Smith";
+ final String firstEntryTemplate = "documentFlow";
+ final String firstEntryScope = "enterprise_12345";
+ final String secondEntryType = "productInfo-9d7b6993-b09e-4e52-b197-e42f0ea995b9";
+ final String secondEntryParent = "file_5010739061";
+ final String secondEntryID = "15d1014a-06c2-47ad-9916-014eab456194";
+ final int secondEntryVersion = 2;
+ final int secondEntryTypeVersion = 1;
+ final int secondEntrySkuNumber = 45334223;
+ final String secondEntryDescription = "Watch";
+ final String secondEntryTemplate = "productInfo";
+ final String secondEntryScope = "enterprise_12345";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"currentDocumentStage\": \"Init\",\n"
+ + " \"$type\": \"documentFlow-452b4c9d-c3ad-4ac7-b1ad-9d5192f2fc5f\",\n"
+ + " \"$parent\": \"file_5010739061\",\n"
+ + " \"$id\": \"50ba0dba-0f89-4395-b867-3e057c1f6ed9\",\n"
+ + " \"$version\": 4,\n"
+ + " \"$typeVersion\": 2,\n"
+ + " \"needsApprovalFrom\": \"Smith\",\n"
+ + " \"$template\": \"documentFlow\",\n"
+ + " \"$scope\": \"enterprise_12345\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"$type\": \"productInfo-9d7b6993-b09e-4e52-b197-e42f0ea995b9\",\n"
+ + " \"$parent\": \"file_5010739061\",\n"
+ + " \"$id\": \"15d1014a-06c2-47ad-9916-014eab456194\",\n"
+ + " \"$version\": 2,\n"
+ + " \"$typeVersion\": 1,\n"
+ + " \"skuNumber\": 45334223,\n"
+ + " \"description\": \"Watch\",\n"
+ + " \"$template\": \"productInfo\",\n"
+ + " \"$scope\": \"enterprise_12345\"\n"
+ + " }\n"
+ + "\n"
+ + " ],\n"
+ + " \"limit\": 100\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxFile file = new BoxFile(api, "0");
+ Iterator iterator = file.getAllMetadata().iterator();
+ Metadata entry = iterator.next();
+ Assert.assertEquals(firstEntrycurrentDocumentStage, entry.get("/currentDocumentStage"));
+ Assert.assertEquals(firstEntryType, entry.getTypeName());
+ Assert.assertEquals(firstEntryParent, entry.getParentID());
+ Assert.assertEquals(firstEntryID, entry.getID());
+ Assert.assertEquals(firstEntryVersion, (int) Integer.valueOf(entry.get("/$version")));
+ Assert.assertEquals(firstEntryTypeVersion, (int) Integer.valueOf(entry.get("/$typeVersion")));
+ Assert.assertEquals(firstEntryNeedApprovalFrom, entry.get("/needsApprovalFrom"));
+ Assert.assertEquals(firstEntryTemplate, entry.getTemplateName());
+ Assert.assertEquals(firstEntryScope, entry.getScope());
+ entry = iterator.next();
+ Assert.assertEquals(secondEntryType, entry.getTypeName());
+ Assert.assertEquals(secondEntryParent, entry.getParentID());
+ Assert.assertEquals(secondEntryID, entry.getID());
+ Assert.assertEquals(secondEntryVersion, (int) Integer.valueOf(entry.get("/$version")));
+ Assert.assertEquals(secondEntryTypeVersion, (int) Integer.valueOf(entry.get("/$typeVersion")));
+ Assert.assertEquals(secondEntrySkuNumber, (int) Integer.valueOf(entry.get("/skuNumber")));
+ Assert.assertEquals(secondEntryDescription, entry.get("/description"));
+ Assert.assertEquals(secondEntryTemplate, entry.getTemplateName());
+ Assert.assertEquals(secondEntryScope, entry.getScope());
+
+ }
+
@Test
@Category(IntegrationTest.class)
public void uploadAndDownloadFileSucceeds() throws IOException {
From da6dd1abde6c967e1689b7bcb9159cd845bd2826 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Mon, 14 Nov 2016 10:53:20 +0100
Subject: [PATCH 010/119] get all metadata on folder feature implementation
---
doc/folders.md | 16 +++
src/main/java/com/box/sdk/BoxFile.java | 17 +++
src/main/java/com/box/sdk/BoxFolder.java | 17 +++
src/main/java/com/box/sdk/BoxItem.java | 7 +
src/main/java/com/box/sdk/Metadata.java | 41 ++++++
src/test/java/com/box/sdk/BoxFileTest.java | 128 ++++++++++++++++++-
src/test/java/com/box/sdk/BoxFolderTest.java | 127 +++++++++++++++++-
7 files changed, 348 insertions(+), 5 deletions(-)
diff --git a/doc/folders.md b/doc/folders.md
index 1df932d0f..63e1fbbd5 100644
--- a/doc/folders.md
+++ b/doc/folders.md
@@ -21,6 +21,7 @@ group, and perform other common folder operations (move, copy, delete, etc.).
* [Get Metadata](#get-metadata)
* [Update Metadata](#update-metadata)
* [Delete Metadata](#delete-metadata)
+* [Get All Metadata on Folder](#get-all-metadata-on-folder)
Get the User's Root Folder
--------------------------
@@ -329,3 +330,18 @@ folder.deleteMetadata();
[delete-metadata]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#deleteMetadata()
[delete-metadata-2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#deleteMetadata(java.lang.String)
[delete-metadata-3]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#deleteMetadata(java.lang.String,%20java.lang.String)
+
+Get All Metadata on Folder
+-------------------------
+
+[`getAllMetadata(String...)`][get-all-metadata] method will return an iterable that will page through all of the metadata associated with the folder.
+
+```java
+BoxFolder file = new BoxFolder(api, "id");
+Iterable metadataList = folder.getAllMetadata("name", "description");
+for (Metadata metadata : metadataList) {
+ // Do something with the metadata.
+}
+```
+
+[get-all-metadata]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#getAllMetadata(java.lang.String...)
\ No newline at end of file
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 8530ac0ae..29efcd4dc 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -75,6 +75,14 @@ public BoxFile(BoxAPIConnection api, String id) {
super(api, id);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected URL getItemURL() {
+ return FILE_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
+ }
+
@Override
public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
BoxSharedLink.Permissions permissions) {
@@ -678,6 +686,15 @@ public void unlock() {
request.send();
}
+ /**
+ * Used to retrieve all metadata associated with the file.
+ * @param fields the optional fields to retrieve.
+ * @return An iterable of metadata instances associated with the file.
+ */
+ public Iterable getAllMetadata(String ... fields) {
+ return Metadata.getAllMetadata(this, fields);
+ }
+
/**
* Gets the file properties metadata.
* @return the metadata returned from the server.
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 8d8c70010..2c00e8784 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -52,6 +52,14 @@ public BoxFolder(BoxAPIConnection api, String id) {
super(api, id);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected URL getItemURL() {
+ return FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
+ }
+
/**
* Gets the current user's root folder.
* @param api the API connection to be used by the folder.
@@ -532,6 +540,15 @@ public BoxWebHook.Info addWebHook(URL address, BoxWebHook.Trigger... triggers) {
return BoxWebHook.create(this, address, triggers);
}
+ /**
+ * Used to retrieve all metadata associated with the folder.
+ * @param fields the optional fields to retrieve.
+ * @return An iterable of metadata instances associated with the folder
+ */
+ public Iterable getAllMetadata(String ... fields) {
+ return Metadata.getAllMetadata(this, fields);
+ }
+
/**
* This method is deprecated, please use the {@link BoxSearch} class instead.
* Searches this folder and all descendant folders using a given queryPlease use BoxSearch Instead.
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index 7248b1a32..073f13890 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -37,6 +37,13 @@ public BoxItem(BoxAPIConnection api, String id) {
super(api, id);
}
+ /**
+ * @return URL for the current object, constructed as base URL pus an item specifier.
+ */
+ protected URL getItemURL() {
+ return new URLTemplate("").build(this.getAPI().getBaseURL());
+ }
+
/**
* Gets an item that was shared with a shared link.
* @param api the API connection to be used by the shared item.
diff --git a/src/main/java/com/box/sdk/Metadata.java b/src/main/java/com/box/sdk/Metadata.java
index 40a87bf81..02f446450 100644
--- a/src/main/java/com/box/sdk/Metadata.java
+++ b/src/main/java/com/box/sdk/Metadata.java
@@ -30,7 +30,24 @@ public class Metadata {
*/
public static final String ENTERPRISE_METADATA_SCOPE = "enterprise";
+ /**
+ * The default limit of entries per response.
+ */
+ public static final int DEFAULT_LIMIT = 100;
+
+ /**
+ * URL template for all metadata associated with item.
+ */
+ private static final URLTemplate GET_ALL_METADATA_URL_TEMPLATE = new URLTemplate("/metadata");
+
+ /**
+ * Values contained by the metadata object.
+ */
private final JsonObject values;
+
+ /**
+ * Operations to be applied to the metadata object.
+ */
private JsonArray operations;
/**
@@ -56,6 +73,30 @@ public Metadata(Metadata other) {
this.values = new JsonObject(other.values);
}
+ /**
+ * Used to retrieve all metadata associated with the item.
+ * @param item item to get metadata for.
+ * @param fields the optional fields to retrieve.
+ * @return An iterable of metadata instances associated with the item.
+ */
+ public static Iterable getAllMetadata(BoxItem item, String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new BoxResourceIterable(
+ item.getAPI(),
+ GET_ALL_METADATA_URL_TEMPLATE.buildWithQuery(item.getItemURL().toString(), builder.toString()),
+ DEFAULT_LIMIT) {
+
+ @Override
+ protected Metadata factory(JsonObject jsonObject) {
+ return new Metadata(jsonObject);
+ }
+
+ };
+ }
+
/**
* Returns the 36 character UUID to identify the metadata object.
* @return the metadata ID.
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 85a039286..1434faf1d 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -15,8 +15,17 @@
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
-
-import static org.hamcrest.Matchers.*;
+import java.util.Iterator;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyLong;
@@ -30,7 +39,122 @@
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxFile} related unit tests.
+ */
public class BoxFileTest {
+
+ /**
+ * Unit test for {@link BoxFile#getAllMetadata(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMetadataSendsCorrectRequest() {
+ final BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/files/5010739061/metadata?fields=name%2Cdescription&limit=100",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ BoxFile file = new BoxFile(api, "5010739061");
+ Iterator iterator = file.getAllMetadata("name", "description").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxFile#getAllMetadata(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMetadateParseAllFieldsCorrectly() {
+ final String firstEntrycurrentDocumentStage = "Init";
+ final String firstEntryType = "documentFlow-452b4c9d-c3ad-4ac7-b1ad-9d5192f2fc5f";
+ final String firstEntryParent = "file_5010739061";
+ final String firstEntryID = "50ba0dba-0f89-4395-b867-3e057c1f6ed9";
+ final int firstEntryVersion = 4;
+ final int firstEntryTypeVersion = 2;
+ final String firstEntryNeedApprovalFrom = "Smith";
+ final String firstEntryTemplate = "documentFlow";
+ final String firstEntryScope = "enterprise_12345";
+ final String secondEntryType = "productInfo-9d7b6993-b09e-4e52-b197-e42f0ea995b9";
+ final String secondEntryParent = "file_5010739061";
+ final String secondEntryID = "15d1014a-06c2-47ad-9916-014eab456194";
+ final int secondEntryVersion = 2;
+ final int secondEntryTypeVersion = 1;
+ final int secondEntrySkuNumber = 45334223;
+ final String secondEntryDescription = "Watch";
+ final String secondEntryTemplate = "productInfo";
+ final String secondEntryScope = "enterprise_12345";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"currentDocumentStage\": \"Init\",\n"
+ + " \"$type\": \"documentFlow-452b4c9d-c3ad-4ac7-b1ad-9d5192f2fc5f\",\n"
+ + " \"$parent\": \"file_5010739061\",\n"
+ + " \"$id\": \"50ba0dba-0f89-4395-b867-3e057c1f6ed9\",\n"
+ + " \"$version\": 4,\n"
+ + " \"$typeVersion\": 2,\n"
+ + " \"needsApprovalFrom\": \"Smith\",\n"
+ + " \"$template\": \"documentFlow\",\n"
+ + " \"$scope\": \"enterprise_12345\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"$type\": \"productInfo-9d7b6993-b09e-4e52-b197-e42f0ea995b9\",\n"
+ + " \"$parent\": \"file_5010739061\",\n"
+ + " \"$id\": \"15d1014a-06c2-47ad-9916-014eab456194\",\n"
+ + " \"$version\": 2,\n"
+ + " \"$typeVersion\": 1,\n"
+ + " \"skuNumber\": 45334223,\n"
+ + " \"description\": \"Watch\",\n"
+ + " \"$template\": \"productInfo\",\n"
+ + " \"$scope\": \"enterprise_12345\"\n"
+ + " }\n"
+ + "\n"
+ + " ],\n"
+ + " \"limit\": 100\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxFile file = new BoxFile(api, "0");
+ Iterator iterator = file.getAllMetadata().iterator();
+ Metadata entry = iterator.next();
+ Assert.assertEquals(firstEntrycurrentDocumentStage, entry.get("/currentDocumentStage"));
+ Assert.assertEquals(firstEntryType, entry.getTypeName());
+ Assert.assertEquals(firstEntryParent, entry.getParentID());
+ Assert.assertEquals(firstEntryID, entry.getID());
+ Assert.assertEquals(firstEntryVersion, (int) Integer.valueOf(entry.get("/$version")));
+ Assert.assertEquals(firstEntryTypeVersion, (int) Integer.valueOf(entry.get("/$typeVersion")));
+ Assert.assertEquals(firstEntryNeedApprovalFrom, entry.get("/needsApprovalFrom"));
+ Assert.assertEquals(firstEntryTemplate, entry.getTemplateName());
+ Assert.assertEquals(firstEntryScope, entry.getScope());
+ entry = iterator.next();
+ Assert.assertEquals(secondEntryType, entry.getTypeName());
+ Assert.assertEquals(secondEntryParent, entry.getParentID());
+ Assert.assertEquals(secondEntryID, entry.getID());
+ Assert.assertEquals(secondEntryVersion, (int) Integer.valueOf(entry.get("/$version")));
+ Assert.assertEquals(secondEntryTypeVersion, (int) Integer.valueOf(entry.get("/$typeVersion")));
+ Assert.assertEquals(secondEntrySkuNumber, (int) Integer.valueOf(entry.get("/skuNumber")));
+ Assert.assertEquals(secondEntryDescription, entry.get("/description"));
+ Assert.assertEquals(secondEntryTemplate, entry.getTemplateName());
+ Assert.assertEquals(secondEntryScope, entry.getScope());
+
+ }
+
@Test
@Category(IntegrationTest.class)
public void uploadAndDownloadFileSucceeds() throws IOException {
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index 1085216ab..8f010a1a5 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -5,7 +5,12 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TimeZone;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@@ -19,14 +24,22 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.skyscreamer.jsonassert.JSONCompareMode.*;
+import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.containing;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
@@ -198,6 +211,114 @@ public String getJSON() {
}
}
+ /**
+ * Unit test for {@link BoxFolder#getAllMetadata(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMetadataSendsCorrectRequest() {
+ final BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/folders/5010739061/metadata?fields=name%2Csize&limit=100",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ BoxFolder folder = new BoxFolder(api, "5010739061");
+ Iterator iterator = folder.getAllMetadata("name", "size").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxFolder#getAllMetadata(String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllMetadateParseAllFieldsCorrectly() {
+ final String firstEntrycurrentDocumentStage = "Init";
+ final String firstEntryType = "documentFlow-452b4c9d-c3ad-4ac7-b1ad-9d5192f2fc5f";
+ final String firstEntryParent = "file_5010739061";
+ final String firstEntryID = "50ba0dba-0f89-4395-b867-3e057c1f6ed9";
+ final int firstEntryVersion = 4;
+ final int firstEntryTypeVersion = 2;
+ final String firstEntryNeedApprovalFrom = "Smith";
+ final String firstEntryTemplate = "documentFlow";
+ final String firstEntryScope = "enterprise_12345";
+ final String secondEntryType = "productInfo-9d7b6993-b09e-4e52-b197-e42f0ea995b9";
+ final String secondEntryParent = "file_5010739061";
+ final String secondEntryID = "15d1014a-06c2-47ad-9916-014eab456194";
+ final int secondEntryVersion = 2;
+ final int secondEntryTypeVersion = 1;
+ final int secondEntrySkuNumber = 45334223;
+ final String secondEntryDescription = "Watch";
+ final String secondEntryTemplate = "productInfo";
+ final String secondEntryScope = "enterprise_12345";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"currentDocumentStage\": \"Init\",\n"
+ + " \"$type\": \"documentFlow-452b4c9d-c3ad-4ac7-b1ad-9d5192f2fc5f\",\n"
+ + " \"$parent\": \"file_5010739061\",\n"
+ + " \"$id\": \"50ba0dba-0f89-4395-b867-3e057c1f6ed9\",\n"
+ + " \"$version\": 4,\n"
+ + " \"$typeVersion\": 2,\n"
+ + " \"needsApprovalFrom\": \"Smith\",\n"
+ + " \"$template\": \"documentFlow\",\n"
+ + " \"$scope\": \"enterprise_12345\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"$type\": \"productInfo-9d7b6993-b09e-4e52-b197-e42f0ea995b9\",\n"
+ + " \"$parent\": \"file_5010739061\",\n"
+ + " \"$id\": \"15d1014a-06c2-47ad-9916-014eab456194\",\n"
+ + " \"$version\": 2,\n"
+ + " \"$typeVersion\": 1,\n"
+ + " \"skuNumber\": 45334223,\n"
+ + " \"description\": \"Watch\",\n"
+ + " \"$template\": \"productInfo\",\n"
+ + " \"$scope\": \"enterprise_12345\"\n"
+ + " }\n"
+ + "\n"
+ + " ],\n"
+ + " \"limit\": 100\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxFolder folder = new BoxFolder(api, "0");
+ Iterator iterator = folder.getAllMetadata().iterator();
+ Metadata entry = iterator.next();
+ Assert.assertEquals(firstEntrycurrentDocumentStage, entry.get("/currentDocumentStage"));
+ Assert.assertEquals(firstEntryType, entry.getTypeName());
+ Assert.assertEquals(firstEntryParent, entry.getParentID());
+ Assert.assertEquals(firstEntryID, entry.getID());
+ Assert.assertEquals(firstEntryVersion, (int) Integer.valueOf(entry.get("/$version")));
+ Assert.assertEquals(firstEntryTypeVersion, (int) Integer.valueOf(entry.get("/$typeVersion")));
+ Assert.assertEquals(firstEntryNeedApprovalFrom, entry.get("/needsApprovalFrom"));
+ Assert.assertEquals(firstEntryTemplate, entry.getTemplateName());
+ Assert.assertEquals(firstEntryScope, entry.getScope());
+ entry = iterator.next();
+ Assert.assertEquals(secondEntryType, entry.getTypeName());
+ Assert.assertEquals(secondEntryParent, entry.getParentID());
+ Assert.assertEquals(secondEntryID, entry.getID());
+ Assert.assertEquals(secondEntryVersion, (int) Integer.valueOf(entry.get("/$version")));
+ Assert.assertEquals(secondEntryTypeVersion, (int) Integer.valueOf(entry.get("/$typeVersion")));
+ Assert.assertEquals(secondEntrySkuNumber, (int) Integer.valueOf(entry.get("/skuNumber")));
+ Assert.assertEquals(secondEntryDescription, entry.get("/description"));
+ Assert.assertEquals(secondEntryTemplate, entry.getTemplateName());
+ Assert.assertEquals(secondEntryScope, entry.getScope());
+
+ }
+
@Test
@Category(IntegrationTest.class)
public void creatingAndDeletingFolderSucceeds() {
From 7fd56819c13d1aba31ebdf1cdcd6175ec6a14838 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Wed, 16 Nov 2016 11:28:26 +0100
Subject: [PATCH 011/119] watermarking features implemented, tested, docimented
---
README.md | 1 +
doc/watermarking.md | 87 ++++++++++++
src/main/java/com/box/sdk/BoxFile.java | 36 +++++
src/main/java/com/box/sdk/BoxFolder.java | 26 ++++
src/main/java/com/box/sdk/BoxItem.java | 55 +++++++
src/main/java/com/box/sdk/BoxWatermark.java | 110 ++++++++++++++
src/test/java/com/box/sdk/BoxFileTest.java | 140 +++++++++++++++++-
src/test/java/com/box/sdk/BoxFolderTest.java | 142 ++++++++++++++++++-
8 files changed, 593 insertions(+), 4 deletions(-)
create mode 100644 doc/watermarking.md
create mode 100644 src/main/java/com/box/sdk/BoxWatermark.java
diff --git a/README.md b/README.md
index 79b201c6f..64a427031 100644
--- a/README.md
+++ b/README.md
@@ -168,6 +168,7 @@ You can find guides and tutorials in the `doc` directory.
* [Collections](doc/collections.md)
* [Devices](doc/devices.md)
* [Retention Policies](doc/retention_policies.md)
+* [Watermarking](doc/watermarking.md)
Javadocs are generated when `gradle javadoc` is run and can be found in
`build/doc/javadoc`.
diff --git a/doc/watermarking.md b/doc/watermarking.md
new file mode 100644
index 000000000..572bde70c
--- /dev/null
+++ b/doc/watermarking.md
@@ -0,0 +1,87 @@
+Watermarking
+======
+
+The ability to watermark files and folders is represented as a sub-resource on the Files and Folders resources, respectively. You can think of the sub-resource as a "label" marking whether the file or folder is watermarked or not. If you apply a watermark label to a folder, then all files inside of it will be protected by the watermark (e.g. previews will be watermarked). However, those files' watermark sub-resource is independent from the folder that got watermarked. This allows you to watermark files and folders independently.
+
+* [Get Watermark on File](#get-watermark-on-file)
+* [Apply Watermark on File](#apply-watermark-on-file)
+* [Remove Watermark on File](#remove-watermark-on-file)
+* [Get Watermark on Folder](#get-watermark-on-folder)
+* [Apply Watermark on Folder](#apply-watermark-on-folder)
+* [Remove Watermark on Folder](#remove-watermark-on-folder)
+
+Get Watermark on File
+--------------
+
+Calling [`getWatermark(String...)`][get-watermark-on-file] will return a BoxWatermark object containing information about the watermark associated for this file. If the file does not have a watermark applied on it, a 404 Not Found will be returned.
+
+```java
+BoxFile file = new BoxFile(api, id);
+BoxWatermark watermark = file.getWatermark();
+```
+
+[get-watermark-on-file]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#getWatermark(java.lang.String...)
+
+Apply Watermark on File
+--------------
+
+To apply watermark on file, call [`applyWatermark()`][apply-watermark-on-file] method. While the endpoint accepts a JSON body describing the watermark to apply, custom watermarks are not supported yet.
+The method will return a BoxWatermark object containing information about the watermark applied on this file.
+
+```java
+BoxFile file = new BoxFile(api, id);
+file.applyWatermark();
+```
+
+[apply-watermark-on-file]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#applyWatermark()
+
+Remove Watermark on File
+--------------
+
+A watermark can be removed by calling the [`removeWatermark()`][remove-watermark-on-file] method.
+If the file did not have a watermark applied on it, a 404 Not Found will be returned by API.
+
+```java
+BoxFile file = new BoxFile(api, id);
+file.removeWatermark();
+```
+
+[remove-watermark-on-file]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#removeWatermark()
+
+Get Watermark on Folder
+--------------
+
+Calling [`getWatermark(String...)`][get-watermark-on-folder] will return a BoxWatermark object containing information about the watermark associated for this folder. If the folder does not have a watermark applied on it, a 404 Not Found will be returned.
+
+```java
+BoxFolder folder = new BoxFolder(api, id);
+BoxWatermark watermark = folder.getWatermark();
+```
+
+[get-watermark-on-folder]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#getWatermark(java.lang.String...)
+
+Apply Watermark on Folder
+--------------
+
+To apply watermark on folder, call [`applyWatermark()`][apply-watermark-on-folder] method. While the endpoint accepts a JSON body describing the watermark to apply, custom watermarks are not supported yet.
+The method will return a BoxWatermark object containing information about the watermark applied on this folder.
+
+```java
+BoxFolder folder = new BoxFolder(api, id);
+fodler.applyWatermark();
+```
+
+[apply-watermark-on-folder]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#applyWatermark()
+
+Remove Watermark on Folder
+--------------
+
+A watermark can be removed by calling the [`removeWatermark()`][remove-watermark-on-folder] method.
+If the folder did not have a watermark applied on it, a 404 Not Found will be returned by API.
+
+```java
+BoxFolder folder = new BoxFolder(api, id);
+folder.removeWatermark();
+```
+
+[remove-watermark-on-folder]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#removeWatermark()
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 8530ac0ae..794b84398 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -758,6 +758,42 @@ public void deleteMetadata(String typeName, String scope) {
request.send();
}
+ /**
+ * Used to retrieve the watermark for the file.
+ * If the file does not have a watermark applied to it, a 404 Not Found will be returned by API.
+ * @param fields the fields to retrieve.
+ * @return the watermark associated with the file.
+ */
+ public BoxWatermark getWatermark(String... fields) {
+ return this.getWatermark(FILE_URL_TEMPLATE, fields);
+ }
+
+ /**
+ * Used to apply or update the watermark for the file.
+ * @return the watermark associated with the file.
+ */
+ public BoxWatermark applyWatermark() {
+ return this.applyWatermark(FILE_URL_TEMPLATE, BoxWatermark.WATERMARK_DEFAULT_IMPRINT);
+ }
+
+ /**
+ * Removes a watermark from the file.
+ * If the file did not have a watermark applied to it, a 404 Not Found will be returned by API.
+ */
+ public void removeWatermark() {
+ this.removeWatermark(FILE_URL_TEMPLATE);
+ }
+
+ private String scopeBasedOnType(String typeName) {
+ String scope;
+ if (typeName.equals(Metadata.DEFAULT_METADATA_TYPE)) {
+ scope = Metadata.GLOBAL_METADATA_SCOPE;
+ } else {
+ scope = Metadata.ENTERPRISE_METADATA_SCOPE;
+ }
+ return scope;
+ }
+
@Override
public BoxFile.Info setCollections(BoxCollection... collections) {
JsonArray jsonArray = new JsonArray();
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 8d8c70010..592f96e25 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -532,6 +532,32 @@ public BoxWebHook.Info addWebHook(URL address, BoxWebHook.Trigger... triggers) {
return BoxWebHook.create(this, address, triggers);
}
+ /**
+ * Used to retrieve the watermark for the folder.
+ * If the folder does not have a watermark applied to it, a 404 Not Found will be returned by API.
+ * @param fields the fields to retrieve.
+ * @return the watermark associated with the folder.
+ */
+ public BoxWatermark getWatermark(String... fields) {
+ return this.getWatermark(FOLDER_INFO_URL_TEMPLATE, fields);
+ }
+
+ /**
+ * Used to apply or update the watermark for the folder.
+ * @return the watermark associated with the folder.
+ */
+ public BoxWatermark applyWatermark() {
+ return this.applyWatermark(FOLDER_INFO_URL_TEMPLATE, BoxWatermark.WATERMARK_DEFAULT_IMPRINT);
+ }
+
+ /**
+ * Removes a watermark from the folder.
+ * If the folder did not have a watermark applied to it, a 404 Not Found will be returned by API.
+ */
+ public void removeWatermark() {
+ this.removeWatermark(FOLDER_INFO_URL_TEMPLATE);
+ }
+
/**
* This method is deprecated, please use the {@link BoxSearch} class instead.
* Searches this folder and all descendant folders using a given queryPlease use BoxSearch Instead.
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index 7248b1a32..d9c151fa1 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -28,6 +28,11 @@ public abstract class BoxItem extends BoxResource {
private static final URLTemplate SHARED_ITEM_URL_TEMPLATE = new URLTemplate("shared_items");
+ /**
+ * Url template for operations with watermarks.
+ */
+ private static final URLTemplate WATERMARK_URL_TEMPLATE = new URLTemplate("/watermark");
+
/**
* Constructs a BoxItem for an item with a given ID.
* @param api the API connection to be used by the item.
@@ -63,6 +68,56 @@ public static BoxItem.Info getSharedItem(BoxAPIConnection api, String sharedLink
return (BoxItem.Info) BoxResource.parseInfo(newAPI, json);
}
+ /**
+ * Used to retrieve the watermark for the item.
+ * If the item does not have a watermark applied to it, a 404 Not Found will be returned by API.
+ * @param itemUrl url template for the item.
+ * @param fields the fields to retrieve.
+ * @return the watermark associated with the item.
+ */
+ protected BoxWatermark getWatermark(URLTemplate itemUrl, String... fields) {
+ URL watermarkUrl = itemUrl.build(this.getAPI().getBaseURL(), this.getID());
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = WATERMARK_URL_TEMPLATE.buildWithQuery(watermarkUrl.toString(), builder.toString());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ return new BoxWatermark(response.getJSON());
+ }
+
+ /**
+ * Used to apply or update the watermark for the item.
+ * @param itemUrl url template for the item.
+ * @param imprint the value must be "default", as custom watermarks is not yet supported.
+ * @return the watermark associated with the item.
+ */
+ protected BoxWatermark applyWatermark(URLTemplate itemUrl, String imprint) {
+ URL watermarkUrl = itemUrl.build(this.getAPI().getBaseURL(), this.getID());
+ URL url = WATERMARK_URL_TEMPLATE.build(watermarkUrl.toString());
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
+ JsonObject body = new JsonObject()
+ .add(BoxWatermark.WATERMARK_JSON_KEY, new JsonObject()
+ .add(BoxWatermark.WATERMARK_IMPRINT_JSON_KEY, imprint));
+ request.setBody(body.toString());
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ return new BoxWatermark(response.getJSON());
+ }
+
+ /**
+ * Removes a watermark from the item.
+ * If the item did not have a watermark applied to it, a 404 Not Found will be returned by API.
+ * @param itemUrl url template for the item.
+ */
+ protected void removeWatermark(URLTemplate itemUrl) {
+ URL watermarkUrl = itemUrl.build(this.getAPI().getBaseURL(), this.getID());
+ URL url = WATERMARK_URL_TEMPLATE.build(watermarkUrl.toString());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
+ BoxAPIResponse response = request.send();
+ response.disconnect();
+ }
+
/**
* Copies this item to another folder.
* @param destination the destination folder.
diff --git a/src/main/java/com/box/sdk/BoxWatermark.java b/src/main/java/com/box/sdk/BoxWatermark.java
new file mode 100644
index 000000000..38fd7f88c
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxWatermark.java
@@ -0,0 +1,110 @@
+package com.box.sdk;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ * Represents a watermark.
+ * Watermarks are used to protect sensitive information in the Box account.
+ *
+ * @see Watermarking
+ */
+public class BoxWatermark extends BoxJSONObject {
+
+ /**
+ * Default imprint for watermarks.
+ */
+ public static final String WATERMARK_DEFAULT_IMPRINT = "default";
+
+ /**
+ * Json key for watermark.
+ * @see BoxWatermark#parseJSONMember(JsonObject.Member)
+ */
+ public static final String WATERMARK_JSON_KEY = "watermark";
+
+ /**
+ * Json key for created_at param.
+ * @see BoxWatermark#parseJSONMember(JsonObject.Member)
+ */
+ public static final String CREATED_AT_JSON_KEY = "created_at";
+
+ /**
+ * Json key for modified_at param.
+ * @see BoxWatermark#parseJSONMember(JsonObject.Member)
+ */
+ public static final String MODIFIED_AT_JSON_KEY = "modified_at";
+
+ /**
+ * Json key for watermark param.
+ */
+ public static final String WATERMARK_IMPRINT_JSON_KEY = "imprint";
+
+ /**
+ * @see #getCreatedAt()
+ */
+ private Date createdAt;
+
+ /**
+ * @see #getModifiedAt()
+ */
+ private Date modifiedAt;
+
+ /**
+ * Constructs an empty watermark object.
+ */
+ public BoxWatermark() {
+ super();
+ }
+
+ /**
+ * Constructs a watermark object by parsing information from a JSON string.
+ * @param json the JSON string to parse.
+ */
+ public BoxWatermark(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs a watermark object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ BoxWatermark(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ /**
+ * @return the time that the watermark was created.
+ */
+ public Date getCreatedAt() {
+ return this.createdAt;
+ }
+
+ /**
+ * @return the time that the watermark was last modified.
+ */
+ public Date getModifiedAt() {
+ return this.modifiedAt;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void parseJSONMember(JsonObject.Member member) {
+ super.parseJSONMember(member);
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals(WATERMARK_JSON_KEY)) {
+ try {
+ this.createdAt = BoxDateFormat.parse(value.asObject().get(CREATED_AT_JSON_KEY).asString());
+ this.modifiedAt = BoxDateFormat.parse(value.asObject().get(MODIFIED_AT_JSON_KEY).asString());
+ } catch (ParseException e) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
+ }
+
+}
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 85a039286..d8ad78056 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -10,13 +10,22 @@
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyLong;
@@ -30,7 +39,136 @@
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxFile} related tests.
+ */
public class BoxFileTest {
+
+ /**
+ * Unit test for {@link BoxFile#getWatermark(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetWatermarkSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/files/0/watermark",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ new BoxFile(api, "0").getWatermark();
+ }
+
+ /**
+ * Unit test for {@link BoxFile#getWatermark(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetWatermarkParseAllFieldsCorrectly() throws ParseException {
+ final Date createdAt = BoxDateFormat.parse("2016-10-31T15:33:33-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2016-11-31T15:33:33-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"watermark\": {\n"
+ + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
+ + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWatermark watermark = new BoxFile(api, "0").getWatermark();
+ Assert.assertEquals(createdAt, watermark.getCreatedAt());
+ Assert.assertEquals(modifiedAt, watermark.getModifiedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxFile#applyWatermark()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testApplyWatermarkSendsCorrectJson() {
+ final String imprint = "default";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/files/0/watermark",
+ request.getUrl().toString());
+ Assert.assertEquals(imprint, json.get("watermark").asObject().get("imprint").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ new BoxFile(api, "0").applyWatermark();
+ }
+
+ /**
+ * Unit test for {@link BoxFile#applyWatermark()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testApplyWatermarkParseAllFieldsCorrectly() throws ParseException {
+ final Date createdAt = BoxDateFormat.parse("2016-10-31T15:33:33-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2016-11-31T15:33:33-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"watermark\": {\n"
+ + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
+ + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWatermark watermark = new BoxFile(api, "0").applyWatermark();
+ Assert.assertEquals(createdAt, watermark.getCreatedAt());
+ Assert.assertEquals(modifiedAt, watermark.getModifiedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxFile#removeWatermark()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testRemoveWatermarkSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/files/0/watermark",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ new BoxFile(api, "0").removeWatermark();
+ }
+
@Test
@Category(IntegrationTest.class)
public void uploadAndDownloadFileSucceeds() throws IOException {
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index 1085216ab..5a550ac5f 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -4,8 +4,13 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.TimeZone;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@@ -19,14 +24,22 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.skyscreamer.jsonassert.JSONCompareMode.*;
+import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.containing;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
@@ -198,6 +211,129 @@ public String getJSON() {
}
}
+ /**
+ * Unit test for {@link BoxFolder#getWatermark(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetWatermarkSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/folders/0/watermark",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ new BoxFolder(api, "0").getWatermark();
+ }
+
+ /**
+ * Unit test for {@link BoxFolder#getWatermark(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetWatermarkParseAllFieldsCorrectly() throws ParseException {
+ final Date createdAt = BoxDateFormat.parse("2016-10-31T15:33:33-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2016-11-31T15:33:33-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"watermark\": {\n"
+ + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
+ + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWatermark watermark = new BoxFolder(api, "0").getWatermark();
+ Assert.assertEquals(createdAt, watermark.getCreatedAt());
+ Assert.assertEquals(modifiedAt, watermark.getModifiedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxFolder#applyWatermark()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testApplyWatermarkSendsCorrectJson() {
+ final String imprint = "default";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/folders/0/watermark",
+ request.getUrl().toString());
+ Assert.assertEquals(imprint, json.get("watermark").asObject().get("imprint").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ new BoxFolder(api, "0").applyWatermark();
+ }
+
+ /**
+ * Unit test for {@link BoxFolder#applyWatermark()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testApplyWatermarkParseAllFieldsCorrectly() throws ParseException {
+ final Date createdAt = BoxDateFormat.parse("2016-10-31T15:33:33-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2016-11-31T15:33:33-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"watermark\": {\n"
+ + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
+ + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWatermark watermark = new BoxFolder(api, "0").applyWatermark();
+ Assert.assertEquals(createdAt, watermark.getCreatedAt());
+ Assert.assertEquals(modifiedAt, watermark.getModifiedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxFolder#removeWatermark()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testRemoveWatermarkSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/folders/0/watermark",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ new BoxFolder(api, "0").removeWatermark();
+ }
+
@Test
@Category(IntegrationTest.class)
public void creatingAndDeletingFolderSucceeds() {
From f0b453fa20fb88ae2fe7960eeb55fd9500051eb4 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Wed, 16 Nov 2016 16:38:30 +0100
Subject: [PATCH 012/119] fixes and tests for tasks
---
src/main/java/com/box/sdk/BoxTask.java | 64 +++
.../java/com/box/sdk/BoxTaskAssignment.java | 18 +
.../box/sdk/BoxTaskAssignmentIterator.java | 67 +++
src/test/java/com/box/sdk/BoxFileTest.java | 127 ++++-
.../com/box/sdk/BoxTaskAssignmentTest.java | 278 +++++++++
src/test/java/com/box/sdk/BoxTaskTest.java | 529 ++++++++++++++++++
6 files changed, 1082 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/box/sdk/BoxTaskAssignmentIterator.java
create mode 100644 src/test/java/com/box/sdk/BoxTaskAssignmentTest.java
diff --git a/src/main/java/com/box/sdk/BoxTask.java b/src/main/java/com/box/sdk/BoxTask.java
index 6139d0254..115a50ce2 100644
--- a/src/main/java/com/box/sdk/BoxTask.java
+++ b/src/main/java/com/box/sdk/BoxTask.java
@@ -4,6 +4,7 @@
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import com.eclipsesource.json.JsonArray;
@@ -66,6 +67,33 @@ public BoxTaskAssignment.Info addAssignment(BoxUser assignTo) {
return addedAssignment.new Info(responseJSON);
}
+ /**
+ * Adds a new assignment to this task using user's login as identifier.
+ * @param assignToLogin the login of user to assign the task to.
+ * @return information about the newly added task assignment.
+ */
+ public BoxTaskAssignment.Info addAssignmentByLogin(String assignToLogin) {
+ JsonObject taskJSON = new JsonObject();
+ taskJSON.add("type", "task");
+ taskJSON.add("id", this.getID());
+
+ JsonObject assignToJSON = new JsonObject();
+ assignToJSON.add("login", assignToLogin);
+
+ JsonObject requestJSON = new JsonObject();
+ requestJSON.add("task", taskJSON);
+ requestJSON.add("assign_to", assignToJSON);
+
+ URL url = ADD_TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL());
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
+ request.setBody(requestJSON.toString());
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+
+ BoxTaskAssignment addedAssignment = new BoxTaskAssignment(this.getAPI(), responseJSON.get("id").asString());
+ return addedAssignment.new Info(responseJSON);
+ }
+
/**
* Gets any assignments for this task.
* @return a list of assignments for this task.
@@ -89,6 +117,25 @@ public List getAssignments() {
return assignments;
}
+ /**
+ * Gets an iterable of all the assignments of this task.
+ * @param fields the fields to retrieve.
+ * @return an iterable containing info about all the assignments.
+ */
+ public Iterable getAllAssignments(String ... fields) {
+ final QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new Iterable() {
+ public Iterator iterator() {
+ URL url = GET_ASSIGNMENTS_URL_TEMPLATE.buildWithQuery(
+ BoxTask.this.getAPI().getBaseURL(), builder.toString(), BoxTask.this.getID());
+ return new BoxTaskAssignmentIterator(BoxTask.this.getAPI(), url);
+ }
+ };
+ }
+
/**
* Gets information about this task.
* @return info about this task.
@@ -101,6 +148,23 @@ public Info getInfo() {
return new Info(responseJSON);
}
+ /**
+ * Gets information about this task.
+ * @param fields the fields to retrieve.
+ * @return info about this task.
+ */
+ public Info getInfo(String... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = TASK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+ return new Info(responseJSON);
+ }
+
/**
* Updates the information about this task with any info fields that have been modified locally.
*
diff --git a/src/main/java/com/box/sdk/BoxTaskAssignment.java b/src/main/java/com/box/sdk/BoxTaskAssignment.java
index 817d4e9a5..46f354e86 100644
--- a/src/main/java/com/box/sdk/BoxTaskAssignment.java
+++ b/src/main/java/com/box/sdk/BoxTaskAssignment.java
@@ -48,6 +48,24 @@ public Info getInfo() {
return new Info(responseJSON);
}
+ /**
+ * Gets information about this task assignment.
+ * @param fields the fields to retrieve.
+ * @return info about this task assignment.
+ */
+ public Info getInfo(String... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = TASK_ASSIGNMENT_URL_TEMPLATE.buildWithQuery(
+ this.getAPI().getBaseURL(), builder.toString(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+ return new Info(responseJSON);
+ }
+
/**
* Updates the information about this task assignment with any info fields that have been modified locally.
*
diff --git a/src/main/java/com/box/sdk/BoxTaskAssignmentIterator.java b/src/main/java/com/box/sdk/BoxTaskAssignmentIterator.java
new file mode 100644
index 000000000..2dd49f813
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxTaskAssignmentIterator.java
@@ -0,0 +1,67 @@
+package com.box.sdk;
+
+import java.net.URL;
+import java.util.Iterator;
+
+import com.eclipsesource.json.JsonObject;
+
+
+/**
+ * An iterator object for {@link BoxTaskAssignment} object.
+ * Supports offset-based paging.
+ */
+class BoxTaskAssignmentIterator implements Iterator {
+
+ /**
+ * The limit of entries per response.
+ */
+ private static final long LIMIT = 100;
+
+ /**
+ * The API connection to be used.
+ */
+ private final BoxAPIConnection api;
+
+ /**
+ * Iterator object with paging support.
+ */
+ private final JSONIterator jsonIterator;
+
+ /**
+ * Creates new BoxTaskAssignment iterator.
+ * @param api The API connection to be used by the iterator.
+ * @param url The endpoint url.
+ */
+ BoxTaskAssignmentIterator(BoxAPIConnection api, URL url) {
+ this.api = api;
+ this.jsonIterator = new JSONIterator(api, url, LIMIT);
+ }
+
+ /**
+ * @return false if current element is the last.
+ */
+ @Override
+ public boolean hasNext() {
+ return this.jsonIterator.hasNext();
+ }
+
+
+ /**
+ * @return next BoxTaskAssignment.Info object in the list.
+ */
+ @Override
+ public BoxTaskAssignment.Info next() {
+ JsonObject nextJSONObject = this.jsonIterator.next();
+ String id = nextJSONObject.get("id").asString();
+
+ BoxTaskAssignment assignment = new BoxTaskAssignment(this.api, id);
+ return assignment.new Info(nextJSONObject);
+ }
+
+ /**
+ * Remove operation is not supported.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 85a039286..1307f994d 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -10,13 +10,22 @@
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyLong;
@@ -30,7 +39,123 @@
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxFile} related tests.
+ */
public class BoxFileTest {
+
+ /**
+ * Unit test for {@link BoxFile#addTask(BoxTask.Action, String, Date)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddTaskSendsCorrectJson() throws ParseException {
+ final String itemType = "file";
+ final String itemID = "1";
+ final String action = "review";
+ final String message = "text message";
+ final Date dueAt = BoxDateFormat.parse("2016-05-09T17:41:27-07:00");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/tasks",
+ request.getUrl().toString());
+ Assert.assertEquals(itemID, json.get("item").asObject().get("id").asString());
+ Assert.assertEquals(itemType, json.get("item").asObject().get("type").asString());
+ Assert.assertEquals(action, json.get("action").asString());
+ Assert.assertEquals(message, json.get("message").asString());
+ try {
+ Assert.assertEquals(dueAt, BoxDateFormat.parse(json.get("due_at").asString()));
+ } catch (ParseException e) {
+ assert false;
+ }
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxFile(api, "1").addTask(BoxTask.Action.REVIEW, message, dueAt);
+ }
+
+ /**
+ * Unit test for {@link BoxFile#addTask(BoxTask.Action, String, Date)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddTaskParseAllFieldsCorrectly() throws ParseException {
+ final String id = "1839355";
+ final String itemID = "7287087200";
+ final String itemSequenceID = "0";
+ final String itemEtag = "0";
+ final String itemSha1 = "0bbd79a105c504f99573e3799756debba4c760cd";
+ final String itemName = "box-logo.png";
+ final Date dueAt = BoxDateFormat.parse("2014-04-03T11:09:43-07:00");
+ final BoxTask.Action action = BoxTask.Action.REVIEW;
+ final String message = "REVIEW PLZ K THX";
+ final int assignmentCount = 0;
+ final boolean isCompleted = false;
+ final String createdByID = "11993747";
+ final String createdByName = "sean";
+ final String createdByLogin = "sean@box.com";
+ final Date createdAt = BoxDateFormat.parse("2013-04-03T11:12:54-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"task\",\n"
+ + " \"id\": \"1839355\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"7287087200\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"sha1\": \"0bbd79a105c504f99573e3799756debba4c760cd\",\n"
+ + " \"name\": \"box-logo.png\"\n"
+ + " },\n"
+ + " \"due_at\": \"2014-04-03T11:09:43-07:00\",\n"
+ + " \"action\": \"review\",\n"
+ + " \"message\": \"REVIEW PLZ K THX\",\n"
+ + " \"task_assignment_collection\": {\n"
+ + " \"total_count\": 0,\n"
+ + " \"entries\": []\n"
+ + " },\n"
+ + " \"is_completed\": false,\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"11993747\",\n"
+ + " \"name\": \"sean\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " },\n"
+ + " \"created_at\": \"2013-04-03T11:12:54-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxTask.Info info = new BoxFile(api, id).addTask(action, message, dueAt);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(itemID, info.getItem().getID());
+ Assert.assertEquals(itemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(itemEtag, info.getItem().getEtag());
+ Assert.assertEquals(itemSha1, info.getItem().getSha1());
+ Assert.assertEquals(itemName, info.getItem().getName());
+ Assert.assertEquals(dueAt, info.getDueAt());
+ Assert.assertEquals(action, info.getAction());
+ Assert.assertEquals(message, info.getMessage());
+ Assert.assertEquals(assignmentCount, info.getTaskAssignments().size());
+ Assert.assertEquals(isCompleted, info.isCompleted());
+ Assert.assertEquals(createdByID, info.getCreatedBy().getID());
+ Assert.assertEquals(createdByName, info.getCreatedBy().getName());
+ Assert.assertEquals(createdByLogin, info.getCreatedBy().getLogin());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ }
+
@Test
@Category(IntegrationTest.class)
public void uploadAndDownloadFileSucceeds() throws IOException {
diff --git a/src/test/java/com/box/sdk/BoxTaskAssignmentTest.java b/src/test/java/com/box/sdk/BoxTaskAssignmentTest.java
new file mode 100644
index 000000000..8be7c1f24
--- /dev/null
+++ b/src/test/java/com/box/sdk/BoxTaskAssignmentTest.java
@@ -0,0 +1,278 @@
+package com.box.sdk;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxTaskAssignment} related tests.
+ */
+public class BoxTaskAssignmentTest {
+
+ /**
+ * Unit test for {@link BoxTaskAssignment#getInfo()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/task_assignments/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxTaskAssignment(api, "0").getInfo();
+ }
+
+ /**
+ * Unit test for {@link BoxTaskAssignment#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequestWithFields() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/task_assignments/0?fields=item%2Cmessage",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxTaskAssignment(api, "0").getInfo("item", "message");
+ }
+
+ /**
+ * Unit test for {@link BoxTaskAssignment#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "2698512";
+ final String itemID = "8018809384";
+ final String itemSequenceID = "0";
+ final String itemEtag = "0";
+ final String itemSha1 = "7840095ee096ee8297676a138d4e316eabb3ec96";
+ final String itemName = "scrumworksToTrello.js";
+ final String assignedToID = "1992432";
+ final String assignedToName = "rhaegar@box.com";
+ final String assignedToLogin = "rhaegar@box.com";
+ final String message = null;
+ final Date completedAt = null;
+ final Date assignedAt = BoxDateFormat.parse("2013-05-10T11:43:41-07:00");
+ final Date remindedAt = null;
+ final BoxTaskAssignment.ResolutionState resolutionState = BoxTaskAssignment.ResolutionState.INCOMPLETE;
+ final String assignedByID = "11993747";
+ final String assignedByName = "sean";
+ final String assignedByLogin = "sean@box.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"task_assignment\",\n"
+ + " \"id\": \"2698512\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"8018809384\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"sha1\": \"7840095ee096ee8297676a138d4e316eabb3ec96\",\n"
+ + " \"name\": \"scrumworksToTrello.js\"\n"
+ + " },\n"
+ + " \"assigned_to\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"1992432\",\n"
+ + " \"name\": \"rhaegar@box.com\",\n"
+ + " \"login\": \"rhaegar@box.com\"\n"
+ + " },\n"
+ + " \"message\": null,\n"
+ + " \"completed_at\": null,\n"
+ + " \"assigned_at\": \"2013-05-10T11:43:41-07:00\",\n"
+ + " \"reminded_at\": null,\n"
+ + " \"resolution_state\": \"incomplete\",\n"
+ + " \"assigned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"11993747\",\n"
+ + " \"name\": \"sean\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxTaskAssignment.Info info = new BoxTaskAssignment(api, id).getInfo("item", "message");
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(itemID, info.getItem().getID());
+ Assert.assertEquals(itemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(itemEtag, info.getItem().getEtag());
+ Assert.assertEquals(itemSha1, ((BoxFile.Info) info.getItem()).getSha1());
+ Assert.assertEquals(itemName, info.getItem().getName());
+ Assert.assertEquals(assignedToID, info.getAssignedTo().getID());
+ Assert.assertEquals(assignedToName, info.getAssignedTo().getName());
+ Assert.assertEquals(assignedToLogin, info.getAssignedTo().getLogin());
+ Assert.assertEquals(message, info.getMessage());
+ Assert.assertEquals(completedAt, info.getCompletedAt());
+ Assert.assertEquals(assignedAt, info.getAssignedAt());
+ Assert.assertEquals(remindedAt, info.getRemindedAt());
+ Assert.assertEquals(resolutionState, info.getResolutionState());
+ Assert.assertEquals(assignedByID, info.getAssignedBy().getID());
+ Assert.assertEquals(assignedByName, info.getAssignedBy().getName());
+ Assert.assertEquals(assignedByLogin, info.getAssignedBy().getLogin());
+ }
+
+ /**
+ * Unit test for {@link BoxTaskAssignment#updateInfo(BoxTaskAssignment.Info)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoSendsCorrectJson() {
+ final String message = "hello!";
+ final String resolutionState = "approved";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/task_assignments/0",
+ request.getUrl().toString());
+ Assert.assertEquals(message, json.get("message").asString());
+ Assert.assertEquals(resolutionState, json.get("resolution_state").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxTaskAssignment assignment = new BoxTaskAssignment(api, "0");
+ BoxTaskAssignment.Info info = assignment.new Info();
+ info.addPendingChange("message", message);
+ info.addPendingChange("resolution_state", resolutionState);
+ assignment.updateInfo(info);
+ }
+
+ /**
+ * Unit test for {@link BoxTaskAssignment#updateInfo(BoxTaskAssignment.Info)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "2698512";
+ final String itemID = "8018809384";
+ final String itemSequenceID = "0";
+ final String itemEtag = "0";
+ final String itemSha1 = "7840095ee096ee8297676a138d4e316eabb3ec96";
+ final String itemName = "scrumworksToTrello.js";
+ final String assignedToID = "1992432";
+ final String assignedToName = "rhaegar@box.com";
+ final String assignedToLogin = "rhaegar@box.com";
+ final String message = "hello!!!";
+ final Date completedAt = null;
+ final Date assignedAt = BoxDateFormat.parse("2013-05-10T11:43:41-07:00");
+ final Date remindedAt = null;
+ final BoxTaskAssignment.ResolutionState resolutionState = BoxTaskAssignment.ResolutionState.INCOMPLETE;
+ final String assignedByID = "11993747";
+ final String assignedByName = "sean";
+ final String assignedByLogin = "sean@box.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"task_assignment\",\n"
+ + " \"id\": \"2698512\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"8018809384\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"sha1\": \"7840095ee096ee8297676a138d4e316eabb3ec96\",\n"
+ + " \"name\": \"scrumworksToTrello.js\"\n"
+ + " },\n"
+ + " \"assigned_to\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"1992432\",\n"
+ + " \"name\": \"rhaegar@box.com\",\n"
+ + " \"login\": \"rhaegar@box.com\"\n"
+ + " },\n"
+ + " \"message\": \"hello!!!\",\n"
+ + " \"completed_at\": null,\n"
+ + " \"assigned_at\": \"2013-05-10T11:43:41-07:00\",\n"
+ + " \"reminded_at\": null,\n"
+ + " \"resolution_state\": \"incomplete\",\n"
+ + " \"assigned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"11993747\",\n"
+ + " \"name\": \"sean\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxTaskAssignment assignment = new BoxTaskAssignment(api, id);
+ BoxTaskAssignment.Info info = assignment.new Info();
+ info.addPendingChange("message", message);
+ assignment.updateInfo(info);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(itemID, info.getItem().getID());
+ Assert.assertEquals(itemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(itemEtag, info.getItem().getEtag());
+ Assert.assertEquals(itemSha1, ((BoxFile.Info) info.getItem()).getSha1());
+ Assert.assertEquals(itemName, info.getItem().getName());
+ Assert.assertEquals(assignedToID, info.getAssignedTo().getID());
+ Assert.assertEquals(assignedToName, info.getAssignedTo().getName());
+ Assert.assertEquals(assignedToLogin, info.getAssignedTo().getLogin());
+ Assert.assertEquals(message, info.getMessage());
+ Assert.assertEquals(completedAt, info.getCompletedAt());
+ Assert.assertEquals(assignedAt, info.getAssignedAt());
+ Assert.assertEquals(remindedAt, info.getRemindedAt());
+ Assert.assertEquals(resolutionState, info.getResolutionState());
+ Assert.assertEquals(assignedByID, info.getAssignedBy().getID());
+ Assert.assertEquals(assignedByName, info.getAssignedBy().getName());
+ Assert.assertEquals(assignedByLogin, info.getAssignedBy().getLogin());
+ }
+
+ /**
+ * Unit test for {@link BoxTaskAssignment#updateInfo(BoxTaskAssignment.Info)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/task_assignments/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxTaskAssignment(api, "0").delete();
+ }
+}
diff --git a/src/test/java/com/box/sdk/BoxTaskTest.java b/src/test/java/com/box/sdk/BoxTaskTest.java
index 848c74938..a016b78d6 100644
--- a/src/test/java/com/box/sdk/BoxTaskTest.java
+++ b/src/test/java/com/box/sdk/BoxTaskTest.java
@@ -2,18 +2,547 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
+import java.util.Iterator;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxTask} related tests.
+ */
public class BoxTaskTest {
+
+ /**
+ * Unit test for {@link BoxTask#getInfo()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/tasks/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxTask(api, "0").getInfo();
+ }
+
+ /**
+ * Unit test for {@link BoxTask#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequestWithFields() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/tasks/0?fields=item%2Cdue_at",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxTask(api, "0").getInfo("item", "due_at");
+ }
+
+ /**
+ * Unit test for {@link BoxTask#getInfo()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "1839355";
+ final String itemID = "7287087200";
+ final String itemSequenceID = "0";
+ final String itemEtag = "0";
+ final String itemSha1 = "0bbd79a105c504f99573e3799756debba4c760cd";
+ final String itemName = "box-logo.png";
+ final Date dueAt = BoxDateFormat.parse("2014-04-03T11:09:43-07:00");
+ final BoxTask.Action action = BoxTask.Action.REVIEW;
+ final String message = "REVIEW PLZ K THX";
+ final int assignmentCount = 0;
+ final boolean isCompleted = false;
+ final String createdByID = "11993747";
+ final String createdByName = "sean";
+ final String createdByLogin = "sean@box.com";
+ final Date createdAt = BoxDateFormat.parse("2013-04-03T11:12:54-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"task\",\n"
+ + " \"id\": \"1839355\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"7287087200\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"sha1\": \"0bbd79a105c504f99573e3799756debba4c760cd\",\n"
+ + " \"name\": \"box-logo.png\"\n"
+ + " },\n"
+ + " \"due_at\": \"2014-04-03T11:09:43-07:00\",\n"
+ + " \"action\": \"review\",\n"
+ + " \"message\": \"REVIEW PLZ K THX\",\n"
+ + " \"task_assignment_collection\": {\n"
+ + " \"total_count\": 0,\n"
+ + " \"entries\": []\n"
+ + " },\n"
+ + " \"is_completed\": false,\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"11993747\",\n"
+ + " \"name\": \"sean\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " },\n"
+ + " \"created_at\": \"2013-04-03T11:12:54-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxTask.Info info = new BoxTask(api, id).getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(itemID, info.getItem().getID());
+ Assert.assertEquals(itemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(itemEtag, info.getItem().getEtag());
+ Assert.assertEquals(itemSha1, info.getItem().getSha1());
+ Assert.assertEquals(itemName, info.getItem().getName());
+ Assert.assertEquals(dueAt, info.getDueAt());
+ Assert.assertEquals(action, info.getAction());
+ Assert.assertEquals(message, info.getMessage());
+ Assert.assertEquals(assignmentCount, info.getTaskAssignments().size());
+ Assert.assertEquals(isCompleted, info.isCompleted());
+ Assert.assertEquals(createdByID, info.getCreatedBy().getID());
+ Assert.assertEquals(createdByName, info.getCreatedBy().getName());
+ Assert.assertEquals(createdByLogin, info.getCreatedBy().getLogin());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxTask#updateInfo(BoxTask.Info)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoSendsCorrectJson() throws ParseException {
+ final String action = "review";
+ final String message = "text message";
+ final Date dueAt = BoxDateFormat.parse("2016-05-09T17:41:27-07:00");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/tasks/0",
+ request.getUrl().toString());
+ Assert.assertEquals(action, json.get("action").asString());
+ Assert.assertEquals(message, json.get("message").asString());
+ try {
+ Assert.assertEquals(dueAt, BoxDateFormat.parse(json.get("due_at").asString()));
+ } catch (ParseException e) {
+ assert false;
+ }
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxTask task = new BoxTask(api, "0");
+ BoxTask.Info info = task.new Info();
+ info.addPendingChange("message", message);
+ info.addPendingChange("action", action);
+ info.addPendingChange("due_at", BoxDateFormat.format(dueAt));
+ task.updateInfo(info);
+ }
+
+ /**
+ * Unit test for {@link BoxTask#updateInfo(BoxTask.Info)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "1839355";
+ final String itemID = "7287087200";
+ final String itemSequenceID = "0";
+ final String itemEtag = "0";
+ final String itemSha1 = "0bbd79a105c504f99573e3799756debba4c760cd";
+ final String itemName = "box-logo.png";
+ final Date dueAt = BoxDateFormat.parse("2014-04-03T11:09:43-07:00");
+ final BoxTask.Action action = BoxTask.Action.REVIEW;
+ final String message = "REVIEW PLZ K THX";
+ final int assignmentCount = 0;
+ final boolean isCompleted = false;
+ final String createdByID = "11993747";
+ final String createdByName = "sean";
+ final String createdByLogin = "sean@box.com";
+ final Date createdAt = BoxDateFormat.parse("2013-04-03T11:12:54-07:00");
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"task\",\n"
+ + " \"id\": \"1839355\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"7287087200\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"sha1\": \"0bbd79a105c504f99573e3799756debba4c760cd\",\n"
+ + " \"name\": \"box-logo.png\"\n"
+ + " },\n"
+ + " \"due_at\": \"2014-04-03T11:09:43-07:00\",\n"
+ + " \"action\": \"review\",\n"
+ + " \"message\": \"REVIEW PLZ K THX\",\n"
+ + " \"task_assignment_collection\": {\n"
+ + " \"total_count\": 0,\n"
+ + " \"entries\": []\n"
+ + " },\n"
+ + " \"is_completed\": false,\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"11993747\",\n"
+ + " \"name\": \"sean\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " },\n"
+ + " \"created_at\": \"2013-04-03T11:12:54-07:00\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxTask task = new BoxTask(api, id);
+ BoxTask.Info info = task.new Info();
+ info.addPendingChange("message", message);
+ task.updateInfo(info);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(itemID, info.getItem().getID());
+ Assert.assertEquals(itemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(itemEtag, info.getItem().getEtag());
+ Assert.assertEquals(itemSha1, info.getItem().getSha1());
+ Assert.assertEquals(itemName, info.getItem().getName());
+ Assert.assertEquals(dueAt, info.getDueAt());
+ Assert.assertEquals(action, info.getAction());
+ Assert.assertEquals(message, info.getMessage());
+ Assert.assertEquals(assignmentCount, info.getTaskAssignments().size());
+ Assert.assertEquals(isCompleted, info.isCompleted());
+ Assert.assertEquals(createdByID, info.getCreatedBy().getID());
+ Assert.assertEquals(createdByName, info.getCreatedBy().getName());
+ Assert.assertEquals(createdByLogin, info.getCreatedBy().getLogin());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxTask#delete()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/tasks/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxTask(api, "0").delete();
+ }
+
+ /**
+ * Unit test for {@link BoxTask#addAssignmentByLogin(String)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddAssignmentByLoginSendsCorrectJson() {
+ final String taskType = "task";
+ final String taskID = "0";
+ final String assignToLogin = "login@somewhere.com";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/task_assignments",
+ request.getUrl().toString());
+ Assert.assertEquals(taskType, json.get("task").asObject().get("type").asString());
+ Assert.assertEquals(taskID, json.get("task").asObject().get("id").asString());
+ Assert.assertEquals(assignToLogin, json.get("assign_to").asObject().get("login").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ new BoxTask(api, taskID).addAssignmentByLogin(assignToLogin);
+ }
+
+ /**
+ * Unit test for {@link BoxTask#addAssignment(BoxUser)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddAssignmentSendsCorrectJson() {
+ final String taskType = "task";
+ final String taskID = "0";
+ final String assignToID = "1";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/task_assignments",
+ request.getUrl().toString());
+ Assert.assertEquals(taskType, json.get("task").asObject().get("type").asString());
+ Assert.assertEquals(taskID, json.get("task").asObject().get("id").asString());
+ Assert.assertEquals(assignToID, json.get("assign_to").asObject().get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, assignToID);
+ new BoxTask(api, taskID).addAssignment(user);
+ }
+
+ /**
+ * Unit test for {@link BoxTask#addAssignment(BoxUser)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAddAssignmentParseAllFieldsCorrectly() throws ParseException {
+ final String id = "2698512";
+ final String itemID = "8018809384";
+ final String itemSequenceID = "0";
+ final String itemEtag = "0";
+ final String itemSha1 = "7840095ee096ee8297676a138d4e316eabb3ec96";
+ final String itemName = "scrumworksToTrello.js";
+ final String assignedToID = "1992432";
+ final String assignedToName = "rhaegar@box.com";
+ final String assignedToLogin = "rhaegar@box.com";
+ final String message = null;
+ final Date completedAt = null;
+ final Date assignedAt = BoxDateFormat.parse("2013-05-10T11:43:41-07:00");
+ final Date remindedAt = null;
+ final BoxTaskAssignment.ResolutionState resolutionState = BoxTaskAssignment.ResolutionState.INCOMPLETE;
+ final String assignedByID = "11993747";
+ final String assignedByName = "sean";
+ final String assignedByLogin = "sean@box.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"task_assignment\",\n"
+ + " \"id\": \"2698512\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"8018809384\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"sha1\": \"7840095ee096ee8297676a138d4e316eabb3ec96\",\n"
+ + " \"name\": \"scrumworksToTrello.js\"\n"
+ + " },\n"
+ + " \"assigned_to\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"1992432\",\n"
+ + " \"name\": \"rhaegar@box.com\",\n"
+ + " \"login\": \"rhaegar@box.com\"\n"
+ + " },\n"
+ + " \"message\": null,\n"
+ + " \"completed_at\": null,\n"
+ + " \"assigned_at\": \"2013-05-10T11:43:41-07:00\",\n"
+ + " \"reminded_at\": null,\n"
+ + " \"resolution_state\": \"incomplete\",\n"
+ + " \"assigned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"11993747\",\n"
+ + " \"name\": \"sean\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxUser user = new BoxUser(api, assignedToID);
+ BoxTaskAssignment.Info info = new BoxTask(api, id).addAssignment(user);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(itemID, info.getItem().getID());
+ Assert.assertEquals(itemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(itemEtag, info.getItem().getEtag());
+ Assert.assertEquals(itemSha1, ((BoxFile.Info) info.getItem()).getSha1());
+ Assert.assertEquals(itemName, info.getItem().getName());
+ Assert.assertEquals(assignedToID, info.getAssignedTo().getID());
+ Assert.assertEquals(assignedToName, info.getAssignedTo().getName());
+ Assert.assertEquals(assignedToLogin, info.getAssignedTo().getLogin());
+ Assert.assertEquals(message, info.getMessage());
+ Assert.assertEquals(completedAt, info.getCompletedAt());
+ Assert.assertEquals(assignedAt, info.getAssignedAt());
+ Assert.assertEquals(remindedAt, info.getRemindedAt());
+ Assert.assertEquals(resolutionState, info.getResolutionState());
+ Assert.assertEquals(assignedByID, info.getAssignedBy().getID());
+ Assert.assertEquals(assignedByName, info.getAssignedBy().getName());
+ Assert.assertEquals(assignedByLogin, info.getAssignedBy().getLogin());
+ }
+
+ /**
+ * Unit test for {@link BoxTask#getAllAssignments(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllAssignmentsSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/tasks/0/assignments?fields=item%2Cmessage&limit=100&offset=0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"total_count\": 1, \"offset\": 0, \"entries\":[]}";
+ }
+ };
+ }
+ });
+
+ Iterator iterator
+ = new BoxTask(api, "0").getAllAssignments("item", "message").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxTask#getAllAssignments(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAllAssignmentsParseAllFieldsCorrectly() {
+ final String firstId = "2485961";
+ final String firstItemID = "7287087200";
+ final String firstItemSequenceID = "0";
+ final String firstItemEtag = "0";
+ final String firstItemSha1 = "0bbd79a105c504f99573e3799756debba4c760cd";
+ final String firstItemName = "box-logo.png";
+ final String firstAssignedToID = "193425559";
+ final String firstAssignedToName = "Rhaegar Targaryen";
+ final String firstAssignedToLogin = "rhaegar@box.com";
+ final String secondId = "2485963";
+ final String secondItemID = "7287087204";
+ final String secondItemSequenceID = "1";
+ final String secondItemEtag = "1";
+ final String secondItemSha1 = "0bbd79a105c504f99573e3799756debb";
+ final String secondItemName = "box-icon.png";
+ final String secondAssignedToID = "1934255";
+ final String secondAssignedToName = "Tyrion Lannister";
+ final String secondAssignedToLogin = "littlebig@box.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"total_count\": 2,\n"
+ + " \"offset\": 0,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"task_assignment\",\n"
+ + " \"id\": \"2485961\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"7287087200\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"sha1\": \"0bbd79a105c504f99573e3799756debba4c760cd\",\n"
+ + " \"name\": \"box-logo.png\"\n"
+ + " },\n"
+ + " \"assigned_to\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"193425559\",\n"
+ + " \"name\": \"Rhaegar Targaryen\",\n"
+ + " \"login\": \"rhaegar@box.com\"\n"
+ + " }\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"task_assignment\",\n"
+ + " \"id\": \"2485963\",\n"
+ + " \"item\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"7287087204\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"sha1\": \"0bbd79a105c504f99573e3799756debb\",\n"
+ + " \"name\": \"box-icon.png\"\n"
+ + " },\n"
+ + " \"assigned_to\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"1934255\",\n"
+ + " \"name\": \"Tyrion Lannister\",\n"
+ + " \"login\": \"littlebig@box.com\"\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ Iterator iterator = new BoxTask(api, "0").getAllAssignments().iterator();
+ BoxTaskAssignment.Info info = iterator.next();
+ Assert.assertEquals(firstId, info.getID());
+ Assert.assertEquals(firstItemID, info.getItem().getID());
+ Assert.assertEquals(firstItemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(firstItemEtag, info.getItem().getEtag());
+ Assert.assertEquals(firstItemSha1, ((BoxFile.Info) info.getItem()).getSha1());
+ Assert.assertEquals(firstItemName, info.getItem().getName());
+ Assert.assertEquals(firstAssignedToID, info.getAssignedTo().getID());
+ Assert.assertEquals(firstAssignedToName, info.getAssignedTo().getName());
+ Assert.assertEquals(firstAssignedToLogin, info.getAssignedTo().getLogin());
+ info = iterator.next();
+ Assert.assertEquals(secondId, info.getID());
+ Assert.assertEquals(secondItemID, info.getItem().getID());
+ Assert.assertEquals(secondItemSequenceID, info.getItem().getSequenceID());
+ Assert.assertEquals(secondItemEtag, info.getItem().getEtag());
+ Assert.assertEquals(secondItemSha1, ((BoxFile.Info) info.getItem()).getSha1());
+ Assert.assertEquals(secondItemName, info.getItem().getName());
+ Assert.assertEquals(secondAssignedToID, info.getAssignedTo().getID());
+ Assert.assertEquals(secondAssignedToName, info.getAssignedTo().getName());
+ Assert.assertEquals(secondAssignedToLogin, info.getAssignedTo().getLogin());
+ Assert.assertEquals(false, iterator.hasNext());
+ }
+
@Test
@Category(IntegrationTest.class)
public void updateInfoSucceeds() {
From 7275777cfa3bb9ffb105db85f9c8fdcec736824c Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 16 Nov 2016 19:12:37 -0800
Subject: [PATCH 013/119] Adding isWatermarked to BoxItem.
---
src/main/java/com/box/sdk/BoxItem.java | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index 7248b1a32..c0b7c57b3 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -24,7 +24,7 @@ public abstract class BoxItem extends BoxResource {
"content_modified_at", "created_by", "modified_by", "owned_by", "shared_link", "parent", "item_status",
"version_number", "comment_count", "permissions", "tags", "lock", "extension", "is_package",
"folder_upload_email", "item_collection", "sync_state", "has_collaborations", "can_non_owners_invite",
- "file_version", "collections"};
+ "file_version", "collections", "watermark_info"};
private static final URLTemplate SHARED_ITEM_URL_TEMPLATE = new URLTemplate("shared_items");
@@ -153,6 +153,9 @@ public abstract class Info extends BoxResource.Info {
private BoxFolder.Info parent;
private String itemStatus;
private Set collections;
+ private Boolean isWatermarked;
+
+
/**
* Constructs an empty Info object.
@@ -373,6 +376,15 @@ public Iterable getCollections() {
return this.collections;
}
+
+ /**
+ * Gets flag indicating whether this file is Watermarked.
+ * @return whether the file is watermarked or not
+ */
+ public Boolean getIsWatermarked() {
+ return this.isWatermarked;
+ }
+
/**
* Sets the collections that this item belongs to.
* @param collections the new list of collections that this item should belong to.
@@ -466,6 +478,9 @@ protected void parseJSONMember(JsonObject.Member member) {
BoxCollection.Info collectionInfo = collection.new Info(jsonObject);
this.collections.add(collectionInfo);
}
+ } else if (memberName.equals("watermark_info")) {
+ JsonObject jsonObject = value.asObject();
+ this.isWatermarked = jsonObject.get("is_watermarked").asBoolean();
}
} catch (ParseException e) {
assert false : "A ParseException indicates a bug in the SDK.";
From b3033dbe65d12792b5a03ad783a630cd42b86827 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 17 Nov 2016 15:59:08 -0800
Subject: [PATCH 014/119] Moving is_watermarked from BoxItem to BoxFile and
BoxFolder
---
src/main/java/com/box/sdk/BoxFile.java | 12 ++++++++++++
src/main/java/com/box/sdk/BoxFolder.java | 12 ++++++++++++
src/main/java/com/box/sdk/BoxItem.java | 13 +------------
3 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 8530ac0ae..d98d2c69e 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -791,6 +791,7 @@ public class Info extends BoxItem.Info {
private BoxFileVersion version;
private URL previewLink;
private BoxLock lock;
+ private boolean isWatermarked;
/**
* Constructs an empty Info object.
@@ -892,6 +893,14 @@ public URL getPreviewLink() {
return this.previewLink;
}
+ /**
+ * Gets flag indicating whether this file is Watermarked.
+ * @return whether the file is watermarked or not
+ */
+ public Boolean getIsWatermarked() {
+ return this.isWatermarked;
+ }
+
@Override
protected void parseJSONMember(JsonObject.Member member) {
super.parseJSONMember(member);
@@ -925,6 +934,9 @@ protected void parseJSONMember(JsonObject.Member member) {
} else {
this.lock = new BoxLock(value.asObject(), BoxFile.this.getAPI());
}
+ } else if (memberName.equals("watermark_info")) {
+ JsonObject jsonObject = value.asObject();
+ this.isWatermarked = jsonObject.get("is_watermarked").asBoolean();
}
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 8d8c70010..5c2bd5a28 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -692,6 +692,7 @@ public class Info extends BoxItem.Info {
private SyncState syncState;
private EnumSet permissions;
private boolean canNonOwnersInvite;
+ private boolean isWatermarked;
/**
* Constructs an empty Info object.
@@ -784,6 +785,14 @@ public boolean getCanNonOwnersInvite() {
return this.canNonOwnersInvite;
}
+ /**
+ * Gets flag indicating whether this file is Watermarked.
+ * @return whether the file is watermarked or not
+ */
+ public Boolean getIsWatermarked() {
+ return this.isWatermarked;
+ }
+
@Override
public BoxFolder getResource() {
return BoxFolder.this;
@@ -813,6 +822,9 @@ protected void parseJSONMember(JsonObject.Member member) {
} else if (memberName.equals("can_non_owners_invite")) {
this.canNonOwnersInvite = value.asBoolean();
+ } else if (memberName.equals("watermark_info")) {
+ JsonObject jsonObject = value.asObject();
+ this.isWatermarked = jsonObject.get("is_watermarked").asBoolean();
}
}
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index c0b7c57b3..50ea912ac 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -153,7 +153,7 @@ public abstract class Info extends BoxResource.Info {
private BoxFolder.Info parent;
private String itemStatus;
private Set collections;
- private Boolean isWatermarked;
+
@@ -377,14 +377,6 @@ public Iterable getCollections() {
}
- /**
- * Gets flag indicating whether this file is Watermarked.
- * @return whether the file is watermarked or not
- */
- public Boolean getIsWatermarked() {
- return this.isWatermarked;
- }
-
/**
* Sets the collections that this item belongs to.
* @param collections the new list of collections that this item should belong to.
@@ -478,9 +470,6 @@ protected void parseJSONMember(JsonObject.Member member) {
BoxCollection.Info collectionInfo = collection.new Info(jsonObject);
this.collections.add(collectionInfo);
}
- } else if (memberName.equals("watermark_info")) {
- JsonObject jsonObject = value.asObject();
- this.isWatermarked = jsonObject.get("is_watermarked").asBoolean();
}
} catch (ParseException e) {
assert false : "A ParseException indicates a bug in the SDK.";
From 009a033789d8fed11efb4de51220244e93dc6e90 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 17 Nov 2016 16:11:06 -0800
Subject: [PATCH 015/119] Moving "watermark_info" fromBoxIyem ALL_FIELDS to
BoxFile and BoxFolder
---
src/main/java/com/box/sdk/BoxFile.java | 2 +-
src/main/java/com/box/sdk/BoxFolder.java | 2 +-
src/main/java/com/box/sdk/BoxItem.java | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index d98d2c69e..acab1c1ca 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -35,7 +35,7 @@ public class BoxFile extends BoxItem {
"description", "size", "path_collection", "created_at", "modified_at", "trashed_at", "purged_at",
"content_created_at", "content_modified_at", "created_by", "modified_by", "owned_by", "shared_link", "parent",
"item_status", "version_number", "comment_count", "permissions", "tags", "lock", "extension", "is_package",
- "file_version", "collections"};
+ "file_version", "collections", "watermark_info"};
/**
* Used to specify what filetype to request for a file thumbnail.
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 5c2bd5a28..91f9fe88a 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -29,7 +29,7 @@ public class BoxFolder extends BoxItem implements Iterable {
"description", "size", "path_collection", "created_by", "modified_by", "trashed_at", "purged_at",
"content_created_at", "content_modified_at", "owned_by", "shared_link", "folder_upload_email", "parent",
"item_status", "item_collection", "sync_state", "has_collaborations", "permissions", "tags",
- "can_non_owners_invite", "collections"};
+ "can_non_owners_invite", "collections", "watermark_info"};
private static final URLTemplate CREATE_FOLDER_URL = new URLTemplate("folders");
private static final URLTemplate CREATE_WEB_LINK_URL = new URLTemplate("web_links");
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index 50ea912ac..9de43eca6 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -24,7 +24,7 @@ public abstract class BoxItem extends BoxResource {
"content_modified_at", "created_by", "modified_by", "owned_by", "shared_link", "parent", "item_status",
"version_number", "comment_count", "permissions", "tags", "lock", "extension", "is_package",
"folder_upload_email", "item_collection", "sync_state", "has_collaborations", "can_non_owners_invite",
- "file_version", "collections", "watermark_info"};
+ "file_version", "collections"};
private static final URLTemplate SHARED_ITEM_URL_TEMPLATE = new URLTemplate("shared_items");
From ae57191383a2862755dbba4d15981181ee282e82 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 17 Nov 2016 16:16:56 -0800
Subject: [PATCH 016/119] removing extraneous blank lines from BoxItem.java
---
src/main/java/com/box/sdk/BoxItem.java | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index 9de43eca6..e32bfa5d0 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -154,9 +154,6 @@ public abstract class Info extends BoxResource.Info {
private String itemStatus;
private Set collections;
-
-
-
/**
* Constructs an empty Info object.
*/
@@ -375,8 +372,7 @@ public String getItemStatus() {
public Iterable getCollections() {
return this.collections;
}
-
-
+
/**
* Sets the collections that this item belongs to.
* @param collections the new list of collections that this item should belong to.
From f063d3d5f839604f279f24984796162efd573e79 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 17 Nov 2016 16:18:51 -0800
Subject: [PATCH 017/119] Removing trailing whitespace from BoxItem.java #375
---
src/main/java/com/box/sdk/BoxItem.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java
index e32bfa5d0..7248b1a32 100644
--- a/src/main/java/com/box/sdk/BoxItem.java
+++ b/src/main/java/com/box/sdk/BoxItem.java
@@ -372,7 +372,7 @@ public String getItemStatus() {
public Iterable getCollections() {
return this.collections;
}
-
+
/**
* Sets the collections that this item belongs to.
* @param collections the new list of collections that this item should belong to.
From 4a4223d45fb5b5046c971b512b6f168d31096015 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 17 Nov 2016 21:18:54 -0800
Subject: [PATCH 018/119] Changed type of getIsWatermarked from Boolean to
boolean
---
src/main/java/com/box/sdk/BoxFile.java | 2 +-
src/main/java/com/box/sdk/BoxFolder.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index acab1c1ca..57bc6edaf 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -897,7 +897,7 @@ public URL getPreviewLink() {
* Gets flag indicating whether this file is Watermarked.
* @return whether the file is watermarked or not
*/
- public Boolean getIsWatermarked() {
+ public boolean getIsWatermarked() {
return this.isWatermarked;
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 91f9fe88a..e0d6d4acd 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -789,7 +789,7 @@ public boolean getCanNonOwnersInvite() {
* Gets flag indicating whether this file is Watermarked.
* @return whether the file is watermarked or not
*/
- public Boolean getIsWatermarked() {
+ public boolean getIsWatermarked() {
return this.isWatermarked;
}
From 9720ab151e4481263e59680ec95d8a0702cc2899 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Tue, 25 Oct 2016 12:10:45 +0200
Subject: [PATCH 019/119] unit tests for BoxWeblink methods
---
README.md | 1 +
doc/weblinks.md | 68 ++++
src/test/java/com/box/sdk/BoxFolderTest.java | 247 +++++++++++++-
src/test/java/com/box/sdk/BoxWebLinkTest.java | 318 +++++++++++++++++-
4 files changed, 630 insertions(+), 4 deletions(-)
create mode 100644 doc/weblinks.md
diff --git a/README.md b/README.md
index 4344725bd..d4275e6ed 100644
--- a/README.md
+++ b/README.md
@@ -169,6 +169,7 @@ You can find guides and tutorials in the `doc` directory.
* [Devices](doc/devices.md)
* [Retention Policies](doc/retention_policies.md)
* [Legal Holds Policy](doc/legal_holds.md)
+* [Web Links](doc/weblinks.md)
Javadocs are generated when `gradle javadoc` is run and can be found in
`build/doc/javadoc`.
diff --git a/doc/weblinks.md b/doc/weblinks.md
new file mode 100644
index 000000000..3a606c935
--- /dev/null
+++ b/doc/weblinks.md
@@ -0,0 +1,68 @@
+Web Links
+======
+
+Web links are objects that point to URLs. These objects are also known as bookmarks within the Box web application. Web link objects are treated similarly to file objects.
+
+* [Create Web Link](#create-web-link)
+* [Get Web Link](#get-web-link)
+* [Update Web Link](#update-web-link)
+* [Delete Web Link](#delete-web-link)
+
+Create Web Link
+--------------
+
+Calling [`BoxFolder.createWebLink(String, URL, String)`][create-web-link] will let you create a new web link with a specified name and description.
+
+```java
+BoxFolder folder = new BoxFolder(api, id);
+folder.createWebLink("name", url, "description");
+```
+
+Name and description params are optional, so it is possible to create web link with only one of them or with URL only: [`BoxFolder.createWebLink(URL)`][create-web-link2]
+
+```java
+BoxFolder folder = new BoxFolder(api, id);
+BoxWebLink.Info webLinkInfo = folder.createWebLink(url);
+```
+
+[create-web-link]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#createWebLink(java.lang.String,%20java.net.URL,%20java.lang.String)
+[create-web-link2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#createWebLink(java.net.URL)
+
+Get Web Link
+--------------
+
+A web link info can be retrieved by calling the [`getInfo(String...)`][get-web-link] method.
+Optional parameters can be used to retrieve specific fields of the Device Pin object.
+
+```java
+BoxWebLink webLink = new BoxWebLink(api, id);
+BoxWebLink.Info webLinkInfo = webLink.getInfo();
+```
+
+[get-web-link]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebLink.html#getInfo(java.lang.String...)
+
+Update Web Link
+--------------
+
+A web link can be updated by calling the [`updateInfo(BoxWebLink.Info)`][update-web-link] method.
+
+```java
+BoxWebLink webLink = new BoxWebLink(api, id);
+BoxWebLink.Info webLinkInfo = webLink.new Info();
+webLinkInfo.addPendingChange("name", "new name for weblink");
+webLink.updateInfo(webLinkInfo);
+```
+
+[update-web-link]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebLink.html#updateInfo(com.box.sdk.BoxWebLink.Info)
+
+Delete Web Link
+---------------------------
+
+A web link can be deleted by calling the [`delete()`][delete] method.
+
+```java
+BoxWebLink webLink = new BoxWebLink(api, id);
+webLink.delete();
+```
+
+[delete]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebLink.html#delete()
\ No newline at end of file
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index 1085216ab..078f33a69 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -4,8 +4,14 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Scanner;
+import java.util.TimeZone;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@@ -19,24 +25,42 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.skyscreamer.jsonassert.JSONCompareMode.*;
+import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.containing;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
+/**
+ * {@link BoxFolder} related tests.
+ */
public class BoxFolderTest {
+
+ /**
+ * Wiremock
+ */
@Rule
public final WireMockRule wireMockRule = new WireMockRule(8080);
+ /**
+ * Unit test of equality of two {@link BoxFolder} objects with the same ID.
+ */
@Test
@Category(UnitTest.class)
public void foldersWithSameIDAreEqual() {
@@ -47,6 +71,9 @@ public void foldersWithSameIDAreEqual() {
assertThat(folder1, equalTo(folder2));
}
+ /**
+ * Unit test for {@link BoxFolder#createFolder(String)}.
+ */
@Test
@Category(UnitTest.class)
public void createFolderSendsRequestWithRequiredFields() {
@@ -66,6 +93,9 @@ public void createFolderSendsRequestWithRequiredFields() {
rootFolder.createFolder(createdFolderName);
}
+ /**
+ * Unit test for {@link BoxFolder.Info#Info(String)}.
+ */
@Test
@Category(UnitTest.class)
public void infoParsesMixedPermissionsCorrectly() {
@@ -95,6 +125,9 @@ public void infoParsesMixedPermissionsCorrectly() {
assertThat(info.getPermissions(), is(equalTo(expectedPermissions)));
}
+ /**
+ * Unit test for {@link BoxFolder#getChildrenRange(long, long, String...)}.
+ */
@Test
@Category(UnitTest.class)
public void getChildrenRangeRequestsCorrectOffsetLimitAndFields() {
@@ -118,6 +151,9 @@ public void getChildrenRangeRequestsCorrectOffsetLimitAndFields() {
assertThat(children.fullSize(), is(equalTo(3L)));
}
+ /**
+ * Unit test for {@link BoxFolder#collaborate(BoxCollaborator, BoxCollaboration.Role)}.
+ */
@Test
@Category(UnitTest.class)
public void collaborateShouldSendCorrectJSONWhenCollaboratingWithAGroup() {
@@ -157,6 +193,9 @@ public String getJSON() {
folder.collaborate(collaborator, BoxCollaboration.Role.CO_OWNER);
}
+ /**
+ * Unit test for {@link BoxFolder#getCollaborations()}.
+ */
@Test
@Category(UnitTest.class)
public void getCollaborationsShouldParseGroupsCorrectly() {
@@ -198,6 +237,208 @@ public String getJSON() {
}
}
+ /**
+ * Unit test for {@link BoxFolder#createWebLink(String, URL, String)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testCreateWeblinkSendsCorrectJsonWithNameAndDescription() throws MalformedURLException {
+ final String url = "https://www.box.com/home";
+ final String parentFolderID = "0";
+ final String name = "non-empty name";
+ final String description = "non-empty description";
+
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("type", "web_link")
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/web_links", request.getUrl().toString());
+ Scanner body = new Scanner(request.getBody()).useDelimiter("\n");
+ JsonObject json = JsonObject.readFrom(body.next());
+ body.close();
+ Assert.assertEquals(url, json.get("url").asString());
+ Assert.assertEquals(parentFolderID, json.get("parent").asObject().get("id").asString());
+ Assert.assertEquals(name, json.get("name").asString());
+ Assert.assertEquals(description, json.get("description").asString());
+
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ new BoxFolder(api, "0").createWebLink(name, new URL(url), description);
+ }
+
+ /**
+ * Unit test for {@link BoxFolder#createWebLink(URL)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testCreateWeblinkSendsCorrectJsonWithoutNameAndDescription() throws MalformedURLException {
+ final String url = "https://www.box.com/home";
+ final String parentFolderID = "0";
+
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("type", "web_link")
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/web_links", request.getUrl().toString());
+ JsonObject json = JsonObject.readFrom(new Scanner(request.getBody()).useDelimiter("\n").next());
+ assertEquals(url, json.get("url").asString());
+ assertEquals(parentFolderID, json.get("parent").asObject().get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ new BoxFolder(api, "0").createWebLink(new URL(url));
+ }
+
+ /**
+ * Unit test for {@link BoxFolder#createWebLink(URL)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testCreateWeblinkParseAllFieldsCorrectly() throws ParseException, MalformedURLException {
+ final String id = "6742981";
+ final String sequenceID = "0";
+ final String etag = "0";
+ final String name = "Box Website";
+ final String url = "https://www.box.com";
+ final String creatorID = "10523870";
+ final String creatorName = "Ted Blosser";
+ final String creatorLogin = "ted+demo@box.com";
+ final Date createdAt = BoxDateFormat.parse("2015-05-07T14:31:16-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2015-05-07T14:31:16-07:00");
+ final String parentID = "848123342";
+ final String parentSequenceID = "1";
+ final String parentEtag = "1";
+ final String parentName = "Documentation";
+ final String description = "Cloud Content Management";
+ final String itemStatus = "active";
+ final Date trashedAt = null;
+ final Date purgedAt = null;
+ final BoxSharedLink sharedLink = null;
+ final String pathID = "848123342";
+ final String pathSequenceID = "1";
+ final String pathEtag = "1";
+ final String pathName = "Documentation";
+ final String modifiedID = "10523870";
+ final String modifiedName = "Ted Blosser";
+ final String modifiedLogin = "ted+demo@box.com";
+ final String ownerID = "10523870";
+ final String ownerName = "Ted Blosser";
+ final String ownerLogin = "ted+demo@box.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"web_link\",\n"
+ + " \"id\": \"6742981\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"name\": \"Box Website\",\n"
+ + " \"url\": \"https://www.box.com\",\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " },\n"
+ + " \"created_at\": \"2015-05-07T14:31:16-07:00\",\n"
+ + " \"modified_at\": \"2015-05-07T14:31:16-07:00\",\n"
+ + " \"parent\": {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"848123342\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"name\": \"Documentation\"\n"
+ + " },\n"
+ + " \"description\": \"Cloud Content Management\",\n"
+ + " \"item_status\": \"active\",\n"
+ + " \"trashed_at\": null,\n"
+ + " \"purged_at\": null,\n"
+ + " \"shared_link\": null,\n"
+ + " \"path_collection\": {\n"
+ + " \"total_count\": 1,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"848123342\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"name\": \"Documentation\"\n"
+ + " }\n"
+ + " ]\n"
+ + " },\n"
+ + " \"modified_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " },\n"
+ + " \"owned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWebLink.Info info = new BoxFolder(api, "0").createWebLink(new URL(url));
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(sequenceID, info.getSequenceID());
+ Assert.assertEquals(etag, info.getEtag());
+ Assert.assertEquals(name, info.getName());
+ Assert.assertEquals(url, info.getLinkURL().toString());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ Assert.assertEquals(description, info.getDescription());
+ Assert.assertEquals(itemStatus, info.getItemStatus());
+ Assert.assertEquals(trashedAt, info.getTrashedAt());
+ Assert.assertEquals(purgedAt, info.getPurgedAt());
+ Assert.assertEquals(sharedLink, info.getSharedLink());
+ BoxUser.Info creatorInfo = info.getCreatedBy();
+ Assert.assertEquals(creatorID, creatorInfo.getID());
+ Assert.assertEquals(creatorName, creatorInfo.getName());
+ Assert.assertEquals(creatorLogin, creatorInfo.getLogin());
+ BoxUser.Info modifiedInfo = info.getModifiedBy();
+ Assert.assertEquals(modifiedID, modifiedInfo.getID());
+ Assert.assertEquals(modifiedName, modifiedInfo.getName());
+ Assert.assertEquals(modifiedLogin, modifiedInfo.getLogin());
+ BoxUser.Info ownerInfo = info.getOwnedBy();
+ Assert.assertEquals(ownerID, ownerInfo.getID());
+ Assert.assertEquals(ownerName, ownerInfo.getName());
+ Assert.assertEquals(ownerLogin, ownerInfo.getLogin());
+ BoxFolder.Info parentInfo = info.getParent();
+ Assert.assertEquals(parentID, parentInfo.getID());
+ Assert.assertEquals(parentSequenceID, parentInfo.getSequenceID());
+ Assert.assertEquals(parentEtag, parentInfo.getEtag());
+ Assert.assertEquals(parentName, parentInfo.getName());
+ BoxFolder.Info pathInfo = info.getPathCollection().get(0);
+ Assert.assertEquals(pathID, pathInfo.getID());
+ Assert.assertEquals(pathSequenceID, pathInfo.getSequenceID());
+ Assert.assertEquals(pathEtag, pathInfo.getEtag());
+ Assert.assertEquals(pathName, pathInfo.getName());
+ }
+
@Test
@Category(IntegrationTest.class)
public void creatingAndDeletingFolderSucceeds() {
diff --git a/src/test/java/com/box/sdk/BoxWebLinkTest.java b/src/test/java/com/box/sdk/BoxWebLinkTest.java
index 63e9c904e..da2d328d2 100644
--- a/src/test/java/com/box/sdk/BoxWebLinkTest.java
+++ b/src/test/java/com/box/sdk/BoxWebLinkTest.java
@@ -2,16 +2,332 @@
import java.net.MalformedURLException;
import java.net.URL;
+import java.text.ParseException;
+import java.util.Date;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxWebLink} related tests.
+ */
public class BoxWebLinkTest {
+ /**
+ * Unit test for {@link BoxWebLink#copy(BoxFolder, String)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testcopyWebLinkSendsCorrectJson() {
+ final String parentFolderID = "0";
+ final String name = "non-empty name";
+
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("type", "web_link")
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals(parentFolderID, json.get("parent").asObject().get("id").asString());
+ Assert.assertEquals(name, json.get("name").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxWebLink weblink = new BoxWebLink(api, "0");
+ weblink.copy(new BoxFolder(api, "0"), name);
+ }
+
+ /**
+ * Unit test for {@link BoxWebLink#move(BoxFolder, String)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testMoveWebLinkSendsCorrectJson() {
+ final String parentFolderID = "0";
+ final String name = "non-empty name";
+
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("type", "web_link")
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals(parentFolderID, json.get("parent").asObject().get("id").asString());
+ Assert.assertEquals(name, json.get("name").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxWebLink weblink = new BoxWebLink(api, "0");
+ weblink.move(new BoxFolder(api, "0"), name);
+ }
+
+ /**
+ * Unit test for {@link BoxWebLink#rename(String)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testRenameWebLinkSendsCorrectJson() {
+ final String name = "non-empty name";
+
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("type", "web_link")
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals(name, json.get("name").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxWebLink weblink = new BoxWebLink(api, "0");
+ weblink.rename(name);
+ }
+
+ /**
+ * Unit test for {@link BoxWebLink#updateInfo(BoxWebLink.Info)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateInfoSendsCorrectJson() {
+ final String name = "non-empty name";
+
+ final JsonObject fakeJSONResponse = new JsonObject()
+ .add("type", "web_link")
+ .add("id", "0");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/web_links/0", request.getUrl().toString());
+ Assert.assertEquals(name, json.get("name").asString());
+
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return fakeJSONResponse.toString();
+ }
+ };
+ }
+ });
+
+ BoxWebLink weblink = new BoxWebLink(api, "0");
+ BoxWebLink.Info info = weblink.new Info();
+ info.addPendingChange("name", name);
+ weblink.updateInfo(info);
+ }
+
+ /**
+ * Unit test for {@link BoxWebLink#delete()}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteWeblinkSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/web_links/0", request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ BoxWebLink weblink = new BoxWebLink(api, "0");
+ weblink.delete();
+ }
+
+ /**
+ * Unit test for {@link BoxWebLink#getInfo()}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/web_links/0", request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{}";
+ }
+ };
+ }
+ });
+
+ BoxWebLink weblink = new BoxWebLink(api, "0");
+ weblink.getInfo();
+ }
+
+ /**
+ * Unit test for {@link BoxWebLink#getInfo()}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "6742981";
+ final String sequenceID = "0";
+ final String etag = "0";
+ final String name = "Box Website";
+ final String url = "https://www.box.com";
+ final String creatorID = "10523870";
+ final String creatorName = "Ted Blosser";
+ final String creatorLogin = "ted+demo@box.com";
+ final Date createdAt = BoxDateFormat.parse("2015-05-07T14:31:16-07:00");
+ final Date modifiedAt = BoxDateFormat.parse("2015-05-07T14:31:16-07:00");
+ final String parentID = "848123342";
+ final String parentSequenceID = "1";
+ final String parentEtag = "1";
+ final String parentName = "Documentation";
+ final String description = "Cloud Content Management";
+ final String itemStatus = "active";
+ final Date trashedAt = null;
+ final Date purgedAt = null;
+ final BoxSharedLink sharedLink = null;
+ final String pathID = "848123342";
+ final String pathSequenceID = "1";
+ final String pathEtag = "1";
+ final String pathName = "Documentation";
+ final String modifiedID = "10523870";
+ final String modifiedName = "Ted Blosser";
+ final String modifiedLogin = "ted+demo@box.com";
+ final String ownerID = "10523870";
+ final String ownerName = "Ted Blosser";
+ final String ownerLogin = "ted+demo@box.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"web_link\",\n"
+ + " \"id\": \"6742981\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"name\": \"Box Website\",\n"
+ + " \"url\": \"https://www.box.com\",\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " },\n"
+ + " \"created_at\": \"2015-05-07T14:31:16-07:00\",\n"
+ + " \"modified_at\": \"2015-05-07T14:31:16-07:00\",\n"
+ + " \"parent\": {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"848123342\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"name\": \"Documentation\"\n"
+ + " },\n"
+ + " \"description\": \"Cloud Content Management\",\n"
+ + " \"item_status\": \"active\",\n"
+ + " \"trashed_at\": null,\n"
+ + " \"purged_at\": null,\n"
+ + " \"shared_link\": null,\n"
+ + " \"path_collection\": {\n"
+ + " \"total_count\": 1,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"848123342\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"name\": \"Documentation\"\n"
+ + " }\n"
+ + " ]\n"
+ + " },\n"
+ + " \"modified_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " },\n"
+ + " \"owned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWebLink.Info info = new BoxWebLink(api, "6742981").getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(sequenceID, info.getSequenceID());
+ Assert.assertEquals(etag, info.getEtag());
+ Assert.assertEquals(name, info.getName());
+ Assert.assertEquals(url, info.getLinkURL().toString());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ Assert.assertEquals(description, info.getDescription());
+ Assert.assertEquals(itemStatus, info.getItemStatus());
+ Assert.assertEquals(trashedAt, info.getTrashedAt());
+ Assert.assertEquals(purgedAt, info.getPurgedAt());
+ Assert.assertEquals(sharedLink, info.getSharedLink());
+ BoxUser.Info creatorInfo = info.getCreatedBy();
+ Assert.assertEquals(creatorID, creatorInfo.getID());
+ Assert.assertEquals(creatorName, creatorInfo.getName());
+ Assert.assertEquals(creatorLogin, creatorInfo.getLogin());
+ BoxUser.Info modifiedInfo = info.getModifiedBy();
+ Assert.assertEquals(modifiedID, modifiedInfo.getID());
+ Assert.assertEquals(modifiedName, modifiedInfo.getName());
+ Assert.assertEquals(modifiedLogin, modifiedInfo.getLogin());
+ BoxUser.Info ownerInfo = info.getOwnedBy();
+ Assert.assertEquals(ownerID, ownerInfo.getID());
+ Assert.assertEquals(ownerName, ownerInfo.getName());
+ Assert.assertEquals(ownerLogin, ownerInfo.getLogin());
+ BoxFolder.Info parentInfo = info.getParent();
+ Assert.assertEquals(parentID, parentInfo.getID());
+ Assert.assertEquals(parentSequenceID, parentInfo.getSequenceID());
+ Assert.assertEquals(parentEtag, parentInfo.getEtag());
+ Assert.assertEquals(parentName, parentInfo.getName());
+ BoxFolder.Info pathInfo = info.getPathCollection().get(0);
+ Assert.assertEquals(pathID, pathInfo.getID());
+ Assert.assertEquals(pathSequenceID, pathInfo.getSequenceID());
+ Assert.assertEquals(pathEtag, pathInfo.getEtag());
+ Assert.assertEquals(pathName, pathInfo.getName());
+ }
+
@Test
@Category(IntegrationTest.class)
public void copyWebLinkSucceeds() throws MalformedURLException {
From e10b2e36f4c62a959778bc26afb236fdba4408ea Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Fri, 11 Nov 2016 20:45:42 +0100
Subject: [PATCH 020/119] webhooks tested and documented
---
README.md | 1 +
doc/webhooks.md | 75 +++
src/main/java/com/box/sdk/BoxWebHook.java | 133 ++++++
src/test/java/com/box/sdk/BoxWebHookTest.java | 430 ++++++++++++++++++
4 files changed, 639 insertions(+)
create mode 100644 doc/webhooks.md
diff --git a/README.md b/README.md
index 4344725bd..96cf972f4 100644
--- a/README.md
+++ b/README.md
@@ -169,6 +169,7 @@ You can find guides and tutorials in the `doc` directory.
* [Devices](doc/devices.md)
* [Retention Policies](doc/retention_policies.md)
* [Legal Holds Policy](doc/legal_holds.md)
+* [Webhooks](doc/webhooks.md)
Javadocs are generated when `gradle javadoc` is run and can be found in
`build/doc/javadoc`.
diff --git a/doc/webhooks.md b/doc/webhooks.md
new file mode 100644
index 000000000..604e1cd42
--- /dev/null
+++ b/doc/webhooks.md
@@ -0,0 +1,75 @@
+Webhooks
+======
+
+Webhooks enable you to attach event triggers to Box files and folders. Event triggers monitor events on Box objects and notify your application when they occur. A webhook notifies your application by sending HTTP requests to a URL of your choosing.
+
+* [Get a Webhook](#get-a-webhook)
+* [Get All Webhooks](#get-all-webhooks)
+* [Create a Webhook](#create-a-webhook)
+* [Delete a Webhook](#delete-a-webhook)
+* [Update a Webhook](#update-a-webhook)
+
+Get a Webhook
+---------------------------
+
+A webhook infocan be retrieved by calling the [`getInfo(String...)`][get-info] method.
+
+```java
+BoxWebHook webhook = new BoxWebHook(api, id);
+BoxWebHook.Info info = weghook.getInfo();
+```
+
+[get-info]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebHook.html#getInfo(java.lang.String...)
+
+Get All Webhooks
+--------------
+
+Calling the static [`all(BoxAPIConnection, String...)`][all] will return an iterable that will page through all defined webhooks for the requesting application and user.
+
+```java
+Iterable webhooks = BoxWebHook.all(BoxAPIConnection api);
+for (BoxWebHook.Info webhookInfo: webhooks) {
+ // Do something with the webhook.
+}
+```
+
+[all]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebHook.html#all(com.box.sdk.BoxAPIConnection,%20java.lang.String...)
+
+Create a Webhook
+--------------
+
+The static [`create(BoxResource, URL, BoxWebHook.Trigger...)`][create-webhook] method will
+let you create a new webhook for a specified target object.
+
+```java
+BoxFolder folder = new BoxFolder(api, id);
+BoxWebHook.Info webhookInfo = BoxWebHook.create(folder, url, BoxWebHook.Trigger.FILE_UPLOADED);
+```
+
+[create-webhook]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebHook.html#create(com.box.sdk.BoxResource,%20java.net.URL,%20com.box.sdk.BoxWebHook.Trigger...)
+
+Delete a Webhook
+--------------
+
+A webhook can be deleted by calling the [`delete()`][delete] method.
+
+```java
+BoxWebHook webhook = new BoxWebHook(api, id);
+webhook.delete();
+```
+
+[delete]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebHook.html#delete()
+
+Update a Webhook
+--------------
+
+A webhook can be updated by calling the [`update(BoxWebHook.Info)`][update] method.
+
+```java
+BoxWebHook webhook = new BoxWebHook(api, id);
+BoxWebHook.Info info = webhook.getInfo();
+info.addPendingChange("address", url);
+webhook.update(info);
+```
+
+[update]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxWebHook.html#update(com.box.sdk.BoxWebHook.Info)
\ No newline at end of file
diff --git a/src/main/java/com/box/sdk/BoxWebHook.java b/src/main/java/com/box/sdk/BoxWebHook.java
index 4cd696b09..266548bfe 100644
--- a/src/main/java/com/box/sdk/BoxWebHook.java
+++ b/src/main/java/com/box/sdk/BoxWebHook.java
@@ -2,9 +2,11 @@
import java.net.MalformedURLException;
import java.net.URL;
+import java.text.ParseException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@@ -53,6 +55,16 @@ public class BoxWebHook extends BoxResource {
*/
private static final String JSON_KEY_TRIGGERS = "triggers";
+ /**
+ * JSON Key for {@link BoxWebHook.Info#getCreatedBy()}.
+ */
+ private static final String JSON_KEY_CREATED_BY = "created_by";
+
+ /**
+ * JSON Key for {@link BoxWebHook.Info#getCreatedAt()}.
+ */
+ private static final String JSON_KEY_CREATED_AT = "created_at";
+
/**
* {@link URLTemplate} for {@link BoxWebHook}s resource.
*/
@@ -183,6 +195,32 @@ protected BoxWebHook.Info factory(JsonObject jsonObject) {
};
}
+ /**
+ * Returns iterator over all {@link BoxWebHook}-s.
+ *
+ * @param api
+ * the API connection to be used by the resource
+ * @param fields
+ * the fields to retrieve.
+ * @return existing {@link BoxWebHook.Info}-s
+ */
+ public static Iterable all(final BoxAPIConnection api, String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new BoxResourceIterable(
+ api, WEBHOOKS_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString()), 64) {
+
+ @Override
+ protected BoxWebHook.Info factory(JsonObject jsonObject) {
+ BoxWebHook webHook = new BoxWebHook(api, jsonObject.get("id").asString());
+ return webHook.new Info(jsonObject);
+ }
+
+ };
+ }
+
/**
* Validates that provided {@link BoxWebHook.Trigger}-s can be applied on the provided {@link BoxResourceType}.
*
@@ -229,6 +267,21 @@ public BoxWebHook.Info getInfo() {
return new Info(JsonObject.readFrom(response.getJSON()));
}
+ /**
+ * @param fields the fields to retrieve.
+ * @return Gets information about this {@link BoxWebHook}.
+ */
+ public BoxWebHook.Info getInfo(String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = WEBHOOK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ return new Info(JsonObject.readFrom(response.getJSON()));
+ }
+
/**
* Updates {@link BoxWebHook} information.
*
@@ -275,6 +328,16 @@ public class Info extends BoxResource.Info {
*/
private Set triggers;
+ /**
+ * @see #getCreatedBy()
+ */
+ private BoxUser.Info createdBy;
+
+ /**
+ * @see #getCreatedAt()
+ */
+ private Date createdAt;
+
/**
* Constructs an Info object with current target.
*/
@@ -311,6 +374,24 @@ public Info(JsonObject jsonObject) {
throw new RuntimeException(e);
}
}
+
+ if (jsonObject.get(JSON_KEY_CREATED_BY) != null) {
+ JsonObject userJSON = jsonObject.get(JSON_KEY_CREATED_BY).asObject();
+ if (this.createdBy == null) {
+ BoxUser user = new BoxUser(getAPI(), userJSON.get(JSON_KEY_TARGET_ID).asString());
+ this.createdBy = user.new Info(userJSON);
+ } else {
+ this.createdBy.update(userJSON);
+ }
+ }
+
+ if (jsonObject.get(JSON_KEY_CREATED_AT) != null) {
+ try {
+ this.createdAt = BoxDateFormat.parse(jsonObject.get(JSON_KEY_CREATED_AT).asString());
+ } catch (ParseException e) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
}
/**
@@ -398,6 +479,58 @@ public Info setTriggers(Set triggers) {
return this;
}
+ /**
+ * @return Info about the user who created this webhook.
+ */
+ public BoxUser.Info getCreatedBy() {
+ return this.createdBy;
+ }
+
+ /**
+ * @return the time this webhook was created.
+ */
+ public Date getCreatedAt() {
+ return this.createdAt;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void parseJSONMember(JsonObject.Member member) {
+ super.parseJSONMember(member);
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ try {
+ if (memberName.equals(JSON_KEY_TARGET)) {
+ String targetType = value.asObject().get(JSON_KEY_TARGET_TYPE).asString();
+ String targetId = value.asObject().get(JSON_KEY_TARGET_ID).asString();
+ this.target = new Target(targetType, targetId);
+ } else if (memberName.equals(JSON_KEY_TRIGGERS)) {
+ this.triggers = new HashSet(
+ CollectionUtils.map(value.asArray().values(), JSON_VALUE_TO_TRIGGER)
+ );
+ } else if (memberName.equals(JSON_KEY_ADDRESS)) {
+ this.address = new URL(value.asString());
+ } else if (memberName.equals(JSON_KEY_CREATED_BY)) {
+ JsonObject userJSON = value.asObject();
+ if (this.createdBy == null) {
+ String userID = userJSON.get(JSON_KEY_ID).asString();
+ BoxUser user = new BoxUser(getAPI(), userID);
+ this.createdBy = user.new Info(userJSON);
+ } else {
+ this.createdBy.update(userJSON);
+ }
+ } else if (memberName.equals("created_at")) {
+ this.createdAt = BoxDateFormat.parse(value.asString());
+ }
+ } catch (ParseException e) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ } catch (MalformedURLException e) {
+ assert false : "A MalformedURLException indicates a bug in the SDK.";
+ }
+ }
+
}
/**
diff --git a/src/test/java/com/box/sdk/BoxWebHookTest.java b/src/test/java/com/box/sdk/BoxWebHookTest.java
index 91a8b67b1..4ec8ee4db 100644
--- a/src/test/java/com/box/sdk/BoxWebHookTest.java
+++ b/src/test/java/com/box/sdk/BoxWebHookTest.java
@@ -3,9 +3,13 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.text.ParseException;
import java.util.Arrays;
+import java.util.Date;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
@@ -16,11 +20,437 @@
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+/**
+ * {@link BoxWebHook} related tests.
+ */
public class BoxWebHookTest {
+
+ /**
+ * Unit test for {@link BoxWebHook#create(BoxResource, URL, BoxWebHook.Trigger...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testCreateSendsCorrectJson() throws MalformedURLException {
+ final String targetID = "1";
+ final String targetType = "folder";
+ final String address = "http://box.com";
+ final String trigger = "FILE.UPLOADED";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/webhooks",
+ request.getUrl().toString());
+ Assert.assertEquals(targetID, json.get("target").asObject().get("id").asString());
+ Assert.assertEquals(targetType, json.get("target").asObject().get("type").asString());
+ Assert.assertEquals(address, json.get("address").asString());
+ Assert.assertEquals(trigger, json.get("triggers").asArray().get(0).asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxWebHook.create(new BoxFolder(api, "1"), new URL(address), BoxWebHook.Trigger.FILE_UPLOADED);
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#create(BoxResource, URL, BoxWebHook.Trigger...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testCreateParseAllFieldsCorrectly() throws ParseException, MalformedURLException {
+ final String id = "4165";
+ final String targetID = "5016243669";
+ final String targetType = "file";
+ final String createdByID = "2030392653";
+ final String createdByName = "John Q. Developer";
+ final String createdByLogin = "johnq@dev.name";
+ final Date createdAt = BoxDateFormat.parse("2016-05-09T17:41:27-07:00");
+ final URL address = new URL("https://dev.name/actions/file_changed");
+ final BoxWebHook.Trigger firstTrigger = BoxWebHook.Trigger.FILE_DOWNLOADED;
+ final BoxWebHook.Trigger secondTrigger = BoxWebHook.Trigger.FILE_UPLOADED;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"id\": \"4165\",\n"
+ + " \"type\": \"webhook\",\n"
+ + " \"target\": {\n"
+ + " \"id\": \"5016243669\",\n"
+ + " \"type\": \"file\"\n"
+ + " },\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"2030392653\",\n"
+ + " \"name\": \"John Q. Developer\",\n"
+ + " \"login\": \"johnq@dev.name\"\n"
+ + " },\n"
+ + " \"created_at\": \"2016-05-09T17:41:27-07:00\",\n"
+ + " \"address\": \"https://dev.name/actions/file_changed\",\n"
+ + " \"triggers\": [\n"
+ + " \"FILE.DOWNLOADED\",\n"
+ + " \"FILE.UPLOADED\"\n"
+ + " ]\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWebHook.Info info = BoxWebHook.create(new BoxFile(api, "0"), address);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(targetID, info.getTarget().getId());
+ Assert.assertEquals(targetType, info.getTarget().getType());
+ Assert.assertEquals(createdByID, info.getCreatedBy().getID());
+ Assert.assertEquals(createdByName, info.getCreatedBy().getName());
+ Assert.assertEquals(createdByLogin, info.getCreatedBy().getLogin());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(address, info.getAddress());
+ Assert.assertEquals(true, info.getTriggers().contains(firstTrigger));
+ Assert.assertEquals(true, info.getTriggers().contains(secondTrigger));
+
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#getInfo())}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequestWithoutFields() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/webhooks/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxWebHook hook = new BoxWebHook(api, "0");
+ hook.getInfo();
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/webhooks/0?fields=created_at",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxWebHook hook = new BoxWebHook(api, "0");
+ hook.getInfo("created_at");
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#getInfo()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException, MalformedURLException {
+ final String id = "4137";
+ final String targetID = "5018848529";
+ final String targetType = "file";
+ final String createdByID = "2030392653";
+ final String createdByName = "John Q. Developer";
+ final String createdByLogin = "johnq@example.net";
+ final Date createdAt = BoxDateFormat.parse("2016-05-04T18:51:45-07:00");
+ final URL address = new URL("https://example.net/actions/file_changed");
+ final BoxWebHook.Trigger trigger = BoxWebHook.Trigger.FILE_PREVIEWED;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"id\": \"4137\",\n"
+ + " \"type\": \"webhook\",\n"
+ + " \"target\": {\n"
+ + " \"id\": \"5018848529\",\n"
+ + " \"type\": \"file\"\n"
+ + " },\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"2030392653\",\n"
+ + " \"name\": \"John Q. Developer\",\n"
+ + " \"login\": \"johnq@example.net\"\n"
+ + " },\n"
+ + " \"created_at\": \"2016-05-04T18:51:45-07:00\",\n"
+ + " \"address\": \"https://example.net/actions/file_changed\",\n"
+ + " \"triggers\": [\n"
+ + " \"FILE.PREVIEWED\"\n"
+ + " ]\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWebHook.Info info = new BoxWebHook(api, id).getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(targetID, info.getTarget().getId());
+ Assert.assertEquals(targetType, info.getTarget().getType());
+ Assert.assertEquals(createdByID, info.getCreatedBy().getID());
+ Assert.assertEquals(createdByName, info.getCreatedBy().getName());
+ Assert.assertEquals(createdByLogin, info.getCreatedBy().getLogin());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(address, info.getAddress());
+ Assert.assertEquals(trigger, info.getTriggers().toArray()[0]);
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#delete()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/webhooks/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxWebHook hook = new BoxWebHook(api, "0");
+ hook.delete();
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#all(BoxAPIConnection)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAllSendsCorrectRequestWithoutParams() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/webhooks?limit=64",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ Iterator iterator = BoxWebHook.all(api).iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#all(BoxAPIConnection, String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAllSendsCorrectRequestWithFields() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/webhooks?fields=created_at%2Ccreated_by&limit=64",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ Iterator iterator = BoxWebHook.all(api, "created_at", "created_by").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#all(BoxAPIConnection)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAllParseAllFieldsCorrectly() {
+ final String firstID = "4161";
+ final String firstTargetID = "5018326685";
+ final String firstTargetType = "folder";
+ final String secondID = "4165";
+ final String secondTargetID = "5016243669";
+ final String secondTargerType = "file";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"id\": \"4161\",\n"
+ + " \"type\": \"webhook\",\n"
+ + " \"target\": {\n"
+ + " \"id\": \"5018326685\",\n"
+ + " \"type\": \"folder\"\n"
+ + " }\n"
+ + " },\n"
+ + " {\n"
+ + " \"id\": \"4165\",\n"
+ + " \"type\": \"webhook\",\n"
+ + " \"target\": {\n"
+ + " \"id\": \"5016243669\",\n"
+ + " \"type\": \"file\"\n"
+ + " }\n"
+ + " }\n"
+ + " ],\n"
+ + " \"limit\": 3\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ Iterator iterator = BoxWebHook.all(api).iterator();
+ BoxWebHook.Info info = iterator.next();
+ Assert.assertEquals(firstID, info.getID());
+ Assert.assertEquals(firstTargetID, info.getTarget().getId());
+ Assert.assertEquals(firstTargetType, info.getTarget().getType());
+ info = iterator.next();
+ Assert.assertEquals(secondID, info.getID());
+ Assert.assertEquals(secondTargetID, info.getTarget().getId());
+ Assert.assertEquals(secondTargerType, info.getTarget().getType());
+ Assert.assertEquals(false, iterator.hasNext());
+
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#updateInfo(BoxWebHook.Info)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateSendCorrectJSON() {
+ final String address = "";
+ final String firstTrigger = "FILE.PREVIEWED";
+ final String secondTrigger = "FILE.DOWNLOADED";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"id\": \"4137\",\n"
+ + " \"type\": \"webhook\",\n"
+ + " \"target\": {\n"
+ + " \"id\": \"5018848529\",\n"
+ + " \"type\": \"file\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWebHook hook = new BoxWebHook(api, "0");
+ BoxWebHook.Info info = hook.new Info();
+
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/webhooks/0",
+ request.getUrl().toString());
+ Assert.assertEquals(address, json.get("address").asString());
+ Assert.assertEquals(firstTrigger, json.get("triggers").asArray().get(0).asString());
+ Assert.assertEquals(secondTrigger, json.get("triggers").asArray().get(1).asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ info.addPendingChange("address", address);
+ info.addPendingChange("triggers", new JsonArray().add(firstTrigger).add(secondTrigger));
+ hook.updateInfo(info);
+ }
+
+ /**
+ * Unit test for {@link BoxWebHook#updateInfo(BoxWebHook.Info)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testUpdateParseAllFieldsCorrectly() throws ParseException, MalformedURLException {
+ final String id = "4133";
+ final String targetID = "1000605797";
+ final String targetType = "folder";
+ final String createdByID = "2030392653";
+ final String createdByName = "John Q. Developer";
+ final String createdByLogin = "john2@example.net";
+ final Date createdAt = BoxDateFormat.parse("2016-05-04T18:51:17-07:00");
+ final URL address = new URL("https://notification.example.net");
+ final BoxWebHook.Trigger firstTrigger = BoxWebHook.Trigger.FILE_PREVIEWED;
+ final BoxWebHook.Trigger secondTrigger = BoxWebHook.Trigger.FILE_DOWNLOADED;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"id\": \"4133\",\n"
+ + " \"type\": \"webhook\",\n"
+ + " \"target\": {\n"
+ + " \"id\": \"1000605797\",\n"
+ + " \"type\": \"folder\"\n"
+ + " },\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"2030392653\",\n"
+ + " \"name\": \"John Q. Developer\",\n"
+ + " \"login\": \"john2@example.net\"\n"
+ + " },\n"
+ + " \"created_at\": \"2016-05-04T18:51:17-07:00\",\n"
+ + " \"address\": \"https://notification.example.net\",\n"
+ + " \"triggers\": [\n"
+ + " \"FILE.PREVIEWED\", \"FILE.DOWNLOADED\"\n"
+ + " ]\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxWebHook hook = new BoxWebHook(api, id);
+ BoxWebHook.Info info = hook.new Info();
+ info.addPendingChange("address", "fake pending change");
+ hook.updateInfo(info);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(targetID, info.getTarget().getId());
+ Assert.assertEquals(targetType, info.getTarget().getType());
+ Assert.assertEquals(createdByID, info.getCreatedBy().getID());
+ Assert.assertEquals(createdByName, info.getCreatedBy().getName());
+ Assert.assertEquals(createdByLogin, info.getCreatedBy().getLogin());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(address, info.getAddress());
+ Assert.assertEquals(true, info.getTriggers().contains(firstTrigger));
+ Assert.assertEquals(true, info.getTriggers().contains(secondTrigger));
+
+ }
+
@Test
@Category(IntegrationTest.class)
public void createWebHookFileSucceeds() throws IOException {
From 119264dfa3ca73e374e56fc2cabe9f0026f8cb4e Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Mon, 14 Nov 2016 13:27:14 +0100
Subject: [PATCH 021/119] get metadata template and get enterprise metadata
features implementation
---
README.md | 1 +
doc/metadata_template.md | 41 ++
src/main/java/com/box/sdk/BoxFile.java | 3 +
.../java/com/box/sdk/MetadataTemplate.java | 390 ++++++++++++++++++
.../com/box/sdk/MetadataTemplateTest.java | 252 +++++++++++
5 files changed, 687 insertions(+)
create mode 100644 doc/metadata_template.md
create mode 100644 src/main/java/com/box/sdk/MetadataTemplate.java
create mode 100644 src/test/java/com/box/sdk/MetadataTemplateTest.java
diff --git a/README.md b/README.md
index 4344725bd..ccd5ddba4 100644
--- a/README.md
+++ b/README.md
@@ -169,6 +169,7 @@ You can find guides and tutorials in the `doc` directory.
* [Devices](doc/devices.md)
* [Retention Policies](doc/retention_policies.md)
* [Legal Holds Policy](doc/legal_holds.md)
+* [Metadata Templates](doc/metadata_template.md)
Javadocs are generated when `gradle javadoc` is run and can be found in
`build/doc/javadoc`.
diff --git a/doc/metadata_template.md b/doc/metadata_template.md
new file mode 100644
index 000000000..7b9677b7b
--- /dev/null
+++ b/doc/metadata_template.md
@@ -0,0 +1,41 @@
+Metadata Templates
+==================
+
+Metadata that belongs to a file is grouped by templates. Templates allow the metadata service to provide a multitude of services, such as pre-defining sets of key:value pairs or schema enforcement on specific fields.
+
+* [Get Metadata Template](#get-metadata-template)
+* [Get Enterprise Metadata Templates](#get-enterprise-metadata-templates)
+
+
+Get Metadata Template
+--------------------
+
+The [`getMetadataTemplate(BoxAPIConnection)`][get-metadata-template-1] method will return information about default metadata schema.
+Also [`getMetadataTemplate(BoxAPIConnection, String)`][get-metadata-template-2] and [`getMetadataTemplate(BoxAPIConnection, String, String, String...)`][get-metadata-template-3] can be used to set metadata template name, metadata scope and fields to retrieve.
+
+```java
+MetadataTemplate template = MetadataTemplate.getMetadataTemplate(api, "templateName");
+```
+
+[get-metadata-template-1]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/MetadataTemplate.html#getEnterpriseMetadataTemplates(com.box.sdk.BoxAPIConnection)
+[get-metadata-template-2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/MetadataTemplate.html#getEnterpriseMetadataTemplates(com.box.sdk.BoxAPIConnection,%20java.lang.String)
+[get-metadata-template-3]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/MetadataTemplate.html#getEnterpriseMetadataTemplates(com.box.sdk.BoxAPIConnection,%20java.lang.String,%20java.lang.String,%20java.lang.String...)
+
+
+Get Enterprise Metadata Templates
+---------------------------------
+
+Calling the static [`getEnterpriseMetadataTemplates(BoxAPIConnection, String...)`][get-enterprise-metadata-1] will
+return an iterable that will page through all metadata templates within a user's enterprise.
+Also [`getEnterpriseMetadataTemplates(String, BoxAPIConnection, String...)`][get-enterprise-metadata-2] and [`getEnterpriseMetadataTemplates(String, int, BoxAPIConnection, String...)`][get-enterprise-metadata-3] can be used to set metadata scope, limit of items per single response.
+
+```java
+Iterable templates = MetadataTemplate.getEnterpriseMetadataTemplates(BoxAPIConnection api);
+for (MetadataTemplate templateInfo : templates) {
+ // Do something with the metadata template.
+}
+```
+
+[get-enterprise-metadata-1]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/MetadataTemplate.html#getEnterpriseMetadataTemplates(com.box.sdk.BoxAPIConnection,%20java.lang.String...)
+[get-enterprise-metadata-2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/MetadataTemplate.html#getEnterpriseMetadataTemplates(java.lang.String,%20com.box.sdk.BoxAPIConnection,%20java.lang.String...)
+[get-enterprise-metadata-3]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/MetadataTemplate.html#getEnterpriseMetadataTemplates(java.lang.String,%20int,%20com.box.sdk.BoxAPIConnection,%20java.lang.String...)
\ No newline at end of file
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 8530ac0ae..48a75693b 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -758,6 +758,9 @@ public void deleteMetadata(String typeName, String scope) {
request.send();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public BoxFile.Info setCollections(BoxCollection... collections) {
JsonArray jsonArray = new JsonArray();
diff --git a/src/main/java/com/box/sdk/MetadataTemplate.java b/src/main/java/com/box/sdk/MetadataTemplate.java
new file mode 100644
index 000000000..518606d6d
--- /dev/null
+++ b/src/main/java/com/box/sdk/MetadataTemplate.java
@@ -0,0 +1,390 @@
+package com.box.sdk;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ * The MetadataTemplate class represents the Box metadata template object.
+ * Templates allow the metadata service to provide a multitude of services,
+ * such as pre-defining sets of key:value pairs or schema enforcement on specific fields.
+ *
+ * @see Box metadata templates
+ */
+public class MetadataTemplate extends BoxJSONObject {
+
+ /**
+ * @see #getMetadataTemplate(BoxAPIConnection)
+ */
+ private static final URLTemplate METADATA_TEMPLATE_URL_TEMPLATE
+ = new URLTemplate("metadata_templates/%s/%s/schema");
+
+ /**
+ * @see #getEnterpriseMetadataTemplates(String, int, BoxAPIConnection, String...)
+ */
+ private static final URLTemplate ENTERPRISE_METADATA_URL_TEMPLATE = new URLTemplate("metadata_templates/%s");
+
+ /**
+ * Default metadata type to be used in query.
+ */
+ private static final String DEFAULT_METADATA_TYPE = "properties";
+
+ /**
+ * Global metadata scope. Used by default if the metadata type is "properties".
+ */
+ private static final String GLOBAL_METADATA_SCOPE = "global";
+
+ /**
+ * Enterprise metadata scope. Used by default if the metadata type is not "properties".
+ */
+ private static final String ENTERPRISE_METADATA_SCOPE = "enterprise";
+
+ /**
+ * Default number of entries per page.
+ */
+ private static final int DEFAULT_ENTRIES_LIMIT = 100;
+
+ /**
+ * @see #getTemplateKey()
+ */
+ private String templateKey;
+
+ /**
+ * @see #getScope()
+ */
+ private String scope;
+
+ /**
+ * @see #getDisplayName()
+ */
+ private String displayName;
+
+ /**
+ * @see #getIsHidden()
+ */
+ private Boolean isHidden;
+
+ /**
+ * @see #getFields()
+ */
+ private List fields;
+
+ /**
+ * Constructs an empty metadata template.
+ */
+ public MetadataTemplate() {
+ super();
+ }
+
+ /**
+ * Constructs a metadata template from a JSON string.
+ * @param json the json encoded metadate template.
+ */
+ public MetadataTemplate(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs a metadate template from a JSON object.
+ * @param jsonObject the json encoded metadate template.
+ */
+ MetadataTemplate(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ /**
+ * Gets the unique template key to identify the metadata template.
+ * @return the unique template key to identify the metadata template.
+ */
+ public String getTemplateKey() {
+ return this.templateKey;
+ }
+
+ /**
+ * Gets the metadata template scope.
+ * @return the metadata template scope.
+ */
+ public String getScope() {
+ return this.scope;
+ }
+
+ /**
+ * Gets the displayed metadata template name.
+ * @return the displayed metadata template name.
+ */
+ public String getDisplayName() {
+ return this.displayName;
+ }
+
+ /**
+ * Gets is the metadata template hidden.
+ * @return is the metadata template hidden.
+ */
+ public Boolean getIsHidden() {
+ return this.isHidden;
+ }
+
+ /**
+ * Gets the iterable with all fields the metadata template contains.
+ * @return the iterable with all fields the metadata template contains.
+ */
+ public List getFields() {
+ return this.fields;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void parseJSONMember(JsonObject.Member member) {
+ JsonValue value = member.getValue();
+ String memberName = member.getName();
+ if (memberName.equals("templateKey")) {
+ this.templateKey = value.asString();
+ } else if (memberName.equals("scope")) {
+ this.scope = value.asString();
+ } else if (memberName.equals("displayName")) {
+ this.displayName = value.asString();
+ } else if (memberName.equals("hidden")) {
+ this.isHidden = value.asBoolean();
+ } else if (memberName.equals("fields")) {
+ this.fields = new ArrayList();
+ for (JsonValue field: value.asArray()) {
+ this.fields.add(new Field(field.asObject()));
+ }
+ }
+ }
+
+ /**
+ * Gets the metadata template of properties.
+ * @param api the API connection to be used.
+ * @return the metadata template returned from the server.
+ */
+ public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api) {
+ return getMetadataTemplate(api, DEFAULT_METADATA_TYPE);
+ }
+
+ /**
+ * Gets the metadata template of specified template type.
+ * @param api the API connection to be used.
+ * @param templateName the metadata template type name.
+ * @return the metadata template returned from the server.
+ */
+ public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api, String templateName) {
+ String scope = scopeBasedOnType(templateName);
+ return getMetadataTemplate(api, templateName, scope);
+ }
+
+ /**
+ * Gets the metadata template of specified template type.
+ * @param api the API connection to be used.
+ * @param templateName the metadata template type name.
+ * @param scope the metadata template scope (global or enterprise).
+ * @param fields the fields to retrieve.
+ * @return the metadata template returned from the server.
+ */
+ public static MetadataTemplate getMetadataTemplate(
+ BoxAPIConnection api, String templateName, String scope, String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildWithQuery(
+ api.getBaseURL(), builder.toString(), scope, templateName);
+ BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ return new MetadataTemplate(response.getJSON());
+ }
+
+ /**
+ * Returns all metadata templates within a user's enterprise.
+ * @param api the API connection to be used.
+ * @param fields the fields to retrieve.
+ * @return the metadata template returned from the server.
+ */
+ public static Iterable getEnterpriseMetadataTemplates(BoxAPIConnection api, String ... fields) {
+ return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, api, fields);
+ }
+
+ /**
+ * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported.
+ * @param scope the scope of the metadata templates.
+ * @param api the API connection to be used.
+ * @param fields the fields to retrieve.
+ * @return the metadata template returned from the server.
+ */
+ public static Iterable getEnterpriseMetadataTemplates(
+ String scope, BoxAPIConnection api, String ... fields) {
+ return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, DEFAULT_ENTRIES_LIMIT, api, fields);
+ }
+
+ /**
+ * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported.
+ * @param scope the scope of the metadata templates.
+ * @param limit maximum number of entries per response.
+ * @param api the API connection to be used.
+ * @param fields the fields to retrieve.
+ * @return the metadata template returned from the server.
+ */
+ public static Iterable getEnterpriseMetadataTemplates(
+ String scope, int limit, BoxAPIConnection api, String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new BoxResourceIterable(
+ api, ENTERPRISE_METADATA_URL_TEMPLATE.buildWithQuery(
+ api.getBaseURL(), builder.toString(), scope), limit) {
+
+ @Override
+ protected MetadataTemplate factory(JsonObject jsonObject) {
+ return new MetadataTemplate(jsonObject);
+ }
+ };
+ }
+
+ /**
+ * Determines the metadata scope based on type.
+ * @param typeName type of the metadata.
+ * @return scope of the metadata.
+ */
+ private static String scopeBasedOnType(String typeName) {
+ return typeName.equals(DEFAULT_METADATA_TYPE) ? GLOBAL_METADATA_SCOPE : ENTERPRISE_METADATA_SCOPE;
+ }
+
+ /**
+ * Class contains information about the metadata template field.
+ */
+ public class Field extends BoxJSONObject {
+
+ /**
+ * @see #getType()
+ */
+ private String type;
+
+ /**
+ * @see #getKey()
+ */
+ private String key;
+
+ /**
+ * @see #getDisplayName()
+ */
+ private String displayName;
+
+ /**
+ * @see #getIsHidden()
+ */
+ private Boolean isHidden;
+
+ /**
+ * @see #getDescription()
+ */
+ private String description;
+
+ /**
+ * @see #getOptions()
+ */
+ private List options;
+
+ /**
+ * Constructs an empty metadata template.
+ */
+ public Field() {
+ super();
+ }
+
+ /**
+ * Constructs a metadate template field from a JSON string.
+ * @param json the json encoded metadate template field.
+ */
+ public Field(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs a metadate template field from a JSON object.
+ * @param jsonObject the json encoded metadate template field.
+ */
+ Field(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ /**
+ * Gets the data type of the field's value.
+ * @return the data type of the field's value.
+ */
+ public String getType() {
+ return this.type;
+ }
+
+ /**
+ * Gets the key of the field.
+ * @return the key of the field.
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * Gets the display name of the field.
+ * @return the display name of the field.
+ */
+ public String getDisplayName() {
+ return this.displayName;
+ }
+
+ /**
+ * Gets is metadata template field hidden.
+ * @return is metadata template field hidden.
+ */
+ public Boolean getIsHidden() {
+ return this.isHidden;
+ }
+
+ /**
+ * Gets the description of the field.
+ * @return the description of the field.
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+ /**
+ * Gets list of possible options for enum type of the field.
+ * @return list of possible options for enum type of the field.
+ */
+ public List getOptions() {
+ return this.options;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void parseJSONMember(JsonObject.Member member) {
+ JsonValue value = member.getValue();
+ String memberName = member.getName();
+ if (memberName.equals("type")) {
+ this.type = value.asString();
+ } else if (memberName.equals("key")) {
+ this.key = value.asString();
+ } else if (memberName.equals("displayName")) {
+ this.displayName = value.asString();
+ } else if (memberName.equals("hidden")) {
+ this.isHidden = value.asBoolean();
+ } else if (memberName.equals("description")) {
+ this.description = value.asString();
+ } else if (memberName.equals("options")) {
+ this.options = new ArrayList();
+ for (JsonValue key: value.asArray()) {
+ this.options.add(key.asObject().get("key").asString());
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/test/java/com/box/sdk/MetadataTemplateTest.java b/src/test/java/com/box/sdk/MetadataTemplateTest.java
new file mode 100644
index 000000000..8ca7c60f6
--- /dev/null
+++ b/src/test/java/com/box/sdk/MetadataTemplateTest.java
@@ -0,0 +1,252 @@
+package com.box.sdk;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.eclipsesource.json.JsonObject;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+
+/**
+ * {@link MetadataTemplate} related unit tests.
+ */
+public class MetadataTemplateTest {
+
+ /**
+ * Wiremock
+ */
+ @Rule
+ public final WireMockRule wireMockRule = new WireMockRule(8080);
+
+ /**
+ * Unit test for {@link MetadataTemplate#getMetadataTemplate(BoxAPIConnection, String, String, String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetMetadataTemplateSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/metadata_templates/global/properties/schema"
+ + "?fields=displayName%2Chidden",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ MetadataTemplate.getMetadataTemplate(api, "properties", "global", "displayName", "hidden");
+ }
+
+ /**
+ * Unit test for {@link MetadataTemplate#getMetadataTemplate(BoxAPIConnection)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetMetadataTemplateParseAllFieldsCorrectly() {
+ final String templateKey = "productInfo";
+ final String scope = "enterprise_12345";
+ final String displayName = "Product Info";
+ final Boolean isHidden = false;
+ final String firstFieldType = "float";
+ final String firstFieldKey = "skuNumber";
+ final String firstFieldDisplayName = "SKU Number";
+ final Boolean firstFieldIsHidden = false;
+ final String secondFieldType = "enum";
+ final String secondFieldKey = "department";
+ final String secondFieldDisplayName = "Department";
+ final Boolean secondFieldIsHidden = false;
+ final String secondFieldFirstOption = "Beauty";
+ final String secondFieldSecondOption = "Accessories";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setBaseURL("http://localhost:8080/");
+ WireMock.stubFor(WireMock.get(WireMock.urlMatching("/metadata_templates/global/properties/schema"))
+ .willReturn(WireMock.aResponse()
+ .withHeader("Content-Type", "application/json")
+ .withBody("{\n"
+ + " \"templateKey\": \"productInfo\",\n"
+ + " \"scope\": \"enterprise_12345\",\n"
+ + " \"displayName\": \"Product Info\",\n"
+ + " \"hidden\": false,\n"
+ + " \"fields\": [\n"
+ + " {\n"
+ + " \"type\": \"float\",\n"
+ + " \"key\": \"skuNumber\",\n"
+ + " \"displayName\": \"SKU Number\",\n"
+ + " \"hidden\": false\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"enum\",\n"
+ + " \"key\": \"department\",\n"
+ + " \"displayName\": \"Department\",\n"
+ + " \"hidden\": false,\n"
+ + " \"options\": [\n"
+ + " {\n"
+ + " \"key\": \"Beauty\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"key\": \"Accessories\"\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + " ]\n"
+ + "}")));
+
+ MetadataTemplate template = MetadataTemplate.getMetadataTemplate(api);
+ Assert.assertEquals(templateKey, template.getTemplateKey());
+ Assert.assertEquals(scope, template.getScope());
+ Assert.assertEquals(displayName, template.getDisplayName());
+ Assert.assertEquals(isHidden, template.getIsHidden());
+ List templateFields = template.getFields();
+ Assert.assertEquals(firstFieldType, templateFields.get(0).getType());
+ Assert.assertEquals(firstFieldKey, templateFields.get(0).getKey());
+ Assert.assertEquals(firstFieldDisplayName, templateFields.get(0).getDisplayName());
+ Assert.assertEquals(firstFieldIsHidden, templateFields.get(0).getIsHidden());
+ Assert.assertEquals(secondFieldType, templateFields.get(1).getType());
+ Assert.assertEquals(secondFieldKey, templateFields.get(1).getKey());
+ Assert.assertEquals(secondFieldDisplayName, templateFields.get(1).getDisplayName());
+ Assert.assertEquals(secondFieldIsHidden, templateFields.get(1).getIsHidden());
+ Assert.assertEquals(secondFieldFirstOption, templateFields.get(1).getOptions().get(0));
+ Assert.assertEquals(secondFieldSecondOption, templateFields.get(1).getOptions().get(1));
+
+ }
+
+ /**
+ * Unit test for {@link MetadataTemplate#getEnterpriseMetadataTemplates(BoxAPIConnection, String...)}.
+ */
+ @Test(expected = NoSuchElementException.class)
+ @Category(UnitTest.class)
+ public void testGetEnterpriseMetadataTemplatesSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/metadata_templates/enterprise?fields=displayName%2Chidden&limit=100",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\":[]}";
+ }
+ };
+ }
+ });
+
+ Iterator iterator =
+ MetadataTemplate.getEnterpriseMetadataTemplates(api, "displayName", "hidden").iterator();
+ iterator.next();
+ }
+
+ /**
+ * Unit test for {@link MetadataTemplate#getEnterpriseMetadataTemplates(BoxAPIConnection, String...)}.
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetEnterpriseMetadataTemplatesParseAllFieldsCorrectly() {
+ final String firstEntryTemplateKey = "documentFlow";
+ final String firstEntryScope = "enterprise_12345";
+ final String firstEntryDisplayName = "Document Flow";
+ final Boolean firstEntryIsHidden = false;
+ final String firstEntryFieldType = "string";
+ final String firstEntryFieldKey = "currentDocumentStage";
+ final String firstEntryFieldDisplayName = "Current Document Stage";
+ final Boolean firstEntryFieldIsHidden = false;
+ final String firstEntryFieldDescription = "What stage in the process the document is in";
+ final String secondEntryTemplateKey = "productInfo";
+ final String secondEntryScope = "enterprise_12345";
+ final String secondEntryDisplayName = "Product Info";
+ final Boolean secondEntryIsHidden = false;
+ final String secondEntryFieldType = "enum";
+ final String secondEntryFieldKey = "department";
+ final String secondEntryFieldDisplayName = "Department";
+ final Boolean secondEntryFieldIsHidden = false;
+ final String secondEntryFieldFirstOption = "Beauty";
+ final String secondEntryFieldSecondOption = "Shoes";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"limit\": 100,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"templateKey\": \"documentFlow\",\n"
+ + " \"scope\": \"enterprise_12345\",\n"
+ + " \"displayName\": \"Document Flow\",\n"
+ + " \"hidden\": false,\n"
+ + " \"fields\": [\n"
+ + " {\n"
+ + " \"type\": \"string\",\n"
+ + " \"key\": \"currentDocumentStage\",\n"
+ + " \"displayName\": \"Current Document Stage\",\n"
+ + " \"hidden\": false,\n"
+ + " \"description\": \"What stage in the process the document is in\"\n"
+ + " }\n"
+ + " ]\n"
+ + " },\n"
+ + " {\n"
+ + " \"templateKey\": \"productInfo\",\n"
+ + " \"scope\": \"enterprise_12345\",\n"
+ + " \"displayName\": \"Product Info\",\n"
+ + " \"hidden\": false,\n"
+ + " \"fields\": [\n"
+ + " {\n"
+ + " \"type\": \"enum\",\n"
+ + " \"key\": \"department\",\n"
+ + " \"displayName\": \"Department\",\n"
+ + " \"hidden\": false,\n"
+ + " \"options\": [\n"
+ + " {\n"
+ + " \"key\": \"Beauty\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"key\": \"Shoes\"\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + " ],\n"
+ + " \"next_marker\": null,\n"
+ + " \"prev_marker\": null\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ Iterator iterator = MetadataTemplate.getEnterpriseMetadataTemplates(api).iterator();
+ MetadataTemplate template = iterator.next();
+ Assert.assertEquals(firstEntryTemplateKey, template.getTemplateKey());
+ Assert.assertEquals(firstEntryScope, template.getScope());
+ Assert.assertEquals(firstEntryDisplayName, template.getDisplayName());
+ Assert.assertEquals(firstEntryIsHidden, template.getIsHidden());
+ Assert.assertEquals(firstEntryFieldType, template.getFields().get(0).getType());
+ Assert.assertEquals(firstEntryFieldKey, template.getFields().get(0).getKey());
+ Assert.assertEquals(firstEntryFieldDisplayName, template.getFields().get(0).getDisplayName());
+ Assert.assertEquals(firstEntryFieldIsHidden, template.getFields().get(0).getIsHidden());
+ Assert.assertEquals(firstEntryFieldDescription, template.getFields().get(0).getDescription());
+ template = iterator.next();
+ Assert.assertEquals(secondEntryTemplateKey, template.getTemplateKey());
+ Assert.assertEquals(secondEntryScope, template.getScope());
+ Assert.assertEquals(secondEntryDisplayName, template.getDisplayName());
+ Assert.assertEquals(secondEntryIsHidden, template.getIsHidden());
+ Assert.assertEquals(secondEntryFieldType, template.getFields().get(0).getType());
+ Assert.assertEquals(secondEntryFieldKey, template.getFields().get(0).getKey());
+ Assert.assertEquals(secondEntryFieldDisplayName, template.getFields().get(0).getDisplayName());
+ Assert.assertEquals(secondEntryFieldIsHidden, template.getFields().get(0).getIsHidden());
+ Assert.assertEquals(secondEntryFieldFirstOption, template.getFields().get(0).getOptions().get(0));
+ Assert.assertEquals(secondEntryFieldSecondOption, template.getFields().get(0).getOptions().get(1));
+ Assert.assertFalse(iterator.hasNext());
+ }
+}
From b2aac578c563168254d44de84332717b760068ff Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Fri, 18 Nov 2016 11:29:32 +0100
Subject: [PATCH 022/119] legal holds assignments and file version legal holds
features implemented
---
doc/legal_holds.md | 95 +++++++
src/main/java/com/box/sdk/BoxFileVersion.java | 17 +-
.../com/box/sdk/BoxFileVersionLegalHold.java | 185 ++++++++++++
src/main/java/com/box/sdk/BoxLegalHold.java | 91 ++++++
.../com/box/sdk/BoxLegalHoldAssignment.java | 265 ++++++++++++++++++
src/main/java/com/box/sdk/BoxResource.java | 2 +
.../box/sdk/BoxFileVersionLegalHoldTest.java | 97 +++++++
.../box/sdk/BoxLegalHoldAssignmentTest.java | 208 ++++++++++++++
.../java/com/box/sdk/BoxLegalHoldTest.java | 200 +++++++++++++
9 files changed, 1159 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/box/sdk/BoxFileVersionLegalHold.java
create mode 100644 src/main/java/com/box/sdk/BoxLegalHoldAssignment.java
create mode 100644 src/test/java/com/box/sdk/BoxFileVersionLegalHoldTest.java
create mode 100644 src/test/java/com/box/sdk/BoxLegalHoldAssignmentTest.java
diff --git a/doc/legal_holds.md b/doc/legal_holds.md
index 82391f0a8..d5c5c6408 100644
--- a/doc/legal_holds.md
+++ b/doc/legal_holds.md
@@ -9,6 +9,12 @@ such as name, description, and filter dates.
* [Create New Legal Hold Policy](#create-new-legal-hold-policy)
* [Update Existing Legal Hold Policy](#update-existing-legal-hold-policy)
* [Delete Legal Hold Policy](#delete-legal-hold-policy)
+* [Get Assignment](#get-assignment)
+* [Get List of Assignments](#get-list-of-assignments)
+* [Create New Assignment](#create-new-assignment)
+* [Delete Assignment](#delete-assignment)
+* [Get File Version Legal Hold](#get-file-version-legal-hold)
+* [Get List of File Version Legal Holds](#get-list-of-file-version-legal-holds)
Get Legal Hold Policy
---------------------
@@ -85,3 +91,92 @@ policy.delete();
```
[delete]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#delete()
+
+Get Assignment
+--------------
+
+Calling [`getInfo(String...)`][get-assignment] will return a BoxLegalHoldAssignment.Info
+object containing information about the legal hold policy assignment.
+
+```java
+BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(api, id);
+BoxLegalHoldAssignment.Info info = assignment.getInfo("assigned_by");
+```
+
+[get-assignment]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldAssignment.html#getInfo(java.lang.String...)
+
+Get List of Assignments
+--------------
+
+Calling the static [`getAssignments(String...)`][get-list-of-assignments] will return
+an iterable that will page through all of the assignments of the legal hold policy.
+It is possible to specify filters for type and id, maximum number of items per single
+response and fields to retrieve by calling [`getAssignments(String, String, int, String...)`][get-list-of-assignments-with-params].
+
+```java
+BoxLegalHold policy = new BoxLegalHold(api, id);
+Iterable assignments = policy.getAssignments(BoxResource.getResourceType(BoxFolder.class), null, 50, "assigned_at");
+for (BoxLegalHoldAssignment.Info assignmentInfo : assignments) {
+ // Do something with the legal hold policy assignment.
+}
+```
+
+[get-list-of-assignments]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getAssignments(java.lang.String...)
+[get-list-of-assignments-with-params]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getAssignments(java.lang.String,%20java.lang.String,%20int,%20java.lang.String...)
+
+Create New Assignment
+--------------
+
+To create new legal hold policy assignment call [`assignTo(BoxResource)`][create-assignment] method.
+Currently only BoxFile, BoxFileVersion, BoxFolder and BoxUser objects are supported as a parameter.
+
+```java
+BoxLegalHold policy = new BoxLegalHold(api, policyID);
+BoxFolder folder = new BoxFolder(api, folderID);
+policy.assignTo(folder);
+```
+
+[create-assignment]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#assignTo(com.box.sdk.BoxResource)
+
+Delete Assignment
+--------------
+
+A legal hold policy assignment can be deleted by calling the [`delete()`][delete-assignment] method
+of BoxLegalHoldAssignment object.
+
+```java
+BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(api, id);
+assignment.delete();
+```
+
+[delete-assignment]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldAssignment.html#delete()
+
+Get File Version Legal Hold
+--------------
+
+Calling [`getInfo(String...)`][get-file-version-legal-hold] will return
+a BoxFileVersionLegalHold.Info object containing information about the file version legal hold policy.
+
+```java
+BoxFileVersionLegalHold hold = new BoxFileVersionLegalHold(api, id);
+hold.getInfo("file");
+```
+
+[get-file-version-legal-hold]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileVersionLegalHold.html#getInfo(java.lang.String...)
+
+Get List of File Version Legal Holds
+--------------
+To get an iterable with all non-deleted file version legal holds for current
+legal hold policy, call [`getFileVersionHolds(String...)`][get-lest-of-file-version-legal-holds].
+It is possible to specify maximum number of items per single response by calling [`getFileVersionHolds(int, String...)`][get-lest-of-file-version-legal-holds-with-limit].
+
+```java
+BoxLegalHold policy = new BoxLegalHold(api, id);
+Iterable fileVersionHolds = policy.getFileVersionHolds();
+for (BoxFileVersionLegalHold.Info fileVersionHold : fileVersionHolds) {
+ // Do something with the file version legal hold.
+}
+```
+
+[get-lest-of-file-version-legal-holds]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getFileVersionHolds(java.lang.String...)
+[get-lest-of-file-version-legal-holds-with-limit]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getFileVersionHolds(int,%20java.lang.String...)
\ No newline at end of file
diff --git a/src/main/java/com/box/sdk/BoxFileVersion.java b/src/main/java/com/box/sdk/BoxFileVersion.java
index 27d3832b6..dcd89b5c9 100644
--- a/src/main/java/com/box/sdk/BoxFileVersion.java
+++ b/src/main/java/com/box/sdk/BoxFileVersion.java
@@ -19,7 +19,7 @@ public class BoxFileVersion extends BoxResource {
private static final URLTemplate VERSION_URL_TEMPLATE = new URLTemplate("files/%s/versions/%s");
private static final int BUFFER_SIZE = 8192;
- private final String fileID;
+ private String fileID;
private String versionID;
private String sha1;
@@ -78,6 +78,21 @@ public BoxFileVersion(BoxAPIConnection api, String json, String fileID) {
}
}
+ /**
+ * Used if no or wrong file id was set with constructor.
+ * @param fileID the file id this file version belongs to.
+ */
+ public void setFileID(String fileID) {
+ this.fileID = fileID;
+ }
+
+ /**
+ * @return the file id this file version belongs to.
+ */
+ public String getFileID() {
+ return this.fileID;
+ }
+
/**
* Gets the version ID of this version of the file.
* @return the version ID of this version of the file.
diff --git a/src/main/java/com/box/sdk/BoxFileVersionLegalHold.java b/src/main/java/com/box/sdk/BoxFileVersionLegalHold.java
new file mode 100644
index 000000000..4afd48cd3
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxFileVersionLegalHold.java
@@ -0,0 +1,185 @@
+package com.box.sdk;
+
+import java.net.URL;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ * Representing all holds on a file version.
+ * Note that every file version can have a maximum of one file version legal hold.
+ */
+@BoxResourceType("file_version_legal_hold")
+public class BoxFileVersionLegalHold extends BoxResource {
+
+ /**
+ * The URL template used for operation with file version legal hold with given ID.
+ * @see #getInfo(String...)
+ */
+ private static final URLTemplate FILE_VERSION_HOLD_URL_TEMPLATE = new URLTemplate("file_version_legal_holds/%s");
+
+ /**
+ * Constructs a file version legal hold with a given ID.
+ *
+ * @param api the API connection to be used by the resource.
+ * @param id the ID of the resource.
+ */
+ public BoxFileVersionLegalHold(BoxAPIConnection api, String id) {
+ super(api, id);
+ }
+
+ /**
+ * @param fields the fields to retrieve.
+ * @return information about this file version legal hold.
+ */
+ public BoxFileVersionLegalHold.Info getInfo(String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = FILE_VERSION_HOLD_URL_TEMPLATE.buildWithQuery(
+ this.getAPI().getBaseURL(), builder.toString(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+ return new Info(responseJSON);
+ }
+
+ /**
+ * Contains information about the file version legal hold.
+ */
+ public class Info extends BoxResource.Info {
+
+ /**
+ * Used for file version in case it was retrieved separately from file.
+ */
+ private static final String DEFAULT_FILE_ID = "0";
+
+ /**
+ * @see #getFileVersion()
+ */
+ private BoxFileVersion fileVersion;
+
+ /**
+ * @see #getFile()
+ */
+ private BoxFile.Info file;
+
+ /**
+ * @see #getAssignments()
+ */
+ private List assignments;
+
+ /**
+ * @see #getDeletedAt()
+ */
+ private Date deletedAt;
+
+ /**
+ * Constructs an empty Info object.
+ */
+ public Info() {
+ super();
+ }
+
+ /**
+ * Constructs an Info object by parsing information from a JSON string.
+ * @param json the JSON string to parse.
+ */
+ public Info(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs an Info object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ Info(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BoxResource getResource() {
+ return BoxFileVersionLegalHold.this;
+ }
+
+ /**
+ * @return the file version that is held.
+ */
+ public BoxFileVersion getFileVersion() {
+ return this.fileVersion;
+ }
+
+ /**
+ * @return the parent file of the file version that is held.
+ * Note that there is no guarantee that the current version of this file is held.
+ */
+ public BoxFile.Info getFile() {
+ return this.file;
+ }
+
+ /**
+ * @return iterable with the assignments contributing to this file version legal hold.
+ */
+ public Iterable getAssignments() {
+ return this.assignments;
+ }
+
+ /**
+ * @return time that this file version legal hold was deleted.
+ */
+ public Date getDeletedAt() {
+ return this.deletedAt;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void parseJSONMember(JsonObject.Member member) {
+ super.parseJSONMember(member);
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ try {
+ if (memberName.equals("file")) {
+ JsonObject fileJSON = value.asObject();
+ if (this.file == null) {
+ String fileID = fileJSON.get("id").asString();
+ BoxFile file = new BoxFile(getAPI(), fileID);
+ this.file = file.new Info(fileJSON);
+ } else {
+ this.file.update(fileJSON);
+ }
+ if (this.fileVersion != null) {
+ this.fileVersion.setFileID(this.file.getID());
+ }
+ } else if (memberName.equals("file_version")) {
+ JsonObject versionJSON = value.asObject();
+ String fileID = this.file != null ? this.file.getID() : DEFAULT_FILE_ID;
+ this.fileVersion = new BoxFileVersion(getAPI(), versionJSON, fileID);
+ } else if (memberName.equals("legal_hold_policy_assignments")) {
+ JsonArray array = value.asArray();
+ this.assignments = new ArrayList();
+ for (JsonValue assignmentJSON : array) {
+ String assignmentID = ((JsonObject) assignmentJSON).get("id").asString();
+ BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(getAPI(), assignmentID);
+ this.assignments.add(assignment.new Info((JsonObject) assignmentJSON));
+ }
+ } else if (memberName.equals("deleted_at")) {
+ this.deletedAt = BoxDateFormat.parse(value.asString());
+ }
+ } catch (ParseException e) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/com/box/sdk/BoxLegalHold.java b/src/main/java/com/box/sdk/BoxLegalHold.java
index a4f0659ba..65fc2b74f 100644
--- a/src/main/java/com/box/sdk/BoxLegalHold.java
+++ b/src/main/java/com/box/sdk/BoxLegalHold.java
@@ -22,6 +22,10 @@ public class BoxLegalHold extends BoxResource {
private static final URLTemplate LEGAL_HOLD_URL_TEMPLATE = new URLTemplate("legal_hold_policies/%s");
private static final URLTemplate ALL_LEGAL_HOLD_URL_TEMPLATE = new URLTemplate("legal_hold_policies");
+ private static final URLTemplate LEGAL_HOLD_ASSIGNMENTS_URL_TEMPLATE
+ = new URLTemplate("legal_hold_policies/%s/assignments");
+ private static final URLTemplate LIST_OF_FILE_VERSION_HOLDS_URL_TEMPLATE
+ = new URLTemplate("file_version_legal_holds");
private static final int DEFAULT_LIMIT = 100;
/**
@@ -153,6 +157,93 @@ protected BoxLegalHold.Info factory(JsonObject jsonObject) {
};
}
+ /**
+ * Assigns this legal holds policy to the given box resource.
+ * Currently only {@link BoxFile}, {@link BoxFileVersion}, {@link BoxFolder} and {@link BoxUser} are supported.
+ * @param resource the box resource to assign legal hold policy to.
+ * @return info about created legal hold policy assignment.
+ */
+ public BoxLegalHoldAssignment.Info assignTo(BoxResource resource) {
+ return BoxLegalHoldAssignment.create(
+ this.getAPI(), this.getID(), BoxResource.getResourceType(resource.getClass()), resource.getID());
+ }
+
+ /**
+ * Returns iterable containing assignments for this single legal hold policy.
+ * @param fields the fields to retrieve.
+ * @return an iterable containing assignments for this single legal hold policy.
+ */
+ public Iterable getAssignments(String ... fields) {
+ return this.getAssignments(null, null, DEFAULT_LIMIT, fields);
+ }
+
+ /**
+ * Returns iterable containing assignments for this single legal hold policy.
+ * Parameters can be used to filter retrieved assignments.
+ * @param type filter assignments of this type only.
+ * Can be "file_version", "file", "folder", "user" or null if no type filter is necessary.
+ * @param id filter assignments to this ID only. Can be null if no id filter is necessary.
+ * @param limit the limit of entries per page. Default limit is 100.
+ * @param fields the fields to retrieve.
+ * @return an iterable containing assignments for this single legal hold policy.
+ */
+ public Iterable getAssignments(String type, String id, int limit, String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (type != null) {
+ builder.appendParam("assign_to_type", type);
+ }
+ if (id != null) {
+ builder.appendParam("assign_to_id", id);
+ }
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new BoxResourceIterable(
+ this.getAPI(), LEGAL_HOLD_ASSIGNMENTS_URL_TEMPLATE.buildWithQuery(
+ this.getAPI().getBaseURL(), builder.toString(), this.getID()), limit) {
+
+ @Override
+ protected BoxLegalHoldAssignment.Info factory(JsonObject jsonObject) {
+ BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(
+ BoxLegalHold.this.getAPI(), jsonObject.get("id").asString());
+ return assignment.new Info(jsonObject);
+ }
+ };
+ }
+
+ /**
+ * Returns iterable with all non-deleted file version legal holds for this legal hold policy.
+ * @param fields the fields to retrieve.
+ * @return an iterable containing file version legal holds info.
+ */
+ public Iterable getFileVersionHolds(String ... fields) {
+ return this.getFileVersionHolds(DEFAULT_LIMIT, fields);
+ }
+
+ /**
+ * Returns iterable with all non-deleted file version legal holds for this legal hold policy.
+ * @param limit the limit of entries per response. The default value is 100.
+ * @param fields the fields to retrieve.
+ * @return an iterable containing file version legal holds info.
+ */
+ public Iterable getFileVersionHolds(int limit, String ... fields) {
+ QueryStringBuilder queryString = new QueryStringBuilder().appendParam("policy_id", this.getID());
+ if (fields.length > 0) {
+ queryString.appendParam("fields", fields);
+ }
+ URL url = LIST_OF_FILE_VERSION_HOLDS_URL_TEMPLATE.buildWithQuery(getAPI().getBaseURL(), queryString.toString());
+ return new BoxResourceIterable(getAPI(), url, limit) {
+
+ @Override
+ protected BoxFileVersionLegalHold.Info factory(JsonObject jsonObject) {
+ BoxFileVersionLegalHold assignment
+ = new BoxFileVersionLegalHold(getAPI(), jsonObject.get("id").asString());
+ return assignment.new Info(jsonObject);
+ }
+
+ };
+ }
+
/**
* Contains information about the legal hold policy.
*/
diff --git a/src/main/java/com/box/sdk/BoxLegalHoldAssignment.java b/src/main/java/com/box/sdk/BoxLegalHoldAssignment.java
new file mode 100644
index 000000000..4d442ef2f
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxLegalHoldAssignment.java
@@ -0,0 +1,265 @@
+package com.box.sdk;
+
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Date;
+
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ * Represents a legal hold policy assignment.
+ * Legal hold assignments are used to assign legal hold policies to custodians, folders, files, or file versions.
+ *
+ * @see Box legal holds
+ *
+ * Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
+ * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
+ * handling for errors related to the Box REST API, you should capture this exception explicitly.
+ */
+@BoxResourceType("legal_hold_assignment")
+public class BoxLegalHoldAssignment extends BoxResource {
+
+ /**
+ * Used to assign legal hold policy to file version.
+ */
+ public static final String TYPE_FILE_VERSION = BoxFileVersion.getResourceType(BoxFileVersion.class);
+
+ /**
+ * Used to assign legal hold policy to file.
+ */
+ public static final String TYPE_FILE = BoxFile.getResourceType(BoxFile.class);
+
+ /**
+ * Used to assign legal hold policy to folder.
+ */
+ public static final String TYPE_FOLDER = BoxFolder.getResourceType(BoxFolder.class);
+
+ /**
+ * Used to assign legal hold policy to user.
+ */
+ public static final String TYPE_USER = BoxUser.getResourceType(BoxUser.class);
+
+ /**
+ * The URL template used for operation with legal hold policy assignments.
+ */
+ private static final URLTemplate ASSIGNMENTS_URL_TEMPLATE = new URLTemplate("legal_hold_policy_assignments");
+
+ /**
+ * The URL template used for operation with legal hold policy assignment with given ID.
+ */
+ private static final URLTemplate LEGAL_HOLD_ASSIGNMENT_URL_TEMPLATE
+ = new URLTemplate("legal_hold_policy_assignments/%s");
+
+ /**
+ * Constructs a BoxLegalHoldAssignment for a resource with a given ID.
+ *
+ * @param api the API connection to be used by the resource.
+ * @param id the ID of the resource.
+ */
+ public BoxLegalHoldAssignment(BoxAPIConnection api, String id) {
+ super(api, id);
+ }
+
+ /**
+ * Creates new legal hold policy assignment.
+ * @param api the API connection to be used by the resource.
+ * @param policyID ID of policy to create assignment for.
+ * @param resourceType type of target resource. Can be 'file_version', 'file', 'folder', or 'user'.
+ * @param resourceID ID of the target resource.
+ * @return info about created legal hold policy assignment.
+ */
+ public static BoxLegalHoldAssignment.Info create(BoxAPIConnection api,
+ String policyID, String resourceType, String resourceID) {
+ URL url = ASSIGNMENTS_URL_TEMPLATE.build(api.getBaseURL());
+ BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
+
+ JsonObject requestJSON = new JsonObject()
+ .add("policy_id", policyID)
+ .add("assign_to", new JsonObject()
+ .add("type", resourceType)
+ .add("id", resourceID));
+ request.setBody(requestJSON.toString());
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+ BoxLegalHoldAssignment createdAssignment = new BoxLegalHoldAssignment(api, responseJSON.get("id").asString());
+ return createdAssignment.new Info(responseJSON);
+ }
+
+ /**
+ * Deletes the legal hold policy assignment.
+ */
+ public void delete() {
+ URL url = LEGAL_HOLD_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
+ BoxAPIResponse response = request.send();
+ response.disconnect();
+ }
+
+ /**
+ * @param fields the fields to retrieve.
+ * @return information about this retention policy.
+ */
+ public BoxLegalHoldAssignment.Info getInfo(String ... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ URL url = LEGAL_HOLD_ASSIGNMENT_URL_TEMPLATE.buildWithQuery(
+ this.getAPI().getBaseURL(), builder.toString(), this.getID());
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+ return new Info(responseJSON);
+ }
+
+ /**
+ * Contains information about the legal hold policy.
+ */
+ public class Info extends BoxResource.Info {
+
+ /**
+ * @see #getLegalHold()
+ */
+ private BoxLegalHold.Info legalHold;
+
+ /**
+ * @see #getAssignedBy()
+ */
+ private BoxUser.Info assignedBy;
+
+ /**
+ * @see #getAssignedAt()
+ */
+ private Date assignedAt;
+
+ /**
+ * @see #getDeletedAt()
+ */
+ private Date deletedAt;
+
+ /**
+ * @see #getAssignedToType()
+ */
+ private String assignedToType;
+
+ /**
+ * @see #getAssignedToID()
+ */
+ private String assignedToID;
+
+ /**
+ * Constructs an empty Info object.
+ */
+ public Info() {
+ super();
+ }
+
+ /**
+ * Constructs an Info object by parsing information from a JSON string.
+ * @param json the JSON string to parse.
+ */
+ public Info(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs an Info object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ Info(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public BoxResource getResource() {
+ return BoxLegalHoldAssignment.this;
+ }
+
+ /**
+ * @return info about the policy that this legal hold policy assignment is part of.
+ */
+ public BoxLegalHold.Info getLegalHold() {
+ return this.legalHold;
+ }
+
+ /**
+ * @return the info about the user who created that legal hold policy assignment.
+ */
+ public BoxUser.Info getAssignedBy() {
+ return this.assignedBy;
+ }
+
+ /**
+ * @return the time that the legal hold policy assignment was created.
+ */
+ public Date getAssignedAt() {
+ return this.assignedAt;
+ }
+
+ /**
+ * @return the time that the assignment release request was sent.
+ */
+ public Date getDeletedAt() {
+ return this.deletedAt;
+ }
+
+ /**
+ * @return the entity type that this is assigned to.
+ */
+ public String getAssignedToType() {
+ return this.assignedToType;
+ }
+
+ /**
+ * @return the entity id that this is assigned to.
+ */
+ public String getAssignedToID() {
+ return this.assignedToID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void parseJSONMember(JsonObject.Member member) {
+ super.parseJSONMember(member);
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ try {
+ if (memberName.equals("legal_hold_policy")) {
+ JsonObject policyJSON = value.asObject();
+ if (this.legalHold == null) {
+ String policyID = policyJSON.get("id").asString();
+ BoxLegalHold policy = new BoxLegalHold(getAPI(), policyID);
+ this.legalHold = policy.new Info(policyJSON);
+ } else {
+ this.legalHold.update(policyJSON);
+ }
+ } else if (memberName.equals("assigned_to")) {
+ JsonObject assignmentJSON = value.asObject();
+ this.assignedToType = assignmentJSON.get("type").asString();
+ this.assignedToID = assignmentJSON.get("id").asString();
+ } else if (memberName.equals("assigned_by")) {
+ JsonObject userJSON = value.asObject();
+ if (this.assignedBy == null) {
+ String userID = userJSON.get("id").asString();
+ BoxUser user = new BoxUser(getAPI(), userID);
+ this.assignedBy = user.new Info(userJSON);
+ } else {
+ this.assignedBy.update(userJSON);
+ }
+ } else if (memberName.equals("assigned_at")) {
+ this.assignedAt = BoxDateFormat.parse(value.asString());
+ } else if (memberName.equals("deleted_at")) {
+ this.deletedAt = BoxDateFormat.parse(value.asString());
+ }
+ } catch (ParseException e) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/box/sdk/BoxResource.java b/src/main/java/com/box/sdk/BoxResource.java
index 10f64068b..15931ed51 100644
--- a/src/main/java/com/box/sdk/BoxResource.java
+++ b/src/main/java/com/box/sdk/BoxResource.java
@@ -58,6 +58,8 @@ private static Map> initResourceClassByType
result.put(getResourceType(BoxRetentionPolicyAssignment.class), BoxRetentionPolicyAssignment.class);
result.put(getResourceType(BoxFileVersionRetention.class), BoxFileVersionRetention.class);
result.put(getResourceType(BoxLegalHold.class), BoxLegalHold.class);
+ result.put(getResourceType(BoxLegalHoldAssignment.class), BoxLegalHoldAssignment.class);
+ result.put(getResourceType(BoxFileVersionLegalHold.class), BoxFileVersionLegalHold.class);
return Collections.unmodifiableMap(result);
}
diff --git a/src/test/java/com/box/sdk/BoxFileVersionLegalHoldTest.java b/src/test/java/com/box/sdk/BoxFileVersionLegalHoldTest.java
new file mode 100644
index 000000000..f277217e3
--- /dev/null
+++ b/src/test/java/com/box/sdk/BoxFileVersionLegalHoldTest.java
@@ -0,0 +1,97 @@
+package com.box.sdk;
+
+import java.util.Date;
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxFileVersionLegalHoldTest} related unit tests.
+ */
+public class BoxFileVersionLegalHoldTest {
+
+ /**
+ * Unit test for {@link BoxFileVersionLegalHold#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/file_version_legal_holds/0?fields=file",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxFileVersionLegalHold hold = new BoxFileVersionLegalHold(api, "0");
+ hold.getInfo("file");
+ }
+
+ /**
+ * Unit test for {@link BoxFileVersionLegalHold#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() {
+ final String id = "240997";
+ final String fileVersionID = "141649417";
+ final String fileID = "5025122933";
+ final String fileEtag = "1";
+ final String firstPolicyID = "255473";
+ final String secondPolicyID = "255617";
+ final Date deletedAt = null;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"legal_hold\",\n"
+ + " \"id\": \"240997\",\n"
+ + " \"file_version\": {\n"
+ + " \"type\": \"file_version\",\n"
+ + " \"id\": \"141649417\"\n"
+ + " },\n"
+ + " \"file\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"5025122933\",\n"
+ + " \"etag\": \"1\"\n"
+ + " },\n"
+ + " \"legal_hold_policy_assignments\": [\n"
+ + " {\n"
+ + " \"type\": \"legal_hold_policy_assignment\",\n"
+ + " \"id\": \"255473\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"legal_hold_policy_assignment\",\n"
+ + " \"id\": \"255617\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"deleted_at\": null\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxFileVersionLegalHold hold = new BoxFileVersionLegalHold(api, id);
+ BoxFileVersionLegalHold.Info info = hold.getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(fileVersionID, info.getFileVersion().getID());
+ Assert.assertEquals(fileID, info.getFileVersion().getFileID());
+ Assert.assertEquals(fileID, info.getFile().getID());
+ Assert.assertEquals(fileEtag, info.getFile().getEtag());
+ Assert.assertEquals(deletedAt, info.getDeletedAt());
+ Iterator iterator = info.getAssignments().iterator();
+ Assert.assertEquals(firstPolicyID, iterator.next().getID());
+ Assert.assertEquals(secondPolicyID, iterator.next().getID());
+ Assert.assertEquals(false, iterator.hasNext());
+ }
+}
diff --git a/src/test/java/com/box/sdk/BoxLegalHoldAssignmentTest.java b/src/test/java/com/box/sdk/BoxLegalHoldAssignmentTest.java
new file mode 100644
index 000000000..fd1f5367a
--- /dev/null
+++ b/src/test/java/com/box/sdk/BoxLegalHoldAssignmentTest.java
@@ -0,0 +1,208 @@
+package com.box.sdk;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxLegalHoldAssignment} related unit tests.
+ */
+public class BoxLegalHoldAssignmentTest {
+
+ /**
+ * Unit test for {@link BoxLegalHoldAssignment#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/legal_hold_policy_assignments/0?fields=assigned_by",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(api, "0");
+ assignment.getInfo("assigned_by");
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHoldAssignment#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "255473";
+ final String policyID = "166757";
+ final String policyName = "Bug Bash 5-12 Policy 3 updated";
+ final String assignedToType = "user";
+ final String assignedToID = "2030388321";
+ final String assignedByID = "2030388322";
+ final String assignedByName = "Steve Boxuser";
+ final String assignedByLogin = "sboxuser@box.com";
+ final Date assignedAt = BoxDateFormat.parse("2016-05-18T10:32:19-07:00");
+ final Date deletedAt = null;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"legal_hold_policy_assignment\",\n"
+ + " \"id\": \"255473\",\n"
+ + " \"legal_hold_policy\": {\n"
+ + " \"type\": \"legal_hold_policy\",\n"
+ + " \"id\": \"166757\",\n"
+ + " \"policy_name\": \"Bug Bash 5-12 Policy 3 updated\"\n"
+ + " },\n"
+ + " \"assigned_to\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"2030388321\"\n"
+ + " },\n"
+ + " \"assigned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"2030388322\",\n"
+ + " \"name\": \"Steve Boxuser\",\n"
+ + " \"login\": \"sboxuser@box.com\"\n"
+ + " },\n"
+ + " \"assigned_at\": \"2016-05-18T10:32:19-07:00\",\n"
+ + " \"deleted_at\": null\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(api, id);
+ BoxLegalHoldAssignment.Info info = assignment.getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(policyID, info.getLegalHold().getID());
+ Assert.assertEquals(policyName, info.getLegalHold().getPolicyName());
+ Assert.assertEquals(assignedToType, info.getAssignedToType());
+ Assert.assertEquals(assignedToID, info.getAssignedToID());
+ Assert.assertEquals(assignedByID, info.getAssignedBy().getID());
+ Assert.assertEquals(assignedByName, info.getAssignedBy().getName());
+ Assert.assertEquals(assignedByLogin, info.getAssignedBy().getLogin());
+ Assert.assertEquals(assignedAt, info.getAssignedAt());
+ Assert.assertEquals(deletedAt, info.getDeletedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHoldAssignment#create(BoxAPIConnection, String, String, String)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testCreateSendsCorrectJSON() {
+ final String policyID = "0";
+ final String resourceType = BoxLegalHoldAssignment.TYPE_FILE_VERSION;
+ final String resourceID = "1";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/legal_hold_policy_assignments",
+ request.getUrl().toString());
+ Assert.assertEquals(policyID, json.get("policy_id").asString());
+ Assert.assertEquals(resourceType, json.get("assign_to").asObject().get("type").asString());
+ Assert.assertEquals(resourceID, json.get("assign_to").asObject().get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxLegalHoldAssignment.create(api, policyID, resourceType, resourceID);
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHoldAssignment#create(BoxAPIConnection, String, String, String)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testCreateParseAllFieldsCorrectly() throws ParseException {
+ final String id = "255613";
+ final String policyID = "166757";
+ final String policyName = "Bug Bash 5-12 Policy 3 updated";
+ final String assignedToType = BoxLegalHoldAssignment.TYPE_FILE;
+ final String assignedToID = "5025127885";
+ final String assignedByID = "2030388321";
+ final String assignedByName = "Steve Boxuser";
+ final String assignedByLogin = "sboxuser@box.com";
+ final Date assignedAt = BoxDateFormat.parse("2016-05-18T17:38:03-07:00");
+ final Date deletedAt = null;
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"legal_hold_policy_assignment\",\n"
+ + " \"id\": \"255613\",\n"
+ + " \"legal_hold_policy\": {\n"
+ + " \"type\": \"legal_hold_policy\",\n"
+ + " \"id\": \"166757\",\n"
+ + " \"policy_name\": \"Bug Bash 5-12 Policy 3 updated\"\n"
+ + " },\n"
+ + " \"assigned_to\": {\n"
+ + " \"type\": \"file\",\n"
+ + " \"id\": \"5025127885\"\n"
+ + " },\n"
+ + " \"assigned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"2030388321\",\n"
+ + " \"name\": \"Steve Boxuser\",\n"
+ + " \"login\": \"sboxuser@box.com\"\n"
+ + " },\n"
+ + " \"assigned_at\": \"2016-05-18T17:38:03-07:00\",\n"
+ + " \"deleted_at\": null\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxLegalHoldAssignment.Info info = BoxLegalHoldAssignment.create(api, policyID, assignedToType, assignedToID);
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(policyID, info.getLegalHold().getID());
+ Assert.assertEquals(policyName, info.getLegalHold().getPolicyName());
+ Assert.assertEquals(assignedToType, info.getAssignedToType());
+ Assert.assertEquals(assignedToID, info.getAssignedToID());
+ Assert.assertEquals(assignedByID, info.getAssignedBy().getID());
+ Assert.assertEquals(assignedByName, info.getAssignedBy().getName());
+ Assert.assertEquals(assignedByLogin, info.getAssignedBy().getLogin());
+ Assert.assertEquals(assignedAt, info.getAssignedAt());
+ Assert.assertEquals(deletedAt, info.getDeletedAt());
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHoldAssignment#delete()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteSendsCorrectJSON() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/legal_hold_policy_assignments/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(api, "0");
+ assignment.delete();
+ }
+}
diff --git a/src/test/java/com/box/sdk/BoxLegalHoldTest.java b/src/test/java/com/box/sdk/BoxLegalHoldTest.java
index c05bec1ef..963708575 100644
--- a/src/test/java/com/box/sdk/BoxLegalHoldTest.java
+++ b/src/test/java/com/box/sdk/BoxLegalHoldTest.java
@@ -418,4 +418,204 @@ public void testGetAllParseAllFieldsCorrectly() {
Assert.assertEquals(false, iterator.hasNext());
}
+ /**
+ * Unit test for {@link BoxLegalHold#assignTo(BoxResource)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testAssignToSendsCorrectJSON() {
+ final String policyID = "0";
+ final String resourceType = BoxLegalHoldAssignment.TYPE_FILE_VERSION;
+ final String resourceID = "1";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/legal_hold_policy_assignments",
+ request.getUrl().toString());
+ Assert.assertEquals(policyID, json.get("policy_id").asString());
+ Assert.assertEquals(resourceType, json.get("assign_to").asObject().get("type").asString());
+ Assert.assertEquals(resourceID, json.get("assign_to").asObject().get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxFileVersion version = new BoxFileVersion(api, "{\"id\": \"1\"}", "2");
+ policy.assignTo(version);
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHold#getAssignments(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAssignmentsSendsCorrectRequestWithFields() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/legal_hold_policies/0/assignments?fields=assigned_at&limit=100",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ BoxLegalHold policy = new BoxLegalHold(api, "0");
+ Iterator iterator = policy.getAssignments("assigned_at").iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHold#getAssignments(String, String, int, String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAssignmentsSendsCorrectRequestWithOptionalParams() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals(
+ "https://api.box.com/2.0/legal_hold_policies/0/assignments"
+ + "?assign_to_type=folder&assign_to_id=1&limit=99",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ BoxLegalHold policy = new BoxLegalHold(api, "0");
+ Iterator iterator
+ = policy.getAssignments(BoxResource.getResourceType(BoxFolder.class), "1", 99).iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHold#getAssignments(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetAssignmentsParseAllFieldsCorrectly() {
+ final String firstEntryID = "255473";
+ final String secondEntryID = "123432";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"legal_hold_policy_assignment\",\n"
+ + " \"id\": \"255473\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"legal_hold_policy_assignment\",\n"
+ + " \"id\": \"123432\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"limit\": 100,\n"
+ + " \"order\": [\n"
+ + " {\n"
+ + " \"by\": \"retention_policy_id, retention_policy_object_id\",\n"
+ + " \"direction\": \"ASC\"\n"
+ + " }\n"
+ + " ]\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxLegalHold policy = new BoxLegalHold(api, "0");
+ Iterator iterator = policy.getAssignments().iterator();
+ BoxLegalHoldAssignment.Info info = iterator.next();
+ Assert.assertEquals(firstEntryID, info.getID());
+ info = iterator.next();
+ Assert.assertEquals(secondEntryID, info.getID());
+ Assert.assertEquals(false, iterator.hasNext());
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHold#getFileVersionHolds(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetFileVersionHoldsSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/file_version_legal_holds?policy_id=0&limit=100",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"entries\": []}";
+ }
+ };
+ }
+ });
+
+ BoxLegalHold policy = new BoxLegalHold(api, "0");
+ Iterator iterator = policy.getFileVersionHolds().iterator();
+ iterator.hasNext();
+ }
+
+ /**
+ * Unit test for {@link BoxLegalHold#getFileVersionHolds(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetFileVersionHoldsParseAllFieldsCorrectly() {
+ final String firstID = "241001";
+ final String secondID = "241005";
+ final String thirdID = "241009";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"legal_hold\",\n"
+ + " \"id\": \"241001\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"legal_hold\",\n"
+ + " \"id\": \"241005\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": \"legal_hold\",\n"
+ + " \"id\": \"241009\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"limit\": 100,\n"
+ + " \"order\": [\n"
+ + " {\n"
+ + " \"by\": \"retention_policy_set_id, file_version_id\",\n"
+ + " \"direction\": \"ASC\"\n"
+ + " }\n"
+ + " ]\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxLegalHold policy = new BoxLegalHold(api, "0");
+ Iterator iterator = policy.getFileVersionHolds().iterator();
+ Assert.assertEquals(firstID, iterator.next().getID());
+ Assert.assertEquals(secondID, iterator.next().getID());
+ Assert.assertEquals(thirdID, iterator.next().getID());
+ Assert.assertEquals(false, iterator.hasNext());
+ }
}
From 059cd28a5124b8127e00f6697fa7f5e8c8f6df98 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Wed, 2 Nov 2016 16:07:04 +0100
Subject: [PATCH 023/119] invite user feature documented
---
doc/users.md | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/doc/users.md b/doc/users.md
index f82fd8a6d..4cceb7b6f 100644
--- a/doc/users.md
+++ b/doc/users.md
@@ -7,6 +7,7 @@ Users represent an individual's account on Box.
* [Create An Enterprise User](#create-an-enterprise-user)
* [Update User](#update-user)
* [Delete User](#delete-user)
+* [Invite User](#invite-user)
* [Get Email Aliases](#get-email-aliases)
* [Add Email Alias](#add-email-alias)
* [Delete Email Alias](#delete-email-alias)
@@ -66,6 +67,18 @@ user.delete(false, false);
[delete]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#delete(boolean,%20boolean)
+Invite User
+-----------
+
+To invite an existing user to join an Enterprise call the [`inviteUser(String, String)`][invite] method.
+
+```java
+BoxUser user = new BoxUser(api, "0");
+user.invite("Enterprise ID", "Invited User Login");
+```
+
+[invite]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#inviteUser(java.lang.String,%java.lang.String)
+
Get Email Aliases
-----------------
From b8747105f20e01f66606e3ebde20b41027e60546 Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Fri, 18 Nov 2016 12:56:31 +0100
Subject: [PATCH 024/119] fixed and tests for delete and promote file version
---
src/main/java/com/box/sdk/BoxFileVersion.java | 28 +++-
.../java/com/box/sdk/BoxFileVersionTest.java | 120 ++++++++++++++++++
2 files changed, 146 insertions(+), 2 deletions(-)
create mode 100644 src/test/java/com/box/sdk/BoxFileVersionTest.java
diff --git a/src/main/java/com/box/sdk/BoxFileVersion.java b/src/main/java/com/box/sdk/BoxFileVersion.java
index 27d3832b6..5e198e075 100644
--- a/src/main/java/com/box/sdk/BoxFileVersion.java
+++ b/src/main/java/com/box/sdk/BoxFileVersion.java
@@ -19,7 +19,7 @@ public class BoxFileVersion extends BoxResource {
private static final URLTemplate VERSION_URL_TEMPLATE = new URLTemplate("files/%s/versions/%s");
private static final int BUFFER_SIZE = 8192;
- private final String fileID;
+ private String fileID;
private String versionID;
private String sha1;
@@ -44,6 +44,14 @@ public BoxFileVersion(BoxAPIConnection api, String json, String fileID) {
super(api, jsonObject.get("id").asString());
this.fileID = fileID;
+ this.parseJSON(jsonObject);
+ }
+
+ /**
+ * Method used to update fields with values received from API.
+ * @param jsonObject JSON-encoded info about File Version object.
+ */
+ private void parseJSON(JsonObject jsonObject) {
for (JsonObject.Member member : jsonObject) {
JsonValue value = member.getValue();
if (value.isNull()) {
@@ -78,6 +86,21 @@ public BoxFileVersion(BoxAPIConnection api, String json, String fileID) {
}
}
+ /**
+ * Used if no or wrong file id was set with constructor.
+ * @param fileID the file id this file version belongs to.
+ */
+ public void setFileID(String fileID) {
+ this.fileID = fileID;
+ }
+
+ /**
+ * @return the file id this file version belongs to.
+ */
+ public String getFileID() {
+ return this.fileID;
+ }
+
/**
* Gets the version ID of this version of the file.
* @return the version ID of this version of the file.
@@ -200,7 +223,8 @@ public void promote() {
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
request.setBody(jsonObject.toString());
- BoxAPIResponse response = request.send();
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
response.disconnect();
+ this.parseJSON(JsonObject.readFrom(response.getJSON()));
}
}
diff --git a/src/test/java/com/box/sdk/BoxFileVersionTest.java b/src/test/java/com/box/sdk/BoxFileVersionTest.java
new file mode 100644
index 000000000..c7bbcbc66
--- /dev/null
+++ b/src/test/java/com/box/sdk/BoxFileVersionTest.java
@@ -0,0 +1,120 @@
+package com.box.sdk;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.eclipsesource.json.JsonObject;
+
+/**
+ * {@link BoxFileVersion} related tests.
+ */
+public class BoxFileVersionTest {
+
+ /**
+ * Unit test for {@link BoxFileVersion#delete()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/files/0/versions/1",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxFile file = new BoxFile(api, "0");
+ BoxFileVersion version = new BoxFileVersion(api, new JsonObject().add("id", "1"), file.getID());
+ version.delete();
+ }
+
+ /**
+ * Unit test for {@link BoxFileVersion#promote()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testPromoteSendsCorrectJSON() {
+ final String type = "file_version";
+ final String id = "1";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/files/0/versions/current", request.getUrl().toString());
+ Assert.assertEquals(type, json.get("type").asString());
+ Assert.assertEquals(id, json.get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxFileVersion version = new BoxFileVersion(api, new JsonObject().add("id", "1"), "0");
+ version.promote();
+ }
+
+ /**
+ * Unit test for {@link BoxFileVersion#promote()}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testPromoteParseAllFieldsCorrectly() throws ParseException {
+ final String id = "871399";
+ final String sha1 = "12039d6dd9a7e6eefc78846802e";
+ final String name = "Stark Family Lineage.doc";
+ final long size = 11;
+ final Date createdAt = BoxDateFormat.parse("2013-11-20T13:20:50-08:00");
+ final Date modifiedAt = BoxDateFormat.parse("2013-11-20T13:26:48-08:00");
+ final String modifiedById = "13711334";
+ final String modifiedByName = "Eddard Stark";
+ final String modifiedByLogin = "ned@winterfell.com";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"file_version\",\n"
+ + " \"id\": \"871399\",\n"
+ + " \"sha1\": \"12039d6dd9a7e6eefc78846802e\",\n"
+ + " \"name\": \"Stark Family Lineage.doc\",\n"
+ + " \"size\": 11,\n"
+ + " \"created_at\": \"2013-11-20T13:20:50-08:00\",\n"
+ + " \"modified_at\": \"2013-11-20T13:26:48-08:00\",\n"
+ + " \"modified_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"13711334\",\n"
+ + " \"name\": \"Eddard Stark\",\n"
+ + " \"login\": \"ned@winterfell.com\"\n"
+ + " }\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxFileVersion version = new BoxFileVersion(api, new JsonObject().add("id", id), "0");
+ version.promote();
+ Assert.assertEquals(id, version.getID());
+ Assert.assertEquals(sha1, version.getSha1());
+ Assert.assertEquals(name, version.getName());
+ Assert.assertEquals(size, version.getSize());
+ Assert.assertEquals(createdAt, version.getCreatedAt());
+ Assert.assertEquals(modifiedAt, version.getModifiedAt());
+ Assert.assertEquals(modifiedById, version.getModifiedBy().getID());
+ Assert.assertEquals(modifiedByName, version.getModifiedBy().getName());
+ Assert.assertEquals(modifiedByLogin, version.getModifiedBy().getLogin());
+
+ }
+}
From 57cdfa20326e1c8b4ae73eb6957ae9e089d97a3f Mon Sep 17 00:00:00 2001
From: gleb-urvanov
Date: Fri, 18 Nov 2016 20:31:06 +0100
Subject: [PATCH 025/119] unit tests for BoxUser methods
---
src/test/java/com/box/sdk/BoxUserTest.java | 407 +++++++++++++++++++++
1 file changed, 407 insertions(+)
diff --git a/src/test/java/com/box/sdk/BoxUserTest.java b/src/test/java/com/box/sdk/BoxUserTest.java
index 84cf83c1f..0a7129c28 100644
--- a/src/test/java/com/box/sdk/BoxUserTest.java
+++ b/src/test/java/com/box/sdk/BoxUserTest.java
@@ -17,6 +17,7 @@
import static org.junit.Assert.fail;
import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -416,6 +417,412 @@ public String getJSON() {
user.addEmailAlias(email);
}
+ /**
+ * Unit test for {@link BoxUser#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequestWithoutParams() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/users/0",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, "0");
+ user.getInfo();
+ }
+
+ /**
+ * Unit test for {@link BoxUser#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoSendsCorrectRequestWithFields() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/users/0?fields=name%2Cstatus",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, "0");
+ user.getInfo("name", "status");
+ }
+
+ /**
+ * Unit test for {@link BoxUser#getInfo(String...)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
+ final String id = "10543463";
+ final String name = "Arielle Frey";
+ final String login = "ariellefrey@box.com";
+ final Date createdAt = BoxDateFormat.parse("2011-01-07T12:37:09-08:00");
+ final Date modifiedAt = BoxDateFormat.parse("2014-05-30T10:39:47-07:00");
+ final String language = "en";
+ final String timezone = "America/Los_Angeles";
+ final long spaceAmount = 10737418240L;
+ final long spaceUsed = 558732L;
+ final long maxUploadSize = 5368709120L;
+ final BoxUser.Status status = BoxUser.Status.ACTIVE;
+ final String jobTitle = "";
+ final String phone = "";
+ final String address = "";
+ final String avatarURL = "https://blosserdemoaccount.app.box.com/api/avatar/large/10543465";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10543463\",\n"
+ + " \"name\": \"Arielle Frey\",\n"
+ + " \"login\": \"ariellefrey@box.com\",\n"
+ + " \"created_at\": \"2011-01-07T12:37:09-08:00\",\n"
+ + " \"modified_at\": \"2014-05-30T10:39:47-07:00\",\n"
+ + " \"language\": \"en\",\n"
+ + " \"timezone\": \"America/Los_Angeles\",\n"
+ + " \"space_amount\": 10737418240,\n"
+ + " \"space_used\": 558732,\n"
+ + " \"max_upload_size\": 5368709120,\n"
+ + " \"status\": \"active\",\n"
+ + " \"job_title\": \"\",\n"
+ + " \"phone\": \"\",\n"
+ + " \"address\": \"\",\n"
+ + " \"avatar_url\": \"https://blosserdemoaccount.app.box.com/api/avatar/large/10543465\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxUser user = new BoxUser(api, id);
+ BoxUser.Info info = user.getInfo();
+ Assert.assertEquals(id, info.getID());
+ Assert.assertEquals(name, info.getName());
+ Assert.assertEquals(login, info.getLogin());
+ Assert.assertEquals(createdAt, info.getCreatedAt());
+ Assert.assertEquals(modifiedAt, info.getModifiedAt());
+ Assert.assertEquals(language, info.getLanguage());
+ Assert.assertEquals(timezone, info.getTimezone());
+ Assert.assertEquals(spaceAmount, info.getSpaceAmount());
+ Assert.assertEquals(spaceUsed, info.getSpaceUsed());
+ Assert.assertEquals(maxUploadSize, info.getMaxUploadSize());
+ Assert.assertEquals(status, info.getStatus());
+ Assert.assertEquals(jobTitle, info.getJobTitle());
+ Assert.assertEquals(phone, info.getPhone());
+ Assert.assertEquals(address, info.getAddress());
+ Assert.assertEquals(avatarURL, info.getAvatarURL());
+
+ }
+
+ /**
+ * Unit test for {@link BoxUser#getCurrentUser(BoxAPIConnection)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetCurrentUserSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/users/me",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxUser.getCurrentUser(api);
+ }
+
+ /**
+ * Unit test for {@link BoxUser#getCurrentUser(BoxAPIConnection)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testGetCurrentUserParseAllFieldsCorrectly() {
+ final String id = "17738362";
+
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"17738362\",\n"
+ + " \"name\": \"sean rose\",\n"
+ + " \"login\": \"sean@box.com\",\n"
+ + " \"created_at\": \"2012-03-26T15:43:07-07:00\",\n"
+ + " \"modified_at\": \"2012-12-12T11:34:29-08:00\",\n"
+ + " \"language\": \"en\",\n"
+ + " \"space_amount\": 5368709120,\n"
+ + " \"space_used\": 2377016,\n"
+ + " \"max_upload_size\": 262144000,\n"
+ + " \"status\": \"active\",\n"
+ + " \"job_title\": \"Employee\",\n"
+ + " \"phone\": \"5555555555\",\n"
+ + " \"address\": \"555 Office Drive\",\n"
+ + " \"avatar_url\": \"https://app.box.com/api/avatar/large/17738362\"\n"
+ + "}");
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+
+ BoxUser user = BoxUser.getCurrentUser(api);
+ Assert.assertEquals(id, user.getID());
+
+ }
+
+ /**
+ * Unit test for {@link BoxUser#delete(boolean, boolean)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteUserSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/users/0?notify=true&force=true",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, "0");
+ user.delete(true, true);
+ }
+
+ /**
+ * Unit test for {@link BoxUser#deleteEmailAlias(String)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testDeleteEmailAliasSendsCorrectRequest() {
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new RequestInterceptor() {
+ @Override
+ public BoxAPIResponse onRequest(BoxAPIRequest request) {
+ Assert.assertEquals("https://api.box.com/2.0/users/0/email_aliases/1",
+ request.getUrl().toString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, "0");
+ user.deleteEmailAlias("1");
+ }
+
+ /**
+ * Unit test for {@link BoxUser#moveFolderToUser(String)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testMoveFolderToUserSendsCorrectJson() {
+ final String ownedByID = "0";
+
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(new JSONRequestInterceptor() {
+ @Override
+ protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
+ Assert.assertEquals("https://api.box.com/2.0/users/1/folders/0",
+ request.getUrl().toString());
+ Assert.assertEquals(ownedByID, json.get("owned_by").asObject().get("id").asString());
+ return new BoxJSONResponse() {
+ @Override
+ public String getJSON() {
+ return "{\"id\": \"0\"}";
+ }
+ };
+ }
+ });
+
+ BoxUser user = new BoxUser(api, "0");
+ user.moveFolderToUser("1");
+
+ }
+
+ /**
+ * Unit test for {@link BoxUser#moveFolderToUser(String)}
+ */
+ @Test
+ @Category(UnitTest.class)
+ public void testMoveFolderToUserParseAllFieldsCorrectly() throws ParseException {
+ final String id = "11446498";
+ final String sequenceID = "1";
+ final String etag = "1";
+ final String name = "Pictures";
+ final Date createdAt = BoxDateFormat.parse("2012-12-12T10:53:43-08:00");
+ final Date modifiedAt = BoxDateFormat.parse("2012-12-12T10:53:43-08:00");
+ final String description = "Some pictures I took";
+ final long size = 629644;
+ final String pathID = "0";
+ final String pathSequenceID = null;
+ final String pathEtag = null;
+ final String pathName = "All Files";
+ final String createdByID = "17738362";
+ final String createdByName = "sean rose";
+ final String createdByLogin = "sean@box.com";
+ final String modifiedByID = "17738362";
+ final String modifiedByName = "sean rose";
+ final String modifiedByLogin = "sean@box.com";
+ final String ownedByID = "17738362";
+ final String ownedByName = "sean rose";
+ final String ownedByLogin = "sean@box.com";
+ final String url = "https://www.box.com/s/vspke7y05sb214wjokpk";
+ final String downloadURL = null;
+ final String vanityUrl = null;
+ final boolean isPasswordEnabled = false;
+ final Date unsharedAt = null;
+ final long downloadCount = 0;
+ final long previewCount = 0;
+ final BoxSharedLink.Access access = BoxSharedLink.Access.OPEN;
+ final boolean canDownload = true;
+ final boolean canPreview = true;
+ final BoxUploadEmail.Access folderUploadEmailAccess = BoxUploadEmail.Access.OPEN;
+ final String folderUploadEmail = "upload.Picture.k13sdz1@u.box.com";
+ final String parentID = "0";
+ final String parentSequenceID = null;
+ final String parentEtag = null;
+ final String parentName = "All Files";
+ final String itemStatus = "active";
+ final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"11446498\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"name\": \"Pictures\",\n"
+ + " \"created_at\": \"2012-12-12T10:53:43-08:00\",\n"
+ + " \"modified_at\": \"2012-12-12T10:53:43-08:00\",\n"
+ + " \"description\": \"Some pictures I took\",\n"
+ + " \"size\": 629644,\n"
+ + " \"path_collection\": {\n"
+ + " \"total_count\": 1,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"0\",\n"
+ + " \"sequence_id\": null,\n"
+ + " \"etag\": null,\n"
+ + " \"name\": \"All Files\"\n"
+ + " }\n"
+ + " ]\n"
+ + " },\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"17738362\",\n"
+ + " \"name\": \"sean rose\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " },\n"
+ + " \"modified_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"17738362\",\n"
+ + " \"name\": \"sean rose\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " },\n"
+ + " \"owned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"17738362\",\n"
+ + " \"name\": \"sean rose\",\n"
+ + " \"login\": \"sean@box.com\"\n"
+ + " },\n"
+ + " \"shared_link\": {\n"
+ + " \"url\": \"https://www.box.com/s/vspke7y05sb214wjokpk\",\n"
+ + " \"download_url\": null,\n"
+ + " \"vanity_url\": null,\n"
+ + " \"is_password_enabled\": false,\n"
+ + " \"unshared_at\": null,\n"
+ + " \"download_count\": 0,\n"
+ + " \"preview_count\": 0,\n"
+ + " \"access\": \"open\",\n"
+ + " \"permissions\": {\n"
+ + " \"can_download\": true,\n"
+ + " \"can_preview\": true\n"
+ + " }\n"
+ + " },\n"
+ + " \"folder_upload_email\": {\n"
+ + " \"access\": \"open\",\n"
+ + " \"email\": \"upload.Picture.k13sdz1@u.box.com\"\n"
+ + " },\n"
+ + " \"parent\": {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"0\",\n"
+ + " \"sequence_id\": null,\n"
+ + " \"etag\": null,\n"
+ + " \"name\": \"All Files\"\n"
+ + " },\n"
+ + " \"item_status\": \"active\"\n"
+ + "}");
+ BoxAPIConnection api = new BoxAPIConnection("");
+ api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
+ BoxUser user = new BoxUser(api, id);
+ BoxFolder.Info folder = user.moveFolderToUser("0");
+ Assert.assertEquals(id, folder.getID());
+ Assert.assertEquals(sequenceID, folder.getSequenceID());
+ Assert.assertEquals(etag, folder.getEtag());
+ Assert.assertEquals(name, folder.getName());
+ Assert.assertEquals(createdAt, folder.getCreatedAt());
+ Assert.assertEquals(modifiedAt, folder.getModifiedAt());
+ Assert.assertEquals(description, folder.getDescription());
+ Assert.assertEquals(size, folder.getSize());
+ Assert.assertEquals(pathID, folder.getPathCollection().get(0).getID());
+ Assert.assertEquals(pathSequenceID, folder.getPathCollection().get(0).getSequenceID());
+ Assert.assertEquals(pathEtag, folder.getPathCollection().get(0).getEtag());
+ Assert.assertEquals(pathName, folder.getPathCollection().get(0).getName());
+ Assert.assertEquals(createdByID, folder.getCreatedBy().getID());
+ Assert.assertEquals(createdByName, folder.getCreatedBy().getName());
+ Assert.assertEquals(createdByLogin, folder.getCreatedBy().getLogin());
+ Assert.assertEquals(modifiedByID, folder.getModifiedBy().getID());
+ Assert.assertEquals(modifiedByName, folder.getModifiedBy().getName());
+ Assert.assertEquals(modifiedByLogin, folder.getModifiedBy().getLogin());
+ Assert.assertEquals(ownedByID, folder.getOwnedBy().getID());
+ Assert.assertEquals(ownedByName, folder.getOwnedBy().getName());
+ Assert.assertEquals(ownedByLogin, folder.getOwnedBy().getLogin());
+ Assert.assertEquals(url, folder.getSharedLink().getURL());
+ Assert.assertEquals(downloadURL, folder.getSharedLink().getDownloadURL());
+ Assert.assertEquals(vanityUrl, folder.getSharedLink().getVanityURL());
+ Assert.assertEquals(isPasswordEnabled, folder.getSharedLink().getIsPasswordEnabled());
+ Assert.assertEquals(unsharedAt, folder.getSharedLink().getUnsharedDate());
+ Assert.assertEquals(downloadCount, folder.getSharedLink().getDownloadCount());
+ Assert.assertEquals(previewCount, folder.getSharedLink().getPreviewCount());
+ Assert.assertEquals(access, folder.getSharedLink().getAccess());
+ Assert.assertEquals(canDownload, folder.getSharedLink().getPermissions().getCanDownload());
+ Assert.assertEquals(canPreview, folder.getSharedLink().getPermissions().getCanPreview());
+ Assert.assertEquals(folderUploadEmailAccess, folder.getUploadEmail().getAccess());
+ Assert.assertEquals(folderUploadEmail, folder.getUploadEmail().getEmail());
+ Assert.assertEquals(parentID, folder.getParent().getID());
+ Assert.assertEquals(parentSequenceID, folder.getParent().getSequenceID());
+ Assert.assertEquals(parentEtag, folder.getParent().getEtag());
+ Assert.assertEquals(parentName, folder.getParent().getName());
+ Assert.assertEquals(itemStatus, folder.getItemStatus());
+ }
+
@Test
@Category(IntegrationTest.class)
public void getCurrentUserInfoIsCorrect() throws InterruptedException {
From add5aeb5d017a7c88f78c968dfceec37ba5ee99a Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 1 Dec 2016 11:20:59 -0800
Subject: [PATCH 026/119] Changed continuation indent fro 8 to 4. Whitespace
change only
---
src/test/java/com/box/sdk/BoxFolderTest.java | 198 +++++++++----------
1 file changed, 99 insertions(+), 99 deletions(-)
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index b5db2b8fa..7f7bf8a34 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -74,11 +74,11 @@ public void createFolderSendsRequestWithRequiredFields() {
String createdFolderName = "[createFolderSendsRequestWithRequiredFields] Child Folder";
stubFor(post(urlMatching("/folders"))
- .withRequestBody(equalToJson("{ \"name\": \"" + createdFolderName + "\", \"parent\": {\"id\": \""
- + parentFolderID + "\"} }", LENIENT))
- .willReturn(aResponse()
- .withHeader("Content-Type", "application/json")
- .withBody("{\"id\": \"0\"}")));
+ .withRequestBody(equalToJson("{ \"name\": \"" + createdFolderName + "\", \"parent\": {\"id\": \""
+ + parentFolderID + "\"} }", LENIENT))
+ .willReturn(aResponse()
+ .withHeader("Content-Type", "application/json")
+ .withBody("{\"id\": \"0\"}")));
rootFolder.createFolder(createdFolderName);
}
@@ -90,7 +90,7 @@ public void infoParsesMixedPermissionsCorrectly() {
String id = "id";
EnumSet expectedPermissions = EnumSet.of(BoxFolder.Permission.CAN_UPLOAD,
- BoxFolder.Permission.CAN_DELETE, BoxFolder.Permission.CAN_INVITE_COLLABORATOR);
+ BoxFolder.Permission.CAN_DELETE, BoxFolder.Permission.CAN_INVITE_COLLABORATOR);
JsonObject permissionsJSON = new JsonObject();
permissionsJSON.add("can_download", false);
@@ -119,13 +119,13 @@ public void getChildrenRangeRequestsCorrectOffsetLimitAndFields() {
api.setBaseURL("http://localhost:8080/");
stubFor(get(urlPathEqualTo("/folders/0/items/"))
- .withQueryParam("offset", WireMock.equalTo("1"))
- .withQueryParam("limit", WireMock.equalTo("2"))
- .withQueryParam("fields", containing("name"))
- .withQueryParam("fields", containing("description"))
- .willReturn(aResponse()
- .withHeader("Content-Type", "application/json")
- .withBody("{\"total_count\": 3, \"entries\":[]}")));
+ .withQueryParam("offset", WireMock.equalTo("1"))
+ .withQueryParam("limit", WireMock.equalTo("2"))
+ .withQueryParam("fields", containing("name"))
+ .withQueryParam("fields", containing("description"))
+ .willReturn(aResponse()
+ .withHeader("Content-Type", "application/json")
+ .withBody("{\"total_count\": 3, \"entries\":[]}")));
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
PartialCollection children = rootFolder.getChildrenRange(1, 2, "name", "description");
@@ -143,8 +143,8 @@ public void collaborateShouldSendCorrectJSONWhenCollaboratingWithAGroup() {
final BoxCollaboration.Role role = BoxCollaboration.Role.CO_OWNER;
final JsonObject fakeJSONResponse = new JsonObject()
- .add("type", "collaboration")
- .add("id", "0");
+ .add("type", "collaboration")
+ .add("id", "0");
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(new JSONRequestInterceptor() {
@@ -181,15 +181,15 @@ public void getCollaborationsShouldParseGroupsCorrectly() {
final String groupName = "non-empty name";
final JsonObject fakeJSONResponse = new JsonObject()
- .add("total_count", 1)
- .add("entries", new JsonArray()
- .add(new JsonObject()
- .add("type", "collaboration")
- .add("id", "non-empty ID")
- .add("accessible_by", new JsonObject()
- .add("type", "group")
- .add("id", groupID)
- .add("name", groupName))));
+ .add("total_count", 1)
+ .add("entries", new JsonArray()
+ .add(new JsonObject()
+ .add("type", "collaboration")
+ .add("id", "non-empty ID")
+ .add("accessible_by", new JsonObject()
+ .add("type", "group")
+ .add("id", groupID)
+ .add("name", groupName))));
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(new RequestInterceptor() {
@@ -226,7 +226,7 @@ public void testGetWatermarkSendsCorrectRequest() {
@Override
public BoxAPIResponse onRequest(BoxAPIRequest request) {
Assert.assertEquals("https://api.box.com/2.0/folders/0/watermark",
- request.getUrl().toString());
+ request.getUrl().toString());
return new BoxJSONResponse() {
@Override
public String getJSON() {
@@ -249,11 +249,11 @@ public void testGetWatermarkParseAllFieldsCorrectly() throws ParseException {
final Date modifiedAt = BoxDateFormat.parse("2016-11-31T15:33:33-07:00");
final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
- + " \"watermark\": {\n"
- + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
- + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
- + " }\n"
- + "}");
+ + " \"watermark\": {\n"
+ + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
+ + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
+ + " }\n"
+ + "}");
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
@@ -276,7 +276,7 @@ public void testApplyWatermarkSendsCorrectJson() {
@Override
protected BoxAPIResponse onJSONRequest(BoxJSONRequest request, JsonObject json) {
Assert.assertEquals("https://api.box.com/2.0/folders/0/watermark",
- request.getUrl().toString());
+ request.getUrl().toString());
Assert.assertEquals(imprint, json.get("watermark").asObject().get("imprint").asString());
return new BoxJSONResponse() {
@Override
@@ -300,11 +300,11 @@ public void testApplyWatermarkParseAllFieldsCorrectly() throws ParseException {
final Date modifiedAt = BoxDateFormat.parse("2016-11-31T15:33:33-07:00");
final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
- + " \"watermark\": {\n"
- + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
- + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
- + " }\n"
- + "}");
+ + " \"watermark\": {\n"
+ + " \"created_at\": \"2016-10-31T15:33:33-07:00\",\n"
+ + " \"modified_at\": \"2016-11-31T15:33:33-07:00\"\n"
+ + " }\n"
+ + "}");
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
@@ -325,7 +325,7 @@ public void testRemoveWatermarkSendsCorrectRequest() {
@Override
public BoxAPIResponse onRequest(BoxAPIRequest request) {
Assert.assertEquals("https://api.box.com/2.0/folders/0/watermark",
- request.getUrl().toString());
+ request.getUrl().toString());
return new BoxJSONResponse() {
@Override
public String getJSON() {
@@ -350,8 +350,8 @@ public void testCreateWeblinkSendsCorrectJsonWithNameAndDescription() throws Mal
final String description = "non-empty description";
final JsonObject fakeJSONResponse = new JsonObject()
- .add("type", "web_link")
- .add("id", "0");
+ .add("type", "web_link")
+ .add("id", "0");
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(new RequestInterceptor() {
@@ -388,8 +388,8 @@ public void testCreateWeblinkSendsCorrectJsonWithoutNameAndDescription() throws
final String parentFolderID = "0";
final JsonObject fakeJSONResponse = new JsonObject()
- .add("type", "web_link")
- .add("id", "0");
+ .add("type", "web_link")
+ .add("id", "0");
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(new RequestInterceptor() {
@@ -448,57 +448,57 @@ public void testCreateWeblinkParseAllFieldsCorrectly() throws ParseException, Ma
final String ownerLogin = "ted+demo@box.com";
final JsonObject fakeJSONResponse = JsonObject.readFrom("{\n"
- + " \"type\": \"web_link\",\n"
- + " \"id\": \"6742981\",\n"
- + " \"sequence_id\": \"0\",\n"
- + " \"etag\": \"0\",\n"
- + " \"name\": \"Box Website\",\n"
- + " \"url\": \"https://www.box.com\",\n"
- + " \"created_by\": {\n"
- + " \"type\": \"user\",\n"
- + " \"id\": \"10523870\",\n"
- + " \"name\": \"Ted Blosser\",\n"
- + " \"login\": \"ted+demo@box.com\"\n"
- + " },\n"
- + " \"created_at\": \"2015-05-07T14:31:16-07:00\",\n"
- + " \"modified_at\": \"2015-05-07T14:31:16-07:00\",\n"
- + " \"parent\": {\n"
- + " \"type\": \"folder\",\n"
- + " \"id\": \"848123342\",\n"
- + " \"sequence_id\": \"1\",\n"
- + " \"etag\": \"1\",\n"
- + " \"name\": \"Documentation\"\n"
- + " },\n"
- + " \"description\": \"Cloud Content Management\",\n"
- + " \"item_status\": \"active\",\n"
- + " \"trashed_at\": null,\n"
- + " \"purged_at\": null,\n"
- + " \"shared_link\": null,\n"
- + " \"path_collection\": {\n"
- + " \"total_count\": 1,\n"
- + " \"entries\": [\n"
- + " {\n"
- + " \"type\": \"folder\",\n"
- + " \"id\": \"848123342\",\n"
- + " \"sequence_id\": \"1\",\n"
- + " \"etag\": \"1\",\n"
- + " \"name\": \"Documentation\"\n"
- + " }\n"
- + " ]\n"
- + " },\n"
- + " \"modified_by\": {\n"
- + " \"type\": \"user\",\n"
- + " \"id\": \"10523870\",\n"
- + " \"name\": \"Ted Blosser\",\n"
- + " \"login\": \"ted+demo@box.com\"\n"
- + " },\n"
- + " \"owned_by\": {\n"
- + " \"type\": \"user\",\n"
- + " \"id\": \"10523870\",\n"
- + " \"name\": \"Ted Blosser\",\n"
- + " \"login\": \"ted+demo@box.com\"\n"
- + " }\n"
- + "}");
+ + " \"type\": \"web_link\",\n"
+ + " \"id\": \"6742981\",\n"
+ + " \"sequence_id\": \"0\",\n"
+ + " \"etag\": \"0\",\n"
+ + " \"name\": \"Box Website\",\n"
+ + " \"url\": \"https://www.box.com\",\n"
+ + " \"created_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " },\n"
+ + " \"created_at\": \"2015-05-07T14:31:16-07:00\",\n"
+ + " \"modified_at\": \"2015-05-07T14:31:16-07:00\",\n"
+ + " \"parent\": {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"848123342\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"name\": \"Documentation\"\n"
+ + " },\n"
+ + " \"description\": \"Cloud Content Management\",\n"
+ + " \"item_status\": \"active\",\n"
+ + " \"trashed_at\": null,\n"
+ + " \"purged_at\": null,\n"
+ + " \"shared_link\": null,\n"
+ + " \"path_collection\": {\n"
+ + " \"total_count\": 1,\n"
+ + " \"entries\": [\n"
+ + " {\n"
+ + " \"type\": \"folder\",\n"
+ + " \"id\": \"848123342\",\n"
+ + " \"sequence_id\": \"1\",\n"
+ + " \"etag\": \"1\",\n"
+ + " \"name\": \"Documentation\"\n"
+ + " }\n"
+ + " ]\n"
+ + " },\n"
+ + " \"modified_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " },\n"
+ + " \"owned_by\": {\n"
+ + " \"type\": \"user\",\n"
+ + " \"id\": \"10523870\",\n"
+ + " \"name\": \"Ted Blosser\",\n"
+ + " \"login\": \"ted+demo@box.com\"\n"
+ + " }\n"
+ + "}");
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
@@ -546,7 +546,7 @@ public void creatingAndDeletingFolderSucceeds() {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
BoxFolder childFolder = rootFolder.createFolder("[creatingAndDeletingFolderSucceeds] Ĥȅľľő Ƒŕőďő")
- .getResource();
+ .getResource();
assertThat(rootFolder, hasItem(Matchers.hasProperty("ID", equalTo(childFolder.getID()))));
@@ -659,8 +659,8 @@ public void uploadFileWithCreatedAndModifiedDatesSucceeds() {
final String fileContent = "Test file";
InputStream stream = new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8));
FileUploadParams params = new FileUploadParams()
- .setName("[uploadFileWithCreatedAndModifiedDatesSucceeds] Test File.txt").setContent(stream)
- .setModified(modified).setCreated(created);
+ .setName("[uploadFileWithCreatedAndModifiedDatesSucceeds] Test File.txt").setContent(stream)
+ .setModified(modified).setCreated(created);
BoxFile.Info info = rootFolder.uploadFile(params);
BoxFile uploadedFile = info.getResource();
@@ -834,7 +834,7 @@ public void getSharedItemAndItsChildrenSucceeds() {
assertThat(sharedItem.getID(), is(equalTo(folder.getID())));
assertThat(sharedItem.getResource(), hasItem(Matchers.hasProperty("ID",
- equalTo(childFolder.getID()))));
+ equalTo(childFolder.getID()))));
folder.delete(true);
}
@@ -846,7 +846,7 @@ public void createWebLinkSucceeds() throws MalformedURLException {
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
BoxWebLink createdWebLink = rootFolder.createWebLink("[createWebLinkSucceeds] Test Web Link",
- new URL("https://api.box.com"), "[createWebLinkSucceeds] Test Web Link").getResource();
+ new URL("https://api.box.com"), "[createWebLinkSucceeds] Test Web Link").getResource();
assertThat(rootFolder, hasItem(Matchers.hasProperty("ID", equalTo(createdWebLink.getID()))));
@@ -861,7 +861,7 @@ public void createWebLinkNoNameSucceeds() throws MalformedURLException {
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
BoxWebLink createdWebLink = rootFolder.createWebLink(new URL("https://api.box.com"),
- "[createWebLinkSucceeds] Test Web Link").getResource();
+ "[createWebLinkSucceeds] Test Web Link").getResource();
assertThat(rootFolder, hasItem(Matchers.hasProperty("ID", equalTo(createdWebLink.getID()))));
@@ -876,7 +876,7 @@ public void createWebLinkNoDescriptionSucceeds() throws MalformedURLException {
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
BoxWebLink createdWebLink = rootFolder.createWebLink("[createWebLinkSucceeds] Test Web Link",
- new URL("https://api.box.com")).getResource();
+ new URL("https://api.box.com")).getResource();
assertThat(rootFolder, hasItem(Matchers.hasProperty("ID", equalTo(createdWebLink.getID()))));
From 943e420f7fc8bc96171b45092765bafb2263618d Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 7 Dec 2016 15:13:45 -0800
Subject: [PATCH 027/119] Fixed warning for missing @return javadoc in
Boxuser.java
---
src/main/java/com/box/sdk/BoxUser.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxUser.java b/src/main/java/com/box/sdk/BoxUser.java
index c5fa0f64d..9099d49b2 100644
--- a/src/main/java/com/box/sdk/BoxUser.java
+++ b/src/main/java/com/box/sdk/BoxUser.java
@@ -204,7 +204,7 @@ public static Iterable getAllEnterpriseOrExternalUsers(final BoxAP
* @param userType The type of users we want to search with this request.
* Valid values are 'managed' (enterprise users), 'external' or 'all'
* @param fields the fields to retrieve. Leave this out for the standard fields.
- * @return
+ * @return An iterator over the selected users.
*/
private static Iterable getUsersInfoForType(final BoxAPIConnection api,
final String filterTerm, final String userType, final String... fields) {
From bf6dd7267df3a9b48db558edb89a6c4cad37939d Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 7 Dec 2016 16:02:08 -0800
Subject: [PATCH 028/119] Adding sourceCompatibility = 1.6 and
targetCompatibility = 1.6to gradle.build
---
build.gradle | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/build.gradle b/build.gradle
index 1febe0b13..a4fd63fc3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -28,6 +28,11 @@ dependencies {
testCompile 'org.slf4j:slf4j-nop:1.7.7'
}
+compileJava {
+ sourceCompatibility = 1.6
+ targetCompatibility = 1.6
+}
+
javadoc {
options.windowTitle 'Box Java SDK'
options.noQualifiers 'all'
From 757b384d915acee375233a2832a59eb51c29335b Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 7 Dec 2016 16:13:14 -0800
Subject: [PATCH 029/119] Fixing merge conflict in doc/retention_policies.md
---
doc/retention_policies.md | 6 ------
1 file changed, 6 deletions(-)
diff --git a/doc/retention_policies.md b/doc/retention_policies.md
index df6da1d24..408eb42ab 100644
--- a/doc/retention_policies.md
+++ b/doc/retention_policies.md
@@ -72,10 +72,7 @@ for (BoxRetentionPolicy.Info policyInfo : policies) {
```
[get-retention-policies]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxRetentionPolicy.html#getAll(com.box.sdk.BoxAPIConnection,%20java.lang.String...)
-<<<<<<< HEAD
-=======
->>>>>>> 7f379dfea0f0ceb84a179f6a062b6572db6e255b
[get-retention-policies-with-fields]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxRetentionPolicy.html#getAll(java.lang.String,%20java.lang.String,%20java.lang.String,%20int,%20com.box.sdk.BoxAPIConnection,%20java.lang.String...)
Get Retention Policy Assignments
@@ -131,8 +128,6 @@ BoxRetentionPolicyAssignment.Info assignmentInfo = assignment.getInfo("assigned_
[get-assignment]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxRetentionPolicyAssignment.html#getInfo(java.lang.String...)
-<<<<<<< HEAD
-=======
Get File Version Retention
--------------
@@ -168,4 +163,3 @@ for (BoxFileVersionRetention.Info retentionInfo : retentions) {
[get-all-file-version-retentions]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileVersionRetention.html#getInfo(com.box.sdk.BoxAPIConnection,%20java.lang.String...)
[query-filter]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileVersionRetention.html#QueryFilter
[get-all-file-version-retentions-with-filter]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileVersionRetention.html#getInfo(com.box.sdk.BoxAPIConnection,%20com.box.sdk.BoxFileVersionRetention.QueryFilter,%20java.lang.String...)
->>>>>>> 7f379dfea0f0ceb84a179f6a062b6572db6e255b
From f9de883252990c986dbc5a4bfd68dbccba6f5d99 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 7 Dec 2016 17:55:57 -0800
Subject: [PATCH 030/119] Refactored BoxLegalHold to be BoxLegalHoldPolicy to
match api documents
---
.../com/box/sdk/BoxLegalHoldAssignment.java | 6 +-
...LegalHold.java => BoxLegalHoldPolicy.java} | 30 ++++----
src/main/java/com/box/sdk/BoxResource.java | 2 +-
... => BoxLegalHoldPolicyAssignmentTest.java} | 2 +-
...dTest.java => BoxLegalHoldPolicyTest.java} | 77 ++++++++++---------
5 files changed, 59 insertions(+), 58 deletions(-)
rename src/main/java/com/box/sdk/{BoxLegalHold.java => BoxLegalHoldPolicy.java} (93%)
rename src/test/java/com/box/sdk/{BoxLegalHoldAssignmentTest.java => BoxLegalHoldPolicyAssignmentTest.java} (99%)
rename src/test/java/com/box/sdk/{BoxLegalHoldTest.java => BoxLegalHoldPolicyTest.java} (89%)
diff --git a/src/main/java/com/box/sdk/BoxLegalHoldAssignment.java b/src/main/java/com/box/sdk/BoxLegalHoldAssignment.java
index 4d442ef2f..1c24c6305 100644
--- a/src/main/java/com/box/sdk/BoxLegalHoldAssignment.java
+++ b/src/main/java/com/box/sdk/BoxLegalHoldAssignment.java
@@ -121,7 +121,7 @@ public class Info extends BoxResource.Info {
/**
* @see #getLegalHold()
*/
- private BoxLegalHold.Info legalHold;
+ private BoxLegalHoldPolicy.Info legalHold;
/**
* @see #getAssignedBy()
@@ -182,7 +182,7 @@ public BoxResource getResource() {
/**
* @return info about the policy that this legal hold policy assignment is part of.
*/
- public BoxLegalHold.Info getLegalHold() {
+ public BoxLegalHoldPolicy.Info getLegalHold() {
return this.legalHold;
}
@@ -234,7 +234,7 @@ void parseJSONMember(JsonObject.Member member) {
JsonObject policyJSON = value.asObject();
if (this.legalHold == null) {
String policyID = policyJSON.get("id").asString();
- BoxLegalHold policy = new BoxLegalHold(getAPI(), policyID);
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(getAPI(), policyID);
this.legalHold = policy.new Info(policyJSON);
} else {
this.legalHold.update(policyJSON);
diff --git a/src/main/java/com/box/sdk/BoxLegalHold.java b/src/main/java/com/box/sdk/BoxLegalHoldPolicy.java
similarity index 93%
rename from src/main/java/com/box/sdk/BoxLegalHold.java
rename to src/main/java/com/box/sdk/BoxLegalHoldPolicy.java
index 65fc2b74f..1a8bb1957 100644
--- a/src/main/java/com/box/sdk/BoxLegalHold.java
+++ b/src/main/java/com/box/sdk/BoxLegalHoldPolicy.java
@@ -18,7 +18,7 @@
* handling for errors related to the Box REST API, you should capture this exception explicitly.
*/
@BoxResourceType("legal_hold")
-public class BoxLegalHold extends BoxResource {
+public class BoxLegalHoldPolicy extends BoxResource {
private static final URLTemplate LEGAL_HOLD_URL_TEMPLATE = new URLTemplate("legal_hold_policies/%s");
private static final URLTemplate ALL_LEGAL_HOLD_URL_TEMPLATE = new URLTemplate("legal_hold_policies");
@@ -29,11 +29,11 @@ public class BoxLegalHold extends BoxResource {
private static final int DEFAULT_LIMIT = 100;
/**
- * Constructs a BoxLegalHold for a resource with a given ID.
+ * Constructs a BoxLegalHoldPolicy for a resource with a given ID.
* @param api the API connection to be used by the resource.
* @param id the ID of the resource.
*/
- public BoxLegalHold(BoxAPIConnection api, String id) {
+ public BoxLegalHoldPolicy(BoxAPIConnection api, String id) {
super(api, id);
}
@@ -60,7 +60,7 @@ public Info getInfo(String ... fields) {
* @param name the name of Legal Hold Policy.
* @return information about the Legal Hold Policy created.
*/
- public static BoxLegalHold.Info create(BoxAPIConnection api, String name) {
+ public static BoxLegalHoldPolicy.Info create(BoxAPIConnection api, String name) {
return create(api, name, null, null, null);
}
@@ -73,8 +73,8 @@ public static BoxLegalHold.Info create(BoxAPIConnection api, String name) {
* @param filterEndedAt optional date filter applies to Custodian assignments only.
* @return information about the Legal Hold Policy created.
*/
- public static BoxLegalHold.Info create(BoxAPIConnection api, String name, String description,
- Date filterStartedAt, Date filterEndedAt) {
+ public static BoxLegalHoldPolicy.Info create(BoxAPIConnection api, String name, String description,
+ Date filterStartedAt, Date filterEndedAt) {
URL url = ALL_LEGAL_HOLD_URL_TEMPLATE.build(api.getBaseURL());
BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
JsonObject requestJSON = new JsonObject()
@@ -91,7 +91,7 @@ public static BoxLegalHold.Info create(BoxAPIConnection api, String name, String
request.setBody(requestJSON.toString());
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
- BoxLegalHold createdPolicy = new BoxLegalHold(api, responseJSON.get("id").asString());
+ BoxLegalHoldPolicy createdPolicy = new BoxLegalHoldPolicy(api, responseJSON.get("id").asString());
return createdPolicy.new Info(responseJSON);
}
@@ -110,7 +110,7 @@ public void delete() {
* Only policy_name, description and release_notes can be modified.
* @param info the updated info.
*/
- public void updateInfo(BoxLegalHold.Info info) {
+ public void updateInfo(BoxLegalHoldPolicy.Info info) {
URL url = LEGAL_HOLD_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
request.setBody(info.getPendingChanges());
@@ -124,7 +124,7 @@ public void updateInfo(BoxLegalHold.Info info) {
* @param api api the API connection to be used by the resource.
* @return the Iterable of Legal Hold Policies in your Enterprise.
*/
- public static Iterable getAll(final BoxAPIConnection api) {
+ public static Iterable getAll(final BoxAPIConnection api) {
return getAll(api, null, DEFAULT_LIMIT);
}
@@ -136,7 +136,7 @@ public static Iterable getAll(final BoxAPIConnection api) {
* @param fields the optional fields to retrieve.
* @return the Iterable of Legal Hold Policies in your Enterprise that match the filter parameters.
*/
- public static Iterable getAll(
+ public static Iterable getAll(
final BoxAPIConnection api, String policyName, int limit, String ... fields) {
QueryStringBuilder builder = new QueryStringBuilder();
if (policyName != null) {
@@ -145,13 +145,13 @@ public static Iterable getAll(
if (fields.length > 0) {
builder.appendParam("fields", fields);
}
- return new BoxResourceIterable(api,
+ return new BoxResourceIterable(api,
ALL_LEGAL_HOLD_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString()),
limit) {
@Override
- protected BoxLegalHold.Info factory(JsonObject jsonObject) {
- BoxLegalHold policy = new BoxLegalHold(api, jsonObject.get("id").asString());
+ protected BoxLegalHoldPolicy.Info factory(JsonObject jsonObject) {
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, jsonObject.get("id").asString());
return policy.new Info(jsonObject);
}
};
@@ -205,7 +205,7 @@ public Iterable getAssignments(String type, String
@Override
protected BoxLegalHoldAssignment.Info factory(JsonObject jsonObject) {
BoxLegalHoldAssignment assignment = new BoxLegalHoldAssignment(
- BoxLegalHold.this.getAPI(), jsonObject.get("id").asString());
+ BoxLegalHoldPolicy.this.getAPI(), jsonObject.get("id").asString());
return assignment.new Info(jsonObject);
}
};
@@ -347,7 +347,7 @@ public Info(String json) {
*/
@Override
public BoxResource getResource() {
- return BoxLegalHold.this;
+ return BoxLegalHoldPolicy.this;
}
/**
diff --git a/src/main/java/com/box/sdk/BoxResource.java b/src/main/java/com/box/sdk/BoxResource.java
index 15931ed51..1dc4299bb 100644
--- a/src/main/java/com/box/sdk/BoxResource.java
+++ b/src/main/java/com/box/sdk/BoxResource.java
@@ -57,7 +57,7 @@ private static Map> initResourceClassByType
result.put(getResourceType(BoxRetentionPolicy.class), BoxRetentionPolicy.class);
result.put(getResourceType(BoxRetentionPolicyAssignment.class), BoxRetentionPolicyAssignment.class);
result.put(getResourceType(BoxFileVersionRetention.class), BoxFileVersionRetention.class);
- result.put(getResourceType(BoxLegalHold.class), BoxLegalHold.class);
+ result.put(getResourceType(BoxLegalHoldPolicy.class), BoxLegalHoldPolicy.class);
result.put(getResourceType(BoxLegalHoldAssignment.class), BoxLegalHoldAssignment.class);
result.put(getResourceType(BoxFileVersionLegalHold.class), BoxFileVersionLegalHold.class);
return Collections.unmodifiableMap(result);
diff --git a/src/test/java/com/box/sdk/BoxLegalHoldAssignmentTest.java b/src/test/java/com/box/sdk/BoxLegalHoldPolicyAssignmentTest.java
similarity index 99%
rename from src/test/java/com/box/sdk/BoxLegalHoldAssignmentTest.java
rename to src/test/java/com/box/sdk/BoxLegalHoldPolicyAssignmentTest.java
index fd1f5367a..ce5520632 100644
--- a/src/test/java/com/box/sdk/BoxLegalHoldAssignmentTest.java
+++ b/src/test/java/com/box/sdk/BoxLegalHoldPolicyAssignmentTest.java
@@ -12,7 +12,7 @@
/**
* {@link BoxLegalHoldAssignment} related unit tests.
*/
-public class BoxLegalHoldAssignmentTest {
+public class BoxLegalHoldPolicyAssignmentTest {
/**
* Unit test for {@link BoxLegalHoldAssignment#getInfo(String...)}
diff --git a/src/test/java/com/box/sdk/BoxLegalHoldTest.java b/src/test/java/com/box/sdk/BoxLegalHoldPolicyTest.java
similarity index 89%
rename from src/test/java/com/box/sdk/BoxLegalHoldTest.java
rename to src/test/java/com/box/sdk/BoxLegalHoldPolicyTest.java
index 963708575..27ae5c6ce 100644
--- a/src/test/java/com/box/sdk/BoxLegalHoldTest.java
+++ b/src/test/java/com/box/sdk/BoxLegalHoldPolicyTest.java
@@ -11,12 +11,12 @@
import com.eclipsesource.json.JsonObject;
/**
- * {@link BoxLegalHold} related unit tests.
+ * {@link BoxLegalHoldPolicy} related unit tests.
*/
-public class BoxLegalHoldTest {
+public class BoxLegalHoldPolicyTest {
/**
- * Unit test for {@link BoxLegalHold#getInfo(String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getInfo(String...)}
*/
@Test
@Category(UnitTest.class)
@@ -36,12 +36,12 @@ public String getJSON() {
}
});
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
policy.getInfo("description", "status");
}
/**
- * Unit test for {@link BoxLegalHold#getInfo(String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getInfo(String...)}
*/
@Test
@Category(UnitTest.class)
@@ -93,8 +93,8 @@ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
- BoxLegalHold policy = new BoxLegalHold(api, id);
- BoxLegalHold.Info info = policy.getInfo();
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, id);
+ BoxLegalHoldPolicy.Info info = policy.getInfo();
Assert.assertEquals(id, info.getID());
Assert.assertEquals(name, info.getPolicyName());
Assert.assertEquals(description, info.getDescription());
@@ -115,7 +115,7 @@ public void testGetInfoParseAllFieldsCorrectly() throws ParseException {
}
/**
- * Unit test for {@link BoxLegalHold#create(BoxAPIConnection, String, String, Date, Date)}
+ * Unit test for {@link BoxLegalHoldPolicy#create(BoxAPIConnection, String, String, Date, Date)}
*/
@Test
@Category(UnitTest.class)
@@ -147,11 +147,11 @@ public String getJSON() {
}
});
- BoxLegalHold.create(api, name, description, startedAt, endedAt);
+ BoxLegalHoldPolicy.create(api, name, description, startedAt, endedAt);
}
/**
- * Unit test for {@link BoxLegalHold#create(BoxAPIConnection, String)}
+ * Unit test for {@link BoxLegalHoldPolicy#create(BoxAPIConnection, String)}
*/
@Test
@Category(UnitTest.class)
@@ -189,7 +189,7 @@ public void testCreateParseAllFieldsCorrectly() throws ParseException {
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
- BoxLegalHold.Info info = BoxLegalHold.create(api, name);
+ BoxLegalHoldPolicy.Info info = BoxLegalHoldPolicy.create(api, name);
Assert.assertEquals(id, info.getID());
Assert.assertEquals(name, info.getPolicyName());
Assert.assertEquals(description, info.getDescription());
@@ -205,7 +205,7 @@ public void testCreateParseAllFieldsCorrectly() throws ParseException {
}
/**
- * Unit test for {@link BoxLegalHold#delete()}
+ * Unit test for {@link BoxLegalHoldPolicy#delete()}
*/
@Test
@Category(UnitTest.class)
@@ -224,12 +224,12 @@ public String getJSON() {
}
});
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
policy.delete();
}
/**
- * Unit test for {@link BoxLegalHold#updateInfo(BoxLegalHold.Info)}
+ * Unit test for {@link BoxLegalHoldPolicy#updateInfo(BoxLegalHoldPolicy.Info)}
*/
@Test
@Category(UnitTest.class)
@@ -255,8 +255,8 @@ public String getJSON() {
}
});
- BoxLegalHold policy = new BoxLegalHold(api, "0");
- BoxLegalHold.Info info = policy.new Info();
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
+ BoxLegalHoldPolicy.Info info = policy.new Info();
info.addPendingChange("policy_name", name);
info.addPendingChange("description", description);
info.addPendingChange("release_note", note);
@@ -264,7 +264,7 @@ public String getJSON() {
}
/**
- * Unit test for {@link BoxLegalHold#updateInfo(BoxLegalHold.Info)}
+ * Unit test for {@link BoxLegalHoldPolicy#updateInfo(BoxLegalHoldPolicy.Info)}
*/
@Test
@Category(UnitTest.class)
@@ -302,8 +302,8 @@ public void testUpdateParseAllFieldsCorrectly() throws ParseException {
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
- BoxLegalHold policy = new BoxLegalHold(api, id);
- BoxLegalHold.Info info = policy.new Info();
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, id);
+ BoxLegalHoldPolicy.Info info = policy.new Info();
info.addPendingChange("policy_name", name);
policy.updateInfo(info);
Assert.assertEquals(id, info.getID());
@@ -321,7 +321,7 @@ public void testUpdateParseAllFieldsCorrectly() throws ParseException {
}
/**
- * Unit test for {@link BoxLegalHold#getAll(BoxAPIConnection)}
+ * Unit test for {@link BoxLegalHoldPolicy#getAll(BoxAPIConnection)}
*/
@Test
@Category(UnitTest.class)
@@ -341,12 +341,12 @@ public String getJSON() {
}
});
- Iterator iterator = BoxLegalHold.getAll(api).iterator();
+ Iterator iterator = BoxLegalHoldPolicy.getAll(api).iterator();
iterator.hasNext();
}
/**
- * Unit test for {@link BoxLegalHold#getAll(BoxAPIConnection, String, int, String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getAll(BoxAPIConnection, String, int, String...)}
*/
@Test
@Category(UnitTest.class)
@@ -368,12 +368,13 @@ public String getJSON() {
}
});
- Iterator iterator = BoxLegalHold.getAll(api, "pol", 100, "description", "status").iterator();
+ Iterator iterator =
+ BoxLegalHoldPolicy.getAll(api, "pol", 100, "description", "status").iterator();
iterator.hasNext();
}
/**
- * Unit test for {@link BoxLegalHold#getAll(BoxAPIConnection)}
+ * Unit test for {@link BoxLegalHoldPolicy#getAll(BoxAPIConnection)}
*/
@Test
@Category(UnitTest.class)
@@ -408,8 +409,8 @@ public void testGetAllParseAllFieldsCorrectly() {
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
- Iterator iterator = BoxLegalHold.getAll(api).iterator();
- BoxLegalHold.Info info = iterator.next();
+ Iterator iterator = BoxLegalHoldPolicy.getAll(api).iterator();
+ BoxLegalHoldPolicy.Info info = iterator.next();
Assert.assertEquals(firstPolicyID, info.getID());
Assert.assertEquals(firstPolicyName, info.getPolicyName());
info = iterator.next();
@@ -419,7 +420,7 @@ public void testGetAllParseAllFieldsCorrectly() {
}
/**
- * Unit test for {@link BoxLegalHold#assignTo(BoxResource)}
+ * Unit test for {@link BoxLegalHoldPolicy#assignTo(BoxResource)}
*/
@Test
@Category(UnitTest.class)
@@ -446,13 +447,13 @@ public String getJSON() {
}
});
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
BoxFileVersion version = new BoxFileVersion(api, "{\"id\": \"1\"}", "2");
policy.assignTo(version);
}
/**
- * Unit test for {@link BoxLegalHold#getAssignments(String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getAssignments(String...)}
*/
@Test
@Category(UnitTest.class)
@@ -473,13 +474,13 @@ public String getJSON() {
}
});
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
Iterator iterator = policy.getAssignments("assigned_at").iterator();
iterator.hasNext();
}
/**
- * Unit test for {@link BoxLegalHold#getAssignments(String, String, int, String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getAssignments(String, String, int, String...)}
*/
@Test
@Category(UnitTest.class)
@@ -501,14 +502,14 @@ public String getJSON() {
}
});
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
Iterator iterator
= policy.getAssignments(BoxResource.getResourceType(BoxFolder.class), "1", 99).iterator();
iterator.hasNext();
}
/**
- * Unit test for {@link BoxLegalHold#getAssignments(String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getAssignments(String...)}
*/
@Test
@Category(UnitTest.class)
@@ -539,7 +540,7 @@ public void testGetAssignmentsParseAllFieldsCorrectly() {
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
Iterator iterator = policy.getAssignments().iterator();
BoxLegalHoldAssignment.Info info = iterator.next();
Assert.assertEquals(firstEntryID, info.getID());
@@ -549,7 +550,7 @@ public void testGetAssignmentsParseAllFieldsCorrectly() {
}
/**
- * Unit test for {@link BoxLegalHold#getFileVersionHolds(String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getFileVersionHolds(String...)}
*/
@Test
@Category(UnitTest.class)
@@ -569,13 +570,13 @@ public String getJSON() {
}
});
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
Iterator iterator = policy.getFileVersionHolds().iterator();
iterator.hasNext();
}
/**
- * Unit test for {@link BoxLegalHold#getFileVersionHolds(String...)}
+ * Unit test for {@link BoxLegalHoldPolicy#getFileVersionHolds(String...)}
*/
@Test
@Category(UnitTest.class)
@@ -611,7 +612,7 @@ public void testGetFileVersionHoldsParseAllFieldsCorrectly() {
BoxAPIConnection api = new BoxAPIConnection("");
api.setRequestInterceptor(JSONRequestInterceptor.respondWith(fakeJSONResponse));
- BoxLegalHold policy = new BoxLegalHold(api, "0");
+ BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, "0");
Iterator iterator = policy.getFileVersionHolds().iterator();
Assert.assertEquals(firstID, iterator.next().getID());
Assert.assertEquals(secondID, iterator.next().getID());
From 0f6e888770b9e8e095980f6bdbe37fb836027be2 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Mon, 12 Dec 2016 18:13:53 -0800
Subject: [PATCH 031/119] Updated Object name form BoxLegalHold to
BoLegalHoldPolicy in ReadMe
---
doc/legal_holds.md | 50 +++++++++++++++++++++++-----------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/doc/legal_holds.md b/doc/legal_holds.md
index d5c5c6408..5077c0567 100644
--- a/doc/legal_holds.md
+++ b/doc/legal_holds.md
@@ -19,16 +19,16 @@ such as name, description, and filter dates.
Get Legal Hold Policy
---------------------
-Calling [`getInfo(String...)`][get-info] will return a BoxLegalHold.Info object
+Calling [`getInfo(String...)`][get-info] will return a BoxLegalHoldPolicy.Info object
containing information about the legal hold policy. If necessary to retrieve
limited set of fields, it is possible to specify them using param.
```java
-BoxLegalHold policy = new BoxLegalHold(api, id);
-BoxLegalHold.Info policyInfo = policy.getInfo();
+BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, id);
+BoxLegalHoldPolicy.Info policyInfo = policy.getInfo();
```
-[get-info]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getInfo(java.lang.String...)
+[get-info]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#getInfo(java.lang.String...)
Get List of Legal Hold Policies
-------------------------------
@@ -40,14 +40,14 @@ response and fields to retrieve by calling the static
[`getAll(BoxAPIConnection, String, int, String...)`][get-list-of-legal-hold-policies-with-fields] method.
```java
-Iterable policies = BoxLegalHold.getAll(api);
-for (BoxLegalHold.Info policyInfo : policies) {
+Iterable policies = BoxLegalHoldPolicy.getAll(api);
+for (BoxLegalHoldPolicy.Info policyInfo : policies) {
// Do something with the legal hold policy.
}
```
-[get-list-of-legal-hold-policies]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getAll(com.box.sdk.BoxAPIConnection)
-[get-list-of-legal-hold-policies-with-fields]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getAll(com.box.sdk.BoxAPIConnection,%20java.lang.String,%20int,%20java.lang.String...)
+[get-list-of-legal-hold-policies]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#getAll(com.box.sdk.BoxAPIConnection)
+[get-list-of-legal-hold-policies-with-fields]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#getAll(com.box.sdk.BoxAPIConnection,%20java.lang.String,%20int,%20java.lang.String...)
Create New Legal Hold Policy
----------------------------
@@ -59,26 +59,26 @@ static
method will let you create a new legal hold policy with a specified name, description, start and end dates.
```java
-BoxLegalHold.Info policyInfo = BoxLegalHold.create(api, name, description, startedAt, endedAt);
+BoxLegalHoldPolicy.Info policyInfo = BoxLegalHoldPolicy.create(api, name, description, startedAt, endedAt);
```
-[create-new-legal-hold-policy]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#create(com.box.sdk.BoxAPIConnection,%20java.lang.String)
-[create-new-legal-hold-policy-with-dates]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#create(com.box.sdk.BoxAPIConnection,%20java.lang.String,%20java.lang.String,%20java.util.Date,%20java.util.Date)
+[create-new-legal-hold-policy]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#create(com.box.sdk.BoxAPIConnection,%20java.lang.String)
+[create-new-legal-hold-policy-with-dates]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#create(com.box.sdk.BoxAPIConnection,%20java.lang.String,%20java.lang.String,%20java.util.Date,%20java.util.Date)
Update Existing Legal Hold Policy
---------------------------------
Updating a legal hold policy's information is done by calling
-[`updateInfo(BoxLegalHold.Info)`][update-info].
+[`updateInfo(BoxLegalHoldPolicy.Info)`][update-info].
```java
-BoxLegalHold policy = new BoxLegalHold(api, id);
-BoxLegalHold.Info policyInfo = policy.new Info();
+BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, id);
+BoxLegalHoldPolicy.Info policyInfo = policy.new Info();
info.addPendingChange("description", "new description");
policy.updateInfo(info);
```
-[update-info]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#update(com.box.sdk.BoxLegalHold.Info)
+[update-info]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#update(com.box.sdk.BoxLegalHoldPolicy.Info)
Delete Legal Hold Policy
------------------------
@@ -86,11 +86,11 @@ Delete Legal Hold Policy
A legal hold policy can be deleted by calling the [`delete()`][delete] method.
```java
-BoxLegalHold policy = new BoxLegalHold(api, id);
+BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, id);
policy.delete();
```
-[delete]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#delete()
+[delete]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#delete()
Get Assignment
--------------
@@ -114,15 +114,15 @@ It is possible to specify filters for type and id, maximum number of items per s
response and fields to retrieve by calling [`getAssignments(String, String, int, String...)`][get-list-of-assignments-with-params].
```java
-BoxLegalHold policy = new BoxLegalHold(api, id);
+BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, id);
Iterable assignments = policy.getAssignments(BoxResource.getResourceType(BoxFolder.class), null, 50, "assigned_at");
for (BoxLegalHoldAssignment.Info assignmentInfo : assignments) {
// Do something with the legal hold policy assignment.
}
```
-[get-list-of-assignments]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getAssignments(java.lang.String...)
-[get-list-of-assignments-with-params]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getAssignments(java.lang.String,%20java.lang.String,%20int,%20java.lang.String...)
+[get-list-of-assignments]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#getAssignments(java.lang.String...)
+[get-list-of-assignments-with-params]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#getAssignments(java.lang.String,%20java.lang.String,%20int,%20java.lang.String...)
Create New Assignment
--------------
@@ -131,12 +131,12 @@ To create new legal hold policy assignment call [`assignTo(BoxResource)`][create
Currently only BoxFile, BoxFileVersion, BoxFolder and BoxUser objects are supported as a parameter.
```java
-BoxLegalHold policy = new BoxLegalHold(api, policyID);
+BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, policyID);
BoxFolder folder = new BoxFolder(api, folderID);
policy.assignTo(folder);
```
-[create-assignment]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#assignTo(com.box.sdk.BoxResource)
+[create-assignment]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#assignTo(com.box.sdk.BoxResource)
Delete Assignment
--------------
@@ -171,12 +171,12 @@ legal hold policy, call [`getFileVersionHolds(String...)`][get-lest-of-file-vers
It is possible to specify maximum number of items per single response by calling [`getFileVersionHolds(int, String...)`][get-lest-of-file-version-legal-holds-with-limit].
```java
-BoxLegalHold policy = new BoxLegalHold(api, id);
+BoxLegalHoldPolicy policy = new BoxLegalHoldPolicy(api, id);
Iterable fileVersionHolds = policy.getFileVersionHolds();
for (BoxFileVersionLegalHold.Info fileVersionHold : fileVersionHolds) {
// Do something with the file version legal hold.
}
```
-[get-lest-of-file-version-legal-holds]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getFileVersionHolds(java.lang.String...)
-[get-lest-of-file-version-legal-holds-with-limit]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHold.html#getFileVersionHolds(int,%20java.lang.String...)
\ No newline at end of file
+[get-lest-of-file-version-legal-holds]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#getFileVersionHolds(java.lang.String...)
+[get-lest-of-file-version-legal-holds-with-limit]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxLegalHoldPolicy.html#getFileVersionHolds(int,%20java.lang.String...)
From 0ace5ee90e3eb7d35a3dfface8a9a254479457cf Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Mon, 12 Dec 2016 18:27:22 -0800
Subject: [PATCH 032/119] Removing Java 1.6 Source Compatibility Check (it
seems to break Travis)
---
build.gradle | 5 -----
1 file changed, 5 deletions(-)
diff --git a/build.gradle b/build.gradle
index a4fd63fc3..1febe0b13 100644
--- a/build.gradle
+++ b/build.gradle
@@ -28,11 +28,6 @@ dependencies {
testCompile 'org.slf4j:slf4j-nop:1.7.7'
}
-compileJava {
- sourceCompatibility = 1.6
- targetCompatibility = 1.6
-}
-
javadoc {
options.windowTitle 'Box Java SDK'
options.noQualifiers 'all'
From e66ded7b29dad157efbb6150dd88d717d2aa3888 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 13 Dec 2016 13:23:18 -0800
Subject: [PATCH 033/119] Adding sourceCompatibility = 1.6 back in gradle.build
---
build.gradle | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/build.gradle b/build.gradle
index 1febe0b13..a4fd63fc3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -28,6 +28,11 @@ dependencies {
testCompile 'org.slf4j:slf4j-nop:1.7.7'
}
+compileJava {
+ sourceCompatibility = 1.6
+ targetCompatibility = 1.6
+}
+
javadoc {
options.windowTitle 'Box Java SDK'
options.noQualifiers 'all'
From 958b2ff38c03d174c62599996d8337c83561b6c1 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 20 Dec 2016 17:56:54 -0800
Subject: [PATCH 034/119] Fix bug in passing SHA1 in uploadVersion
---
src/main/java/com/box/sdk/BoxFile.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index a78b32d0b..48fbd7b68 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -457,7 +457,7 @@ public void uploadVersion(InputStream fileContent) {
*
*/
public void uploadVersion(InputStream fileContent, String fileContentSHA1) {
- this.uploadVersion(fileContent, null, null);
+ this.uploadVersion(fileContent, fileContentSHA1, null);
}
/**
From 5204b047a369a0afb9390ed0dc1045d0bd497243 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 21 Dec 2016 10:51:29 -0800
Subject: [PATCH 035/119] Updated version to 3.0.0-SNAPSHOT
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index a4fd63fc3..ed2628bd8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ sourceCompatibility = 1.6
group = 'com.box'
archivesBaseName = 'box-java-sdk'
-version = '2.2.2-SNAPSHOT'
+version = '3.0.0-SNAPSHOT'
repositories {
mavenCentral()
From e0376474d56b94f937b8b4e2c0064277138dc306 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 21 Dec 2016 10:54:01 -0800
Subject: [PATCH 036/119] Changing version to 2.2.3-SNAPSHOT (trying to fix
sonatype error)
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index ed2628bd8..672baf262 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ sourceCompatibility = 1.6
group = 'com.box'
archivesBaseName = 'box-java-sdk'
-version = '3.0.0-SNAPSHOT'
+version = '2.2.3-SNAPSHOT'
repositories {
mavenCentral()
From 41c4763233b9979dced62f0f2be7083a2314b9a2 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 4 Jan 2017 16:54:16 -0800
Subject: [PATCH 037/119] Updating Version # to 2.3.0
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 672baf262..7f51765e1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ sourceCompatibility = 1.6
group = 'com.box'
archivesBaseName = 'box-java-sdk'
-version = '2.2.3-SNAPSHOT'
+version = '2.3.0'
repositories {
mavenCentral()
From 09ce2f9e75959294ff12a6f9600bb68ac9decc88 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 10 Jan 2017 16:04:53 -0800
Subject: [PATCH 038/119] Updating version number in the UserAgent.
---
src/main/java/com/box/sdk/BoxAPIConnection.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index ff8b5f4d8..79b472a84 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -83,7 +83,7 @@ public BoxAPIConnection(String clientID, String clientSecret, String accessToken
this.autoRefresh = true;
this.maxRequestAttempts = DEFAULT_MAX_ATTEMPTS;
this.refreshLock = new ReentrantReadWriteLock();
- this.userAgent = "Box Java SDK v2.2.1-SNAPSHOT";
+ this.userAgent = "Box Java SDK v2.3.0";
this.listeners = new ArrayList();
}
From 67dd31f2b6f59a53d612fca0563b44495ea7b3a6 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 9 Feb 2017 18:22:00 -0800
Subject: [PATCH 039/119] Adding event type
CONTENT_WORKFLOW_UPLOAD_POLICY_VIOLATION
---
src/main/java/com/box/sdk/BoxEvent.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxEvent.java b/src/main/java/com/box/sdk/BoxEvent.java
index f46fff8e4..c03332710 100644
--- a/src/main/java/com/box/sdk/BoxEvent.java
+++ b/src/main/java/com/box/sdk/BoxEvent.java
@@ -604,7 +604,11 @@ public enum Type {
/**
* Deletion of metadata instance. This is an enterprise-only event.
*/
- METADATA_INSTANCE_DELETE;
+ METADATA_INSTANCE_DELETE,
+ /**
+ * Content Workflow upload policy violation. This is an enterprise-only event.
+ */
+ CONTENT_WORKFLOW_UPLOAD_POLICY_VIOLATION;
}
}
From 9e5a5ad5c9aa55ad24c8826e8b233d5c8d28136a Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 26 Jan 2017 18:11:52 -0800
Subject: [PATCH 040/119] Some changes to enable getting log output from
Integration Tests
---
build.gradle | 3 ++-
src/test/java/com/box/sdk/TestConfig.java | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index 7f51765e1..d1a4e0018 100644
--- a/build.gradle
+++ b/build.gradle
@@ -88,9 +88,10 @@ task sourcesJar(type: Jar) {
task integrationTest(type: Test) {
description 'Runs the integration tests.'
group 'Verification'
-
+ testLogging.showStandardStreams = true
useJUnit {
includeCategories 'com.box.sdk.IntegrationTest'
+
}
}
diff --git a/src/test/java/com/box/sdk/TestConfig.java b/src/test/java/com/box/sdk/TestConfig.java
index 087a0dc2f..876ff7eed 100644
--- a/src/test/java/com/box/sdk/TestConfig.java
+++ b/src/test/java/com/box/sdk/TestConfig.java
@@ -25,7 +25,7 @@ final class TestConfig {
private TestConfig() { }
- public static void setLogLevel(String levelString) {
+ public static Logger setLogLevel(String levelString) {
Level level = Level.parse(levelString);
Logger logger = Logger.getLogger("com.box.sdk");
logger.setLevel(level);
@@ -43,6 +43,7 @@ public static void setLogLevel(String levelString) {
handler.setLevel(level);
logger.addHandler(handler);
}
+ return logger;
}
public static String getAccessToken() {
From 0a43984bab801b5a1c2bd3dafc7943c3f852c9e4 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Wed, 8 Feb 2017 18:41:44 -0800
Subject: [PATCH 041/119] Changes to improve Integration Tests
---
.gitignore | 3 +++
src/main/java/com/box/sdk/BoxFile.java | 8 ++++----
src/main/java/com/box/sdk/BoxFileVersion.java | 1 -
src/test/java/com/box/sdk/BoxCollectionTest.java | 1 +
src/test/java/com/box/sdk/BoxFileTest.java | 3 ++-
src/test/java/com/box/sdk/BoxTaskTest.java | 1 +
src/test/java/com/box/sdk/BoxUserTest.java | 8 ++++++--
src/test/java/com/box/sdk/BoxWebHookTest.java | 11 ++++++-----
src/test/java/com/box/sdk/EventStreamTest.java | 10 ++++++++--
src/test/java/com/box/sdk/TestConfig.java | 2 +-
10 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/.gitignore b/.gitignore
index 2e1e79263..39827a815 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+gradle/
+gradlew
+gradlew.bat
.gradle/
gradle.properties
build/
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 48fbd7b68..d9fbc1d1d 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -513,13 +513,13 @@ public void uploadVersion(InputStream fileContent, String fileContentSHA1, Date
request.putField("content_modified_at", modified);
}
- BoxAPIResponse response;
+ BoxJSONResponse response;
if (listener == null) {
- response = request.send();
+ response = (BoxJSONResponse)request.send();
} else {
- response = request.send(listener);
+ response = (BoxJSONResponse)request.send(listener);
}
- response.disconnect();
+ response.getJSON();
}
/**
diff --git a/src/main/java/com/box/sdk/BoxFileVersion.java b/src/main/java/com/box/sdk/BoxFileVersion.java
index 5e198e075..e5792ea00 100644
--- a/src/main/java/com/box/sdk/BoxFileVersion.java
+++ b/src/main/java/com/box/sdk/BoxFileVersion.java
@@ -224,7 +224,6 @@ public void promote() {
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
request.setBody(jsonObject.toString());
BoxJSONResponse response = (BoxJSONResponse) request.send();
- response.disconnect();
this.parseJSON(JsonObject.readFrom(response.getJSON()));
}
}
diff --git a/src/test/java/com/box/sdk/BoxCollectionTest.java b/src/test/java/com/box/sdk/BoxCollectionTest.java
index 282ac7550..6aea05fab 100644
--- a/src/test/java/com/box/sdk/BoxCollectionTest.java
+++ b/src/test/java/com/box/sdk/BoxCollectionTest.java
@@ -192,5 +192,6 @@ public void getCollectionItemsSucceeds() {
uploadedFile.setCollections(favorites);
assertThat(favorites, hasItem(Matchers.hasProperty("ID", equalTo(uploadedFile.getID()))));
+ uploadedFile.delete();
}
}
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index be0158303..27c587892 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -17,6 +17,7 @@
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
+import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@@ -846,7 +847,7 @@ public void addTaskSucceeds() {
byte[] fileBytes = "Non-empty string".getBytes(StandardCharsets.UTF_8);
String taskMessage = "Non-empty message";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
- Date dueAt = new Date();
+ Date dueAt = new Date(new Date().getTime()+1000*24*60*60);
InputStream uploadStream = new ByteArrayInputStream(fileBytes);
BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
diff --git a/src/test/java/com/box/sdk/BoxTaskTest.java b/src/test/java/com/box/sdk/BoxTaskTest.java
index a016b78d6..735c4e8ea 100644
--- a/src/test/java/com/box/sdk/BoxTaskTest.java
+++ b/src/test/java/com/box/sdk/BoxTaskTest.java
@@ -559,6 +559,7 @@ public void updateInfoSucceeds() {
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
+ calendar.add(Calendar.DATE,1);
Date dueAt = calendar.getTime();
BoxTask.Info taskInfo = uploadedFile.addTask(BoxTask.Action.REVIEW, originalMessage, dueAt);
diff --git a/src/test/java/com/box/sdk/BoxUserTest.java b/src/test/java/com/box/sdk/BoxUserTest.java
index 18ed8266a..dc507e50b 100644
--- a/src/test/java/com/box/sdk/BoxUserTest.java
+++ b/src/test/java/com/box/sdk/BoxUserTest.java
@@ -5,6 +5,7 @@
import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
@@ -962,7 +963,10 @@ public void getCurrentUserInfoIsCorrect() throws InterruptedException {
@Category(IntegrationTest.class)
public void createAndDeleteEnterpriseUserSucceeds() {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
- final String login = "login@box.com";
+ // Since deleting users happens in a separate process in the backend
+ // it is really an asynchronous call. So we have to use a new user in
+ // this test in case the previous user's deletion hasn't completed.
+ final String login = "login2@box.com";
final String name = "non-empty name";
BoxUser.Info createdUserInfo = BoxUser.createEnterpriseUser(api, login, name);
@@ -998,7 +1002,7 @@ public void getMembershipsHasCorrectMemberships() {
@Category(IntegrationTest.class)
public void updateInfoSucceeds() {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
- final String login = "login@box.com";
+ final String login = "login3@box.com";
final String originalName = "original name";
final String updatedName = "updated name";
diff --git a/src/test/java/com/box/sdk/BoxWebHookTest.java b/src/test/java/com/box/sdk/BoxWebHookTest.java
index 4ec8ee4db..cd009ea24 100644
--- a/src/test/java/com/box/sdk/BoxWebHookTest.java
+++ b/src/test/java/com/box/sdk/BoxWebHookTest.java
@@ -10,6 +10,7 @@
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.logging.Logger;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
@@ -463,7 +464,7 @@ public void createWebHookFileSucceeds() throws IOException {
BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
try {
- URL address = new URL("https://0.0.0.0");
+ URL address = new URL("https://www.google.com");
BoxWebHook.Info info = BoxWebHook.create(uploadedFile, address,
BoxWebHook.Trigger.FILE_PREVIEWED, BoxWebHook.Trigger.FILE_LOCKED);
@@ -489,7 +490,7 @@ public void createWebHookFolderSucceeds() throws IOException {
BoxFolder folder = rootFolder.createFolder(folderName).getResource();
try {
- URL address = new URL("https://0.0.0.0");
+ URL address = new URL("https://www.google.com");
BoxWebHook.Info info = BoxWebHook.create(folder, address,
BoxWebHook.Trigger.FOLDER_DOWNLOADED, BoxWebHook.Trigger.FOLDER_COPIED);
@@ -518,7 +519,7 @@ public void listWebHooksSucceeds() throws IOException {
BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
try {
- URL address = new URL("https://0.0.0.0");
+ URL address = new URL("https://www.google.com");
BoxWebHook.Info info = BoxWebHook.create(uploadedFile, address, BoxWebHook.Trigger.FILE_PREVIEWED);
Iterable webhooks = BoxWebHook.all(api);
@@ -545,11 +546,11 @@ public void updateWebHookInfoSucceeds() throws IOException {
BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
try {
- URL address = new URL("https://0.0.0.0");
+ URL address = new URL("https://www.google.com");
BoxWebHook webHook = BoxWebHook.create(uploadedFile, address,
BoxWebHook.Trigger.FILE_PREVIEWED, BoxWebHook.Trigger.FILE_LOCKED).getResource();
- URL newAddress = new URL("https://0.0.0.1");
+ URL newAddress = new URL("https://www.yahoo.com");
BoxWebHook.Info newInfo = webHook.new Info();
newInfo.setTriggers(BoxWebHook.Trigger.FILE_UNLOCKED);
diff --git a/src/test/java/com/box/sdk/EventStreamTest.java b/src/test/java/com/box/sdk/EventStreamTest.java
index 74977fb9b..bee17d3d0 100644
--- a/src/test/java/com/box/sdk/EventStreamTest.java
+++ b/src/test/java/com/box/sdk/EventStreamTest.java
@@ -2,6 +2,7 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@@ -28,8 +29,8 @@ public class EventStreamTest {
@Test
@Category(IntegrationTest.class)
public void receiveEventsForFolderCreateAndFolderDelete() throws InterruptedException {
+ // Logger logger = TestConfig.setLogLevel("FINE");
final LinkedBlockingQueue observedEvents = new LinkedBlockingQueue();
-
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
EventStream stream = new EventStream(api);
stream.addListener(new EventListener() {
@@ -60,7 +61,12 @@ public boolean onException(Throwable e) {
boolean deletedEventFound = false;
while (!createdEventFound || !deletedEventFound) {
BoxEvent event = observedEvents.poll(1, TimeUnit.MINUTES);
- BoxResource source = event.getSourceInfo().getResource();
+ BoxResource.Info sourceInfo = event.getSourceInfo();
+ // Some events may not have sourceInfo
+ if (sourceInfo == null) {
+ continue;
+ }
+ BoxResource source = sourceInfo.getResource();
if (source instanceof BoxFolder) {
BoxFolder sourceFolder = (BoxFolder) source;
if (sourceFolder.getID().equals(expectedID)) {
diff --git a/src/test/java/com/box/sdk/TestConfig.java b/src/test/java/com/box/sdk/TestConfig.java
index 876ff7eed..86d3f8fd6 100644
--- a/src/test/java/com/box/sdk/TestConfig.java
+++ b/src/test/java/com/box/sdk/TestConfig.java
@@ -25,7 +25,7 @@ final class TestConfig {
private TestConfig() { }
- public static Logger setLogLevel(String levelString) {
+ public static Logger enableLogger(String levelString) {
Level level = Level.parse(levelString);
Logger logger = Logger.getLogger("com.box.sdk");
logger.setLevel(level);
From cfbb4ed2c07a7b4fd8c54a93ec623593e920eddd Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 9 Feb 2017 17:57:23 -0800
Subject: [PATCH 042/119] Added a new IntegrationTest type for JWT tests
---
build.gradle | 12 ++++++++++++
src/main/java/com/box/sdk/BoxFile.java | 4 ++--
src/test/java/com/box/sdk/BoxAPIConnectionTest.java | 4 ++--
src/test/java/com/box/sdk/BoxFileTest.java | 3 +--
src/test/java/com/box/sdk/BoxTaskTest.java | 2 +-
.../box/sdk/BoxTransactionalAPIConnectionTest.java | 8 ++++----
src/test/java/com/box/sdk/BoxUserTest.java | 5 ++---
src/test/java/com/box/sdk/BoxWebHookTest.java | 1 -
src/test/java/com/box/sdk/EventStreamTest.java | 2 --
src/test/java/com/box/sdk/IntegrationTestJWT.java | 7 +++++++
10 files changed, 31 insertions(+), 17 deletions(-)
create mode 100644 src/test/java/com/box/sdk/IntegrationTestJWT.java
diff --git a/build.gradle b/build.gradle
index d1a4e0018..c03819a83 100644
--- a/build.gradle
+++ b/build.gradle
@@ -95,6 +95,17 @@ task integrationTest(type: Test) {
}
}
+task integrationTestJWT(type: Test) {
+ description 'Runs the JWT based integration tests.'
+ group 'Verification'
+ testLogging.showStandardStreams = true
+ useJUnit {
+ includeCategories 'com.box.sdk.IntegrationTestJWT'
+
+ }
+}
+
+
jacocoTestReport.dependsOn(integrationTest);
tasks.withType(JavaCompile) {
@@ -125,6 +136,7 @@ artifacts {
test {
useJUnit {
excludeCategories 'com.box.sdk.IntegrationTest'
+ excludeCategories 'com.box.sdk.IntegrationTestJWT'
}
}
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index d9fbc1d1d..730b38ad9 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -515,9 +515,9 @@ public void uploadVersion(InputStream fileContent, String fileContentSHA1, Date
BoxJSONResponse response;
if (listener == null) {
- response = (BoxJSONResponse)request.send();
+ response = (BoxJSONResponse) request.send();
} else {
- response = (BoxJSONResponse)request.send(listener);
+ response = (BoxJSONResponse) request.send(listener);
}
response.getJSON();
}
diff --git a/src/test/java/com/box/sdk/BoxAPIConnectionTest.java b/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
index f7b45d660..c37cd6ce9 100644
--- a/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
+++ b/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
@@ -210,7 +210,7 @@ public void successfullySavesAndRestoresConnection() {
}
@Test
- @Category(IntegrationTest.class)
+ @Category(IntegrationTestJWT.class)
public void developerEditionAppAuthWorks() {
final String enterpriseId = TestConfig.getEnterpriseID();
final String clientId = TestConfig.getClientID();
@@ -253,7 +253,7 @@ public void developerEditionAppAuthWorks() {
}
@Test
- @Category(IntegrationTest.class)
+ @Category(IntegrationTestJWT.class)
public void developerEditionAppUserWorks() {
final String enterpriseId = TestConfig.getEnterpriseID();
final String clientId = TestConfig.getClientID();
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 27c587892..ca1a1ace3 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -17,7 +17,6 @@
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
-import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@@ -847,7 +846,7 @@ public void addTaskSucceeds() {
byte[] fileBytes = "Non-empty string".getBytes(StandardCharsets.UTF_8);
String taskMessage = "Non-empty message";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
- Date dueAt = new Date(new Date().getTime()+1000*24*60*60);
+ Date dueAt = new Date(new Date().getTime() + (1000 * 24 * 60 * 60));
InputStream uploadStream = new ByteArrayInputStream(fileBytes);
BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
diff --git a/src/test/java/com/box/sdk/BoxTaskTest.java b/src/test/java/com/box/sdk/BoxTaskTest.java
index 735c4e8ea..114ee177a 100644
--- a/src/test/java/com/box/sdk/BoxTaskTest.java
+++ b/src/test/java/com/box/sdk/BoxTaskTest.java
@@ -559,7 +559,7 @@ public void updateInfoSucceeds() {
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
- calendar.add(Calendar.DATE,1);
+ calendar.add(Calendar.DATE, 1);
Date dueAt = calendar.getTime();
BoxTask.Info taskInfo = uploadedFile.addTask(BoxTask.Action.REVIEW, originalMessage, dueAt);
diff --git a/src/test/java/com/box/sdk/BoxTransactionalAPIConnectionTest.java b/src/test/java/com/box/sdk/BoxTransactionalAPIConnectionTest.java
index 5bbde4cbe..a6c7d4b5f 100644
--- a/src/test/java/com/box/sdk/BoxTransactionalAPIConnectionTest.java
+++ b/src/test/java/com/box/sdk/BoxTransactionalAPIConnectionTest.java
@@ -12,7 +12,7 @@
public class BoxTransactionalAPIConnectionTest {
@Test
- @Category(IntegrationTest.class)
+ @Category(IntegrationTestJWT.class)
public void successfullyCreatesTransactionalConnection() {
final String transactionalAccessToken = TestConfig.getTransactionalAccessToken();
@@ -22,7 +22,7 @@ public void successfullyCreatesTransactionalConnection() {
}
@Test
- @Category(IntegrationTest.class)
+ @Category(IntegrationTestJWT.class)
public void successfullyCreatesEmbedLinkWithTransactionalConnection() {
final String transactionalAccessToken = TestConfig.getTransactionalAccessToken();
@@ -55,7 +55,7 @@ public void successfullyCreatesEmbedLinkWithTransactionalConnection() {
}
@Test
- @Category(IntegrationTest.class)
+ @Category(IntegrationTestJWT.class)
public void successfullyCreatesEmbedLinkWithResourceScopedTransactionalConnection() {
final String transactionalAccessToken = TestConfig.getTransactionalAccessToken();
@@ -83,7 +83,7 @@ public void successfullyCreatesEmbedLinkWithResourceScopedTransactionalConnectio
}
@Test(expected = BoxAPIException.class)
- @Category(IntegrationTest.class)
+ @Category(IntegrationTestJWT.class)
public void throwsWhenAttemptingToCreatesEmbedLinkWithAnotherFilesResourceScopedTransactionalConnection() {
final String transactionalAccessToken = TestConfig.getTransactionalAccessToken();
diff --git a/src/test/java/com/box/sdk/BoxUserTest.java b/src/test/java/com/box/sdk/BoxUserTest.java
index dc507e50b..d60c0c42e 100644
--- a/src/test/java/com/box/sdk/BoxUserTest.java
+++ b/src/test/java/com/box/sdk/BoxUserTest.java
@@ -5,7 +5,6 @@
import java.util.Date;
import java.util.Iterator;
import java.util.List;
-import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
@@ -966,7 +965,7 @@ public void createAndDeleteEnterpriseUserSucceeds() {
// Since deleting users happens in a separate process in the backend
// it is really an asynchronous call. So we have to use a new user in
// this test in case the previous user's deletion hasn't completed.
- final String login = "login2@box.com";
+ final String login = "login2@boz.com";
final String name = "non-empty name";
BoxUser.Info createdUserInfo = BoxUser.createEnterpriseUser(api, login, name);
@@ -1002,7 +1001,7 @@ public void getMembershipsHasCorrectMemberships() {
@Category(IntegrationTest.class)
public void updateInfoSucceeds() {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
- final String login = "login3@box.com";
+ final String login = "login3@boz.com";
final String originalName = "original name";
final String updatedName = "updated name";
diff --git a/src/test/java/com/box/sdk/BoxWebHookTest.java b/src/test/java/com/box/sdk/BoxWebHookTest.java
index cd009ea24..f04a95bc0 100644
--- a/src/test/java/com/box/sdk/BoxWebHookTest.java
+++ b/src/test/java/com/box/sdk/BoxWebHookTest.java
@@ -10,7 +10,6 @@
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.logging.Logger;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/box/sdk/EventStreamTest.java b/src/test/java/com/box/sdk/EventStreamTest.java
index bee17d3d0..67bf16d2d 100644
--- a/src/test/java/com/box/sdk/EventStreamTest.java
+++ b/src/test/java/com/box/sdk/EventStreamTest.java
@@ -2,7 +2,6 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@@ -29,7 +28,6 @@ public class EventStreamTest {
@Test
@Category(IntegrationTest.class)
public void receiveEventsForFolderCreateAndFolderDelete() throws InterruptedException {
- // Logger logger = TestConfig.setLogLevel("FINE");
final LinkedBlockingQueue observedEvents = new LinkedBlockingQueue();
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
EventStream stream = new EventStream(api);
diff --git a/src/test/java/com/box/sdk/IntegrationTestJWT.java b/src/test/java/com/box/sdk/IntegrationTestJWT.java
new file mode 100644
index 000000000..4713c7a9f
--- /dev/null
+++ b/src/test/java/com/box/sdk/IntegrationTestJWT.java
@@ -0,0 +1,7 @@
+package com.box.sdk;
+
+/**
+ * Created by dmaynard on 2/9/17.
+ */
+public interface IntegrationTestJWT {
+}
From 1e596fb696a459fc7e66ac5cf5abc39bac253e77 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 21 Feb 2017 15:56:18 -0800
Subject: [PATCH 043/119] Create and update operations are added to Metadata
Template
---
.../java/com/box/sdk/MetadataTemplate.java | 437 +++++++++++++++++-
.../com/box/sdk/MetadataTemplateTest.java | 83 ++++
2 files changed, 519 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/MetadataTemplate.java b/src/main/java/com/box/sdk/MetadataTemplate.java
index 518606d6d..9ca9b3082 100644
--- a/src/main/java/com/box/sdk/MetadataTemplate.java
+++ b/src/main/java/com/box/sdk/MetadataTemplate.java
@@ -1,12 +1,15 @@
package com.box.sdk;
+import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
+import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
+
/**
* The MetadataTemplate class represents the Box metadata template object.
* Templates allow the metadata service to provide a multitude of services,
@@ -22,6 +25,12 @@ public class MetadataTemplate extends BoxJSONObject {
private static final URLTemplate METADATA_TEMPLATE_URL_TEMPLATE
= new URLTemplate("metadata_templates/%s/%s/schema");
+ /**
+ * @see #createMetadataTemplate(BoxAPIConnection, String, String, String, boolean, List)
+ */
+ private static final URLTemplate METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE
+ = new URLTemplate("metadata_templates/schema");
+
/**
* @see #getEnterpriseMetadataTemplates(String, int, BoxAPIConnection, String...)
*/
@@ -158,6 +167,201 @@ void parseJSONMember(JsonObject.Member member) {
}
}
+ /**
+ * Creates new metadata template.
+ * @param api the API connection to be used.
+ * @param scope the scope of the object.
+ * @param templateKey a unique identifier for the template.
+ * @param displayName the display name of the field.
+ * @param hidden whether this template is hidden in the UI.
+ * @param fields the ordered set of fields for the template
+ * @return the metadata template returned from the server.
+ */
+ public static MetadataTemplate createMetadataTemplate(BoxAPIConnection api, String scope, String templateKey,
+ String displayName, boolean hidden, List fields) {
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.add("scope", scope);
+ jsonObject.add("displayName", displayName);
+ jsonObject.add("hidden", hidden);
+
+ if (templateKey != null) {
+ jsonObject.add("templateKey", templateKey);
+ }
+
+ JsonArray fieldsArray = new JsonArray();
+ if (fields != null && !fields.isEmpty()) {
+ for (Field field : fields) {
+ JsonObject fieldObj = getFieldJsonObject(field);
+
+ fieldsArray.add(fieldObj);
+ }
+
+ jsonObject.add("fields", fieldsArray);
+ }
+
+ URL url = METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE.build(api.getBaseURL());
+ BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
+ request.setBody(jsonObject.toString());
+ System.out.println("Result: " + jsonObject.toString());
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+
+ return new MetadataTemplate(responseJSON);
+ }
+
+ /**
+ * Gets the JsonObject representation of the given field object
+ * @param field represents a template field
+ * @return the json object
+ */
+ private static JsonObject getFieldJsonObject(Field field) {
+ JsonObject fieldObj = new JsonObject();
+ fieldObj.add("type", field.getType());
+ fieldObj.add("key", field.getKey());
+ fieldObj.add("displayName", field.getDisplayName());
+
+ String fieldDesc = field.getDescription();
+ if (fieldDesc != null) {
+ fieldObj.add("description", field.getDescription());
+ }
+
+ Boolean fieldIsHidden = field.getIsHidden();
+ if(fieldIsHidden != null) {
+ fieldObj.add("hidden", field.getIsHidden());
+ }
+
+ JsonArray array = new JsonArray();
+ List options = field.getOptions();
+ if (options != null && !options.isEmpty()) {
+ for (String option : options) {
+ JsonObject optionObj = new JsonObject();
+ optionObj.add("key", option);
+
+ array.add(optionObj);
+ }
+ fieldObj.add("options", array);
+ }
+
+ return fieldObj;
+ }
+
+ /**
+ * Updates the schema of an existing metadata template
+ *
+ * @param api the API connection to be used
+ * @param scope the scope of the object
+ * @param template Unique identifier of the template
+ * @param fieldOperations the fields that needs to be updated / added in the template
+ * @return the updated metadata template
+ */
+ public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, String scope, String template, List fieldOperations) {
+ JsonArray array = new JsonArray();
+
+ for (FieldOperation fieldOperation : fieldOperations) {
+ JsonObject jsonObject = getFieldOperationJsonObject(fieldOperation);
+ array.add(jsonObject);
+ }
+
+ QueryStringBuilder builder = new QueryStringBuilder();
+ URL url = METADATA_TEMPLATE_URL_TEMPLATE.build(api.getBaseURL(), scope, template);
+ BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT");
+ request.setBody(array.toString());
+
+ System.out.println("Array: " + array.toString());
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJson = JsonObject.readFrom(response.getJSON());
+
+ return new MetadataTemplate(responseJson);
+ }
+
+ /**
+ * Gets the JsonObject representation of the Field Operation
+ * @param fieldOperation represents the template update operation
+ * @return the json object
+ */
+ private static JsonObject getFieldOperationJsonObject(FieldOperation fieldOperation) {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.add("op", fieldOperation.getOp().toString());
+
+ String fieldKey = fieldOperation.getFieldKey();
+ if (fieldKey != null) {
+ jsonObject.add("fieldKey", fieldKey);
+ }
+
+ Field field = fieldOperation.getData();
+ if (field != null) {
+ JsonObject fieldObj = new JsonObject();
+
+ String type = field.getType();
+ if(type != null) {
+ fieldObj.add("type", type);
+ }
+
+ String key = field.getKey();
+ if (key != null) {
+ fieldObj.add("key", key);
+ }
+
+ String displayName = field.getDisplayName();
+ if(displayName != null) {
+ fieldObj.add("displayName", displayName);
+ }
+
+ String description = field.getDescription();
+ if (description != null) {
+ fieldObj.add("description", description);
+ }
+
+ Boolean hidden = field.getIsHidden();
+ if (hidden != null) {
+ fieldObj.add("hidden", hidden);
+ }
+
+ List options = field.getOptions();
+ if (options != null) {
+ JsonArray array = new JsonArray();
+ for (String option: options) {
+ JsonObject optionObj = new JsonObject();
+ optionObj.add("key", option);
+
+ array.add(optionObj);
+ }
+
+ fieldObj.add("options", array);
+ }
+
+ jsonObject.add("data", fieldObj);
+ }
+
+ List fieldKeys = fieldOperation.getFieldKeys();
+ if (fieldKeys != null) {
+ jsonObject.add("fieldKeys", getJsonArray(fieldKeys));
+ }
+
+ List enumOptionKeys = fieldOperation.getEnumOptionKeys();
+ if (enumOptionKeys != null) {
+ jsonObject.add("enumOptionKeys", getJsonArray(enumOptionKeys));
+ }
+
+ return jsonObject;
+ }
+
+ /**
+ * Gets the Json Array representation of the given list of strings
+ * @param keys List of strings
+ * @return the JsonArray represents the list of keys
+ */
+ private static JsonArray getJsonArray(List keys) {
+ JsonArray array = new JsonArray();
+ for (String key : keys) {
+ array.add(key);
+ }
+
+ return array;
+ }
+
/**
* Gets the metadata template of properties.
* @param api the API connection to be used.
@@ -258,7 +462,7 @@ private static String scopeBasedOnType(String typeName) {
/**
* Class contains information about the metadata template field.
*/
- public class Field extends BoxJSONObject {
+ public static class Field extends BoxJSONObject {
/**
* @see #getType()
@@ -321,6 +525,14 @@ public String getType() {
return this.type;
}
+ /**
+ * Sets the data type of the field's value.
+ * @param type the data type of the field's value.
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
/**
* Gets the key of the field.
* @return the key of the field.
@@ -329,6 +541,14 @@ public String getKey() {
return this.key;
}
+ /**
+ * Sets the key of the field.
+ * @param key the key of the field.
+ */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
/**
* Gets the display name of the field.
* @return the display name of the field.
@@ -337,6 +557,14 @@ public String getDisplayName() {
return this.displayName;
}
+ /**
+ * Sets the display name of the field.
+ * @param displayName the display name of the field.
+ */
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
/**
* Gets is metadata template field hidden.
* @return is metadata template field hidden.
@@ -345,6 +573,14 @@ public Boolean getIsHidden() {
return this.isHidden;
}
+ /**
+ * Sets is metadata template field hidden.
+ * @param isHidden is metadata template field hidden?
+ */
+ public void setIsHidden(boolean isHidden) {
+ this.isHidden = isHidden;
+ }
+
/**
* Gets the description of the field.
* @return the description of the field.
@@ -353,6 +589,14 @@ public String getDescription() {
return this.description;
}
+ /**
+ * Sets the description of the field.
+ * @param description the description of the field.
+ */
+ public void setDescription() {
+ this.description = description;
+ }
+
/**
* Gets list of possible options for enum type of the field.
* @return list of possible options for enum type of the field.
@@ -361,6 +605,14 @@ public List getOptions() {
return this.options;
}
+ /**
+ * Sets list of possible options for enum type of the field.
+ * @param options list of possible options for enum type of the field.
+ */
+ public void setOptions(List options) {
+ this.options = options;
+ }
+
/**
* {@inheritDoc}
*/
@@ -387,4 +639,187 @@ void parseJSONMember(JsonObject.Member member) {
}
}
+ /**
+ * Posssible operations that can be performed in a Metadata template
+ * Add an enum option
+ * Add a field
+ * Edit a field
+ * Edit template
+ * Reorder the enum option
+ * Reorder the field list
+ */
+ public static class FieldOperation extends BoxJSONObject {
+
+ private Operation op;
+ private Field data;
+ private String fieldKey;
+ private List fieldKeys;
+ private List enumOptionKeys;
+
+ /**
+ * Constructs an empty FieldOperation.
+ */
+ public FieldOperation() {
+ super();
+ }
+
+ /**
+ * Constructs a Field operation from a JSON string.
+ * @param json the json encoded metadate template field.
+ */
+ public FieldOperation(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs a Field operation from a JSON object.
+ * @param jsonObject the json encoded metadate template field.
+ */
+ FieldOperation(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ /**
+ * Gets the operation
+ * @return the operation
+ */
+ public Operation getOp() {
+ return op;
+ }
+
+ /**
+ * Gets the data associated with the operation
+ * @return the field object representing the data
+ */
+ public Field getData() {
+ return data;
+ }
+
+ /**
+ * Gets the field key
+ * @return the field key
+ */
+ public String getFieldKey() {
+ return fieldKey;
+ }
+
+ /**
+ * Gets the list of field keys
+ * @return the list of Strings
+ */
+ public List getFieldKeys() {
+ return fieldKeys;
+ }
+
+ /**
+ * Gets the list of keys of the Enum options
+ * @return the list of Strings
+ */
+ public List getEnumOptionKeys() {
+ return enumOptionKeys;
+ }
+
+ /**
+ * Sets the operation
+ * @param op the operation
+ */
+ public void setOp(Operation op) {
+ this.op = op;
+ }
+
+ /**
+ * Sets the data
+ * @param data the Field object representing the data
+ */
+ public void setData(Field data) {
+ this.data = data;
+ }
+
+ /**
+ * Sets the field key
+ * @param fieldKey the key of the field
+ */
+ public void setFieldKey(String fieldKey) {
+ this.fieldKey = fieldKey;
+ }
+
+ /**
+ * Sets the list of the field keys
+ * @param fieldKeys the list of strings
+ */
+ public void setFieldKeys(List fieldKeys) {
+ this.fieldKeys = fieldKeys;
+ }
+
+ /**
+ * Sets the list of the enum option keys
+ * @param enumOptionKeys the list of Strings
+ */
+ public void setEnumOptionKeys(List enumOptionKeys) {
+ this.enumOptionKeys = enumOptionKeys;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void parseJSONMember(JsonObject.Member member) {
+ JsonValue value = member.getValue();
+ String memberName = member.getName();
+ if (memberName.equals("op")) {
+ this.op = Operation.valueOf(value.asString());
+ } else if (memberName.equals("data")) {
+ this.data = new Field(value.asObject());
+ } else if (memberName.equals("fieldKey")) {
+ this.fieldKey = value.asString();
+ } else if (memberName.equals("fieldKeys")) {
+ if(this.fieldKeys == null) {
+ fieldKeys = new ArrayList();
+ } else {
+ fieldKeys.clear();
+ }
+
+ JsonArray array = value.asArray();
+ for (JsonValue jsonValue: array) {
+ fieldKeys.add(jsonValue.asString());
+ }
+ } else if (memberName.equals("enumOptionKeys")) {
+ if(this.enumOptionKeys == null) {
+ enumOptionKeys = new ArrayList();
+ } else {
+ enumOptionKeys.clear();
+ }
+
+ JsonArray array = value.asArray();
+ for (JsonValue jsonValue: array) {
+ enumOptionKeys.add(jsonValue.asString());
+ }
+ }
+ }
+ }
+
+ /**
+ * Possible template operations
+ */
+ public enum Operation {
+
+ //Adds an enum option at the end of the enum option list for the specified field
+ addEnumOption,
+
+ //Adds a field at the end of the field list for the template
+ addField,
+
+ //Edits any number of the base properties of a field: displayName, hidden, description
+ editField,
+
+ //Edits any number of the base properties of a template: displayName, hidden
+ editTemplate,
+
+ //Reorders the enum option list to match the requested enum option list
+ reorderEnumOptions,
+
+ //Reorders the field list to match the requested field list
+ reorderFields
+ }
+
}
diff --git a/src/test/java/com/box/sdk/MetadataTemplateTest.java b/src/test/java/com/box/sdk/MetadataTemplateTest.java
index 8ca7c60f6..40af0e967 100644
--- a/src/test/java/com/box/sdk/MetadataTemplateTest.java
+++ b/src/test/java/com/box/sdk/MetadataTemplateTest.java
@@ -1,5 +1,6 @@
package com.box.sdk;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
@@ -249,4 +250,86 @@ public void testGetEnterpriseMetadataTemplatesParseAllFieldsCorrectly() {
Assert.assertEquals(secondEntryFieldSecondOption, template.getFields().get(0).getOptions().get(1));
Assert.assertFalse(iterator.hasNext());
}
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void createMetadataTemplateSucceeds() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+
+ MetadataTemplate.Field ctField = new MetadataTemplate.Field();
+ ctField.setType("string");
+ ctField.setKey("customerTeam");
+ ctField.setDisplayName("Customer Team");
+
+ MetadataTemplate.Field fyField = new MetadataTemplate.Field();
+ fyField.setType("enum");
+ fyField.setKey("fy");
+ fyField.setDisplayName("FY");
+
+ List options = new ArrayList();
+ options.add("FY16");
+ options.add("FY17");
+ fyField.setOptions(options);
+
+ List fields = new ArrayList();
+ fields.add(ctField);
+ fields.add(fyField);
+
+ MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise", "documentFlow03", "Document Flow 03", false, fields);
+
+ MetadataTemplate storedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
+ Assert.assertNotNull(storedTemplate);
+ }
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void updateMetadataTemplateSucceeds() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+
+ List fieldOperations = new ArrayList();
+ MetadataTemplate.FieldOperation editField = new MetadataTemplate.FieldOperation();
+ editField.setOp(MetadataTemplate.Operation.editField);
+ editField.setFieldKey("customerTeam");
+
+ MetadataTemplate.Field customerTeam = new MetadataTemplate.Field();
+ customerTeam.setDisplayName("Customer Team modified");
+ editField.setData(customerTeam);
+ fieldOperations.add(editField);
+
+ MetadataTemplate.FieldOperation newField = new MetadataTemplate.FieldOperation();
+ newField.setOp(MetadataTemplate.Operation.addField);
+
+ MetadataTemplate.Field deptField = new MetadataTemplate.Field();
+ deptField.setType("enum");
+ deptField.setKey("department");
+ deptField.setDisplayName("Department");
+
+ List options = new ArrayList();
+ options.add("Beauty");
+ options.add("Shoes");
+ deptField.setOptions(options);
+ newField.setData(deptField);
+
+ fieldOperations.add(newField);
+
+ MetadataTemplate template = MetadataTemplate.updateMetadataTemplate(api, "enterprise", "documentFlow03", fieldOperations);
+ Assert.assertNotNull(template);
+
+ MetadataTemplate updatedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
+ List fields = updatedTemplate.getFields();
+ Assert.assertEquals(4, fields.size());
+
+ boolean found = false;
+ for (MetadataTemplate.Field field: fields) {
+ if ("department".equals(field.getKey())) {
+ Assert.assertEquals("enum", field.getType());
+ Assert.assertEquals("Department", field.getDisplayName());
+ Assert.assertEquals(2, field.getOptions().size());
+
+ found = true;
+ }
+ }
+
+ Assert.assertEquals(found, true);
+ }
}
From d1f763ef0b64fe75b3dee5716120264de428c578 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 21 Feb 2017 16:14:41 -0800
Subject: [PATCH 044/119] Javadoc fixes
---
.../java/com/box/sdk/MetadataTemplate.java | 108 ++++++++++--------
1 file changed, 60 insertions(+), 48 deletions(-)
diff --git a/src/main/java/com/box/sdk/MetadataTemplate.java b/src/main/java/com/box/sdk/MetadataTemplate.java
index 9ca9b3082..713bb9284 100644
--- a/src/main/java/com/box/sdk/MetadataTemplate.java
+++ b/src/main/java/com/box/sdk/MetadataTemplate.java
@@ -1,6 +1,5 @@
package com.box.sdk;
-import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
@@ -212,7 +211,7 @@ public static MetadataTemplate createMetadataTemplate(BoxAPIConnection api, Stri
}
/**
- * Gets the JsonObject representation of the given field object
+ * Gets the JsonObject representation of the given field object.
* @param field represents a template field
* @return the json object
*/
@@ -228,7 +227,7 @@ private static JsonObject getFieldJsonObject(Field field) {
}
Boolean fieldIsHidden = field.getIsHidden();
- if(fieldIsHidden != null) {
+ if (fieldIsHidden != null) {
fieldObj.add("hidden", field.getIsHidden());
}
@@ -248,7 +247,7 @@ private static JsonObject getFieldJsonObject(Field field) {
}
/**
- * Updates the schema of an existing metadata template
+ * Updates the schema of an existing metadata template.
*
* @param api the API connection to be used
* @param scope the scope of the object
@@ -256,7 +255,9 @@ private static JsonObject getFieldJsonObject(Field field) {
* @param fieldOperations the fields that needs to be updated / added in the template
* @return the updated metadata template
*/
- public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, String scope, String template, List fieldOperations) {
+ public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, String scope, String template,
+ List fieldOperations) {
+
JsonArray array = new JsonArray();
for (FieldOperation fieldOperation : fieldOperations) {
@@ -277,7 +278,7 @@ public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, Stri
}
/**
- * Gets the JsonObject representation of the Field Operation
+ * Gets the JsonObject representation of the Field Operation.
* @param fieldOperation represents the template update operation
* @return the json object
*/
@@ -295,7 +296,7 @@ private static JsonObject getFieldOperationJsonObject(FieldOperation fieldOperat
JsonObject fieldObj = new JsonObject();
String type = field.getType();
- if(type != null) {
+ if (type != null) {
fieldObj.add("type", type);
}
@@ -305,7 +306,7 @@ private static JsonObject getFieldOperationJsonObject(FieldOperation fieldOperat
}
String displayName = field.getDisplayName();
- if(displayName != null) {
+ if (displayName != null) {
fieldObj.add("displayName", displayName);
}
@@ -349,7 +350,7 @@ private static JsonObject getFieldOperationJsonObject(FieldOperation fieldOperat
}
/**
- * Gets the Json Array representation of the given list of strings
+ * Gets the Json Array representation of the given list of strings.
* @param keys List of strings
* @return the JsonArray represents the list of keys
*/
@@ -593,7 +594,7 @@ public String getDescription() {
* Sets the description of the field.
* @param description the description of the field.
*/
- public void setDescription() {
+ public void setDescription(String description) {
this.description = description;
}
@@ -640,13 +641,13 @@ void parseJSONMember(JsonObject.Member member) {
}
/**
- * Posssible operations that can be performed in a Metadata template
- * Add an enum option
- * Add a field
- * Edit a field
- * Edit template
- * Reorder the enum option
- * Reorder the field list
+ * Posssible operations that can be performed in a Metadata template.
+ *
+ *
+ *
+ *
+ *
+ *
*/
public static class FieldOperation extends BoxJSONObject {
@@ -680,47 +681,47 @@ public FieldOperation(String json) {
}
/**
- * Gets the operation
+ * Gets the operation.
* @return the operation
*/
public Operation getOp() {
- return op;
+ return this.op;
}
/**
- * Gets the data associated with the operation
+ * Gets the data associated with the operation.
* @return the field object representing the data
*/
public Field getData() {
- return data;
+ return this.data;
}
/**
- * Gets the field key
+ * Gets the field key.
* @return the field key
*/
public String getFieldKey() {
- return fieldKey;
+ return this.fieldKey;
}
/**
- * Gets the list of field keys
+ * Gets the list of field keys.
* @return the list of Strings
*/
public List getFieldKeys() {
- return fieldKeys;
+ return this.fieldKeys;
}
/**
- * Gets the list of keys of the Enum options
+ * Gets the list of keys of the Enum options.
* @return the list of Strings
*/
public List getEnumOptionKeys() {
- return enumOptionKeys;
+ return this.enumOptionKeys;
}
/**
- * Sets the operation
+ * Sets the operation.
* @param op the operation
*/
public void setOp(Operation op) {
@@ -728,7 +729,7 @@ public void setOp(Operation op) {
}
/**
- * Sets the data
+ * Sets the data.
* @param data the Field object representing the data
*/
public void setData(Field data) {
@@ -736,7 +737,7 @@ public void setData(Field data) {
}
/**
- * Sets the field key
+ * Sets the field key.
* @param fieldKey the key of the field
*/
public void setFieldKey(String fieldKey) {
@@ -744,7 +745,7 @@ public void setFieldKey(String fieldKey) {
}
/**
- * Sets the list of the field keys
+ * Sets the list of the field keys.
* @param fieldKeys the list of strings
*/
public void setFieldKeys(List fieldKeys) {
@@ -752,7 +753,7 @@ public void setFieldKeys(List fieldKeys) {
}
/**
- * Sets the list of the enum option keys
+ * Sets the list of the enum option keys.
* @param enumOptionKeys the list of Strings
*/
public void setEnumOptionKeys(List enumOptionKeys) {
@@ -773,53 +774,64 @@ void parseJSONMember(JsonObject.Member member) {
} else if (memberName.equals("fieldKey")) {
this.fieldKey = value.asString();
} else if (memberName.equals("fieldKeys")) {
- if(this.fieldKeys == null) {
- fieldKeys = new ArrayList();
+ if (this.fieldKeys == null) {
+ this.fieldKeys = new ArrayList();
} else {
- fieldKeys.clear();
+ this.fieldKeys.clear();
}
JsonArray array = value.asArray();
for (JsonValue jsonValue: array) {
- fieldKeys.add(jsonValue.asString());
+ this.fieldKeys.add(jsonValue.asString());
}
} else if (memberName.equals("enumOptionKeys")) {
- if(this.enumOptionKeys == null) {
- enumOptionKeys = new ArrayList();
+ if (this.enumOptionKeys == null) {
+ this.enumOptionKeys = new ArrayList();
} else {
- enumOptionKeys.clear();
+ this.enumOptionKeys.clear();
}
JsonArray array = value.asArray();
for (JsonValue jsonValue: array) {
- enumOptionKeys.add(jsonValue.asString());
+ this.enumOptionKeys.add(jsonValue.asString());
}
}
}
}
/**
- * Possible template operations
+ * Possible template operations.
*/
public enum Operation {
- //Adds an enum option at the end of the enum option list for the specified field
+ /**
+ * Adds an enum option at the end of the enum option list for the specified field
+ */
addEnumOption,
- //Adds a field at the end of the field list for the template
+ /**
+ * Adds a field at the end of the field list for the template
+ */
addField,
- //Edits any number of the base properties of a field: displayName, hidden, description
+ /**
+ * Edits any number of the base properties of a field: displayName, hidden, description
+ */
editField,
- //Edits any number of the base properties of a template: displayName, hidden
+ /**
+ * Edits any number of the base properties of a template: displayName, hidden
+ */
editTemplate,
- //Reorders the enum option list to match the requested enum option list
+ /**
+ * Reorders the enum option list to match the requested enum option list
+ */
reorderEnumOptions,
- //Reorders the field list to match the requested field list
+ /**
+ * Reorders the field list to match the requested field list
+ */
reorderFields
}
-
}
From 6f98eb52291edb34ab064875692aad9c47100d22 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 21 Feb 2017 16:18:07 -0800
Subject: [PATCH 045/119] Javadoc fixes
---
src/main/java/com/box/sdk/MetadataTemplate.java | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/main/java/com/box/sdk/MetadataTemplate.java b/src/main/java/com/box/sdk/MetadataTemplate.java
index 713bb9284..88fab8368 100644
--- a/src/main/java/com/box/sdk/MetadataTemplate.java
+++ b/src/main/java/com/box/sdk/MetadataTemplate.java
@@ -805,32 +805,32 @@ void parseJSONMember(JsonObject.Member member) {
public enum Operation {
/**
- * Adds an enum option at the end of the enum option list for the specified field
+ * Adds an enum option at the end of the enum option list for the specified field.
*/
addEnumOption,
/**
- * Adds a field at the end of the field list for the template
+ * Adds a field at the end of the field list for the template.
*/
addField,
/**
- * Edits any number of the base properties of a field: displayName, hidden, description
+ * Edits any number of the base properties of a field: displayName, hidden, description.
*/
editField,
/**
- * Edits any number of the base properties of a template: displayName, hidden
+ * Edits any number of the base properties of a template: displayName, hidden.
*/
editTemplate,
/**
- * Reorders the enum option list to match the requested enum option list
+ * Reorders the enum option list to match the requested enum option list.
*/
reorderEnumOptions,
/**
- * Reorders the field list to match the requested field list
+ * Reorders the field list to match the requested field list.
*/
reorderFields
}
From cec7b1fb3602da9e455aa355ec8c1266b22020a7 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 21 Feb 2017 16:20:43 -0800
Subject: [PATCH 046/119] breaking a long line in to two
---
src/test/java/com/box/sdk/MetadataTemplateTest.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/test/java/com/box/sdk/MetadataTemplateTest.java b/src/test/java/com/box/sdk/MetadataTemplateTest.java
index 40af0e967..4d42d65ef 100644
--- a/src/test/java/com/box/sdk/MetadataTemplateTest.java
+++ b/src/test/java/com/box/sdk/MetadataTemplateTest.java
@@ -275,7 +275,8 @@ public void createMetadataTemplateSucceeds() {
fields.add(ctField);
fields.add(fyField);
- MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise", "documentFlow03", "Document Flow 03", false, fields);
+ MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise",
+ "documentFlow03", "Document Flow 03", false, fields);
MetadataTemplate storedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
Assert.assertNotNull(storedTemplate);
From e921f840e5e82f8494ef4d3498d8364a0ead727f Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 21 Feb 2017 16:22:32 -0800
Subject: [PATCH 047/119] breaking a long line in to two
---
src/test/java/com/box/sdk/MetadataTemplateTest.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/test/java/com/box/sdk/MetadataTemplateTest.java b/src/test/java/com/box/sdk/MetadataTemplateTest.java
index 4d42d65ef..d568f9e9f 100644
--- a/src/test/java/com/box/sdk/MetadataTemplateTest.java
+++ b/src/test/java/com/box/sdk/MetadataTemplateTest.java
@@ -313,7 +313,8 @@ public void updateMetadataTemplateSucceeds() {
fieldOperations.add(newField);
- MetadataTemplate template = MetadataTemplate.updateMetadataTemplate(api, "enterprise", "documentFlow03", fieldOperations);
+ MetadataTemplate template = MetadataTemplate.updateMetadataTemplate(api,
+ "enterprise", "documentFlow03", fieldOperations);
Assert.assertNotNull(template);
MetadataTemplate updatedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
From 08252d5e7568bc1dc766d3f35c829d2c4e6f08c6 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Wed, 22 Feb 2017 09:27:28 -0800
Subject: [PATCH 048/119] 409 error handling
---
src/test/java/com/box/sdk/MetadataTemplateTest.java | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/test/java/com/box/sdk/MetadataTemplateTest.java b/src/test/java/com/box/sdk/MetadataTemplateTest.java
index d568f9e9f..7c5cc9d91 100644
--- a/src/test/java/com/box/sdk/MetadataTemplateTest.java
+++ b/src/test/java/com/box/sdk/MetadataTemplateTest.java
@@ -275,8 +275,14 @@ public void createMetadataTemplateSucceeds() {
fields.add(ctField);
fields.add(fyField);
- MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise",
- "documentFlow03", "Document Flow 03", false, fields);
+ try {
+ MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise",
+ "documentFlow03", "Document Flow 03", false, fields);
+ } catch (BoxAPIException apiEx) {
+ //Delete MetadataTemplate is yet to be supported. Due to that template might be existing already.
+ //This expects the conflict error. To check the MetadataTemplate creation, please replace the id.
+ Assert.assertEquals(apiEx.getResponseCode(), 409);
+ }
MetadataTemplate storedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
Assert.assertNotNull(storedTemplate);
From 3a42fb59456a289e859bc38cda411ece3018a6be Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Wed, 22 Feb 2017 09:29:26 -0800
Subject: [PATCH 049/119] Removing System.out.println
---
src/main/java/com/box/sdk/MetadataTemplate.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/main/java/com/box/sdk/MetadataTemplate.java b/src/main/java/com/box/sdk/MetadataTemplate.java
index 88fab8368..e7986a92a 100644
--- a/src/main/java/com/box/sdk/MetadataTemplate.java
+++ b/src/main/java/com/box/sdk/MetadataTemplate.java
@@ -202,7 +202,6 @@ public static MetadataTemplate createMetadataTemplate(BoxAPIConnection api, Stri
URL url = METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE.build(api.getBaseURL());
BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
request.setBody(jsonObject.toString());
- System.out.println("Result: " + jsonObject.toString());
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
@@ -270,7 +269,6 @@ public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, Stri
BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT");
request.setBody(array.toString());
- System.out.println("Array: " + array.toString());
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject responseJson = JsonObject.readFrom(response.getJSON());
From 0c63e33966fc0d82913c13cdc3ad63968bc72a69 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Wed, 22 Feb 2017 12:00:38 -0800
Subject: [PATCH 050/119] update metadatatemplate test fix
---
src/main/java/com/box/sdk/MetadataTemplate.java | 14 ++++++++------
.../java/com/box/sdk/MetadataTemplateTest.java | 13 +++++++++----
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/src/main/java/com/box/sdk/MetadataTemplate.java b/src/main/java/com/box/sdk/MetadataTemplate.java
index e7986a92a..3895b0526 100644
--- a/src/main/java/com/box/sdk/MetadataTemplate.java
+++ b/src/main/java/com/box/sdk/MetadataTemplate.java
@@ -640,12 +640,14 @@ void parseJSONMember(JsonObject.Member member) {
/**
* Posssible operations that can be performed in a Metadata template.
- *
- *
- *
- *
- *
- *
+ *
+ * - Add an enum option
+ * - Add a field
+ * - Edit a field
+ * - Edit template
+ * - Reorder the enum option
+ * - Reorder the field list
+ *
*/
public static class FieldOperation extends BoxJSONObject {
diff --git a/src/test/java/com/box/sdk/MetadataTemplateTest.java b/src/test/java/com/box/sdk/MetadataTemplateTest.java
index 7c5cc9d91..96e2ffb28 100644
--- a/src/test/java/com/box/sdk/MetadataTemplateTest.java
+++ b/src/test/java/com/box/sdk/MetadataTemplateTest.java
@@ -319,13 +319,18 @@ public void updateMetadataTemplateSucceeds() {
fieldOperations.add(newField);
- MetadataTemplate template = MetadataTemplate.updateMetadataTemplate(api,
- "enterprise", "documentFlow03", fieldOperations);
- Assert.assertNotNull(template);
+ try {
+ MetadataTemplate template = MetadataTemplate.updateMetadataTemplate(api,
+ "enterprise", "documentFlow03", fieldOperations);
+ Assert.assertNotNull(template);
+ } catch (BoxAPIException apiEx) {
+ //Delete MetadataTemplate is yet to be supported. Due to that template might be existing already.
+ //This 400 invalid request error if the field already exists.
+ Assert.assertEquals(apiEx.getResponseCode(), 400);
+ }
MetadataTemplate updatedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
List fields = updatedTemplate.getFields();
- Assert.assertEquals(4, fields.size());
boolean found = false;
for (MetadataTemplate.Field field: fields) {
From e0c228349391d56280f479d5df6511acca483a40 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 23 Feb 2017 10:42:21 -0800
Subject: [PATCH 051/119] Inital check-in for supercharged file upload create
session implementation
---
.../java/com/box/sdk/BoxAPIConnection.java | 19 +++
src/main/java/com/box/sdk/BoxFile.java | 47 +++++-
.../com/box/sdk/BoxFileUploadSession.java | 146 ++++++++++++++++++
src/main/java/com/box/sdk/BoxFolder.java | 19 +++
src/test/java/com/box/sdk/BoxFileTest.java | 48 ++++++
src/test/java/com/box/sdk/BoxFolderTest.java | 19 +++
6 files changed, 293 insertions(+), 5 deletions(-)
create mode 100644 src/main/java/com/box/sdk/BoxFileUploadSession.java
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index 79b472a84..0114ad76f 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -26,6 +26,7 @@ public class BoxAPIConnection {
private static final String TOKEN_URL_STRING = "https://api.box.com/oauth2/token";
private static final String DEFAULT_BASE_URL = "https://api.box.com/2.0/";
private static final String DEFAULT_BASE_UPLOAD_URL = "https://upload.box.com/api/2.0/";
+ private static final String DEFAULT_BASE_UPLOAD_SESSION_URL = "https://upload.app.box.com/api/2.1/";
/**
* The amount of buffer time, in milliseconds, to use when determining if an access token should be refreshed. For
@@ -52,6 +53,7 @@ public class BoxAPIConnection {
private String tokenURL;
private String baseURL;
private String baseUploadURL;
+ private String baseUploadSessionURL;
private boolean autoRefresh;
private int maxRequestAttempts;
private List listeners;
@@ -80,6 +82,7 @@ public BoxAPIConnection(String clientID, String clientSecret, String accessToken
this.tokenURL = TOKEN_URL_STRING;
this.baseURL = DEFAULT_BASE_URL;
this.baseUploadURL = DEFAULT_BASE_UPLOAD_URL;
+ this.baseUploadSessionURL = DEFAULT_BASE_UPLOAD_SESSION_URL;
this.autoRefresh = true;
this.maxRequestAttempts = DEFAULT_MAX_ATTEMPTS;
this.refreshLock = new ReentrantReadWriteLock();
@@ -237,6 +240,22 @@ public void setBaseUploadURL(String baseUploadURL) {
this.baseUploadURL = baseUploadURL;
}
+ /**
+ * Gets the base upload session URL that's used when performing supercharged uploads to Box.
+ * @return the base upload session URL.
+ */
+ public String getBaseUploadSessionURL() {
+ return this.baseUploadSessionURL;
+ }
+
+ /**
+ * Sets the base upload URL to be used when performing supercharged uploads to Box.
+ * @param baseUploadSessionURL a base upload URL.
+ */
+ public void setBaseUploadSessionURL(String baseUploadSessionURL) {
+ this.baseUploadSessionURL = baseUploadSessionURL;
+ }
+
/**
* Gets the user agent that's used when sending requests to the Box API.
* @return the user agent.
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 730b38ad9..46620e70f 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -6,11 +6,7 @@
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.List;
+import java.util.*;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
@@ -63,6 +59,11 @@ public enum ThumbnailFileType {
private static final URLTemplate GET_TASKS_URL_TEMPLATE = new URLTemplate("files/%s/tasks");
private static final URLTemplate GET_THUMBNAIL_PNG_TEMPLATE = new URLTemplate("files/%s/thumbnail.png");
private static final URLTemplate GET_THUMBNAIL_JPG_TEMPLATE = new URLTemplate("files/%s/thumbnail.jpg");
+ private static final URLTemplate UPLOAD_SESSION_URL_TEMPLATE = new URLTemplate("files/%s/upload-session");
+ private static final URLTemplate UPLOAD_SESSION_STATUS_URL_TEMPLATE = new URLTemplate(
+ "files/upload-session/%s/status");
+ private static final URLTemplate ABORT_UPLOAD_SESSION_URL_TEMPLATE = new URLTemplate("files/upload-session/%s");
+
private static final int BUFFER_SIZE = 8192;
@@ -856,6 +857,42 @@ public BoxFile.Info setCollections(BoxCollection... collections) {
return new Info(jsonObject);
}
+ public BoxFileUploadSession createUploadSession(long fileSize) {
+ String queryString = new QueryStringBuilder().appendParam("file_size", fileSize).toString();
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
+ queryString, this.getID());
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
+ request.addHeader("Content-Type", "application/json");
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(jsonObject);
+ }
+
+ public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(jsonObject);
+ }
+
+ public void abortUploadSession(String sessionId) {
+ URL url = ABORT_UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "DELETE");
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ }
+
/**
* Contains information about a BoxFile.
*/
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
new file mode 100644
index 000000000..0deee7543
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -0,0 +1,146 @@
+package com.box.sdk;
+
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ *
+ */
+public class BoxFileUploadSession extends BoxJSONObject {
+
+ private Date sessionExpiresAt;
+ private String uploadSessionId;
+ private long partSize;
+ private Endpoints sessionEndpoints;
+ private int totalParts;
+ private int partsProcessed;
+
+ public BoxFileUploadSession() {
+ super();
+ }
+
+ public BoxFileUploadSession(String json) {
+ super(json);
+ }
+
+ BoxFileUploadSession(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public Date getSessionExpiresAt() {
+ return sessionExpiresAt;
+ }
+
+ public String getUploadSessionId() {
+ return uploadSessionId;
+ }
+
+ public long getPartSize() {
+ return partSize;
+ }
+
+ public Endpoints getSessionEndpoints() {
+ return sessionEndpoints;
+ }
+
+ public int getTotalParts() {
+ return this.totalParts;
+ }
+
+ public int getPartsProcessed() {
+ return this.partsProcessed;
+ }
+
+ @Override
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("session_expires_at")) {
+ try {
+ String dateStr = value.asString();
+ this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
+ } catch (ParseException pe) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ } else if (memberName.equals("upload_session_id")) {
+ this.uploadSessionId = value.asString();
+ } else if (memberName.equals("part_size")) {
+ this.partSize = Double.valueOf(value.toString()).longValue();
+ } else if (memberName.equals("session_endpoints")) {
+ this.sessionEndpoints = new Endpoints(value.asObject());
+ } else if (memberName.equals("total_parts")) {
+ this.totalParts = value.asInt();
+ } if (memberName.equals("num_parts_processed")) {
+ this.partsProcessed = value.asInt();
+ }
+ }
+
+ public class Endpoints extends BoxJSONObject {
+ private URL listPartsEndpoint;
+ private URL commitEndpoint;
+ private URL uploadPartEndpoint;
+ private URL statusEndpoint;
+ private URL abortEndpoint;
+
+ public Endpoints() {
+ super();
+ }
+
+ public Endpoints(String json) {
+ super(json);
+ }
+
+ Endpoints(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public URL getListPartsEndpoint() {
+ return listPartsEndpoint;
+ }
+
+ public URL getCommitEndpoint() {
+ return commitEndpoint;
+ }
+
+ public URL getUploadPartEndpoint() {
+ return uploadPartEndpoint;
+ }
+
+ public URL getStatusEndpoint() {
+ return statusEndpoint;
+ }
+
+ public URL getAbortEndpoint() {
+ return abortEndpoint;
+ }
+
+ @Override
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ try {
+ if (memberName.equals("list_parts")) {
+ this.listPartsEndpoint = new URL(value.asString());
+ } else if (memberName.equals("commit")) {
+ this.commitEndpoint = new URL(value.asString());
+ } else if (memberName.equals("upload_part")) {
+ this.uploadPartEndpoint = new URL(value.asString());
+ } else if (memberName.equals("status")) {
+ this.statusEndpoint = new URL(value.asString());
+ } else if (memberName.equals("abort")) {
+ this.abortEndpoint = new URL(value.asString());
+ }
+ } catch(MalformedURLException mue) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index d07ee7039..13d6f0cc1 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -42,6 +42,7 @@ public class BoxFolder extends BoxItem implements Iterable {
private static final URLTemplate GET_ITEMS_URL = new URLTemplate("folders/%s/items/");
private static final URLTemplate SEARCH_URL_TEMPLATE = new URLTemplate("search");
private static final URLTemplate METADATA_URL_TEMPLATE = new URLTemplate("folders/%s/metadata/%s/%s");
+ private static final URLTemplate UPLOAD_SESSION_URL_TEMPLATE = new URLTemplate("files/upload-session");
/**
* Constructs a BoxFolder for a folder with a given ID.
@@ -728,6 +729,24 @@ public void deleteMetadata(String templateName, String scope) {
response.disconnect();
}
+ public BoxFileUploadSession createUploadSession(String folderId, long fileSize, String fileName) {
+
+ String queryString = new QueryStringBuilder()
+ .appendParam("folder_id", folderId)
+ .appendParam("file_size", fileSize)
+ .appendParam("file_name", fileName)
+ .toString();
+
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
+ queryString);
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(jsonObject);
+ }
+
/**
* Contains information about a BoxFolder.
*/
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index ca1a1ace3..2a87411e6 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -966,6 +966,54 @@ public void setCollectionsWithInfoSucceeds() {
uploadedFile.delete();
}
+ @Test
+ @Category(IntegrationTest.class)
+ public void uploadSessionSucceeds() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ String fileName = "[createUploadSessionSucceeds] Test File.txt";
+ String fileContent = "Test file";
+ byte[] fileBytes = fileContent.getBytes(StandardCharsets.UTF_8);
+
+ InputStream uploadStream = new ByteArrayInputStream(fileBytes);
+ BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
+ try {
+ BoxFileUploadSession session = uploadedFile.createUploadSession(10000000);
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+
+ //Verify the status of the session
+ getUploadSessionStatusSucceeds(uploadedFile, session.getUploadSessionId());
+
+ //Verify the delete session
+ abortUploadSessionStatusSucceeds(uploadedFile, session.getUploadSessionId());
+ } finally {
+ uploadedFile.delete();
+ }
+ }
+
+ private void getUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
+ BoxFileUploadSession session = file.getUploadSessionStatus(sessionId);
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+ Assert.assertNotNull(session.getTotalParts());
+ Assert.assertNotNull(session.getPartsProcessed());
+ }
+
+ private void abortUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
+ file.abortUploadSession(sessionId);
+
+ }
+
private static byte[] readAllBytes(String fileName) throws IOException {
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int) f.length()];
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index fdc7d75d3..c24f22642 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -1065,4 +1065,23 @@ public void sharedLinkInfoHasEffectiveAccess() {
folder.delete(true);
}
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void createUploadSessionSucceeds() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ BoxFileUploadSession session = rootFolder.createUploadSession("0", 1000000, "Test_File.txt");
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+ }
}
From 147345ca71b8f39345fa6329d8ce950cece2170b Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 23 Feb 2017 11:14:29 -0800
Subject: [PATCH 052/119] Abort session implementation
---
src/main/java/com/box/sdk/BoxFile.java | 6 +++---
src/test/java/com/box/sdk/BoxFileTest.java | 8 ++++++++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 46620e70f..835b52414 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -873,7 +873,7 @@ public BoxFileUploadSession createUploadSession(long fileSize) {
}
public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
- URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
+ URL url = UPLOAD_SESSION_STATUS_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
@@ -889,8 +889,8 @@ public void abortUploadSession(String sessionId) {
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "DELETE");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ BoxAPIResponse response = (BoxAPIResponse) request.send();
+ System.out.println("Abort session status: " + response.getResponseCode());
}
/**
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 2a87411e6..19ad7a168 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -1012,6 +1012,14 @@ private void getUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
private void abortUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
file.abortUploadSession(sessionId);
+ try {
+ BoxFileUploadSession session = file.getUploadSessionStatus(sessionId);
+
+ //If the session is aborted, this line should not be executed.
+ Assert.assertFalse("Upload session is not deleted", true);
+ } catch(BoxAPIException apiEx) {
+ Assert.assertEquals(apiEx.getResponseCode(), 404);
+ }
}
private static byte[] readAllBytes(String fileName) throws IOException {
From 054cb0118d95d8ab9e168324b0bab14d601bc807 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 23 Feb 2017 14:50:51 -0800
Subject: [PATCH 053/119] Added getAllMetadata Integration Test Upped version
to 2.3.1-SNAPSHOT
---
build.gradle | 2 +-
.../java/com/box/sdk/BoxAPIConnection.java | 2 +-
.../com/box/sdk/MetadataTemplateTest.java | 78 +++++++++++++++++++
3 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index c03819a83..b18bfdb48 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ sourceCompatibility = 1.6
group = 'com.box'
archivesBaseName = 'box-java-sdk'
-version = '2.3.0'
+version = '2.3.1-SNAPSHOT'
repositories {
mavenCentral()
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index 79b472a84..84e7bdf68 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -83,7 +83,7 @@ public BoxAPIConnection(String clientID, String clientSecret, String accessToken
this.autoRefresh = true;
this.maxRequestAttempts = DEFAULT_MAX_ATTEMPTS;
this.refreshLock = new ReentrantReadWriteLock();
- this.userAgent = "Box Java SDK v2.3.0";
+ this.userAgent = "Box Java SDK v2.3.1";
this.listeners = new ArrayList();
}
diff --git a/src/test/java/com/box/sdk/MetadataTemplateTest.java b/src/test/java/com/box/sdk/MetadataTemplateTest.java
index 96e2ffb28..4991d90b0 100644
--- a/src/test/java/com/box/sdk/MetadataTemplateTest.java
+++ b/src/test/java/com/box/sdk/MetadataTemplateTest.java
@@ -1,5 +1,7 @@
package com.box.sdk;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -282,6 +284,7 @@ public void createMetadataTemplateSucceeds() {
//Delete MetadataTemplate is yet to be supported. Due to that template might be existing already.
//This expects the conflict error. To check the MetadataTemplate creation, please replace the id.
Assert.assertEquals(apiEx.getResponseCode(), 409);
+ Assert.assertTrue(apiEx.getResponse().contains("Template key already exists in this scope"));
}
MetadataTemplate storedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
@@ -345,4 +348,79 @@ public void updateMetadataTemplateSucceeds() {
Assert.assertEquals(found, true);
}
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void getAllMetadataSucceeds() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ String fileName = "[getAllMetadataSucceeds] Test File.txt";
+ byte[] fileBytes = "Non-empty string".getBytes(StandardCharsets.UTF_8);
+
+ InputStream uploadStream = new ByteArrayInputStream(fileBytes);
+ BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
+
+ uploadedFile.createMetadata(new Metadata().add("/firstName", "John").add("/lastName", "Smith"));
+ Metadata check1 = uploadedFile.getMetadata();
+ Assert.assertNotNull(check1);
+ Assert.assertEquals("John", check1.get("/firstName"));
+ Assert.assertEquals("Smith", check1.get("/lastName"));
+
+ MetadataTemplate.Field ctField = new MetadataTemplate.Field();
+ ctField.setType("string");
+ ctField.setKey("customerTeam");
+ ctField.setDisplayName("Customer Team");
+
+ MetadataTemplate.Field fyField = new MetadataTemplate.Field();
+ fyField.setType("enum");
+ fyField.setKey("fy");
+ fyField.setDisplayName("FY");
+
+ List options = new ArrayList();
+ options.add("FY16");
+ options.add("FY17");
+ fyField.setOptions(options);
+
+ List fields = new ArrayList();
+ fields.add(ctField);
+ fields.add(fyField);
+
+ try {
+ MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise",
+ "documentFlow03", "Document Flow 03", false, fields);
+ } catch (BoxAPIException apiEx) {
+ //Delete MetadataTemplate is yet to be supported. Due to that template might be existing already.
+ //This expects the conflict error.
+ Assert.assertEquals(apiEx.getResponseCode(), 409);
+ Assert.assertTrue(apiEx.getResponse().contains("Template key already exists in this scope"));
+ }
+
+ MetadataTemplate storedTemplate = MetadataTemplate.getMetadataTemplate(api, "documentFlow03");
+ Assert.assertNotNull(storedTemplate);
+
+ Metadata customerMetaData = new Metadata();
+ customerMetaData.add("/customerTeam", "MyTeam");
+ customerMetaData.add("/fy", "FY17");
+
+ uploadedFile.createMetadata("documentFlow03", "enterprise", customerMetaData);
+
+ Iterable allMetadata = uploadedFile.getAllMetadata("/firstName", "/lastName");
+ Assert.assertNotNull(allMetadata);
+ Iterator iter = allMetadata.iterator();
+ int numTemplates = 0;
+ while (iter.hasNext()) {
+ Metadata metadata = iter.next();
+ numTemplates++;
+ if (metadata.getTemplateName().equals("properties")) {
+ Assert.assertEquals(metadata.get("/firstName"), "John");
+ Assert.assertEquals(metadata.get("/lastName"), "Smith");
+ }
+ if (metadata.getTemplateName().equals("documentFlow03")) {
+ Assert.assertEquals(metadata.get("/customerTeam"), "MyTeam");
+ Assert.assertEquals(metadata.get("/fy"), "FY17");
+ }
+ }
+ Assert.assertEquals(numTemplates, 2);
+ uploadedFile.delete();
+ }
}
From 3493c8c030f1a11844e503d109f9187ceb25fadb Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Thu, 23 Feb 2017 15:36:54 -0800
Subject: [PATCH 054/119] Updated version number to 2.4.0 since we have a new
createMetadata endpoint
---
build.gradle | 2 +-
src/main/java/com/box/sdk/BoxAPIConnection.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index b18bfdb48..76c9fde6d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ sourceCompatibility = 1.6
group = 'com.box'
archivesBaseName = 'box-java-sdk'
-version = '2.3.1-SNAPSHOT'
+version = '2.4.0-SNAPSHOT'
repositories {
mavenCentral()
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index 84e7bdf68..2c54aeb6e 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -83,7 +83,7 @@ public BoxAPIConnection(String clientID, String clientSecret, String accessToken
this.autoRefresh = true;
this.maxRequestAttempts = DEFAULT_MAX_ATTEMPTS;
this.refreshLock = new ReentrantReadWriteLock();
- this.userAgent = "Box Java SDK v2.3.1";
+ this.userAgent = "Box Java SDK v2.4.0";
this.listeners = new ArrayList();
}
From 17510414a2ef3ae6772b5dd81d013cdde6f46481 Mon Sep 17 00:00:00 2001
From: Harish Gokavarapu
Date: Thu, 23 Feb 2017 17:32:48 -0800
Subject: [PATCH 055/119] First attempt at generalising FileUploadSession
---
src/main/java/com/box/sdk/BoxAPIRequest.java | 6 +
src/main/java/com/box/sdk/BoxFile.java | 23 +---
.../com/box/sdk/BoxFileUploadSession.java | 108 +++++++++++++-----
src/main/java/com/box/sdk/BoxFolder.java | 2 +-
.../java/com/box/sdk/http/ContentType.java | 8 ++
.../java/com/box/sdk/http/HttpHeaders.java | 12 ++
.../java/com/box/sdk/http/HttpMethod.java | 8 ++
7 files changed, 113 insertions(+), 54 deletions(-)
create mode 100644 src/main/java/com/box/sdk/http/ContentType.java
create mode 100644 src/main/java/com/box/sdk/http/HttpHeaders.java
create mode 100644 src/main/java/com/box/sdk/http/HttpMethod.java
diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java
index 11e779cfa..5e15bd372 100644
--- a/src/main/java/com/box/sdk/BoxAPIRequest.java
+++ b/src/main/java/com/box/sdk/BoxAPIRequest.java
@@ -1,5 +1,7 @@
package com.box.sdk;
+import com.box.sdk.http.HttpMethod;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -76,6 +78,10 @@ public BoxAPIRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Accept-Charset", "utf-8");
}
+ public BoxAPIRequest(BoxAPIConnection api, URL uploadPartEndpoint, HttpMethod post) {
+ this(api, uploadPartEndpoint, post.name());
+ }
+
/**
* Adds an HTTP header to this request.
* @param key the header key.
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 835b52414..0eda0637c 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -869,28 +869,7 @@ public BoxFileUploadSession createUploadSession(long fileSize) {
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(jsonObject);
- }
-
- public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
- URL url = UPLOAD_SESSION_STATUS_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
-
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
-
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- System.out.println("Response: " + jsonObject);
-
- return new BoxFileUploadSession(jsonObject);
- }
-
- public void abortUploadSession(String sessionId) {
- URL url = ABORT_UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
-
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "DELETE");
-
- BoxAPIResponse response = (BoxAPIResponse) request.send();
- System.out.println("Abort session status: " + response.getResponseCode());
+ return new BoxFileUploadSession(this.getAPI(), jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 0deee7543..fc8032f71 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -1,36 +1,51 @@
package com.box.sdk;
+import com.box.sdk.http.ContentType;
+import com.box.sdk.http.HttpHeaders;
+import com.box.sdk.http.HttpMethod;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.Date;
-import java.util.Map;
/**
*
*/
public class BoxFileUploadSession extends BoxJSONObject {
+ private BoxAPIConnection api;
private Date sessionExpiresAt;
private String uploadSessionId;
- private long partSize;
private Endpoints sessionEndpoints;
+ private long partSize;
private int totalParts;
private int partsProcessed;
- public BoxFileUploadSession() {
- super();
+ private BoxAPIConnection getAPI() {
+ return api;
}
- public BoxFileUploadSession(String json) {
- super(json);
+ private void setAPI(BoxAPIConnection api) {
+ this.api = api;
}
- BoxFileUploadSession(JsonObject jsonObject) {
- super(jsonObject);
+ public BoxFileUploadSession getResource() {
+ return BoxFileUploadSession.this;
+ }
+
+ public int getTotalParts() {
+ return this.totalParts;
+ }
+
+ public int getPartsProcessed() {
+ return this.partsProcessed;
}
public Date getSessionExpiresAt() {
@@ -41,31 +56,27 @@ public String getUploadSessionId() {
return uploadSessionId;
}
- public long getPartSize() {
- return partSize;
- }
-
public Endpoints getSessionEndpoints() {
return sessionEndpoints;
}
- public int getTotalParts() {
- return this.totalParts;
+ public long getPartSize() {
+ return partSize;
}
- public int getPartsProcessed() {
- return this.partsProcessed;
+ public BoxFileUploadSession(BoxAPIConnection api, JsonObject jsonObject) {
+ super(jsonObject);
+ this.api = api;
}
- @Override
protected void parseJSONMember(JsonObject.Member member) {
String memberName = member.getName();
JsonValue value = member.getValue();
if (memberName.equals("session_expires_at")) {
- try {
+ try {
String dateStr = value.asString();
- this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
+ this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
} catch (ParseException pe) {
assert false : "A ParseException indicates a bug in the SDK.";
}
@@ -83,23 +94,23 @@ protected void parseJSONMember(JsonObject.Member member) {
}
public class Endpoints extends BoxJSONObject {
- private URL listPartsEndpoint;
- private URL commitEndpoint;
- private URL uploadPartEndpoint;
- private URL statusEndpoint;
- private URL abortEndpoint;
+ private URL listPartsEndpoint;
+ private URL commitEndpoint;
+ private URL uploadPartEndpoint;
+ private URL statusEndpoint;
+ private URL abortEndpoint;
public Endpoints() {
- super();
- }
+ super();
+ }
- public Endpoints(String json) {
+ public Endpoints(String json) {
super(json);
- }
+ }
- Endpoints(JsonObject jsonObject) {
+ Endpoints(JsonObject jsonObject) {
super(jsonObject);
- }
+ }
public URL getListPartsEndpoint() {
return listPartsEndpoint;
@@ -128,7 +139,7 @@ protected void parseJSONMember(JsonObject.Member member) {
JsonValue value = member.getValue();
try {
if (memberName.equals("list_parts")) {
- this.listPartsEndpoint = new URL(value.asString());
+ this.listPartsEndpoint = new URL(value.asString());
} else if (memberName.equals("commit")) {
this.commitEndpoint = new URL(value.asString());
} else if (memberName.equals("upload_part")) {
@@ -143,4 +154,39 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
}
+
+ /**
+ *
+ */
+ public void uploadPart(String xBoxPartId, byte[] bytes, long offset, Long partSize, long totalSizeOfFile, String contentRangeUnits) throws MalformedURLException, NoSuchAlgorithmException {
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), this.getSessionEndpoints().getUploadPartEndpoint(), HttpMethod.POST);
+ request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
+ request.addHeader(HttpHeaders.X_BOX_PART_ID, xBoxPartId);
+ byte[] digestBytes = MessageDigest.getInstance("SHA1").digest(bytes);
+ String digest = Base64.encode(digestBytes);
+ request.addHeader("Digest", "sha=" + digest);
+ if(null == contentRangeUnits){
+ contentRangeUnits = "bytes";
+ }
+ request.addHeader(HttpHeaders.CONTENT_RANGE, contentRangeUnits+" "+offset+"-"+(offset+partSize-1)+"/"+totalSizeOfFile);
+ request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
+ request.setBody(new ByteArrayInputStream(bytes));
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ }
+
+ public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getStatusEndpoint(), "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(this.getAPI(), jsonObject);
+ }
+
+
+ public void abortUploadSession(String sessionId) {
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getAbortEndpoint(), "DELETE");
+ BoxAPIResponse response = (BoxAPIResponse) request.send();
+ System.out.println("Abort session status: " + response.getResponseCode());
+ }
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 13d6f0cc1..c6df62074 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -744,7 +744,7 @@ public BoxFileUploadSession createUploadSession(String folderId, long fileSize,
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(jsonObject);
+ return new BoxFileUploadSession(this.getAPI(), jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/http/ContentType.java b/src/main/java/com/box/sdk/http/ContentType.java
new file mode 100644
index 000000000..4f6b4ebb4
--- /dev/null
+++ b/src/main/java/com/box/sdk/http/ContentType.java
@@ -0,0 +1,8 @@
+package com.box.sdk.http;
+
+/**
+ *
+ */
+public class ContentType {
+ public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+}
diff --git a/src/main/java/com/box/sdk/http/HttpHeaders.java b/src/main/java/com/box/sdk/http/HttpHeaders.java
new file mode 100644
index 000000000..fa9b12404
--- /dev/null
+++ b/src/main/java/com/box/sdk/http/HttpHeaders.java
@@ -0,0 +1,12 @@
+package com.box.sdk.http;
+
+/**
+ *
+ */
+public class HttpHeaders {
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String CONTENT_LENGTH = "Content-Length";
+ public static final String CONTENT_RANGE = "Content-Range";
+ public static final String DIGEST = "Digest";
+ public static final String X_BOX_PART_ID = "X-Box-Part-Id";
+}
diff --git a/src/main/java/com/box/sdk/http/HttpMethod.java b/src/main/java/com/box/sdk/http/HttpMethod.java
new file mode 100644
index 000000000..4121191b5
--- /dev/null
+++ b/src/main/java/com/box/sdk/http/HttpMethod.java
@@ -0,0 +1,8 @@
+package com.box.sdk.http;
+
+/**
+ *
+ */
+public enum HttpMethod {
+ GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
+}
From 7dcb943bf789e7af96854e25ea166db0c6f9160c Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Sun, 26 Feb 2017 19:20:42 -0800
Subject: [PATCH 056/119] Upload implementation changes & code refactoring to
match existing code style
---
src/main/java/com/box/sdk/BoxAPIRequest.java | 8 +-
src/main/java/com/box/sdk/BoxFile.java | 12 +-
.../com/box/sdk/BoxFileUploadSession.java | 436 +++++++++++-------
src/main/java/com/box/sdk/BoxFolder.java | 7 +-
src/main/java/com/box/sdk/BoxJSONRequest.java | 14 +
src/main/java/com/box/sdk/BoxResource.java | 2 +
.../java/com/box/sdk/http/ContentType.java | 10 +-
.../java/com/box/sdk/http/HttpHeaders.java | 17 +-
.../java/com/box/sdk/http/HttpMethod.java | 3 +-
9 files changed, 314 insertions(+), 195 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java
index 5e15bd372..de7b3585a 100644
--- a/src/main/java/com/box/sdk/BoxAPIRequest.java
+++ b/src/main/java/com/box/sdk/BoxAPIRequest.java
@@ -1,7 +1,5 @@
package com.box.sdk;
-import com.box.sdk.http.HttpMethod;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -16,6 +14,8 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import com.box.sdk.http.HttpMethod;
+
/**
* Used to make HTTP requests to the Box API.
*
@@ -78,8 +78,8 @@ public BoxAPIRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Accept-Charset", "utf-8");
}
- public BoxAPIRequest(BoxAPIConnection api, URL uploadPartEndpoint, HttpMethod post) {
- this(api, uploadPartEndpoint, post.name());
+ public BoxAPIRequest(BoxAPIConnection api, URL uploadPartEndpoint, HttpMethod method) {
+ this(api, uploadPartEndpoint, method.name());
}
/**
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 0eda0637c..bda7859e5 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -6,7 +6,11 @@
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.List;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
@@ -857,7 +861,7 @@ public BoxFile.Info setCollections(BoxCollection... collections) {
return new Info(jsonObject);
}
- public BoxFileUploadSession createUploadSession(long fileSize) {
+ public BoxFileUploadSession.Info createUploadSession(long fileSize) {
String queryString = new QueryStringBuilder().appendParam("file_size", fileSize).toString();
URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
queryString, this.getID());
@@ -869,7 +873,9 @@ public BoxFileUploadSession createUploadSession(long fileSize) {
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(this.getAPI(), jsonObject);
+ String sessionId = jsonObject.get("upload_session_id").asString();
+ BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId);
+ return session.new Info(jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index fc8032f71..7cae4c53f 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -1,11 +1,5 @@
package com.box.sdk;
-import com.box.sdk.http.ContentType;
-import com.box.sdk.http.HttpHeaders;
-import com.box.sdk.http.HttpMethod;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -15,178 +9,266 @@
import java.text.ParseException;
import java.util.Date;
+import com.box.sdk.http.ContentType;
+import com.box.sdk.http.HttpHeaders;
+import com.box.sdk.http.HttpMethod;
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
/**
*
*/
-public class BoxFileUploadSession extends BoxJSONObject {
-
- private BoxAPIConnection api;
- private Date sessionExpiresAt;
- private String uploadSessionId;
- private Endpoints sessionEndpoints;
- private long partSize;
- private int totalParts;
- private int partsProcessed;
-
- private BoxAPIConnection getAPI() {
- return api;
- }
-
- private void setAPI(BoxAPIConnection api) {
- this.api = api;
- }
-
- public BoxFileUploadSession getResource() {
- return BoxFileUploadSession.this;
- }
-
- public int getTotalParts() {
- return this.totalParts;
- }
-
- public int getPartsProcessed() {
- return this.partsProcessed;
- }
-
- public Date getSessionExpiresAt() {
- return sessionExpiresAt;
- }
-
- public String getUploadSessionId() {
- return uploadSessionId;
- }
-
- public Endpoints getSessionEndpoints() {
- return sessionEndpoints;
- }
-
- public long getPartSize() {
- return partSize;
- }
-
- public BoxFileUploadSession(BoxAPIConnection api, JsonObject jsonObject) {
- super(jsonObject);
- this.api = api;
- }
-
- protected void parseJSONMember(JsonObject.Member member) {
-
- String memberName = member.getName();
- JsonValue value = member.getValue();
- if (memberName.equals("session_expires_at")) {
- try {
- String dateStr = value.asString();
- this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
- } catch (ParseException pe) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- } else if (memberName.equals("upload_session_id")) {
- this.uploadSessionId = value.asString();
- } else if (memberName.equals("part_size")) {
- this.partSize = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("session_endpoints")) {
- this.sessionEndpoints = new Endpoints(value.asObject());
- } else if (memberName.equals("total_parts")) {
- this.totalParts = value.asInt();
- } if (memberName.equals("num_parts_processed")) {
- this.partsProcessed = value.asInt();
- }
- }
-
- public class Endpoints extends BoxJSONObject {
- private URL listPartsEndpoint;
- private URL commitEndpoint;
- private URL uploadPartEndpoint;
- private URL statusEndpoint;
- private URL abortEndpoint;
-
- public Endpoints() {
- super();
- }
-
- public Endpoints(String json) {
- super(json);
- }
-
- Endpoints(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- public URL getListPartsEndpoint() {
- return listPartsEndpoint;
- }
-
- public URL getCommitEndpoint() {
- return commitEndpoint;
- }
-
- public URL getUploadPartEndpoint() {
- return uploadPartEndpoint;
- }
-
- public URL getStatusEndpoint() {
- return statusEndpoint;
- }
-
- public URL getAbortEndpoint() {
- return abortEndpoint;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
-
- String memberName = member.getName();
- JsonValue value = member.getValue();
- try {
- if (memberName.equals("list_parts")) {
- this.listPartsEndpoint = new URL(value.asString());
- } else if (memberName.equals("commit")) {
- this.commitEndpoint = new URL(value.asString());
- } else if (memberName.equals("upload_part")) {
- this.uploadPartEndpoint = new URL(value.asString());
- } else if (memberName.equals("status")) {
- this.statusEndpoint = new URL(value.asString());
- } else if (memberName.equals("abort")) {
- this.abortEndpoint = new URL(value.asString());
- }
- } catch(MalformedURLException mue) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
- }
-
- /**
- *
- */
- public void uploadPart(String xBoxPartId, byte[] bytes, long offset, Long partSize, long totalSizeOfFile, String contentRangeUnits) throws MalformedURLException, NoSuchAlgorithmException {
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), this.getSessionEndpoints().getUploadPartEndpoint(), HttpMethod.POST);
- request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
- request.addHeader(HttpHeaders.X_BOX_PART_ID, xBoxPartId);
- byte[] digestBytes = MessageDigest.getInstance("SHA1").digest(bytes);
- String digest = Base64.encode(digestBytes);
- request.addHeader("Digest", "sha=" + digest);
- if(null == contentRangeUnits){
- contentRangeUnits = "bytes";
- }
- request.addHeader(HttpHeaders.CONTENT_RANGE, contentRangeUnits+" "+offset+"-"+(offset+partSize-1)+"/"+totalSizeOfFile);
- request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
- request.setBody(new ByteArrayInputStream(bytes));
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- }
-
- public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getStatusEndpoint(), "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- System.out.println("Response: " + jsonObject);
-
- return new BoxFileUploadSession(this.getAPI(), jsonObject);
- }
-
-
- public void abortUploadSession(String sessionId) {
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getAbortEndpoint(), "DELETE");
- BoxAPIResponse response = (BoxAPIResponse) request.send();
- System.out.println("Abort session status: " + response.getResponseCode());
- }
+public class BoxFileUploadSession extends BoxResource {
+
+ private static final String DIGEST_HEADER_PREFIX_SHA = "sha=";
+ private static final String DIGEST_ALGORITHM_SHA1 = "SHA1";
+
+ private static final String MARKER_QUERY_STRING = "marker";
+ private static final String LIMIT_QUERY_STRING = "limit";
+
+ private Info sessionInfo;
+
+ BoxFileUploadSession(BoxAPIConnection api, String id) {
+ super(api, id);
+ }
+
+ public class Info extends BoxResource.Info {
+ private BoxAPIConnection api;
+ private Date sessionExpiresAt;
+ private String uploadSessionId;
+ private Endpoints sessionEndpoints;
+ private long partSize;
+ private int totalParts;
+ private int partsProcessed;
+
+ /**
+ * Constructs an empty Info object.
+ */
+ public Info() {
+ super();
+ BoxFileUploadSession.this.sessionInfo = this;
+ }
+
+ /**
+ * Constructs an Info object by parsing information from a JSON string.
+ * @param json the JSON string to parse.
+ */
+ public Info(String json) {
+ super(json);
+ BoxFileUploadSession.this.sessionInfo = this;
+ }
+
+ /**
+ * Constructs an Info object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ Info(JsonObject jsonObject) {
+ super(jsonObject);
+ BoxFileUploadSession.this.sessionInfo = this;
+ }
+
+ private BoxAPIConnection getAPI() {
+ return this.api;
+ }
+
+ private void setAPI(BoxAPIConnection api) {
+ this.api = api;
+ }
+
+ public BoxFileUploadSession getResource() {
+ return BoxFileUploadSession.this;
+ }
+
+ public int getTotalParts() {
+ return this.totalParts;
+ }
+
+ public int getPartsProcessed() {
+ return this.partsProcessed;
+ }
+
+ public Date getSessionExpiresAt() {
+ return this.sessionExpiresAt;
+ }
+
+ public String getUploadSessionId() {
+ return this.uploadSessionId;
+ }
+
+ public Endpoints getSessionEndpoints() {
+ return this.sessionEndpoints;
+ }
+
+ public long getPartSize() {
+ return this.partSize;
+ }
+
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("session_expires_at")) {
+ try {
+ String dateStr = value.asString();
+ this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length() - 1) + "-00:00");
+ } catch (ParseException pe) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ } else if (memberName.equals("upload_session_id")) {
+ this.uploadSessionId = value.asString();
+ } else if (memberName.equals("part_size")) {
+ this.partSize = Double.valueOf(value.toString()).longValue();
+ } else if (memberName.equals("session_endpoints")) {
+ this.sessionEndpoints = new Endpoints(value.asObject());
+ } else if (memberName.equals("total_parts")) {
+ this.totalParts = value.asInt();
+ } else if (memberName.equals("num_parts_processed")) {
+ this.partsProcessed = value.asInt();
+ }
+ }
+ }
+
+ public class Endpoints extends BoxJSONObject {
+ private URL listPartsEndpoint;
+ private URL commitEndpoint;
+ private URL uploadPartEndpoint;
+ private URL statusEndpoint;
+ private URL abortEndpoint;
+
+ public Endpoints() {
+ super();
+ }
+
+ public Endpoints(String json) {
+ super(json);
+ }
+
+ Endpoints(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public URL getListPartsEndpoint() {
+ return this.listPartsEndpoint;
+ }
+
+ public URL getCommitEndpoint() {
+ return this.commitEndpoint;
+ }
+
+ public URL getUploadPartEndpoint() {
+ return this.uploadPartEndpoint;
+ }
+
+ public URL getStatusEndpoint() {
+ return this.statusEndpoint;
+ }
+
+ public URL getAbortEndpoint() {
+ return this.abortEndpoint;
+ }
+
+ @Override
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ try {
+ if (memberName.equals("list_parts")) {
+ this.listPartsEndpoint = new URL(value.asString());
+ } else if (memberName.equals("commit")) {
+ this.commitEndpoint = new URL(value.asString());
+ } else if (memberName.equals("upload_part")) {
+ this.uploadPartEndpoint = new URL(value.asString());
+ } else if (memberName.equals("status")) {
+ this.statusEndpoint = new URL(value.asString());
+ } else if (memberName.equals("abort")) {
+ this.abortEndpoint = new URL(value.asString());
+ }
+ } catch (MalformedURLException mue) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
+ }
+
+ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSize, long totalSizeOfFile)
+ throws MalformedURLException, NoSuchAlgorithmException {
+
+ URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), uploadPartURL, HttpMethod.POST);
+ request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
+ request.addHeader(HttpHeaders.X_BOX_PART_ID, partId);
+
+ byte[] digestBytes = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1).digest(bytes);
+ String digest = Base64.encode(digestBytes);
+ request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
+ request.addHeader(HttpHeaders.CONTENT_RANGE,
+ "bytes " + startRange + "-" + (startRange + partSize - 1) + "/" + totalSizeOfFile);
+ request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
+
+ request.setBody(new ByteArrayInputStream(bytes));
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ }
+
+ public int listParts(String sessionId, int marker, int limit) {
+ URL listPartsURL = this.sessionInfo.getSessionEndpoints().getListPartsEndpoint();
+ URLTemplate template = new URLTemplate(listPartsURL.toString());
+
+ String queryString = new QueryStringBuilder()
+ .appendParam(MARKER_QUERY_STRING, marker)
+ .appendParam(LIMIT_QUERY_STRING, limit)
+ .toString();
+ URL url = template.buildWithQuery("", queryString);
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, HttpMethod.GET);
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+// System.out.println("Response: " + jsonObject);
+
+ return response.getResponseCode();
+ }
+
+ public int commit(String sessionId, String digest, JsonObject jsonObject, String ifMatch, String ifNonMatch) {
+ URL commitURL = this.sessionInfo.getSessionEndpoints().getCommitEndpoint();
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), commitURL, HttpMethod.POST);
+ request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
+ request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON);
+
+ request.setBody(jsonObject.toString());
+
+ BoxAPIResponse response = request.send();
+ //System.out.println("Response: " + response.getResponseCode());
+
+ try {
+ InputStream stream = response.getBody();
+ int value = stream.read();
+ StringBuffer buffer = new StringBuffer();
+ while (value != -1) {
+ buffer.append(value);
+ value = stream.read();
+ }
+ //System.out.println("Response: " + buffer.toString());
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ return response.getResponseCode();
+ }
+
+ public BoxFileUploadSession.Info getUploadSessionStatus() {
+ URL statusURL = this.sessionInfo.getSessionEndpoints().getStatusEndpoint();
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), statusURL, HttpMethod.GET);
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+
+ this.sessionInfo.update(jsonObject);
+
+ return this.sessionInfo;
+ }
+
+ public void abortUploadSession() {
+ URL abortURL = this.sessionInfo.getSessionEndpoints().getAbortEndpoint();
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), abortURL, "DELETE");
+ BoxAPIResponse response = request.send();
+ //System.out.println("Abort session status: " + response.getResponseCode());
+ }
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index c6df62074..c2d933c78 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -729,7 +729,7 @@ public void deleteMetadata(String templateName, String scope) {
response.disconnect();
}
- public BoxFileUploadSession createUploadSession(String folderId, long fileSize, String fileName) {
+ public BoxFileUploadSession.Info createUploadSession(String folderId, long fileSize, String fileName) {
String queryString = new QueryStringBuilder()
.appendParam("folder_id", folderId)
@@ -744,7 +744,10 @@ public BoxFileUploadSession createUploadSession(String folderId, long fileSize,
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(this.getAPI(), jsonObject);
+ String sessionId = jsonObject.get("upload_session_id").asString();
+ BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId);
+
+ return session.new Info(jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/BoxJSONRequest.java b/src/main/java/com/box/sdk/BoxJSONRequest.java
index c67e51a40..1c86b1241 100644
--- a/src/main/java/com/box/sdk/BoxJSONRequest.java
+++ b/src/main/java/com/box/sdk/BoxJSONRequest.java
@@ -2,6 +2,8 @@
import java.net.URL;
+import com.box.sdk.http.HttpMethod;
+
/**
* Used to make HTTP requests containing JSON to the Box API.
*
@@ -23,6 +25,18 @@ public BoxJSONRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Content-Type", "application/json");
}
+ /**
+ * Constructs an authenticated BoxJSONRequest using a provided BoxAPIConnection.
+ * @param api an API connection for authenticating the request.
+ * @param url the URL of the request.
+ * @param method the HTTP method of the request.
+ */
+ public BoxJSONRequest(BoxAPIConnection api, URL url, HttpMethod method) {
+ super(api, url, method);
+
+ this.addHeader("Content-Type", "application/json");
+ }
+
/**
* Sets the body of this request to a given JSON string.
* @param body the JSON string to use as the body.
diff --git a/src/main/java/com/box/sdk/BoxResource.java b/src/main/java/com/box/sdk/BoxResource.java
index 1dc4299bb..4deb7343e 100644
--- a/src/main/java/com/box/sdk/BoxResource.java
+++ b/src/main/java/com/box/sdk/BoxResource.java
@@ -60,6 +60,8 @@ private static Map> initResourceClassByType
result.put(getResourceType(BoxLegalHoldPolicy.class), BoxLegalHoldPolicy.class);
result.put(getResourceType(BoxLegalHoldAssignment.class), BoxLegalHoldAssignment.class);
result.put(getResourceType(BoxFileVersionLegalHold.class), BoxFileVersionLegalHold.class);
+ result.put(getResourceType(BoxFileUploadSession.class), BoxFileUploadSession.class);
+
return Collections.unmodifiableMap(result);
}
diff --git a/src/main/java/com/box/sdk/http/ContentType.java b/src/main/java/com/box/sdk/http/ContentType.java
index 4f6b4ebb4..c16312e1d 100644
--- a/src/main/java/com/box/sdk/http/ContentType.java
+++ b/src/main/java/com/box/sdk/http/ContentType.java
@@ -3,6 +3,12 @@
/**
*
*/
-public class ContentType {
- public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+public final class ContentType {
+
+ public static final String APPLICATION_JSON = "application/json";
+ public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+
+ //Prevents instantiation
+ private ContentType() {
+ }
}
diff --git a/src/main/java/com/box/sdk/http/HttpHeaders.java b/src/main/java/com/box/sdk/http/HttpHeaders.java
index fa9b12404..ecb942aa1 100644
--- a/src/main/java/com/box/sdk/http/HttpHeaders.java
+++ b/src/main/java/com/box/sdk/http/HttpHeaders.java
@@ -3,10 +3,15 @@
/**
*
*/
-public class HttpHeaders {
- public static final String CONTENT_TYPE = "Content-Type";
- public static final String CONTENT_LENGTH = "Content-Length";
- public static final String CONTENT_RANGE = "Content-Range";
- public static final String DIGEST = "Digest";
- public static final String X_BOX_PART_ID = "X-Box-Part-Id";
+public final class HttpHeaders {
+
+ public static final String CONTENT_LENGTH = "Content-Length";
+ public static final String CONTENT_RANGE = "Content-Range";
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String DIGEST = "Digest";
+ public static final String X_BOX_PART_ID = "X-Box-Part-Id";
+
+ //Prevents instantiation
+ private HttpHeaders() {
+ }
}
diff --git a/src/main/java/com/box/sdk/http/HttpMethod.java b/src/main/java/com/box/sdk/http/HttpMethod.java
index 4121191b5..062b94f54 100644
--- a/src/main/java/com/box/sdk/http/HttpMethod.java
+++ b/src/main/java/com/box/sdk/http/HttpMethod.java
@@ -4,5 +4,6 @@
*
*/
public enum HttpMethod {
- GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
+
+ GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
}
From d0e0b1a91e09acce97d3359b022c10831504775a Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Sun, 26 Feb 2017 23:05:02 -0800
Subject: [PATCH 057/119] Upload session list parts and commit are added
---
.../com/box/sdk/BoxFileUploadSessionPart.java | 73 +++++++++++++++++++
.../box/sdk/BoxFileUploadSessionPartList.java | 57 +++++++++++++++
2 files changed, 130 insertions(+)
create mode 100644 src/main/java/com/box/sdk/BoxFileUploadSessionPart.java
create mode 100644 src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSessionPart.java b/src/main/java/com/box/sdk/BoxFileUploadSessionPart.java
new file mode 100644
index 000000000..dad0d21be
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxFileUploadSessionPart.java
@@ -0,0 +1,73 @@
+package com.box.sdk;
+
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ *
+ */
+public class BoxFileUploadSessionPart extends BoxJSONObject {
+
+ private String partId;
+ private long offset;
+ private long size;
+
+ /**
+ * Constructs an empty BoxFileUploadSessionPart object.
+ */
+ public BoxFileUploadSessionPart() {
+ super();
+ }
+
+ /**
+ * Constructs an BoxFileUploadSessionPart object by parsing information from a JSON string.
+ * @param json the JSON string to parse.
+ */
+ public BoxFileUploadSessionPart(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs an BoxFileUploadSessionPart object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ BoxFileUploadSessionPart(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public String getPartId() {
+ return this.partId;
+ }
+
+ public long getOffset() {
+ return this.offset;
+ }
+
+ public long getSize() {
+ return this.size;
+ }
+
+ public void setPartId(String partId) {
+ this.partId = partId;
+ }
+
+ public void setOffset(long offset) {
+ this.offset = offset;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ protected void parseJSONMember(JsonObject.Member member) {
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("part_id")) {
+ this.partId = value.asString();
+ } else if (memberName.equals("offset")) {
+ this.offset = Double.valueOf(value.toString()).longValue();
+ } else if (memberName.equals("size")) {
+ this.size = Double.valueOf(value.toString()).longValue();
+ }
+ }
+}
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java b/src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java
new file mode 100644
index 000000000..76ca989a1
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java
@@ -0,0 +1,57 @@
+package com.box.sdk;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ *
+ */
+public class BoxFileUploadSessionPartList extends BoxJSONObject {
+
+ private List parts;
+ private int marker;
+
+ /**
+ * Constructs an BoxFileUploadSessionPart object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ BoxFileUploadSessionPartList(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public List getParts() {
+ return this.parts;
+ }
+
+ public int getMarker() {
+ return this.marker;
+ }
+
+ protected void parseJSONMember(JsonObject.Member member) {
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("parts")) {
+ JsonArray array = (JsonArray) value;
+
+ if (array.size() > 0) {
+ this.parts = this.getParts(array);
+ }
+ } else if (memberName.equals("marker")) {
+ this.marker = Double.valueOf(value.toString()).intValue();
+ }
+ }
+
+ private List getParts(JsonArray partsArray) {
+ List parts = new ArrayList();
+ for (JsonValue value: partsArray) {
+ BoxFileUploadSessionPart part = new BoxFileUploadSessionPart((JsonObject) value);
+ parts.add(part);
+ }
+
+ return parts;
+ }
+}
From 0f374d0d6d0f54b1327cd2ce793fff8889e17ea5 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Sun, 26 Feb 2017 23:05:25 -0800
Subject: [PATCH 058/119] Upload session list parts and commit are added
---
.../com/box/sdk/BoxFileUploadSession.java | 62 +++++++++++++------
1 file changed, 42 insertions(+), 20 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 7cae4c53f..396f35042 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -8,16 +8,18 @@
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
import com.box.sdk.http.ContentType;
import com.box.sdk.http.HttpHeaders;
import com.box.sdk.http.HttpMethod;
+import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
-/**
- *
- */
+@BoxResourceType("upload-session")
public class BoxFileUploadSession extends BoxResource {
private static final String DIGEST_HEADER_PREFIX_SHA = "sha=";
@@ -135,14 +137,6 @@ public class Endpoints extends BoxJSONObject {
private URL statusEndpoint;
private URL abortEndpoint;
- public Endpoints() {
- super();
- }
-
- public Endpoints(String json) {
- super(json);
- }
-
Endpoints(JsonObject jsonObject) {
super(jsonObject);
}
@@ -194,7 +188,8 @@ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSi
throws MalformedURLException, NoSuchAlgorithmException {
URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), uploadPartURL, HttpMethod.POST);
+
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), uploadPartURL, HttpMethod.PUT);
request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
request.addHeader(HttpHeaders.X_BOX_PART_ID, partId);
@@ -203,13 +198,12 @@ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSi
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
request.addHeader(HttpHeaders.CONTENT_RANGE,
"bytes " + startRange + "-" + (startRange + partSize - 1) + "/" + totalSizeOfFile);
- request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
request.setBody(new ByteArrayInputStream(bytes));
- BoxJSONResponse response = (BoxJSONResponse) request.send();
+ BoxAPIResponse response = (BoxAPIResponse) request.send();
}
- public int listParts(String sessionId, int marker, int limit) {
+ public BoxFileUploadSessionPartList listParts(int marker, int limit) {
URL listPartsURL = this.sessionInfo.getSessionEndpoints().getListPartsEndpoint();
URLTemplate template = new URLTemplate(listPartsURL.toString());
@@ -222,18 +216,21 @@ public int listParts(String sessionId, int marker, int limit) {
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, HttpMethod.GET);
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
-// System.out.println("Response: " + jsonObject);
+ //System.out.println("List parts: " + jsonObject);
- return response.getResponseCode();
+ return new BoxFileUploadSessionPartList(jsonObject);
}
- public int commit(String sessionId, String digest, JsonObject jsonObject, String ifMatch, String ifNonMatch) {
+ public int commit(String digest, List parts,
+ Map attributes, String ifMatch, String ifNonMatch) {
+
URL commitURL = this.sessionInfo.getSessionEndpoints().getCommitEndpoint();
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), commitURL, HttpMethod.POST);
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON);
- request.setBody(jsonObject.toString());
+ String body = this.getCommitBody(parts, attributes);
+ request.setBody(body);
BoxAPIResponse response = request.send();
//System.out.println("Response: " + response.getResponseCode());
@@ -254,6 +251,31 @@ public int commit(String sessionId, String digest, JsonObject jsonObject, String
return response.getResponseCode();
}
+ private String getCommitBody(List parts, Map attributes) {
+ JsonObject jsonObject = new JsonObject();
+
+ JsonArray array = new JsonArray();
+ for (BoxFileUploadSessionPart part: parts) {
+ JsonObject partObj = new JsonObject();
+ partObj.add("part_id", part.getPartId());
+ partObj.add("offset", part.getOffset());
+ partObj.add("size", part.getSize());
+
+ array.add(partObj);
+ }
+ jsonObject.add("parts", array);
+
+ if (attributes != null) {
+ JsonObject attrObj = new JsonObject();
+ for (String key: attributes.keySet()) {
+ attrObj.add(key, attributes.get(key));
+ }
+ jsonObject.add("attributes", attrObj);
+ }
+
+ return jsonObject.toString();
+ }
+
public BoxFileUploadSession.Info getUploadSessionStatus() {
URL statusURL = this.sessionInfo.getSessionEndpoints().getStatusEndpoint();
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), statusURL, HttpMethod.GET);
@@ -267,7 +289,7 @@ public BoxFileUploadSession.Info getUploadSessionStatus() {
public void abortUploadSession() {
URL abortURL = this.sessionInfo.getSessionEndpoints().getAbortEndpoint();
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), abortURL, "DELETE");
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), abortURL, HttpMethod.DELETE);
BoxAPIResponse response = request.send();
//System.out.println("Abort session status: " + response.getResponseCode());
}
From 088ff528d1e0b3bfc54d6268b49706d381db6254 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Mon, 27 Feb 2017 11:20:31 -0800
Subject: [PATCH 059/119] Commit operation returning BoxFile
---
.../com/box/sdk/BoxFileUploadSession.java | 20 +++++--------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 396f35042..c057840aa 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -221,7 +221,7 @@ public BoxFileUploadSessionPartList listParts(int marker, int limit) {
return new BoxFileUploadSessionPartList(jsonObject);
}
- public int commit(String digest, List parts,
+ public BoxFile.Info commit(String digest, List parts,
Map attributes, String ifMatch, String ifNonMatch) {
URL commitURL = this.sessionInfo.getSessionEndpoints().getCommitEndpoint();
@@ -232,23 +232,13 @@ public int commit(String digest, List parts,
String body = this.getCommitBody(parts, attributes);
request.setBody(body);
- BoxAPIResponse response = request.send();
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
//System.out.println("Response: " + response.getResponseCode());
- try {
- InputStream stream = response.getBody();
- int value = stream.read();
- StringBuffer buffer = new StringBuffer();
- while (value != -1) {
- buffer.append(value);
- value = stream.read();
- }
- //System.out.println("Response: " + buffer.toString());
- } catch (Exception ex) {
- ex.printStackTrace();
- }
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ BoxFile file = new BoxFile(this.getAPI(), jsonObject.get("id").toString());
- return response.getResponseCode();
+ return file.new Info(jsonObject);
}
private String getCommitBody(List parts, Map attributes) {
From 94e3bac30d4991c816c7969dbe96f71f15fcb9e4 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Mon, 27 Feb 2017 12:00:58 -0800
Subject: [PATCH 060/119] If-Match and If-None-Match headers implementation
---
src/main/java/com/box/sdk/BoxFile.java | 1 -
.../com/box/sdk/BoxFileUploadSession.java | 19 +++++++++++--------
src/main/java/com/box/sdk/BoxFolder.java | 1 -
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index bda7859e5..b9e31b834 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -871,7 +871,6 @@ public BoxFileUploadSession.Info createUploadSession(long fileSize) {
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- System.out.println("Response: " + jsonObject);
String sessionId = jsonObject.get("upload_session_id").asString();
BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId);
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index c057840aa..41d8a8bc3 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -1,7 +1,6 @@
package com.box.sdk;
import java.io.ByteArrayInputStream;
-import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
@@ -10,7 +9,6 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
-import java.util.Random;
import com.box.sdk.http.ContentType;
import com.box.sdk.http.HttpHeaders;
@@ -200,7 +198,7 @@ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSi
"bytes " + startRange + "-" + (startRange + partSize - 1) + "/" + totalSizeOfFile);
request.setBody(new ByteArrayInputStream(bytes));
- BoxAPIResponse response = (BoxAPIResponse) request.send();
+ request.send();
}
public BoxFileUploadSessionPartList listParts(int marker, int limit) {
@@ -216,24 +214,30 @@ public BoxFileUploadSessionPartList listParts(int marker, int limit) {
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, HttpMethod.GET);
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- //System.out.println("List parts: " + jsonObject);
return new BoxFileUploadSessionPartList(jsonObject);
}
public BoxFile.Info commit(String digest, List parts,
- Map attributes, String ifMatch, String ifNonMatch) {
+ Map attributes, String ifMatch, String ifNoneMatch) {
URL commitURL = this.sessionInfo.getSessionEndpoints().getCommitEndpoint();
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), commitURL, HttpMethod.POST);
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON);
+ if (ifMatch != null) {
+ request.addHeader(HttpHeaders.IF_MATCH, ifMatch);
+ }
+
+ if (ifNoneMatch != null) {
+ request.addHeader(HttpHeaders.IF_NONE_MATCH, ifNoneMatch);
+ }
+
String body = this.getCommitBody(parts, attributes);
request.setBody(body);
BoxJSONResponse response = (BoxJSONResponse) request.send();
- //System.out.println("Response: " + response.getResponseCode());
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
BoxFile file = new BoxFile(this.getAPI(), jsonObject.get("id").toString());
@@ -280,7 +284,6 @@ public BoxFileUploadSession.Info getUploadSessionStatus() {
public void abortUploadSession() {
URL abortURL = this.sessionInfo.getSessionEndpoints().getAbortEndpoint();
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), abortURL, HttpMethod.DELETE);
- BoxAPIResponse response = request.send();
- //System.out.println("Abort session status: " + response.getResponseCode());
+ request.send();
}
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index c2d933c78..dd10f4e4b 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -742,7 +742,6 @@ public BoxFileUploadSession.Info createUploadSession(String folderId, long fileS
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- System.out.println("Response: " + jsonObject);
String sessionId = jsonObject.get("upload_session_id").asString();
BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId);
From ed0ecab538268d55de308ff674fbeaaa7ae4d6f2 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Mon, 27 Feb 2017 12:01:45 -0800
Subject: [PATCH 061/119] If-Match and If-None-Match headers implementation
---
src/main/java/com/box/sdk/http/HttpHeaders.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/main/java/com/box/sdk/http/HttpHeaders.java b/src/main/java/com/box/sdk/http/HttpHeaders.java
index ecb942aa1..f9b151afa 100644
--- a/src/main/java/com/box/sdk/http/HttpHeaders.java
+++ b/src/main/java/com/box/sdk/http/HttpHeaders.java
@@ -9,6 +9,8 @@ public final class HttpHeaders {
public static final String CONTENT_RANGE = "Content-Range";
public static final String CONTENT_TYPE = "Content-Type";
public static final String DIGEST = "Digest";
+ public static final String IF_MATCH = "If-Match";
+ public static final String IF_NONE_MATCH = "If-None-Match";
public static final String X_BOX_PART_ID = "X-Box-Part-Id";
//Prevents instantiation
From 515d9fed2f85851035b4ea56ef0d9e30da303a3e Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 28 Feb 2017 13:31:58 -0800
Subject: [PATCH 062/119] Fix event stream to handle no events in the stream
---
src/test/java/com/box/sdk/EventStreamTest.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/test/java/com/box/sdk/EventStreamTest.java b/src/test/java/com/box/sdk/EventStreamTest.java
index 67bf16d2d..3dc86c72a 100644
--- a/src/test/java/com/box/sdk/EventStreamTest.java
+++ b/src/test/java/com/box/sdk/EventStreamTest.java
@@ -57,8 +57,14 @@ public boolean onException(Throwable e) {
boolean createdEventFound = false;
boolean deletedEventFound = false;
- while (!createdEventFound || !deletedEventFound) {
+ int timeouts = 0;
+ while ( timeouts < 3 && (!createdEventFound || !deletedEventFound)) {
BoxEvent event = observedEvents.poll(1, TimeUnit.MINUTES);
+ if( null == event) {
+ timeouts++;
+ System.out.println("Time outs: " + timeouts);
+ continue;
+ }
BoxResource.Info sourceInfo = event.getSourceInfo();
// Some events may not have sourceInfo
if (sourceInfo == null) {
From 8272cb85391dffc960fb727d39f921401f7f6dd1 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 28 Feb 2017 13:43:10 -0800
Subject: [PATCH 063/119] Fix checkstyle whitespace issues
---
src/test/java/com/box/sdk/EventStreamTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/test/java/com/box/sdk/EventStreamTest.java b/src/test/java/com/box/sdk/EventStreamTest.java
index 3dc86c72a..eef8b677b 100644
--- a/src/test/java/com/box/sdk/EventStreamTest.java
+++ b/src/test/java/com/box/sdk/EventStreamTest.java
@@ -58,9 +58,9 @@ public boolean onException(Throwable e) {
boolean createdEventFound = false;
boolean deletedEventFound = false;
int timeouts = 0;
- while ( timeouts < 3 && (!createdEventFound || !deletedEventFound)) {
+ while (timeouts < 3 && (!createdEventFound || !deletedEventFound)) {
BoxEvent event = observedEvents.poll(1, TimeUnit.MINUTES);
- if( null == event) {
+ if (null == event) {
timeouts++;
System.out.println("Time outs: " + timeouts);
continue;
From 21d860b85568693dfe5a25708a79c70f4f8d7e7a Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 28 Feb 2017 16:26:59 -0800
Subject: [PATCH 064/119] Integration tests for the commit
---
src/main/java/com/box/sdk/BoxAPIRequest.java | 2 +-
.../com/box/sdk/BoxFileUploadSession.java | 7 +-
src/main/java/com/box/sdk/BoxFolder.java | 4 +-
src/test/java/com/box/sdk/BoxFileTest.java | 213 ++++++++++++++++--
src/test/java/com/box/sdk/BoxFolderTest.java | 64 ++++--
5 files changed, 256 insertions(+), 34 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java
index de7b3585a..62eb7cc6f 100644
--- a/src/main/java/com/box/sdk/BoxAPIRequest.java
+++ b/src/main/java/com/box/sdk/BoxAPIRequest.java
@@ -425,7 +425,7 @@ private BoxAPIResponse trySend(ProgressListener listener) {
BoxAPIResponse response;
if (contentType == null) {
response = new BoxAPIResponse(connection);
- } else if (contentType.contains("application/json")) {
+ } else if (contentType.contains("application/json") || contentType.contains("text/plain")) {
response = new BoxJSONResponse(connection);
} else {
response = new BoxAPIResponse(connection);
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 41d8a8bc3..21f512e20 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -182,7 +182,7 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
- public void uploadPart(String partId, byte[] bytes, long startRange, Long partSize, long totalSizeOfFile)
+ public void uploadPart(String partId, byte[] bytes, long offset, Long partSize, long totalSizeOfFile)
throws MalformedURLException, NoSuchAlgorithmException {
URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
@@ -195,7 +195,7 @@ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSi
String digest = Base64.encode(digestBytes);
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
request.addHeader(HttpHeaders.CONTENT_RANGE,
- "bytes " + startRange + "-" + (startRange + partSize - 1) + "/" + totalSizeOfFile);
+ "bytes " + offset + "-" + (offset + partSize - 1) + "/" + totalSizeOfFile);
request.setBody(new ByteArrayInputStream(bytes));
request.send();
@@ -238,9 +238,8 @@ public BoxFile.Info commit(String digest, List parts,
request.setBody(body);
BoxJSONResponse response = (BoxJSONResponse) request.send();
-
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- BoxFile file = new BoxFile(this.getAPI(), jsonObject.get("id").toString());
+ BoxFile file = new BoxFile(this.getAPI(), jsonObject.get("id").asString());
return file.new Info(jsonObject);
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index dd10f4e4b..45d9c5d20 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -729,10 +729,10 @@ public void deleteMetadata(String templateName, String scope) {
response.disconnect();
}
- public BoxFileUploadSession.Info createUploadSession(String folderId, long fileSize, String fileName) {
+ public BoxFileUploadSession.Info createUploadSession(String fileName, long fileSize) {
String queryString = new QueryStringBuilder()
- .appendParam("folder_id", folderId)
+ .appendParam("folder_id", this.getID())
.appendParam("file_size", fileSize)
.appendParam("file_name", fileName)
.toString();
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 19ad7a168..d073c6e37 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -10,6 +10,8 @@
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -17,6 +19,8 @@
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
@@ -968,17 +972,182 @@ public void setCollectionsWithInfoSucceeds() {
@Test
@Category(IntegrationTest.class)
- public void uploadSessionSucceeds() {
+ public void uploadSessionCommitFlowSuccess() throws Exception {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
- String fileName = "[createUploadSessionSucceeds] Test File.txt";
+
+ BoxFile uploadedFile = null;
+ try {
+ String fileName = "Tamme-Lauri_tamm_suvepäeval.jpg";
+ URL fileURL = this.getClass().getResource("/sample-files/" + fileName);
+ String filePath = URLDecoder.decode(fileURL.getFile(), "utf-8");
+ File file = new File(filePath);
+ long fileSize = file.length();
+
+ //Create the session
+ BoxFileUploadSession.Info session = createFileUploadSession(rootFolder, fileName, fileSize);
+
+ //Create the parts
+ MessageDigest fileDigest = uploadParts(uploadedFile, session, fileSize);
+
+ //List the session parts
+ List parts = listUploadSessionParts(session.getResource());
+
+ byte[] digestBytes = fileDigest.digest();
+ String digest = Base64.encode(digestBytes);
+
+ //Verify the delete session
+ uploadedFile = commitSession(session.getResource(), digest, parts);
+ } finally {
+ if (uploadedFile != null) {
+ uploadedFile.delete();
+ }
+ }
+ }
+
+ private BoxFileUploadSession.Info createFileUploadSession(BoxFolder folder, String fileName, long fileSize) {
+ BoxFileUploadSession.Info session = folder.createUploadSession(fileName, fileSize);
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+
+ return session;
+ }
+
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void uploadSessionVersionCommitFlowSuccess() throws Exception {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+
+ BoxFile.Info imageFileInfo = createImageFile(rootFolder);
+
+ BoxFile uploadedFile = imageFileInfo.getResource();
+ try {
+ //Create the session
+ BoxFileUploadSession.Info session = createFileUploadSession(uploadedFile, imageFileInfo.getSize());
+
+ //Create the parts
+ MessageDigest fileDigest = uploadParts(uploadedFile, session, imageFileInfo.getSize());
+
+ //List the session parts
+ List parts = listUploadSessionParts(session.getResource());
+
+ byte[] digestBytes = fileDigest.digest();
+ String digest = Base64.encode(digestBytes);
+
+ //Verify the delete session
+ uploadedFile = commitSession(session.getResource(), digest, parts);
+ } finally {
+ uploadedFile.delete();
+ }
+ }
+
+ private BoxFileUploadSession.Info createFileUploadSession(BoxFile uploadedFile, long fileSize) {
+ BoxFileUploadSession.Info session = uploadedFile.createUploadSession(fileSize);
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+
+ return session;
+ }
+
+ private MessageDigest uploadParts(BoxFile uploadedFile, BoxFileUploadSession.Info session,
+ long fileSize) throws Exception {
+
+ String fileName = "Tamme-Lauri_tamm_suvepäeval.jpg";
+ URL fileURL = this.getClass().getResource("/sample-files/" + fileName);
+ String filePath = URLDecoder.decode(fileURL.getFile(), "utf-8");
+ File file = new File(filePath);
+
+ FileInputStream stream = new FileInputStream(file);
+ MessageDigest fileDigest = MessageDigest.getInstance("SHA1");
+ DigestInputStream dis = new DigestInputStream(stream, fileDigest);
+
+ long offset = 0;
+ byte[] bytes = null;
+ long processed = 0;
+ boolean canBreak = false;
+ while(true) {
+ long min = session.getPartSize();
+ long diff = fileSize - processed;
+ if (diff < min) {
+ min = diff;
+ canBreak = true;
+ }
+
+ bytes = new byte[(int) min];
+ dis.read(bytes);
+
+ session.getResource().uploadPart(generateHex(), bytes, offset, min, fileSize);
+
+ offset = offset + session.getPartSize();
+ processed += min;
+ if (canBreak) {
+ break;
+ }
+ }
+
+ return fileDigest;
+ }
+
+ private String generateHex() {
+ String hex = "";
+ while (hex.length() != 8) {
+ Random random = new Random();
+ int val = random.nextInt();
+ hex = Integer.toHexString(val);
+ }
+
+ return hex;
+ }
+
+ private BoxFile.Info createImageFile(BoxFolder folder) throws IOException {
+ String fileName = "Tamme-Lauri_tamm_suvepäeval.jpg";
+ URL fileURL = this.getClass().getResource("/sample-files/" + fileName);
+ String filePath = URLDecoder.decode(fileURL.getFile(), "utf-8");
+ File file = new File(filePath);
+ long fileSize = file.length();
+
+ FileInputStream stream = new FileInputStream(file);
+
+ byte[] fileBytes = new byte[(int) fileSize];
+
+ InputStream uploadStream = new ByteArrayInputStream(fileBytes);
+ return folder.uploadFile(uploadStream, fileName);
+ }
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void uploadSessionAbortFlowSuccess() throws Exception {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+
+ String fileName = "[setCollectionsWithInfoSucceeds] Test File.txt";
String fileContent = "Test file";
byte[] fileBytes = fileContent.getBytes(StandardCharsets.UTF_8);
InputStream uploadStream = new ByteArrayInputStream(fileBytes);
BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
try {
- BoxFileUploadSession session = uploadedFile.createUploadSession(10000000);
+ BoxFileUploadSession.Info session = uploadedFile.createUploadSession(fileBytes.length);
Assert.assertNotNull(session.getUploadSessionId());
Assert.assertNotNull(session.getSessionExpiresAt());
Assert.assertNotNull(session.getPartSize());
@@ -992,28 +1161,44 @@ public void uploadSessionSucceeds() {
Assert.assertNotNull(endpoints.getAbortEndpoint());
//Verify the status of the session
- getUploadSessionStatusSucceeds(uploadedFile, session.getUploadSessionId());
+ getUploadSessionStatus(session.getResource());
//Verify the delete session
- abortUploadSessionStatusSucceeds(uploadedFile, session.getUploadSessionId());
+ abortUploadSession(session.getResource());
} finally {
uploadedFile.delete();
}
}
- private void getUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
- BoxFileUploadSession session = file.getUploadSessionStatus(sessionId);
- Assert.assertNotNull(session.getSessionExpiresAt());
- Assert.assertNotNull(session.getPartSize());
- Assert.assertNotNull(session.getTotalParts());
- Assert.assertNotNull(session.getPartsProcessed());
+ private List listUploadSessionParts(BoxFileUploadSession session) {
+ BoxFileUploadSessionPartList list = session.listParts(0, 10);
+
+ List parts = list.getParts();
+ Assert.assertEquals(parts.size(), 3);
+
+ return parts;
+ }
+
+ private BoxFile commitSession(BoxFileUploadSession session, String digest, List parts) {
+ BoxFile.Info file = session.commit(digest, parts, null, null, null);
+ Assert.assertNotNull(file);
+
+ return file.getResource();
+ }
+
+ private void getUploadSessionStatus(BoxFileUploadSession session) {
+ BoxFileUploadSession.Info sessionInfo = session.getUploadSessionStatus();
+ Assert.assertNotNull(sessionInfo.getSessionExpiresAt());
+ Assert.assertNotNull(sessionInfo.getPartSize());
+ Assert.assertNotNull(sessionInfo.getTotalParts());
+ Assert.assertNotNull(sessionInfo.getPartsProcessed());
}
- private void abortUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
- file.abortUploadSession(sessionId);
+ private void abortUploadSession(BoxFileUploadSession session) {
+ session.abortUploadSession();
try {
- BoxFileUploadSession session = file.getUploadSessionStatus(sessionId);
+ BoxFileUploadSession.Info sessionInfo = session.getUploadSessionStatus();
//If the session is aborted, this line should not be executed.
Assert.assertFalse("Upload session is not deleted", true);
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index c24f22642..5da3f0e12 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -1068,20 +1068,58 @@ public void sharedLinkInfoHasEffectiveAccess() {
@Test
@Category(IntegrationTest.class)
- public void createUploadSessionSucceeds() {
+ public void uploadSessionAbortFlowSuccess() throws Exception {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
- BoxFileUploadSession session = rootFolder.createUploadSession("0", 1000000, "Test_File.txt");
- Assert.assertNotNull(session.getUploadSessionId());
- Assert.assertNotNull(session.getSessionExpiresAt());
- Assert.assertNotNull(session.getPartSize());
-
- BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
- Assert.assertNotNull(endpoints);
- Assert.assertNotNull(endpoints.getUploadPartEndpoint());
- Assert.assertNotNull(endpoints.getStatusEndpoint());
- Assert.assertNotNull(endpoints.getListPartsEndpoint());
- Assert.assertNotNull(endpoints.getCommitEndpoint());
- Assert.assertNotNull(endpoints.getAbortEndpoint());
+
+ String fileName = "[setCollectionsWithInfoSucceeds] Test File.txt";
+ String fileContent = "Test file";
+ byte[] fileBytes = fileContent.getBytes(StandardCharsets.UTF_8);
+
+ InputStream uploadStream = new ByteArrayInputStream(fileBytes);
+ BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
+ try {
+ BoxFileUploadSession.Info session = uploadedFile.createUploadSession(fileBytes.length);
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+
+ //Verify the status of the session
+ getUploadSessionStatus(session.getResource());
+
+ //Verify the delete session
+ abortUploadSession(session.getResource());
+ } finally {
+ uploadedFile.delete();
+ }
+ }
+
+ private void getUploadSessionStatus(BoxFileUploadSession session) {
+ BoxFileUploadSession.Info sessionInfo = session.getUploadSessionStatus();
+ Assert.assertNotNull(sessionInfo.getSessionExpiresAt());
+ Assert.assertNotNull(sessionInfo.getPartSize());
+ Assert.assertNotNull(sessionInfo.getTotalParts());
+ Assert.assertNotNull(sessionInfo.getPartsProcessed());
+ }
+
+ private void abortUploadSession(BoxFileUploadSession session) {
+ session.abortUploadSession();
+
+ try {
+ BoxFileUploadSession.Info sessionInfo = session.getUploadSessionStatus();
+
+ //If the session is aborted, this line should not be executed.
+ Assert.assertFalse("Upload session is not deleted", true);
+ } catch(BoxAPIException apiEx) {
+ Assert.assertEquals(apiEx.getResponseCode(), 404);
+ }
}
}
From 06d545f193a01efeb27b67f120d38081feeb1e2c Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 28 Feb 2017 17:25:56 -0800
Subject: [PATCH 065/119] public api support for upload file is moved to 2.0
from 2.1
---
.../java/com/box/sdk/BoxAPIConnection.java | 2 +-
src/main/java/com/box/sdk/BoxFile.java | 8 +++++---
.../com/box/sdk/BoxFileUploadSession.java | 19 ++++++++++++++++---
src/main/java/com/box/sdk/BoxFolder.java | 16 ++++++++--------
4 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index 0114ad76f..896e0d7c3 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -26,7 +26,7 @@ public class BoxAPIConnection {
private static final String TOKEN_URL_STRING = "https://api.box.com/oauth2/token";
private static final String DEFAULT_BASE_URL = "https://api.box.com/2.0/";
private static final String DEFAULT_BASE_UPLOAD_URL = "https://upload.box.com/api/2.0/";
- private static final String DEFAULT_BASE_UPLOAD_SESSION_URL = "https://upload.app.box.com/api/2.1/";
+ private static final String DEFAULT_BASE_UPLOAD_SESSION_URL = "https://upload.app.box.com/api/2.0/";
/**
* The amount of buffer time, in milliseconds, to use when determining if an access token should be refreshed. For
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index b9e31b834..298a94d25 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -862,13 +862,15 @@ public BoxFile.Info setCollections(BoxCollection... collections) {
}
public BoxFileUploadSession.Info createUploadSession(long fileSize) {
- String queryString = new QueryStringBuilder().appendParam("file_size", fileSize).toString();
- URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
- queryString, this.getID());
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), this.getID());
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
request.addHeader("Content-Type", "application/json");
+ JsonObject body = new JsonObject();
+ body.add("file_size", fileSize);
+ request.setBody(body.toString());
+
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 21f512e20..8ee6f7f9e 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -237,11 +237,24 @@ public BoxFile.Info commit(String digest, List parts,
String body = this.getCommitBody(parts, attributes);
request.setBody(body);
- BoxJSONResponse response = (BoxJSONResponse) request.send();
+ BoxAPIResponse response = (BoxAPIResponse) request.send();
+ if (response instanceof BoxJSONResponse) {
+ return getFile((BoxJSONResponse) response);
+ } else {
+ throw new BoxAPIException("Commit response content type is not application/json. The response code : " + response.getResponseCode());
+ }
+ }
+
+ private BoxFile.Info getFile(BoxJSONResponse response) {
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- BoxFile file = new BoxFile(this.getAPI(), jsonObject.get("id").asString());
+ System.out.println("Response: " + response.getResponseCode() + " : " + response.getJSON());
+
+ JsonArray array = (JsonArray) jsonObject.get("entries");
+ JsonObject fileObj = (JsonObject) array.get(0);
+
+ BoxFile file = new BoxFile(this.getAPI(), fileObj.get("id").asString());
- return file.new Info(jsonObject);
+ return file.new Info(fileObj);
}
private String getCommitBody(List parts, Map attributes) {
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 45d9c5d20..87867bb6e 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -731,15 +731,15 @@ public void deleteMetadata(String templateName, String scope) {
public BoxFileUploadSession.Info createUploadSession(String fileName, long fileSize) {
- String queryString = new QueryStringBuilder()
- .appendParam("folder_id", this.getID())
- .appendParam("file_size", fileSize)
- .appendParam("file_name", fileName)
- .toString();
-
- URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
- queryString);
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL());
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
+
+ JsonObject body = new JsonObject();
+ body.add("folder_id", this.getID());
+ body.add("file_name", fileName);
+ body.add("file_size", fileSize);
+ request.setBody(body.toString());
+
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
From 9196b0acd6eab70769f4e72ea7bb9115bd0e4788 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Wed, 1 Mar 2017 14:13:50 -0800
Subject: [PATCH 066/119] upload large file method is added
---
src/main/java/com/box/sdk/BoxFile.java | 6 +
src/main/java/com/box/sdk/BoxFolder.java | 6 +
.../java/com/box/sdk/LargeFileUpload.java | 153 ++++++++++++++++++
3 files changed, 165 insertions(+)
create mode 100644 src/main/java/com/box/sdk/LargeFileUpload.java
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 298a94d25..b1bf9bf36 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -879,6 +879,12 @@ public BoxFileUploadSession.Info createUploadSession(long fileSize) {
return session.new Info(jsonObject);
}
+ public BoxFile.Info uploadLargeFile(InputStream inputStream, long fileSize) throws Exception {
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), this.getID());
+
+ return LargeFileUpload.upload(this.getAPI(), inputStream, url, fileSize);
+ }
+
/**
* Contains information about a BoxFile.
*/
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 87867bb6e..cf49647d3 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -749,6 +749,12 @@ public BoxFileUploadSession.Info createUploadSession(String fileName, long fileS
return session.new Info(jsonObject);
}
+ public BoxFile.Info uploadLargeFile(InputStream inputStream, String fileName, long fileSize) throws Exception {
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL());
+
+ return LargeFileUpload.upload(this.getAPI(), this.getID(), inputStream, url, fileName, fileSize);
+ }
+
/**
* Contains information about a BoxFolder.
*/
diff --git a/src/main/java/com/box/sdk/LargeFileUpload.java b/src/main/java/com/box/sdk/LargeFileUpload.java
new file mode 100644
index 000000000..159c52687
--- /dev/null
+++ b/src/main/java/com/box/sdk/LargeFileUpload.java
@@ -0,0 +1,153 @@
+package com.box.sdk;
+
+import com.box.sdk.*;
+import com.box.sdk.http.ContentType;
+import com.box.sdk.http.HttpHeaders;
+import com.box.sdk.http.HttpMethod;
+import com.eclipsesource.json.JsonObject;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
+
+/**
+ *
+ */
+public final class LargeFileUpload {
+
+ private static final String DIGEST_HEADER_PREFIX_SHA = "sha=";
+ private static final String DIGEST_ALGORITHM_SHA1 = "SHA1";
+
+ private static final String MARKER_QUERY_STRING = "marker";
+ private static final String LIMIT_QUERY_STRING = "limit";
+
+ private LargeFileUpload() {
+ }
+
+ static BoxFile.Info upload(BoxAPIConnection boxApi, String folderId, InputStream stream, URL url,
+ String fileName, long fileSize) throws Exception {
+
+ BoxFileUploadSession.Info session = createUploadSession(boxApi, folderId, url, fileName, fileSize);
+
+ MessageDigest digest = uploadParts(session, stream, fileSize);
+ byte[] digestBytes = digest.digest();
+ String digestStr = Base64.encode(digestBytes);
+
+ BoxFileUploadSessionPartList list = session.getResource().listParts(0, 1000);
+ try {
+ return session.getResource().commit(digestStr, list.getParts(), null, null, null);
+ } finally {
+ session.getResource().abortUploadSession();
+ }
+ }
+
+ private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection boxApi, String folderId,
+ URL url, String fileName, long fileSize) {
+
+ BoxJSONRequest request = new BoxJSONRequest(boxApi, url, HttpMethod.POST);
+
+ JsonObject body = new JsonObject();
+ body.add("folder_id", folderId);
+ body.add("file_name", fileName);
+ body.add("file_size", fileSize);
+ request.setBody(body.toString());
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+
+ String sessionId = jsonObject.get("upload_session_id").asString();
+ BoxFileUploadSession session = new BoxFileUploadSession(boxApi, sessionId);
+
+ return session.new Info(jsonObject);
+ }
+
+ static BoxFile.Info upload(BoxAPIConnection boxApi, InputStream stream, URL url, long fileSize) throws Exception {
+ BoxFileUploadSession.Info session = createUploadSession(boxApi, url, fileSize);
+
+ MessageDigest digest = uploadParts(session, stream, fileSize);
+ byte[] digestBytes = digest.digest();
+ String digestStr = Base64.encode(digestBytes);
+
+ BoxFileUploadSessionPartList list = session.getResource().listParts(0, 1000);
+ try {
+ return session.getResource().commit(digestStr, list.getParts(), null, null, null);
+ } finally {
+ session.getResource().abortUploadSession();
+ }
+ }
+
+ private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection boxApi, URL url, long fileSize) {
+ BoxJSONRequest request = new BoxJSONRequest(boxApi, url, HttpMethod.POST);
+ JsonObject body = new JsonObject();
+ body.add("file_size", fileSize);
+ request.setBody(body.toString());
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+
+ String sessionId = jsonObject.get("upload_session_id").asString();
+ BoxFileUploadSession session = new BoxFileUploadSession(boxApi, sessionId);
+
+ return session.new Info(jsonObject);
+ }
+
+ private static MessageDigest uploadParts(BoxFileUploadSession.Info session, InputStream stream, long fileSize)
+ throws Exception {
+
+ MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ DigestInputStream dis = new DigestInputStream(stream, digest);
+
+ long partSize = session.getPartSize();
+ long offset = 0;
+ long processed = 0;
+ while (processed < fileSize) {
+ long diff = fileSize - processed;
+ if (diff < partSize) {
+ partSize = diff;
+ }
+
+ uploadPart(session.getResource(), dis, offset, partSize, fileSize);
+
+ processed += partSize;
+ offset += partSize;
+ }
+
+ return digest;
+ }
+
+ private static void uploadPart(BoxFileUploadSession session, InputStream stream, long offset,
+ long partSize, long fileSize) throws Exception {
+
+ String partId = generateHex();
+ byte[] bytes = new byte[(int) partSize];
+ stream.read(bytes);
+
+ for(int i = 0; i < 3; i++) {
+ try {
+ session.uploadPart(partId, bytes, offset, partSize, fileSize);
+ break;
+ } catch (BoxAPIException ex) {
+ if (i == 2) {
+ throw ex;
+ }
+ }
+ }
+ }
+
+ public static String generateHex() {
+ String hex = "";
+ while (hex.length() != 8) {
+ Random random = new Random();
+ int val = random.nextInt();
+ hex = Integer.toHexString(val);
+ }
+
+ return hex;
+ }
+
+}
From b91fc4e279378134681d5bfe5cd626a9f526c413 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Wed, 1 Mar 2017 15:30:30 -0800
Subject: [PATCH 067/119] upload part takes stream as input
---
.../com/box/sdk/BoxFileUploadSession.java | 9 ++++-
.../java/com/box/sdk/LargeFileUpload.java | 4 +-
src/test/java/com/box/sdk/BoxFileTest.java | 39 +++++++++++++++++--
3 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 8ee6f7f9e..f04509f8d 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -1,6 +1,8 @@
package com.box.sdk;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
@@ -182,8 +184,8 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
- public void uploadPart(String partId, byte[] bytes, long offset, Long partSize, long totalSizeOfFile)
- throws MalformedURLException, NoSuchAlgorithmException {
+ public void uploadPart(String partId, InputStream stream, long offset, long partSize, long totalSizeOfFile)
+ throws IOException, NoSuchAlgorithmException {
URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
@@ -191,6 +193,9 @@ public void uploadPart(String partId, byte[] bytes, long offset, Long partSize,
request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
request.addHeader(HttpHeaders.X_BOX_PART_ID, partId);
+ byte[] bytes = new byte[(int) partSize];
+ stream.read(bytes);
+
byte[] digestBytes = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1).digest(bytes);
String digest = Base64.encode(digestBytes);
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
diff --git a/src/main/java/com/box/sdk/LargeFileUpload.java b/src/main/java/com/box/sdk/LargeFileUpload.java
index 159c52687..c6f3a77a3 100644
--- a/src/main/java/com/box/sdk/LargeFileUpload.java
+++ b/src/main/java/com/box/sdk/LargeFileUpload.java
@@ -124,12 +124,10 @@ private static void uploadPart(BoxFileUploadSession session, InputStream stream,
long partSize, long fileSize) throws Exception {
String partId = generateHex();
- byte[] bytes = new byte[(int) partSize];
- stream.read(bytes);
for(int i = 0; i < 3; i++) {
try {
- session.uploadPart(partId, bytes, offset, partSize, fileSize);
+ session.uploadPart(partId, stream, offset, partSize, fileSize);
break;
} catch (BoxAPIException ex) {
if (i == 2) {
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index d073c6e37..c6a0620fd 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -1093,10 +1093,7 @@ private MessageDigest uploadParts(BoxFile uploadedFile, BoxFileUploadSession.Inf
canBreak = true;
}
- bytes = new byte[(int) min];
- dis.read(bytes);
-
- session.getResource().uploadPart(generateHex(), bytes, offset, min, fileSize);
+ session.getResource().uploadPart(generateHex(), dis, offset, min, fileSize);
offset = offset + session.getPartSize();
processed += min;
@@ -1213,4 +1210,38 @@ private static byte[] readAllBytes(String fileName) throws IOException {
f.read(b);
return b;
}
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void uploadLargeFile() throws Exception {
+ File file = new File("/Users/kshanmugasundaram/Downloads/tenmb");
+ FileInputStream stream = new FileInputStream(file);
+
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ BoxFile.Info fileUploaded = rootFolder.uploadLargeFile(stream, "tenmb", file.length());
+ Assert.assertNotNull(fileUploaded);
+
+ fileUploaded.getResource().delete();
+ }
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void uploadLargeFileVersion() throws Exception {
+ String fileName = "Tamme-Lauri_tamm_suvepäeval.jpg";
+ URL fileURL = this.getClass().getResource("/sample-files/" + fileName);
+ String filePath = URLDecoder.decode(fileURL.getFile(), "utf-8");
+ File file = new File(filePath);
+ FileInputStream stream = new FileInputStream(file);
+
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ BoxFile.Info uploadedFile = rootFolder.uploadFile(stream, "tenmb");
+
+ stream = new FileInputStream(file);
+ BoxFile.Info fileVerion = uploadedFile.getResource().uploadLargeFile(stream, file.length());
+ Assert.assertNotNull(fileVerion);
+
+ fileVerion.getResource().delete();
+ }
}
From 10283ac64a1cea70916a9d59f50b232da709e032 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Wed, 1 Mar 2017 16:01:42 -0800
Subject: [PATCH 068/119] Checkstyle clean up
---
.../java/com/box/sdk/BoxFileUploadSession.java | 7 ++++---
src/main/java/com/box/sdk/LargeFileUpload.java | 14 ++++----------
2 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index f04509f8d..42fe7acb2 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -242,11 +242,12 @@ public BoxFile.Info commit(String digest, List parts,
String body = this.getCommitBody(parts, attributes);
request.setBody(body);
- BoxAPIResponse response = (BoxAPIResponse) request.send();
+ BoxAPIResponse response = request.send();
if (response instanceof BoxJSONResponse) {
- return getFile((BoxJSONResponse) response);
+ return this.getFile((BoxJSONResponse) response);
} else {
- throw new BoxAPIException("Commit response content type is not application/json. The response code : " + response.getResponseCode());
+ throw new BoxAPIException("Commit response content type is not application/json. The response code : "
+ + response.getResponseCode());
}
}
diff --git a/src/main/java/com/box/sdk/LargeFileUpload.java b/src/main/java/com/box/sdk/LargeFileUpload.java
index c6f3a77a3..c76d93397 100644
--- a/src/main/java/com/box/sdk/LargeFileUpload.java
+++ b/src/main/java/com/box/sdk/LargeFileUpload.java
@@ -1,20 +1,14 @@
package com.box.sdk;
-import com.box.sdk.*;
-import com.box.sdk.http.ContentType;
-import com.box.sdk.http.HttpHeaders;
-import com.box.sdk.http.HttpMethod;
-import com.eclipsesource.json.JsonObject;
-
-import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.net.MalformedURLException;
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.util.Random;
+import com.box.sdk.http.HttpMethod;
+import com.eclipsesource.json.JsonObject;
+
/**
*
*/
@@ -125,7 +119,7 @@ private static void uploadPart(BoxFileUploadSession session, InputStream stream,
String partId = generateHex();
- for(int i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
try {
session.uploadPart(partId, stream, offset, partSize, fileSize);
break;
From c32f37ab57edc752e88df9f6c2053b90ed1bfae8 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 2 Mar 2017 10:03:24 -0800
Subject: [PATCH 069/119] Upload part signature change and 202 response code
fix
---
src/main/java/com/box/sdk/BoxAPIResponse.java | 9 +++++
.../com/box/sdk/BoxFileUploadSession.java | 25 ++++++++++++--
.../java/com/box/sdk/LargeFileUpload.java | 33 +++++++++++--------
3 files changed, 51 insertions(+), 16 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIResponse.java b/src/main/java/com/box/sdk/BoxAPIResponse.java
index 92f376661..424ae94b5 100644
--- a/src/main/java/com/box/sdk/BoxAPIResponse.java
+++ b/src/main/java/com/box/sdk/BoxAPIResponse.java
@@ -89,6 +89,15 @@ public long getContentLength() {
return this.connection.getContentLength();
}
+ /**
+ * Gets the value of the given header field.
+ * @param fieldName name of the header field.
+ * @return value of the header.
+ */
+ public String getHeaderField(String fieldName) {
+ return this.connection.getHeaderField(fieldName);
+ }
+
/**
* Gets an InputStream for reading this response's body.
* @return an InputStream for reading the response's body.
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 42fe7acb2..05ab31a35 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -184,8 +184,8 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
- public void uploadPart(String partId, InputStream stream, long offset, long partSize, long totalSizeOfFile)
- throws IOException, NoSuchAlgorithmException {
+ public BoxFileUploadSessionPart uploadPart(String partId, InputStream stream, long offset, long partSize,
+ long totalSizeOfFile) throws IOException, NoSuchAlgorithmException {
URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
@@ -204,6 +204,13 @@ public void uploadPart(String partId, InputStream stream, long offset, long part
request.setBody(new ByteArrayInputStream(bytes));
request.send();
+
+ BoxFileUploadSessionPart part = new BoxFileUploadSessionPart();
+ part.setPartId(partId);
+ part.setOffset(offset);
+ part.setSize(partSize);
+
+ return part;
}
public BoxFileUploadSessionPartList listParts(int marker, int limit) {
@@ -243,6 +250,19 @@ public BoxFile.Info commit(String digest, List parts,
request.setBody(body);
BoxAPIResponse response = request.send();
+ if (response.getResponseCode() == 202) {
+ String retryInterval = response.getHeaderField("retry-after");
+ if (retryInterval != null) {
+ try {
+ Thread.sleep(new Integer(retryInterval) * 1000);
+ } catch (InterruptedException ie) {
+ throw new BoxAPIException("Commit retry failed. ", ie);
+ }
+
+ return this.commit(digest, parts, attributes, ifMatch, ifNoneMatch);
+ }
+ }
+
if (response instanceof BoxJSONResponse) {
return this.getFile((BoxJSONResponse) response);
} else {
@@ -253,7 +273,6 @@ public BoxFile.Info commit(String digest, List parts,
private BoxFile.Info getFile(BoxJSONResponse response) {
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- System.out.println("Response: " + response.getResponseCode() + " : " + response.getJSON());
JsonArray array = (JsonArray) jsonObject.get("entries");
JsonObject fileObj = (JsonObject) array.get(0);
diff --git a/src/main/java/com/box/sdk/LargeFileUpload.java b/src/main/java/com/box/sdk/LargeFileUpload.java
index c76d93397..8024cf749 100644
--- a/src/main/java/com/box/sdk/LargeFileUpload.java
+++ b/src/main/java/com/box/sdk/LargeFileUpload.java
@@ -4,6 +4,8 @@
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
import com.box.sdk.http.HttpMethod;
@@ -28,13 +30,15 @@ static BoxFile.Info upload(BoxAPIConnection boxApi, String folderId, InputStream
BoxFileUploadSession.Info session = createUploadSession(boxApi, folderId, url, fileName, fileSize);
- MessageDigest digest = uploadParts(session, stream, fileSize);
+ MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ List parts = uploadParts(session, stream, fileSize, digest);
+
byte[] digestBytes = digest.digest();
String digestStr = Base64.encode(digestBytes);
BoxFileUploadSessionPartList list = session.getResource().listParts(0, 1000);
try {
- return session.getResource().commit(digestStr, list.getParts(), null, null, null);
+ return session.getResource().commit(digestStr, parts, null, null, null);
} finally {
session.getResource().abortUploadSession();
}
@@ -63,13 +67,15 @@ private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection bo
static BoxFile.Info upload(BoxAPIConnection boxApi, InputStream stream, URL url, long fileSize) throws Exception {
BoxFileUploadSession.Info session = createUploadSession(boxApi, url, fileSize);
- MessageDigest digest = uploadParts(session, stream, fileSize);
+ MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ List parts = uploadParts(session, stream, fileSize, digest);
+
byte[] digestBytes = digest.digest();
String digestStr = Base64.encode(digestBytes);
BoxFileUploadSessionPartList list = session.getResource().listParts(0, 1000);
try {
- return session.getResource().commit(digestStr, list.getParts(), null, null, null);
+ return session.getResource().commit(digestStr, parts, null, null, null);
} finally {
session.getResource().abortUploadSession();
}
@@ -90,11 +96,11 @@ private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection bo
return session.new Info(jsonObject);
}
- private static MessageDigest uploadParts(BoxFileUploadSession.Info session, InputStream stream, long fileSize)
- throws Exception {
+ private static List uploadParts(BoxFileUploadSession.Info session, InputStream stream,
+ long fileSize, MessageDigest digest) throws Exception {
- MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
DigestInputStream dis = new DigestInputStream(stream, digest);
+ List parts = new ArrayList();
long partSize = session.getPartSize();
long offset = 0;
@@ -105,30 +111,32 @@ private static MessageDigest uploadParts(BoxFileUploadSession.Info session, Inpu
partSize = diff;
}
- uploadPart(session.getResource(), dis, offset, partSize, fileSize);
+ BoxFileUploadSessionPart part = uploadPart(session.getResource(), dis, offset, partSize, fileSize);
+ parts.add(part);
processed += partSize;
offset += partSize;
}
- return digest;
+ return parts;
}
- private static void uploadPart(BoxFileUploadSession session, InputStream stream, long offset,
+ private static BoxFileUploadSessionPart uploadPart(BoxFileUploadSession session, InputStream stream, long offset,
long partSize, long fileSize) throws Exception {
String partId = generateHex();
for (int i = 0; i < 3; i++) {
try {
- session.uploadPart(partId, stream, offset, partSize, fileSize);
- break;
+ return session.uploadPart(partId, stream, offset, partSize, fileSize);
} catch (BoxAPIException ex) {
if (i == 2) {
throw ex;
}
}
}
+
+ return null;
}
public static String generateHex() {
@@ -141,5 +149,4 @@ public static String generateHex() {
return hex;
}
-
}
From 6e839c93042f20ad129225ac016100b870c06785 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 2 Mar 2017 13:25:38 -0800
Subject: [PATCH 070/119] Added Javadoc
---
src/main/java/com/box/sdk/BoxAPIRequest.java | 6 +
src/main/java/com/box/sdk/BoxFile.java | 14 +-
.../com/box/sdk/BoxFileUploadSession.java | 161 ++++++++++++++----
.../com/box/sdk/BoxFileUploadSessionPart.java | 37 ++--
.../box/sdk/BoxFileUploadSessionPartList.java | 15 +-
src/main/java/com/box/sdk/BoxFolder.java | 16 +-
.../java/com/box/sdk/LargeFileUpload.java | 105 +++++++++++-
.../java/com/box/sdk/http/ContentType.java | 9 +-
.../java/com/box/sdk/http/HttpHeaders.java | 31 +++-
.../java/com/box/sdk/http/HttpMethod.java | 41 ++++-
10 files changed, 379 insertions(+), 56 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java
index 62eb7cc6f..036da1671 100644
--- a/src/main/java/com/box/sdk/BoxAPIRequest.java
+++ b/src/main/java/com/box/sdk/BoxAPIRequest.java
@@ -78,6 +78,12 @@ public BoxAPIRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Accept-Charset", "utf-8");
}
+ /**
+ * Constructs an authenticated BoxAPIRequest using a provided BoxAPIConnection.
+ * @param api an API connection for authenticating the request.
+ * @param uploadPartEndpoint the URL of the request.
+ * @param method the HTTP method of the request.
+ */
public BoxAPIRequest(BoxAPIConnection api, URL uploadPartEndpoint, HttpMethod method) {
this(api, uploadPartEndpoint, method.name());
}
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index b1bf9bf36..b49814677 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -861,6 +861,12 @@ public BoxFile.Info setCollections(BoxCollection... collections) {
return new Info(jsonObject);
}
+ /**
+ * Creates an upload session to create a new version of a file in chunks.
+ * This will first verify that the version can be created and then open a session for uploading pieces of the file.
+ * @param fileSize the size of the file that will be uploaded.
+ * @return the created upload session instance.
+ */
public BoxFileUploadSession.Info createUploadSession(long fileSize) {
URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), this.getID());
@@ -879,7 +885,13 @@ public BoxFileUploadSession.Info createUploadSession(long fileSize) {
return session.new Info(jsonObject);
}
- public BoxFile.Info uploadLargeFile(InputStream inputStream, long fileSize) throws Exception {
+ /**
+ * Creates a new version of a file.
+ * @param inputStream the stream instance that contains the data.
+ * @param fileSize the size of the file that will be uploaded.
+ * @return the created file instance.
+ */
+ public BoxFile.Info uploadLargeFile(InputStream inputStream, long fileSize) {
URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), this.getID());
return LargeFileUpload.upload(this.getAPI(), inputStream, url, fileSize);
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 05ab31a35..995c5268f 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -19,6 +19,12 @@
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
+/**
+ * This API provides a way to reliably upload larger files to Box by chunking them into a sequence of parts.
+ * When using this APIinstead of the single file upload API, a request failure means a client only needs to
+ * retry upload of a single part instead of the entire file. Parts can also be uploaded in parallel allowing
+ * for potential performance improvement.
+ */
@BoxResourceType("upload-session")
public class BoxFileUploadSession extends BoxResource {
@@ -30,12 +36,20 @@ public class BoxFileUploadSession extends BoxResource {
private Info sessionInfo;
+ /**
+ * Constructs a BoxFileUploadSession for a file with a given ID.
+ * @param api the API connection to be used by the upload session.
+ * @param id the ID of the upload session.
+ */
BoxFileUploadSession(BoxAPIConnection api, String id) {
super(api, id);
}
+ /**
+ * Model contains the upload session information.
+ */
public class Info extends BoxResource.Info {
- private BoxAPIConnection api;
+
private Date sessionExpiresAt;
private String uploadSessionId;
private Endpoints sessionEndpoints;
@@ -43,23 +57,6 @@ public class Info extends BoxResource.Info {
private int totalParts;
private int partsProcessed;
- /**
- * Constructs an empty Info object.
- */
- public Info() {
- super();
- BoxFileUploadSession.this.sessionInfo = this;
- }
-
- /**
- * Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
- */
- public Info(String json) {
- super(json);
- BoxFileUploadSession.this.sessionInfo = this;
- }
-
/**
* Constructs an Info object using an already parsed JSON object.
* @param jsonObject the parsed JSON object.
@@ -69,42 +66,63 @@ public Info(String json) {
BoxFileUploadSession.this.sessionInfo = this;
}
- private BoxAPIConnection getAPI() {
- return this.api;
- }
-
- private void setAPI(BoxAPIConnection api) {
- this.api = api;
- }
-
+ /**
+ * Returns the BoxFileUploadSession isntance to which this object belongs to.
+ * @return the instance of upload session.
+ */
public BoxFileUploadSession getResource() {
return BoxFileUploadSession.this;
}
+ /**
+ * Returns the total parts of the file that is uploaded in the upload session.
+ * @return the total number of parts.
+ */
public int getTotalParts() {
return this.totalParts;
}
+ /**
+ * Returns the parts that are processed so for.
+ * @return the number of the processed parts.
+ */
public int getPartsProcessed() {
return this.partsProcessed;
}
+ /**
+ * Returns the date and time at which the upload session expires.
+ * @return the date and time in UTC format.
+ */
public Date getSessionExpiresAt() {
return this.sessionExpiresAt;
}
+ /**
+ * Returns the upload session id.
+ * @return the id string.
+ */
public String getUploadSessionId() {
return this.uploadSessionId;
}
+ /**
+ * Returns the session endpoints that can be called for this upload session.
+ * @return the Endpoints instance.
+ */
public Endpoints getSessionEndpoints() {
return this.sessionEndpoints;
}
+ /**
+ * Returns the size of the each part. Only the last part of the file can be lessor than this value.
+ * @return the part size.
+ */
public long getPartSize() {
return this.partSize;
}
+ @Override
protected void parseJSONMember(JsonObject.Member member) {
String memberName = member.getName();
@@ -130,6 +148,9 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
+ /**
+ * Represents the end points specific to an upload session.
+ */
public class Endpoints extends BoxJSONObject {
private URL listPartsEndpoint;
private URL commitEndpoint;
@@ -137,26 +158,50 @@ public class Endpoints extends BoxJSONObject {
private URL statusEndpoint;
private URL abortEndpoint;
+ /**
+ * Constructs an Endpoints object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
Endpoints(JsonObject jsonObject) {
super(jsonObject);
}
+ /**
+ * Returns the list parts end point.
+ * @return the url of the list parts end point.
+ */
public URL getListPartsEndpoint() {
return this.listPartsEndpoint;
}
+ /**
+ * Returns the commit end point.
+ * @return the url of the commit end point.
+ */
public URL getCommitEndpoint() {
return this.commitEndpoint;
}
+ /**
+ * Returns the upload part end point.
+ * @return the url of the upload part end point.
+ */
public URL getUploadPartEndpoint() {
return this.uploadPartEndpoint;
}
+ /**
+ * Returns the upload session status end point.
+ * @return the url of the session end point.
+ */
public URL getStatusEndpoint() {
return this.statusEndpoint;
}
+ /**
+ * Returns the abort upload session end point.
+ * @return the url of the abort end point.
+ */
public URL getAbortEndpoint() {
return this.abortEndpoint;
}
@@ -184,8 +229,18 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
+ /**
+ * Uploads a chunk of a file to an open upload session.
+ * @param partId a unique 8 character hex number that identifies the part.
+ * @param stream the stream that is used to read the chunck using the offset and part size.
+ * @param offset the byte position where the chunk begins in the file.
+ * @param partSize the part size returned as part of the upload session instance creation.
+ * Only the last chunk can have a lesser value.
+ * @param totalSizeOfFile The total size of the file being uploaded.
+ * @return the part instance that contains the part id, offset and part size.
+ */
public BoxFileUploadSessionPart uploadPart(String partId, InputStream stream, long offset, long partSize,
- long totalSizeOfFile) throws IOException, NoSuchAlgorithmException {
+ long totalSizeOfFile) {
URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
@@ -193,15 +248,30 @@ public BoxFileUploadSessionPart uploadPart(String partId, InputStream stream, lo
request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
request.addHeader(HttpHeaders.X_BOX_PART_ID, partId);
+ //Read the partSize bytes from the stream
byte[] bytes = new byte[(int) partSize];
- stream.read(bytes);
+ try {
+ stream.read(bytes);
+ } catch (IOException ioe) {
+ throw new BoxAPIException("Reading data from stream failed.", ioe);
+ }
+
+ MessageDigest digestInstance = null;
+ try {
+ digestInstance = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ } catch (NoSuchAlgorithmException ae) {
+ throw new BoxAPIException("Digest algorithm not found", ae);
+ }
- byte[] digestBytes = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1).digest(bytes);
+ //Creates the digest using SHA1 algorithm. Then encodes the bytes using Base64.
+ byte[] digestBytes = digestInstance.digest(bytes);
String digest = Base64.encode(digestBytes);
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
+ //Content-Range: bytes offset-part/totalSize
request.addHeader(HttpHeaders.CONTENT_RANGE,
"bytes " + offset + "-" + (offset + partSize - 1) + "/" + totalSizeOfFile);
+ //Creates the body
request.setBody(new ByteArrayInputStream(bytes));
request.send();
@@ -213,6 +283,12 @@ public BoxFileUploadSessionPart uploadPart(String partId, InputStream stream, lo
return part;
}
+ /**
+ * Returns a list of all parts that have been uploaded to an upload session.
+ * @param marker paging marker for the list of parts.
+ * @param limit maximum number of parts to return.
+ * @return the list of parts.
+ */
public BoxFileUploadSessionPartList listParts(int marker, int limit) {
URL listPartsURL = this.sessionInfo.getSessionEndpoints().getListPartsEndpoint();
URLTemplate template = new URLTemplate(listPartsURL.toString());
@@ -221,6 +297,7 @@ public BoxFileUploadSessionPartList listParts(int marker, int limit) {
.appendParam(MARKER_QUERY_STRING, marker)
.appendParam(LIMIT_QUERY_STRING, limit)
.toString();
+ //Template is initalized with the full URL. So empty string for the path.
URL url = template.buildWithQuery("", queryString);
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, HttpMethod.GET);
@@ -230,6 +307,15 @@ public BoxFileUploadSessionPartList listParts(int marker, int limit) {
return new BoxFileUploadSessionPartList(jsonObject);
}
+ /**
+ * Commit an upload session after all parts have been uploaded, creating the new file or the version.
+ * @param digest the base64-encoded SHA-1 hash of the file being uploaded.
+ * @param parts the list of uploaded parts to be committed.
+ * @param attributes the key value pairs of attributes from the file instance.
+ * @param ifMatch ensures that your app only alters files/folders on Box if you have the current version.
+ * @param ifNoneMatch ensure that it retrieve unnecessary data if the most current version of file is on-hand.
+ * @return the created file instance.
+ */
public BoxFile.Info commit(String digest, List parts,
Map attributes, String ifMatch, String ifNoneMatch) {
@@ -246,10 +332,12 @@ public BoxFile.Info commit(String digest, List parts,
request.addHeader(HttpHeaders.IF_NONE_MATCH, ifNoneMatch);
}
+ //Creates the body of the request
String body = this.getCommitBody(parts, attributes);
request.setBody(body);
BoxAPIResponse response = request.send();
+ //Retry the commit operation after the given number of seconds if the HTTP response code is 202.
if (response.getResponseCode() == 202) {
String retryInterval = response.getHeaderField("retry-after");
if (retryInterval != null) {
@@ -264,6 +352,7 @@ public BoxFile.Info commit(String digest, List parts,
}
if (response instanceof BoxJSONResponse) {
+ //Create the file instance from the response
return this.getFile((BoxJSONResponse) response);
} else {
throw new BoxAPIException("Commit response content type is not application/json. The response code : "
@@ -271,6 +360,9 @@ public BoxFile.Info commit(String digest, List parts,
}
}
+ /*
+ * Creates the file isntance from the JSON body of the response.
+ */
private BoxFile.Info getFile(BoxJSONResponse response) {
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
@@ -282,6 +374,9 @@ private BoxFile.Info getFile(BoxJSONResponse response) {
return file.new Info(fileObj);
}
+ /*
+ * Creates the JSON body for the commit request.
+ */
private String getCommitBody(List parts, Map attributes) {
JsonObject jsonObject = new JsonObject();
@@ -307,6 +402,11 @@ private String getCommitBody(List parts, Map getParts() {
return this.parts;
}
+ /**
+ * Returns the paging marker for the list of parts.
+ * @return the paging marker.
+ */
public int getMarker() {
return this.marker;
}
+ @Override
protected void parseJSONMember(JsonObject.Member member) {
String memberName = member.getName();
JsonValue value = member.getValue();
@@ -45,6 +55,9 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
+ /*
+ * Creates List of parts from the JSON array
+ */
private List getParts(JsonArray partsArray) {
List parts = new ArrayList();
for (JsonValue value: partsArray) {
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index cf49647d3..68b7a9467 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -729,6 +729,13 @@ public void deleteMetadata(String templateName, String scope) {
response.disconnect();
}
+ /**
+ * Creates an upload session to create a new file in chunks.
+ * This will first verify that the file can be created and then open a session for uploading pieces of the file.
+ * @param fileName the name of the file to be created
+ * @param fileSize the size of the file that will be uploaded
+ * @return the created upload session instance
+ */
public BoxFileUploadSession.Info createUploadSession(String fileName, long fileSize) {
URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL());
@@ -749,7 +756,14 @@ public BoxFileUploadSession.Info createUploadSession(String fileName, long fileS
return session.new Info(jsonObject);
}
- public BoxFile.Info uploadLargeFile(InputStream inputStream, String fileName, long fileSize) throws Exception {
+ /**
+ * Creates a new file.
+ * @param inputStream the stream instance that contains the data.
+ * @param fileName the name of the file to be created.
+ * @param fileSize the size of the file that will be uploaded.
+ * @return the created file instance.
+ */
+ public BoxFile.Info uploadLargeFile(InputStream inputStream, String fileName, long fileSize) {
URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL());
return LargeFileUpload.upload(this.getAPI(), this.getID(), inputStream, url, fileName, fileSize);
diff --git a/src/main/java/com/box/sdk/LargeFileUpload.java b/src/main/java/com/box/sdk/LargeFileUpload.java
index 8024cf749..44fd9bce7 100644
--- a/src/main/java/com/box/sdk/LargeFileUpload.java
+++ b/src/main/java/com/box/sdk/LargeFileUpload.java
@@ -1,9 +1,11 @@
package com.box.sdk;
+import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@@ -12,7 +14,7 @@
import com.eclipsesource.json.JsonObject;
/**
- *
+ * Utility class for uploading large files.
*/
public final class LargeFileUpload {
@@ -25,18 +27,37 @@ public final class LargeFileUpload {
private LargeFileUpload() {
}
+ /**
+ * Uploads a new large file.
+ * @param boxApi the API connection to be used by the upload session.
+ * @param folderId the id of the folder in which the file will be uploaded.
+ * @param stream the input stream that feeds the content of the file.
+ * @param url the upload session URL.
+ * @param fileName the name of the file to be created.
+ * @param fileSize the total size of the file.
+ * @return the created file instance.
+ */
static BoxFile.Info upload(BoxAPIConnection boxApi, String folderId, InputStream stream, URL url,
- String fileName, long fileSize) throws Exception {
+ String fileName, long fileSize) {
+ //Create a upload session
BoxFileUploadSession.Info session = createUploadSession(boxApi, folderId, url, fileName, fileSize);
- MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ MessageDigest digest = null;
+ try {
+ digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ } catch (NoSuchAlgorithmException ae) {
+ throw new BoxAPIException("Digest algorithm not found", ae);
+ }
+
+ //Upload parts using the upload session
List parts = uploadParts(session, stream, fileSize, digest);
+ //Creates the file hash
byte[] digestBytes = digest.digest();
String digestStr = Base64.encode(digestBytes);
- BoxFileUploadSessionPartList list = session.getResource().listParts(0, 1000);
+ //Commit the upload session. If there is a failure, abort the commit.
try {
return session.getResource().commit(digestStr, parts, null, null, null);
} finally {
@@ -49,6 +70,7 @@ private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection bo
BoxJSONRequest request = new BoxJSONRequest(boxApi, url, HttpMethod.POST);
+ //Create the JSON body of the request
JsonObject body = new JsonObject();
body.add("folder_id", folderId);
body.add("file_name", fileName);
@@ -64,15 +86,34 @@ private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection bo
return session.new Info(jsonObject);
}
- static BoxFile.Info upload(BoxAPIConnection boxApi, InputStream stream, URL url, long fileSize) throws Exception {
+ /**
+ * Creates a new version of a large file.
+ * @param boxApi the API connection to be used by the upload session.
+ * @param stream the input stream that feeds the content of the file.
+ * @param url the upload session URL.
+ * @param fileSize the total size of the file.
+ * @return the file instance that also contains the version information.
+ */
+ static BoxFile.Info upload(BoxAPIConnection boxApi, InputStream stream, URL url, long fileSize) {
+
+ //creates a upload session
BoxFileUploadSession.Info session = createUploadSession(boxApi, url, fileSize);
- MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ MessageDigest digest = null;
+ try {
+ digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ } catch (NoSuchAlgorithmException ae) {
+ throw new BoxAPIException("Digest algorithm not found", ae);
+ }
+
+ //Upload parts using the upload session
List parts = uploadParts(session, stream, fileSize, digest);
+ //Creates the file hash
byte[] digestBytes = digest.digest();
String digestStr = Base64.encode(digestBytes);
+ //Commit the upload session. If there is a failure, abort the commit.
BoxFileUploadSessionPartList list = session.getResource().listParts(0, 1000);
try {
return session.getResource().commit(digestStr, parts, null, null, null);
@@ -83,6 +124,8 @@ static BoxFile.Info upload(BoxAPIConnection boxApi, InputStream stream, URL url,
private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection boxApi, URL url, long fileSize) {
BoxJSONRequest request = new BoxJSONRequest(boxApi, url, HttpMethod.POST);
+
+ //Creates the body of the request
JsonObject body = new JsonObject();
body.add("file_size", fileSize);
request.setBody(body.toString());
@@ -96,8 +139,11 @@ private static BoxFileUploadSession.Info createUploadSession(BoxAPIConnection bo
return session.new Info(jsonObject);
}
+ /*
+ * Upload parts of the file. The part size is retrieved from the upload session.
+ */
private static List uploadParts(BoxFileUploadSession.Info session, InputStream stream,
- long fileSize, MessageDigest digest) throws Exception {
+ long fileSize, MessageDigest digest) {
DigestInputStream dis = new DigestInputStream(stream, digest);
List parts = new ArrayList();
@@ -107,13 +153,16 @@ private static List uploadParts(BoxFileUploadSession.I
long processed = 0;
while (processed < fileSize) {
long diff = fileSize - processed;
+ //The size last part of the file can be lesser than the part size.
if (diff < partSize) {
partSize = diff;
}
+ //Upload a part
BoxFileUploadSessionPart part = uploadPart(session.getResource(), dis, offset, partSize, fileSize);
parts.add(part);
+ //Increase the offset and proceesed bytes to calculate the Content-Range header.
processed += partSize;
offset += partSize;
}
@@ -121,11 +170,15 @@ private static List uploadParts(BoxFileUploadSession.I
return parts;
}
+ /*
+ * Uploads the part of the file.
+ */
private static BoxFileUploadSessionPart uploadPart(BoxFileUploadSession session, InputStream stream, long offset,
- long partSize, long fileSize) throws Exception {
+ long partSize, long fileSize) {
String partId = generateHex();
+ //Retries the upload part 3 times in case of failure.
for (int i = 0; i < 3; i++) {
try {
return session.uploadPart(partId, stream, offset, partSize, fileSize);
@@ -136,9 +189,13 @@ private static BoxFileUploadSessionPart uploadPart(BoxFileUploadSession session,
}
}
- return null;
+ throw new BoxAPIException("Upload part failed for offset: " + offset + " range: " + partSize);
}
+ /**
+ * Generates a 8 character random hex value.
+ * @return the hex string.
+ */
public static String generateHex() {
String hex = "";
while (hex.length() != 8) {
@@ -149,4 +206,34 @@ public static String generateHex() {
return hex;
}
+
+ /**
+ * Generates the Base64 encoded SHA-1 hash for content available in the stream.
+ * It can be used to calculate the hash of a file.
+ * @param stream the input stream of the file or data.
+ * @return the Base64 encoded hash string.
+ */
+ public static String generateDigest(InputStream stream) {
+ MessageDigest digest = null;
+ try {
+ digest = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1);
+ } catch (NoSuchAlgorithmException ae) {
+ throw new BoxAPIException("Digest algorithm not found", ae);
+ }
+
+ //Calcuate the digest using the stream.
+ DigestInputStream dis = new DigestInputStream(stream, digest);
+ try {
+ int value = dis.read();
+ while (value != -1) {
+ value = dis.read();
+ }
+ } catch (IOException ioe) {
+ throw new BoxAPIException("Reading the stream failed.", ioe);
+ }
+
+ //Get the calculated digest for the stream
+ byte[] digestBytes = digest.digest();
+ return Base64.encode(digestBytes);
+ }
}
diff --git a/src/main/java/com/box/sdk/http/ContentType.java b/src/main/java/com/box/sdk/http/ContentType.java
index c16312e1d..1106cc26b 100644
--- a/src/main/java/com/box/sdk/http/ContentType.java
+++ b/src/main/java/com/box/sdk/http/ContentType.java
@@ -1,11 +1,18 @@
package com.box.sdk.http;
/**
- *
+ * HTTP Content-Type constants.
*/
public final class ContentType {
+ /**
+ * It is used when the HTTP request content type is application/json.
+ */
public static final String APPLICATION_JSON = "application/json";
+
+ /**
+ * It is used when the HTTP request content type is application/octet-stream.
+ */
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
//Prevents instantiation
diff --git a/src/main/java/com/box/sdk/http/HttpHeaders.java b/src/main/java/com/box/sdk/http/HttpHeaders.java
index f9b151afa..aac67afeb 100644
--- a/src/main/java/com/box/sdk/http/HttpHeaders.java
+++ b/src/main/java/com/box/sdk/http/HttpHeaders.java
@@ -1,16 +1,43 @@
package com.box.sdk.http;
/**
- *
+ * HTTP header Key constants.
*/
public final class HttpHeaders {
+ /**
+ * HTTP header key Content-Length.
+ */
public static final String CONTENT_LENGTH = "Content-Length";
- public static final String CONTENT_RANGE = "Content-Range";
+
+ /**
+ * HTTP header key Content-Type.
+ */
public static final String CONTENT_TYPE = "Content-Type";
+
+ /**
+ * HTTP header key Content-Range.
+ */
+ public static final String CONTENT_RANGE = "Content-Range";
+
+ /**
+ * HTTP header key DIgest.
+ */
public static final String DIGEST = "Digest";
+
+ /**
+ * HTTP header key If-Match.
+ */
public static final String IF_MATCH = "If-Match";
+
+ /**
+ * HTTP header key If-None-Match.
+ */
public static final String IF_NONE_MATCH = "If-None-Match";
+
+ /**
+ * HTTP header key X-Box-Part-Id.
+ */
public static final String X_BOX_PART_ID = "X-Box-Part-Id";
//Prevents instantiation
diff --git a/src/main/java/com/box/sdk/http/HttpMethod.java b/src/main/java/com/box/sdk/http/HttpMethod.java
index 062b94f54..8c08ff287 100644
--- a/src/main/java/com/box/sdk/http/HttpMethod.java
+++ b/src/main/java/com/box/sdk/http/HttpMethod.java
@@ -1,9 +1,46 @@
package com.box.sdk.http;
/**
- *
+ * HTTP method constants.
*/
public enum HttpMethod {
+ /**
+ * HTTP GET method.
+ */
+ GET,
- GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
+ /**
+ * HTTP HEAD method.
+ */
+ HEAD,
+
+ /**
+ * HTTP POST method.
+ */
+ POST,
+
+ /**
+ * HTTP PUT method.
+ */
+ PUT,
+
+ /**
+ * HTTP PATCH method.
+ */
+ PATCH,
+
+ /**
+ * HTTP DELETE method.
+ */
+ DELETE,
+
+ /**
+ * HTTP OPTIONS method.
+ */
+ OPTIONS,
+
+ /**
+ * HTTP TRACE method.
+ */
+ TRACE;
}
From 0273dbaa0686b58bf9b3434a731f77ea9add003e Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 2 Mar 2017 13:31:05 -0800
Subject: [PATCH 071/119] coding style changes
---
src/test/java/com/box/sdk/BoxFileTest.java | 28 ++++++++++----------
src/test/java/com/box/sdk/BoxFolderTest.java | 6 ++---
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index c6a0620fd..3c7da109a 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -985,19 +985,19 @@ public void uploadSessionCommitFlowSuccess() throws Exception {
long fileSize = file.length();
//Create the session
- BoxFileUploadSession.Info session = createFileUploadSession(rootFolder, fileName, fileSize);
+ BoxFileUploadSession.Info session = this.createFileUploadSession(rootFolder, fileName, fileSize);
//Create the parts
- MessageDigest fileDigest = uploadParts(uploadedFile, session, fileSize);
+ MessageDigest fileDigest = this.uploadParts(uploadedFile, session, fileSize);
//List the session parts
- List parts = listUploadSessionParts(session.getResource());
+ List parts = this.listUploadSessionParts(session.getResource());
byte[] digestBytes = fileDigest.digest();
String digest = Base64.encode(digestBytes);
//Verify the delete session
- uploadedFile = commitSession(session.getResource(), digest, parts);
+ uploadedFile = this.commitSession(session.getResource(), digest, parts);
} finally {
if (uploadedFile != null) {
uploadedFile.delete();
@@ -1029,24 +1029,24 @@ public void uploadSessionVersionCommitFlowSuccess() throws Exception {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
- BoxFile.Info imageFileInfo = createImageFile(rootFolder);
+ BoxFile.Info imageFileInfo = this.createImageFile(rootFolder);
BoxFile uploadedFile = imageFileInfo.getResource();
try {
//Create the session
- BoxFileUploadSession.Info session = createFileUploadSession(uploadedFile, imageFileInfo.getSize());
+ BoxFileUploadSession.Info session = this.createFileUploadSession(uploadedFile, imageFileInfo.getSize());
//Create the parts
- MessageDigest fileDigest = uploadParts(uploadedFile, session, imageFileInfo.getSize());
+ MessageDigest fileDigest = this.uploadParts(uploadedFile, session, imageFileInfo.getSize());
//List the session parts
- List parts = listUploadSessionParts(session.getResource());
+ List parts = this.listUploadSessionParts(session.getResource());
byte[] digestBytes = fileDigest.digest();
String digest = Base64.encode(digestBytes);
//Verify the delete session
- uploadedFile = commitSession(session.getResource(), digest, parts);
+ uploadedFile = this.commitSession(session.getResource(), digest, parts);
} finally {
uploadedFile.delete();
}
@@ -1085,7 +1085,7 @@ private MessageDigest uploadParts(BoxFile uploadedFile, BoxFileUploadSession.Inf
byte[] bytes = null;
long processed = 0;
boolean canBreak = false;
- while(true) {
+ while (true) {
long min = session.getPartSize();
long diff = fileSize - processed;
if (diff < min) {
@@ -1093,7 +1093,7 @@ private MessageDigest uploadParts(BoxFile uploadedFile, BoxFileUploadSession.Inf
canBreak = true;
}
- session.getResource().uploadPart(generateHex(), dis, offset, min, fileSize);
+ session.getResource().uploadPart(this.generateHex(), dis, offset, min, fileSize);
offset = offset + session.getPartSize();
processed += min;
@@ -1158,10 +1158,10 @@ public void uploadSessionAbortFlowSuccess() throws Exception {
Assert.assertNotNull(endpoints.getAbortEndpoint());
//Verify the status of the session
- getUploadSessionStatus(session.getResource());
+ this.getUploadSessionStatus(session.getResource());
//Verify the delete session
- abortUploadSession(session.getResource());
+ this.abortUploadSession(session.getResource());
} finally {
uploadedFile.delete();
}
@@ -1199,7 +1199,7 @@ private void abortUploadSession(BoxFileUploadSession session) {
//If the session is aborted, this line should not be executed.
Assert.assertFalse("Upload session is not deleted", true);
- } catch(BoxAPIException apiEx) {
+ } catch (BoxAPIException apiEx) {
Assert.assertEquals(apiEx.getResponseCode(), 404);
}
}
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index 5da3f0e12..1a94b1a42 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -1093,10 +1093,10 @@ public void uploadSessionAbortFlowSuccess() throws Exception {
Assert.assertNotNull(endpoints.getAbortEndpoint());
//Verify the status of the session
- getUploadSessionStatus(session.getResource());
+ this.getUploadSessionStatus(session.getResource());
//Verify the delete session
- abortUploadSession(session.getResource());
+ this.abortUploadSession(session.getResource());
} finally {
uploadedFile.delete();
}
@@ -1118,7 +1118,7 @@ private void abortUploadSession(BoxFileUploadSession session) {
//If the session is aborted, this line should not be executed.
Assert.assertFalse("Upload session is not deleted", true);
- } catch(BoxAPIException apiEx) {
+ } catch (BoxAPIException apiEx) {
Assert.assertEquals(apiEx.getResponseCode(), 404);
}
}
From faf746b6f17b015dccf254fe478ba2a5738a2cb5 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 2 Mar 2017 17:29:22 -0800
Subject: [PATCH 072/119] BoxFile.Info variable added in files.md
---
doc/files.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/files.md b/doc/files.md
index 6b7113c74..67d997f7e 100644
--- a/doc/files.md
+++ b/doc/files.md
@@ -111,7 +111,7 @@ Files are uploaded to a folder by calling the
```java
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
FileInputStream stream = new FileInputStream("My File.txt");
-rootFolder.uploadFile(stream, "My File.txt");
+BoxFile.Info newFileInfo = rootFolder.uploadFile(stream, "My File.txt");
stream.close();
```
@@ -123,7 +123,7 @@ Upload progress can be tracked by providing the size of the file and a
```java
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
FileInputStream stream = new FileInputStream("My File.txt");
-rootFolder.uploadFile(stream, "My File.txt", 1024, new ProgressListener() {
+BoxFile.Info newFileInfo = rootFolder.uploadFile(stream, "My File.txt", 1024, new ProgressListener() {
public void onProgressChanged(long numBytes, long totalBytes) {
double percentComplete = numBytes / totalBytes;
}
@@ -371,4 +371,4 @@ for (Metadata metadata : metadataList) {
}
```
-[get-all-metadata]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#getAllMetadata(java.lang.String...)
\ No newline at end of file
+[get-all-metadata]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#getAllMetadata(java.lang.String...)
From 8921da7ad2179f70319916292074bccf19d95084 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Sun, 5 Mar 2017 21:53:08 -0800
Subject: [PATCH 073/119] getAuthorizationURL implementation
---
.../java/com/box/sdk/BoxAPIConnection.java | 36 +++++++++++++++++++
.../com/box/sdk/BoxAPIConnectionTest.java | 35 ++++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index 896e0d7c3..32065e454 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -2,6 +2,7 @@
import java.net.MalformedURLException;
import java.net.Proxy;
+import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
@@ -23,6 +24,7 @@ public class BoxAPIConnection {
*/
public static final int DEFAULT_MAX_ATTEMPTS = 3;
+ private static final String AUTHORIZATION_URL = "https://account.box.com/api/oauth2/authorize";
private static final String TOKEN_URL_STRING = "https://api.box.com/oauth2/token";
private static final String DEFAULT_BASE_URL = "https://api.box.com/2.0/";
private static final String DEFAULT_BASE_UPLOAD_URL = "https://upload.box.com/api/2.0/";
@@ -125,6 +127,40 @@ public static BoxAPIConnection restore(String clientID, String clientSecret, Str
return api;
}
+ /**
+ * Return the authorization URL which is used to perform the authorization_code based OAuth2 flow.
+ * @param clientID the client ID to use with the connection.
+ * @param redirectUri the URL to which Box redirects the browser when authentication completes.
+ * @param state the text string that you choose.
+ * Box sends the same string to your redirect URL when authentication is complete.
+ * @param scopes this optional parameter identifies the Box scopes available
+ * to the application once it's authenticated.
+ * @return the authorization URL
+ */
+ public static URL getAuthorizationURL(String clientID, URI redirectUri, String state, List scopes) {
+ URLTemplate template = new URLTemplate(AUTHORIZATION_URL);
+ QueryStringBuilder queryBuilder = new QueryStringBuilder().appendParam("client_id", clientID)
+ .appendParam("response_type", "code")
+ .appendParam("redirect_uri", redirectUri.toString())
+ .appendParam("state", state);
+
+ if (scopes != null && !scopes.isEmpty()) {
+ StringBuilder builder = new StringBuilder();
+ int size = scopes.size() - 1;
+ int i = 0;
+ while (i < size) {
+ builder.append(scopes.get(i));
+ builder.append(",");
+ i++;
+ }
+ builder.append(scopes.get(i));
+
+ queryBuilder.appendParam("scope", builder.toString());
+ }
+
+ return template.buildWithQuery("", queryBuilder.toString());
+ }
+
/**
* Authenticates the API connection by obtaining access and refresh tokens using the auth code that was obtained
* from the first half of OAuth.
diff --git a/src/test/java/com/box/sdk/BoxAPIConnectionTest.java b/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
index c37cd6ce9..a4ea5bb18 100644
--- a/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
+++ b/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
@@ -1,7 +1,11 @@
package com.box.sdk;
import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertFalse;
@@ -11,6 +15,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -119,6 +124,36 @@ public String getJSON() {
assertFalse(restoredAPI.needsRefresh());
}
+ @Test
+ @Category(UnitTest.class)
+ public void getAuthorizetionURLSuccess() throws Exception {
+ List scopes = new ArrayList();
+ scopes.add("root_readwrite");
+
+ URL authURL = BoxAPIConnection.getAuthorizationURL("wncmz88sacf5oyaxf502dybcruqbzzy0",
+ new URI("http://localhost:3000"), "test", scopes);
+
+ System.out.println("Response: " + authURL.toString());
+
+ Assert.assertTrue(authURL.toString().startsWith("https://account.box.com/api/oauth2/authorize"));
+
+ StringTokenizer tokenizer = new StringTokenizer(authURL.getQuery(), "&");
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ if (token.startsWith("client_id")) {
+ Assert.assertEquals(token, "client_id=wncmz88sacf5oyaxf502dybcruqbzzy0");
+ } else if (token.startsWith("response_type")) {
+ Assert.assertEquals(token, "response_type=code");
+ } else if (token.startsWith("redirect_uri")) {
+ Assert.assertEquals(token, "redirect_uri=http%3A%2F%2Flocalhost%3A3000");
+ } else if (token.startsWith("state")) {
+ Assert.assertEquals(token, "state=test");
+ } else if (token.startsWith("scope")) {
+ Assert.assertEquals(token, "scope=root_readwrite");
+ }
+ }
+ }
+
@Test
@Category(IntegrationTest.class)
public void requestIsSentNormallyWhenInterceptorReturnsNullResponse() throws MalformedURLException {
From 1583029bdef02124e2859cab282760a1ca6dc95f Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Mon, 6 Mar 2017 13:48:57 -0800
Subject: [PATCH 074/119] Scopes are delimited by spaces
---
src/main/java/com/box/sdk/BoxAPIConnection.java | 2 +-
src/test/java/com/box/sdk/BoxAPIConnectionTest.java | 5 ++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index 32065e454..709a58726 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -150,7 +150,7 @@ public static URL getAuthorizationURL(String clientID, URI redirectUri, String s
int i = 0;
while (i < size) {
builder.append(scopes.get(i));
- builder.append(",");
+ builder.append(" ");
i++;
}
builder.append(scopes.get(i));
diff --git a/src/test/java/com/box/sdk/BoxAPIConnectionTest.java b/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
index a4ea5bb18..895ac561a 100644
--- a/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
+++ b/src/test/java/com/box/sdk/BoxAPIConnectionTest.java
@@ -129,12 +129,11 @@ public String getJSON() {
public void getAuthorizetionURLSuccess() throws Exception {
List scopes = new ArrayList();
scopes.add("root_readwrite");
+ scopes.add("manage_groups");
URL authURL = BoxAPIConnection.getAuthorizationURL("wncmz88sacf5oyaxf502dybcruqbzzy0",
new URI("http://localhost:3000"), "test", scopes);
- System.out.println("Response: " + authURL.toString());
-
Assert.assertTrue(authURL.toString().startsWith("https://account.box.com/api/oauth2/authorize"));
StringTokenizer tokenizer = new StringTokenizer(authURL.getQuery(), "&");
@@ -149,7 +148,7 @@ public void getAuthorizetionURLSuccess() throws Exception {
} else if (token.startsWith("state")) {
Assert.assertEquals(token, "state=test");
} else if (token.startsWith("scope")) {
- Assert.assertEquals(token, "scope=root_readwrite");
+ Assert.assertEquals(token, "scope=root_readwrite+manage_groups");
}
}
}
From 7a75bcf2d5ba332c5d0d5329336b0903af246549 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 7 Mar 2017 11:29:33 -0800
Subject: [PATCH 075/119] Files examples updates
---
doc/files.md | 229 ++++++++++++++++++
.../com/box/sdk/BoxFileUploadSession.java | 4 +-
.../java/com/box/sdk/LargeFileUpload.java | 5 +-
src/test/java/com/box/sdk/BoxFileTest.java | 6 +-
src/test/java/com/box/sdk/BoxFolderTest.java | 6 +-
5 files changed, 239 insertions(+), 11 deletions(-)
diff --git a/doc/files.md b/doc/files.md
index 67d997f7e..44fcb8908 100644
--- a/doc/files.md
+++ b/doc/files.md
@@ -134,6 +134,119 @@ stream.close();
[upload]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#uploadFile(java.io.InputStream,%20java.lang.String)
[upload2]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#uploadFile(java.io.InputStream,%20java.lang.String,%20long,%20com.box.sdk.ProgressListener)
+Upload a large File in chunks
+--------------------------------------
+
+An upload session can be created with the [`createUploadSession(fileName, fileSize)`][create-upload-session] method to
+upload a large file in chunks.
+
+```java
+//Create the upload session
+BoxFile file = new BoxFile(api, "id");
+BoxFileUploadSession.Info sessionInfo = file.createUploadSession("My_Large_File.txt", fileSize);
+
+//Get the session resource from the session info
+BoxFileUploadSession session = sessionInfo.getResource();
+
+//Create the Message Digest for the whole file
+MessageDigest digest = null;
+try {
+ digest = MessageDigest.getInstance("SHA1");
+} catch (NoSuchAlgorithmException ae) {
+ throw new BoxAPIException("Digest algorithm not found", ae);
+}
+```
+Once the upload session is created, using that session the large file can be uploaded in chuncks with the
+[`uploadPart(partId, stream, offset, partSize, totalSizeOfFile)`][upload-part] method of the session instance.
+If there is a failure in uploading any of the parts,
+the failed part can be uploaded again without affecting the other parts.
+
+```java
+//Reading a large file
+FileInputStream fis = new FileInputStream("My_Large_File.txt");
+//Create the digest input stream to calculate the digest for the whole file.
+DigestInputStream dis = new DigestInputStream(fis, digest);
+
+List parts = new ArrayList();
+
+//Get the part size. Each uploaded part should match the part size returned as part of the upload session.
+//The last part of the file can be less than part size if the remaining bytes of the last part is less than
+//the given part size
+long partSize = sessionInfo.getPartSize();
+//Start byte of the part
+long offset = 0;
+//Overall of bytes processed so far
+long processed = 0;
+while (processed < fileSize) {
+ long diff = fileSize - processed;
+ //The size last part of the file can be lesser than the part size.
+ if (diff < partSize) {
+ partSize = diff;
+ }
+
+ //Generate a unique partId
+ String partId = LargeFileUpload.generateHex();
+ //Upload a part. It can be uploaded asynchorously
+ BoxFileUploadSessionPart part = session.uploadPart(partId, dis, offset, partSize, fileSize);
+ parts.add(part);
+
+ //Increase the offset and proceesed bytes to calculate the Content-Range header.
+ processed += partSize;
+ offset += partSize;
+}
+```
+
+At any point in time, the list of parts that are being uploaded successfully can be retrivied with the
+[`listParts(marker, limit)`][list-parts] method of the session instance.
+
+```java
+//The following snippet retrives first 1000 parts that are uploaded. Both can be modified based on the needs.
+BoxFileUploadSessionPartList partList = session.listParts(0, 1000);
+List parts = partList.getParts();
+```
+Once all the parts are uploaded successfully. the upload sessiion can be commited with the
+[`commit(digest, parts, attributes, ifMatch, ifNoneMatch)`][upload-session-commit] method.
+
+```java
+//Creates the file hash
+byte[] digestBytes = digest.digest();
+//Base64 encoding of the hash
+String digestStr = Base64.encode(digestBytes);
+
+//Commit the upload session. If there is a failure, abort the commit.
+BoxFile.Info fileInfo = session.commit(digestStr, parts, null, null, null);
+```
+
+The upload session can be aborted at any time with the [`abort()`][upload-session-abort] method of the session instance.
+
+```java
+session.abort();
+```
+
+The upload session status can be retrived at any time with the [`getstatus()`][upload-session-status] method.
+This call will update the parts processed and other information in the session info instance.
+```java
+BoxFileUploadSession.Info updatedSessionInfo = session.getStatus();
+```
+
+[create-upload-session]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#createUploadSession(java.lang.String,%20long)
+
+Create a large File
+-------------------
+
+A large file can be uploaded with the [`uploadLargeFile(InputStream, fileName, fileSize)`][upload-large-file] method.
+
+```java
+File myFile = new File("My Large_File.txt");
+FileInputStream stream = new FileInputStream(myFile);
+
+BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+BoxFile.Info fileInfo = rootFolder.uploadLargeFile(inputStream, "My_Large_File.txt", myFile.length());
+```
+
+[upload-large-file]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#uploadLargeFile(java.io.InputStream,%20java.lang.String,%20long)
+
+
Copy a File
-----------
@@ -239,6 +352,122 @@ firstVersion.delete();
[delete-version]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileVersion.html#delete()
+Create a versioning of a large File by uploading its content in chunks
+----------------------------------------------------------------------
+
+An upload session can be created with the [`createUploadSession(fileSize)`][create-upload-session-version]
+method to upload new version of a large file in chunks.
+
+```java
+BoxFile file = new BoxFile(api, "id");
+BoxFileUploadSession.Info session = file.createUploadSession(fileSize);
+
+//Get the session resource from the session info
+BoxFileUploadSession session = sessionInfo.getResource();
+
+//Create the Message Digest for the whole file
+MessageDigest digest = null;
+try {
+ digest = MessageDigest.getInstance("SHA1");
+} catch (NoSuchAlgorithmException ae) {
+ throw new BoxAPIException("Digest algorithm not found", ae);
+}
+```
+Once the upload session is created, the large file can be uploaded in chuncks with the
+[`uploadPart(partId, stream, offset, partSize, totalSizeOfFile)`][upload-part] method of the session instance.
+If there is a failure in uploading any of the parts, the failed part can be uploaded again without
+affecting the other parts.
+
+```java
+//Reading a large file
+FileInputStream fis = new FileInputStream("My_Large_File.txt");
+//Create the digest input stream to calculate the digest for the whole file.
+DigestInputStream dis = new DigestInputStream(fis, digest);
+
+List parts = new ArrayList();
+
+//Get the part size. Each uploaded part should match the part size returned as part of the upload session.
+//The last part of the file can be less than part size if the remaining bytes of the last part is less than
+//the given part size
+long partSize = sessionInfo.getPartSize();
+//Start byte of the part
+long offset = 0;
+//Overall of bytes processed so far
+long processed = 0;
+while (processed < fileSize) {
+ long diff = fileSize - processed;
+ //The size last part of the file can be lesser than the part size.
+ if (diff < partSize) {
+ partSize = diff;
+ }
+
+ //Generate a unique partId
+ String partId = LargeFileUpload.generateHex();
+ //Upload a part. It can be uploaded asynchorously
+ BoxFileUploadSessionPart part = session.uploadPart(partId, dis, offset, partSize, fileSize);
+ parts.add(part);
+
+ //Increase the offset and proceesed bytes to calculate the Content-Range header.
+ processed += partSize;
+ offset += partSize;
+}
+```
+At any point in time, the list of parts that are being uploaded successfully can be retrivied with the
+[`listParts(marker, limit)`][list-parts] method of the session instance.
+
+```java
+//The following snippet retrives first 1000 parts that are uploaded. Both can be modified based on the needs.
+BoxFileUploadSessionPartList partList = session.listParts(0, 1000);
+List parts = partList.getParts();
+```
+Once all the parts are uploaded successfully. the upload sessiion can be commited with the
+[`commit(digest, parts, attributes, ifMatch, ifNoneMatch)`][upload-session-commit] method.
+
+```java
+//Creates the file hash
+byte[] digestBytes = digest.digest();
+//Base64 encoding of the hash
+String digestStr = Base64.encode(digestBytes);
+
+//Commit the upload session. If there is a failure, abort the commit.
+BoxFile.Info fileInfo = session.commit(digestStr, parts, null, null, null);
+```
+
+The upload session can be aborted at any time with the [`abort()`][upload-session-abort] method of the session instance.
+
+```java
+session.abort();
+```
+
+The upload session status can be retrived at any time with the [`getstatus()`][upload-session-status] method.
+This call will update the parts processed and other information in the session info instance.
+```java
+BoxFileUploadSession.Info sessionInfo = session.getStatus();
+```
+
+[create-upload-session-version]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#uploadVersion(long)
+[upload-part]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileUploadSession.html#uploadPart(java.lang.String,%20java.io.InputStream,%20long,%20long,%20long)
+[list-parts]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileUploadSession.html#listParts(int,%20int)
+[upload-session-commit]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileUploadSession.html#commit(java.lang.String,%20java.util.List,%20java.util.Map,%20java.lang.String,%20java.lang.String)
+[upload-session-abort]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileUploadSession.html#abort()
+[upload-session-status]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFileUploadSession.html#getStatus()
+
+Create new version of a large File
+----------------------------------
+
+New versions of a large file can be uploaded with the
+[`uploadLargeFile(InputStream, fileSize)`][upload-large-file-version] method.
+
+```java
+File myFile = new File("My File.txt");
+FileInputStream stream = new FileInputStream(myFile);
+
+BoxFile file = new BoxFile(api, "id");
+BoxFile.Info versionedFileInfo = file.uploadLargeFile(inputStream, myFile.length());
+```
+
+[upload-large-file-version]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#uploadLargeFile(java.io.InputStream,%20long)
+
Lock a File
-----------
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 995c5268f..11bb2f621 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -407,7 +407,7 @@ private String getCommitBody(List parts, Map
Date: Tue, 7 Mar 2017 13:58:03 -0800
Subject: [PATCH 076/119] large file upload test file input modified
---
src/test/java/com/box/sdk/BoxFileTest.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index a2683a309..71835d737 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -1214,7 +1214,10 @@ private static byte[] readAllBytes(String fileName) throws IOException {
@Test
@Category(IntegrationTest.class)
public void uploadLargeFile() throws Exception {
- File file = new File("/Users/kshanmugasundaram/Downloads/tenmb");
+ String fileName = "Tamme-Lauri_tamm_suvepäeval.jpg";
+ URL fileURL = this.getClass().getResource("/sample-files/" + fileName);
+ String filePath = URLDecoder.decode(fileURL.getFile(), "utf-8");
+ File file = new File(filePath);
FileInputStream stream = new FileInputStream(file);
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
From 6a3ed5680532ddce096e08202ed721a7d938e220 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 7 Mar 2017 14:13:34 -0800
Subject: [PATCH 077/119] 1st cut at single file collab. adds to Box file
---
build.gradle | 11 ++++
src/main/java/com/box/sdk/BoxFile.java | 64 +++++++++++++++++++
.../com/box/sdk/BoxCollaborationTest.java | 34 ++++++++++
.../com/box/sdk/IntegrationTestDebug.java | 7 ++
4 files changed, 116 insertions(+)
create mode 100644 src/test/java/com/box/sdk/IntegrationTestDebug.java
diff --git a/build.gradle b/build.gradle
index 76c9fde6d..6fd312a8c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -95,6 +95,16 @@ task integrationTest(type: Test) {
}
}
+task integrationTestDebug(type: Test) {
+ description 'Runs the integration tests.'
+ group 'Verification'
+ testLogging.showStandardStreams = true
+ useJUnit {
+ includeCategories 'com.box.sdk.IntegrationTestDebug'
+
+ }
+}
+
task integrationTestJWT(type: Test) {
description 'Runs the JWT based integration tests.'
group 'Verification'
@@ -136,6 +146,7 @@ artifacts {
test {
useJUnit {
excludeCategories 'com.box.sdk.IntegrationTest'
+ excludeCategories 'com.box.sdk.IntegrationTestDebug'
excludeCategories 'com.box.sdk.IntegrationTestJWT'
}
}
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 730b38ad9..023489442 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -63,6 +63,9 @@ public enum ThumbnailFileType {
private static final URLTemplate GET_TASKS_URL_TEMPLATE = new URLTemplate("files/%s/tasks");
private static final URLTemplate GET_THUMBNAIL_PNG_TEMPLATE = new URLTemplate("files/%s/thumbnail.png");
private static final URLTemplate GET_THUMBNAIL_JPG_TEMPLATE = new URLTemplate("files/%s/thumbnail.jpg");
+ private static final URLTemplate ADD_COLLABORATION_URL = new URLTemplate("collaborations");
+ private static final URLTemplate GET_COLLABORATIONS_URL = new URLTemplate("folders/%s/collaborations");
+
private static final int BUFFER_SIZE = 8192;
@@ -1112,4 +1115,65 @@ String toJSONValue() {
return this.jsonValue;
}
}
+ private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxCollaboration.Role role) {
+ BoxAPIConnection api = this.getAPI();
+ URL url = ADD_COLLABORATION_URL.build(api.getBaseURL());
+
+ JsonObject itemField = new JsonObject();
+ itemField.add("id", this.getID());
+ itemField.add("type", "file");
+
+ JsonObject requestJSON = new JsonObject();
+ requestJSON.add("item", itemField);
+ requestJSON.add("accessible_by", accessibleByField);
+ requestJSON.add("role", role.toJSONString());
+
+ BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
+ request.setBody(requestJSON.toString());
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+
+ BoxCollaboration newCollaboration = new BoxCollaboration(api, responseJSON.get("id").asString());
+ BoxCollaboration.Info info = newCollaboration.new Info(responseJSON);
+ return info;
+ }
+ /**
+ * Adds a collaborator to this file.
+ * @param collaborator the collaborator to add.
+ * @param role the role of the collaborator.
+ * @return info about the new collaboration.
+ */
+ public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role) {
+ JsonObject accessibleByField = new JsonObject();
+ accessibleByField.add("id", collaborator.getID());
+
+ if (collaborator instanceof BoxUser) {
+ accessibleByField.add("type", "user");
+ } else if (collaborator instanceof BoxGroup) {
+ accessibleByField.add("type", "group");
+ } else {
+ throw new IllegalArgumentException("The given collaborator is of an unknown type.");
+ }
+
+ return this.collaborate(accessibleByField, role);
+ }
+
+
+ /**
+ * Adds a collaborator to this folder. An email will be sent to the collaborator if they don't already have a Box
+ * account.
+ * @param email the email address of the collaborator to add.
+ * @param role the role of the collaborator.
+ * @return info about the new collaboration.
+ */
+ public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role) {
+ JsonObject accessibleByField = new JsonObject();
+ accessibleByField.add("login", email);
+ accessibleByField.add("type", "user");
+
+ return this.collaborate(accessibleByField, role);
+ }
+
+
+
}
diff --git a/src/test/java/com/box/sdk/BoxCollaborationTest.java b/src/test/java/com/box/sdk/BoxCollaborationTest.java
index 6be3d8240..fd325d4ad 100644
--- a/src/test/java/com/box/sdk/BoxCollaborationTest.java
+++ b/src/test/java/com/box/sdk/BoxCollaborationTest.java
@@ -7,6 +7,10 @@
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.logging.Logger;
+
public class BoxCollaborationTest {
@Test
@Category(IntegrationTest.class)
@@ -50,4 +54,34 @@ public void deleteSucceeds() {
folder.delete(false);
}
+
+ @Test
+ @Category(IntegrationTestDebug.class)
+ public void singleFileCollabSucceeds() {
+ Logger logger = TestConfig.enableLogger("FINE");
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ String fileName = "[singleFileCollabSucceeds] Test File.txt";
+ String fileContent = "Test file";
+ byte[] fileBytes = fileContent.getBytes(StandardCharsets.UTF_8);
+ InputStream uploadStream = new ByteArrayInputStream(fileBytes);
+ BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
+
+ String collaboratorLogin = TestConfig.getCollaborator();
+ BoxCollaboration.Role originalRole = BoxCollaboration.Role.VIEWER;
+ BoxCollaboration.Role newRole = BoxCollaboration.Role.EDITOR;
+
+ BoxCollaboration.Info collabInfo = uploadedFile.collaborate(collaboratorLogin, originalRole);
+
+ assertThat(collabInfo.getRole(), is(equalTo(originalRole)));
+
+ BoxCollaboration collab = collabInfo.getResource();
+ collabInfo.setRole(newRole);
+ collab.updateInfo(collabInfo);
+
+ assertThat(collabInfo.getRole(), is(equalTo(newRole)));
+
+ uploadedFile.delete();
+ }
+
}
diff --git a/src/test/java/com/box/sdk/IntegrationTestDebug.java b/src/test/java/com/box/sdk/IntegrationTestDebug.java
new file mode 100644
index 000000000..233180a55
--- /dev/null
+++ b/src/test/java/com/box/sdk/IntegrationTestDebug.java
@@ -0,0 +1,7 @@
+package com.box.sdk;
+
+/**
+ * Created by dmaynard on 3/7/17.
+ */
+public interface IntegrationTestDebug {
+}
From 91b0b62b74d468544073abcff381c8a86ab287b5 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 7 Mar 2017 16:17:56 -0800
Subject: [PATCH 078/119] list parts marker fix
---
.../java/com/box/sdk/BoxFileUploadSession.java | 12 +++++++-----
src/test/java/com/box/sdk/BoxFileTest.java | 18 ++++++++++++------
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 11bb2f621..08f61edce 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -289,14 +289,16 @@ public BoxFileUploadSessionPart uploadPart(String partId, InputStream stream, lo
* @param limit maximum number of parts to return.
* @return the list of parts.
*/
- public BoxFileUploadSessionPartList listParts(int marker, int limit) {
+ public BoxFileUploadSessionPartList listParts(String marker, int limit) {
URL listPartsURL = this.sessionInfo.getSessionEndpoints().getListPartsEndpoint();
URLTemplate template = new URLTemplate(listPartsURL.toString());
- String queryString = new QueryStringBuilder()
- .appendParam(MARKER_QUERY_STRING, marker)
- .appendParam(LIMIT_QUERY_STRING, limit)
- .toString();
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (marker != null) {
+ builder.appendParam(MARKER_QUERY_STRING, marker);
+ }
+ String queryString = builder.appendParam(LIMIT_QUERY_STRING, limit).toString();
+
//Template is initalized with the full URL. So empty string for the path.
URL url = template.buildWithQuery("", queryString);
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 71835d737..29b96cd77 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -1134,14 +1134,20 @@ private BoxFile.Info createImageFile(BoxFolder folder) throws IOException {
@Test
@Category(IntegrationTest.class)
public void uploadSessionAbortFlowSuccess() throws Exception {
- BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
- BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ String fileName = "Tamme-Lauri_tamm_suvepäeval.jpg";
+ URL fileURL = this.getClass().getResource("/sample-files/" + fileName);
+ String filePath = URLDecoder.decode(fileURL.getFile(), "utf-8");
+ File file = new File(filePath);
+ long fileSize = file.length();
- String fileName = "[setCollectionsWithInfoSucceeds] Test File.txt";
- String fileContent = "Test file";
- byte[] fileBytes = fileContent.getBytes(StandardCharsets.UTF_8);
+ FileInputStream stream = new FileInputStream(file);
+ byte[] fileBytes = new byte[(int) file.length()];
+ stream.read(fileBytes);
InputStream uploadStream = new ByteArrayInputStream(fileBytes);
+
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
try {
BoxFileUploadSession.Info session = uploadedFile.createUploadSession(fileBytes.length);
@@ -1168,7 +1174,7 @@ public void uploadSessionAbortFlowSuccess() throws Exception {
}
private List listUploadSessionParts(BoxFileUploadSession session) {
- BoxFileUploadSessionPartList list = session.listParts(0, 10);
+ BoxFileUploadSessionPartList list = session.listParts(null, 10);
List parts = list.getParts();
Assert.assertEquals(parts.size(), 3);
From fbd651866e31673d4932c07a94cfe4f90b019bda Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Tue, 7 Mar 2017 16:23:58 -0800
Subject: [PATCH 079/119] Abort flow implementation
---
src/test/java/com/box/sdk/BoxFolderTest.java | 58 +++++++++++---------
1 file changed, 32 insertions(+), 26 deletions(-)
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index c8a8e78d9..1df2ef634 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -1,9 +1,12 @@
package com.box.sdk;
import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
@@ -1072,34 +1075,37 @@ public void uploadSessionAbortFlowSuccess() throws Exception {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
- String fileName = "[setCollectionsWithInfoSucceeds] Test File.txt";
- String fileContent = "Test file";
- byte[] fileBytes = fileContent.getBytes(StandardCharsets.UTF_8);
+ String fileName = "Tamme-Lauri_tamm_suvepäeval.jpg";
+ URL fileURL = this.getClass().getResource("/sample-files/" + fileName);
+ String filePath = URLDecoder.decode(fileURL.getFile(), "utf-8");
+ File file = new File(filePath);
+ long fileSize = file.length();
+ FileInputStream stream = new FileInputStream(file);
+
+ byte[] fileBytes = new byte[(int) file.length()];
+ stream.read(fileBytes);
InputStream uploadStream = new ByteArrayInputStream(fileBytes);
- BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
- try {
- BoxFileUploadSession.Info session = uploadedFile.createUploadSession(fileBytes.length);
- Assert.assertNotNull(session.getUploadSessionId());
- Assert.assertNotNull(session.getSessionExpiresAt());
- Assert.assertNotNull(session.getPartSize());
-
- BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
- Assert.assertNotNull(endpoints);
- Assert.assertNotNull(endpoints.getUploadPartEndpoint());
- Assert.assertNotNull(endpoints.getStatusEndpoint());
- Assert.assertNotNull(endpoints.getListPartsEndpoint());
- Assert.assertNotNull(endpoints.getCommitEndpoint());
- Assert.assertNotNull(endpoints.getAbortEndpoint());
-
- //Verify the status of the session
- this.getUploadSessionStatus(session.getResource());
-
- //Verify the delete session
- this.abortUploadSession(session.getResource());
- } finally {
- uploadedFile.delete();
- }
+
+ BoxFileUploadSession.Info session = rootFolder.createUploadSession(
+ "Tamme-Lauri_tamm_suvepäeval.jpg", fileBytes.length);
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+
+ //Verify the status of the session
+ this.getUploadSessionStatus(session.getResource());
+
+ //Verify the delete session
+ this.abortUploadSession(session.getResource());
}
private void getUploadSessionStatus(BoxFileUploadSession session) {
From 506de44f319202fb5457b60e104003c1414f0d62 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 9 Mar 2017 09:16:45 -0800
Subject: [PATCH 080/119] Encoding utf-8 is enabled for the build
---
build.gradle | 1 +
1 file changed, 1 insertion(+)
diff --git a/build.gradle b/build.gradle
index 76c9fde6d..d5e199739 100644
--- a/build.gradle
+++ b/build.gradle
@@ -42,6 +42,7 @@ javadoc {
options.noHelp true
options.noDeprecatedList true
options.noNavBar true
+ options.encoding 'utf-8'
options.docEncoding 'utf-8'
options.charSet 'utf-8'
options.linkSource true
From ce816e99c4a6223c47940f782998a614956946e0 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 14 Mar 2017 16:21:03 -0700
Subject: [PATCH 081/119] Adding Single file Collabs and Integration tests
fixes for FolderCollabs
---
.../java/com/box/sdk/BoxCollaboration.java | 75 ++++++--
src/main/java/com/box/sdk/BoxFile.java | 176 ++++++++++++------
src/main/java/com/box/sdk/BoxFolder.java | 78 ++++++++
.../java/com/box/sdk/BoxResourceIterable.java | 2 +-
.../com/box/sdk/BoxCollaborationTest.java | 74 +++++++-
src/test/java/com/box/sdk/BoxFolderTest.java | 76 ++++----
6 files changed, 371 insertions(+), 110 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxCollaboration.java b/src/main/java/com/box/sdk/BoxCollaboration.java
index 255405d44..7c1080eb6 100644
--- a/src/main/java/com/box/sdk/BoxCollaboration.java
+++ b/src/main/java/com/box/sdk/BoxCollaboration.java
@@ -23,20 +23,24 @@ public class BoxCollaboration extends BoxResource {
private static final URLTemplate COLLABORATIONS_URL_TEMPLATE = new URLTemplate("collaborations");
private static final URLTemplate PENDING_COLLABORATIONS_URL = new URLTemplate("collaborations?status=pending");
private static final URLTemplate COLLABORATION_URL_TEMPLATE = new URLTemplate("collaborations/%s");
+ private static final URLTemplate GET_ALL_FILE_COLLABORATIONS_URL = new URLTemplate("files/%s/collaborations/");
/**
* Constructs a BoxCollaboration for a collaboration with a given ID.
- * @param api the API connection to be used by the collaboration.
- * @param id the ID of the collaboration.
+ *
+ * @param api the API connection to be used by the collaboration.
+ * @param id the ID of the collaboration.
*/
public BoxCollaboration(BoxAPIConnection api, String id) {
super(api, id);
}
+
/**
* Gets all pending collaboration invites for the current user.
- * @param api the API connection to use.
- * @return a collection of pending collaboration infos.
+ *
+ * @param api the API connection to use.
+ * @return a collection of pending collaboration infos.
*/
public static Collection getPendingCollaborations(BoxAPIConnection api) {
URL url = PENDING_COLLABORATIONS_URL.build(api.getBaseURL());
@@ -60,6 +64,7 @@ public static Collection getPendingCollaborations(BoxAPIConnection api) {
/**
* Gets information about this collaboration.
+ *
* @return info about this collaboration.
*/
public Info getInfo() {
@@ -74,6 +79,7 @@ public Info getInfo() {
/**
* Updates the information about this collaboration with any info fields that have been modified locally.
+ *
* @param info the updated info.
*/
public void updateInfo(Info info) {
@@ -116,6 +122,7 @@ public class Info extends BoxResource.Info {
private Role role;
private Date acknowledgedAt;
private BoxFolder.Info item;
+ private BoxFile.Info fileItem;
/**
* Constructs an empty Info object.
@@ -126,7 +133,8 @@ public Info() {
/**
* Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
+ *
+ * @param json the JSON string to parse.
*/
public Info(String json) {
super(json);
@@ -138,6 +146,7 @@ public Info(String json) {
/**
* Gets the user who created the collaboration.
+ *
* @return the user who created the collaboration.
*/
public BoxUser.Info getCreatedBy() {
@@ -146,6 +155,7 @@ public BoxUser.Info getCreatedBy() {
/**
* Gets the time the collaboration was created.
+ *
* @return the time the collaboration was created.
*/
public Date getCreatedAt() {
@@ -154,6 +164,7 @@ public Date getCreatedAt() {
/**
* Gets the time the collaboration was last modified.
+ *
* @return the time the collaboration was last modified.
*/
public Date getModifiedAt() {
@@ -162,6 +173,7 @@ public Date getModifiedAt() {
/**
* Gets the time the collaboration will expire.
+ *
* @return the time the collaboration will expire.
*/
public Date getExpiresAt() {
@@ -170,6 +182,7 @@ public Date getExpiresAt() {
/**
* Gets the status of the collaboration.
+ *
* @return the status of the collaboration.
*/
public Status getStatus() {
@@ -178,6 +191,7 @@ public Status getStatus() {
/**
* Sets the status of the collaboration in order to accept or reject the collaboration if it's pending.
+ *
* @param status the new status of the collaboration.
*/
public void setStatus(Status status) {
@@ -187,6 +201,7 @@ public void setStatus(Status status) {
/**
* Gets the collaborator who this collaboration applies to.
+ *
* @return the collaborator who this collaboration applies to.
*/
public BoxCollaborator.Info getAccessibleBy() {
@@ -195,6 +210,7 @@ public BoxCollaborator.Info getAccessibleBy() {
/**
* Gets the level of access the collaborator has.
+ *
* @return the level of access the collaborator has.
*/
public Role getRole() {
@@ -203,6 +219,7 @@ public Role getRole() {
/**
* Sets the level of access the collaborator has.
+ *
* @param role the new level of access to give the collaborator.
*/
public void setRole(Role role) {
@@ -212,6 +229,7 @@ public void setRole(Role role) {
/**
* Gets the time the collaboration's status was changed.
+ *
* @return the time the collaboration's status was changed.
*/
public Date getAcknowledgedAt() {
@@ -220,6 +238,7 @@ public Date getAcknowledgedAt() {
/**
* Gets the folder the collaboration is related to.
+ *
* @return the folder the collaboration is related to.
*/
public BoxFolder.Info getItem() {
@@ -292,7 +311,7 @@ protected void parseJSONMember(JsonObject.Member member) {
private void updateAccessibleBy(JsonObject json) {
String type = json.get("type").asString();
if ((type.equals("user") && this.accessibleBy instanceof BoxUser.Info)
- || (type.equals("group") && this.accessibleBy instanceof BoxGroup.Info)) {
+ || (type.equals("group") && this.accessibleBy instanceof BoxGroup.Info)) {
this.accessibleBy.update(json);
} else {
@@ -345,28 +364,28 @@ public enum Role {
* download, upload, edit, delete, copy, move, rename, generate shared links, make comments, assign tasks,
* create tags, and invite/remove collaborators. They will not be able to delete or move root level folders.
*/
- EDITOR ("editor"),
+ EDITOR("editor"),
/**
* The viewer role has full read access to a folder. Once invited to a folder, they will be able to preview,
* download, make comments, and generate shared links. They will not be able to add tags, invite new
* collaborators, upload, edit, or delete items in the folder.
*/
- VIEWER ("viewer"),
+ VIEWER("viewer"),
/**
* The previewer role has limited read access to a folder. They will only be able to preview the items in the
* folder using the integrated content viewer. They will not be able to share, upload, edit, or delete any
* content. This role is only available to enterprise accounts.
*/
- PREVIEWER ("previewer"),
+ PREVIEWER("previewer"),
/**
* The uploader has limited write access to a folder. They will only be able to upload and see the names of the
* items in a folder. They will not able to download or view any content. This role is only available to
* enterprise accounts.
*/
- UPLOADER ("uploader"),
+ UPLOADER("uploader"),
/**
* The previewer-uploader role is a combination of previewer and uploader. A user with this access level will be
@@ -374,7 +393,7 @@ public enum Role {
* not be able to download, edit, or share, items in the folder. This role is only available to enterprise
* accounts.
*/
- PREVIEWER_UPLOADER ("previewer uploader"),
+ PREVIEWER_UPLOADER("previewer uploader"),
/**
* The viewer-uploader role is a combination of viewer and uploader. A viewer-uploader has full read access to a
@@ -382,7 +401,7 @@ public enum Role {
* upload content to the folder. They will not be able to add tags, invite new collaborators, edit, or delete
* items in the folder. This role is only available to enterprise accounts.
*/
- VIEWER_UPLOADER ("viewer uploader"),
+ VIEWER_UPLOADER("viewer uploader"),
/**
* The co-owner role has all of the functional read/write access that an editor does. This permission level has
@@ -391,14 +410,14 @@ public enum Role {
* manipulate the owner of the folder or transfer ownership to another user. This role is only available to
* enterprise accounts.
*/
- CO_OWNER ("co-owner"),
+ CO_OWNER("co-owner"),
/**
* The owner role has all of the functional capabilities of a co-owner. However, they will be able to manipulate
* the owner of the folder or transfer ownership to another user. This role is only available to enterprise
* accounts.
*/
- OWNER ("owner");
+ OWNER("owner");
private final String jsonValue;
@@ -432,4 +451,32 @@ String toJSONString() {
return this.jsonValue;
}
}
+
+ /**
+ * Used to retrieve all collaborations associated with the item.
+ *
+ * @param api BoxAPIConnection from the associated file.
+ * @param fileID FileID of the assocyaed file
+ * @param pageSize page size for server pages of the Iterable
+ * @param fields the optional fields to retrieve.
+ * @return An iterable of BoxCollaboration.Info instances associated with the item.
+ */
+ public static BoxResourceIterable getAllFileCollaborations(final BoxAPIConnection api, String fileID,
+ int pageSize, String... fields) {
+ QueryStringBuilder builder = new QueryStringBuilder();
+ if (fields.length > 0) {
+ builder.appendParam("fields", fields);
+ }
+ return new BoxResourceIterable(
+ api, GET_ALL_FILE_COLLABORATIONS_URL.buildWithQuery(api.getBaseURL(), builder.toString(), fileID),
+ pageSize) {
+
+ @Override
+ protected BoxCollaboration.Info factory(JsonObject jsonObject) {
+ String id = jsonObject.get("id").asString();
+ return new BoxCollaboration(api, id).new Info(jsonObject);
+ }
+
+ };
+ }
}
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 023489442..2be3d1219 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -23,7 +23,7 @@
*
* Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
* meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
- * handling for errors related to the Box REST API, you should capture this exception explicitly.
+ * handling for errors related to the Box REST API, you should capture this exception explicitly.
*/
@BoxResourceType("file")
public class BoxFile extends BoxItem {
@@ -32,10 +32,12 @@ public class BoxFile extends BoxItem {
* An array of all possible file fields that can be requested when calling {@link #getInfo()}.
*/
public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "sha1", "name",
- "description", "size", "path_collection", "created_at", "modified_at", "trashed_at", "purged_at",
- "content_created_at", "content_modified_at", "created_by", "modified_by", "owned_by", "shared_link", "parent",
- "item_status", "version_number", "comment_count", "permissions", "tags", "lock", "extension", "is_package",
- "file_version", "collections", "watermark_info"};
+ "description", "size", "path_collection", "created_at", "modified_at",
+ "trashed_at", "purged_at", "content_created_at", "content_modified_at",
+ "created_by", "modified_by", "owned_by", "shared_link", "parent",
+ "item_status", "version_number", "comment_count", "permissions", "tags",
+ "lock", "extension", "is_package", "file_version", "collections",
+ "watermark_info"};
/**
* Used to specify what filetype to request for a file thumbnail.
@@ -64,15 +66,17 @@ public enum ThumbnailFileType {
private static final URLTemplate GET_THUMBNAIL_PNG_TEMPLATE = new URLTemplate("files/%s/thumbnail.png");
private static final URLTemplate GET_THUMBNAIL_JPG_TEMPLATE = new URLTemplate("files/%s/thumbnail.jpg");
private static final URLTemplate ADD_COLLABORATION_URL = new URLTemplate("collaborations");
- private static final URLTemplate GET_COLLABORATIONS_URL = new URLTemplate("folders/%s/collaborations");
+ private static final URLTemplate GET_ALL_FILE_COLLABORATIONS_URL = new URLTemplate("files/%s/collaborations");
- private static final int BUFFER_SIZE = 8192;
+ private static final int BUFFER_SIZE = 8192;
+ private static final int GET_COLLABORATORS_PAGE_SIZE = 1000;
/**
* Constructs a BoxFile for a file with a given ID.
- * @param api the API connection to be used by the file.
- * @param id the ID of the file.
+ *
+ * @param api the API connection to be used by the file.
+ * @param id the ID of the file.
*/
public BoxFile(BoxAPIConnection api, String id) {
super(api, id);
@@ -88,7 +92,7 @@ protected URL getItemURL() {
@Override
public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
- BoxSharedLink.Permissions permissions) {
+ BoxSharedLink.Permissions permissions) {
BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions);
Info info = new Info();
@@ -101,10 +105,8 @@ public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareD
/**
* Adds new {@link BoxWebHook} to this {@link BoxFile}.
*
- * @param address
- * {@link BoxWebHook.Info#getAddress()}
- * @param triggers
- * {@link BoxWebHook.Info#getTriggers()}
+ * @param address {@link BoxWebHook.Info#getAddress()}
+ * @param triggers {@link BoxWebHook.Info#getTriggers()}
* @return created {@link BoxWebHook.Info}
*/
public BoxWebHook.Info addWebHook(URL address, BoxWebHook.Trigger... triggers) {
@@ -114,10 +116,11 @@ public BoxWebHook.Info addWebHook(URL address, BoxWebHook.Trigger... triggers) {
/**
* Adds a comment to this file. The message can contain @mentions by using the string @[userid:username] anywhere
* within the message, where userid and username are the ID and username of the person being mentioned.
- * @see the tagged_message field
- * for including @mentions.
- * @param message the comment's message.
+ *
+ * @param message the comment's message.
* @return information about the newly added comment.
+ * @see the tagged_message field
+ * for including @mentions.
*/
public BoxComment.Info addComment(String message) {
JsonObject itemJSON = new JsonObject();
@@ -144,9 +147,10 @@ public BoxComment.Info addComment(String message) {
/**
* Adds a new task to this file. The task can have an optional message to include, and a due date.
- * @param action the action the task assignee will be prompted to do.
+ *
+ * @param action the action the task assignee will be prompted to do.
* @param message an optional message to include with the task.
- * @param dueAt the day at which this task is due.
+ * @param dueAt the day at which this task is due.
* @return information about the newly added task.
*/
public BoxTask.Info addTask(BoxTask.Action action, String message, Date dueAt) {
@@ -180,6 +184,7 @@ public BoxTask.Info addTask(BoxTask.Action action, String message, Date dueAt) {
* Gets an expiring URL for downloading a file directly from Box. This can be user,
* for example, for sending as a redirect to a browser to cause the browser
* to download the file directly from Box.
+ *
* @return the temporary download URL
*/
public URL getDownloadURL() {
@@ -194,6 +199,7 @@ public URL getDownloadURL() {
/**
* Downloads the contents of this file to a given OutputStream.
+ *
* @param output the stream to where the file will be written.
*/
public void download(OutputStream output) {
@@ -202,6 +208,7 @@ public void download(OutputStream output) {
/**
* Downloads the contents of this file to a given OutputStream while reporting the progress to a ProgressListener.
+ *
* @param output the stream to where the file will be written.
* @param listener a listener for monitoring the download's progress.
*/
@@ -227,6 +234,7 @@ public void download(OutputStream output, ProgressListener listener) {
/**
* Downloads a part of this file's contents, starting at specified byte offset.
+ *
* @param output the stream to where the file will be written.
* @param offset the byte offset at which to start the download.
*/
@@ -236,6 +244,7 @@ public void downloadRange(OutputStream output, long offset) {
/**
* Downloads a part of this file's contents, starting at rangeStart and stopping at rangeEnd.
+ *
* @param output the stream to where the file will be written.
* @param rangeStart the byte offset at which to start the download.
* @param rangeEnd the byte offset at which to stop the download.
@@ -247,6 +256,7 @@ public void downloadRange(OutputStream output, long rangeStart, long rangeEnd) {
/**
* Downloads a part of this file's contents, starting at rangeStart and stopping at rangeEnd, while reporting the
* progress to a ProgressListener.
+ *
* @param output the stream to where the file will be written.
* @param rangeStart the byte offset at which to start the download.
* @param rangeEnd the byte offset at which to stop the download.
@@ -257,7 +267,7 @@ public void downloadRange(OutputStream output, long rangeStart, long rangeEnd, P
BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
if (rangeEnd > 0) {
request.addHeader("Range", String.format("bytes=%s-%s", Long.toString(rangeStart),
- Long.toString(rangeEnd)));
+ Long.toString(rangeEnd)));
} else {
request.addHeader("Range", String.format("bytes=%s-", Long.toString(rangeStart)));
}
@@ -343,6 +353,7 @@ public BoxItem.Info move(BoxFolder destination, String newName) {
/**
* Renames this file.
+ *
* @param newName the new name of the file.
*/
public void rename(String newName) {
@@ -383,8 +394,8 @@ public BoxFile.Info getInfo(String... fields) {
* changed:
*
* BoxFile file = new File(api, id);
- *BoxFile.Info info = file.getInfo();
- *file.updateInfo(info);
+ * BoxFile.Info info = file.getInfo();
+ * file.updateInfo(info);
*
* @param info the updated info.
*/
@@ -400,6 +411,7 @@ public void updateInfo(BoxFile.Info info) {
/**
* Gets any previous versions of this file. Note that only users with premium accounts will be able to retrieve
* previous versions of their files.
+ *
* @return a list of previous file versions.
*/
public Collection getVersions() {
@@ -419,9 +431,10 @@ public Collection getVersions() {
/**
* Checks if the file can be successfully uploaded by using the preflight check.
- * @param name the name to give the uploaded file or null to use existing name.
- * @param fileSize the size of the file used for account capacity calculations.
- * @param parentID the ID of the parent folder that the new version is being uploaded to.
+ *
+ * @param name the name to give the uploaded file or null to use existing name.
+ * @param fileSize the size of the file used for account capacity calculations.
+ * @param parentID the ID of the parent folder that the new version is being uploaded to.
*/
public void canUploadVersion(String name, long fileSize, String parentID) {
URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
@@ -446,6 +459,7 @@ public void canUploadVersion(String name, long fileSize, String parentID) {
/**
* Uploads a new version of this file, replacing the current version. Note that only users with premium accounts
* will be able to view and recover previous versions of the file.
+ *
* @param fileContent a stream containing the new file contents.
*/
public void uploadVersion(InputStream fileContent) {
@@ -455,9 +469,9 @@ public void uploadVersion(InputStream fileContent) {
/**
* Uploads a new version of this file, replacing the current version. Note that only users with premium accounts
* will be able to view and recover previous versions of the file.
+ *
* @param fileContent a stream containing the new file contents.
* @param fileContentSHA1 a string containing the SHA1 hash of the new file contents.
- *
*/
public void uploadVersion(InputStream fileContent, String fileContentSHA1) {
this.uploadVersion(fileContent, fileContentSHA1, null);
@@ -466,6 +480,7 @@ public void uploadVersion(InputStream fileContent, String fileContentSHA1) {
/**
* Uploads a new version of this file, replacing the current version. Note that only users with premium accounts
* will be able to view and recover previous versions of the file.
+ *
* @param fileContent a stream containing the new file contents.
* @param fileContentSHA1 a string containing the SHA1 hash of the new file contents.
* @param modified the date that the new version was modified.
@@ -478,10 +493,11 @@ public void uploadVersion(InputStream fileContent, String fileContentSHA1, Date
* Uploads a new version of this file, replacing the current version, while reporting the progress to a
* ProgressListener. Note that only users with premium accounts will be able to view and recover previous versions
* of the file.
- * @param fileContent a stream containing the new file contents.
- * @param modified the date that the new version was modified.
- * @param fileSize the size of the file used for determining the progress of the upload.
- * @param listener a listener for monitoring the upload's progress.
+ *
+ * @param fileContent a stream containing the new file contents.
+ * @param modified the date that the new version was modified.
+ * @param fileSize the size of the file used for determining the progress of the upload.
+ * @param listener a listener for monitoring the upload's progress.
*/
public void uploadVersion(InputStream fileContent, Date modified, long fileSize, ProgressListener listener) {
this.uploadVersion(fileContent, null, modified, fileSize, listener);
@@ -491,6 +507,7 @@ public void uploadVersion(InputStream fileContent, Date modified, long fileSize,
* Uploads a new version of this file, replacing the current version, while reporting the progress to a
* ProgressListener. Note that only users with premium accounts will be able to view and recover previous versions
* of the file.
+ *
* @param fileContent a stream containing the new file contents.
* @param fileContentSHA1 the SHA1 hash of the file contents. will be sent along in the Content-MD5 header
* @param modified the date that the new version was modified.
@@ -528,6 +545,7 @@ public void uploadVersion(InputStream fileContent, String fileContentSHA1, Date
/**
* Gets an expiring URL for creating an embedded preview session. The URL will expire after 60 seconds and the
* preview session will expire after 60 minutes.
+ *
* @return the expiring preview link
*/
public URL getPreviewLink() {
@@ -541,11 +559,12 @@ public URL getPreviewLink() {
* Retrieves a thumbnail, or smaller image representation, of this file. Sizes of 32x32, 64x64, 128x128,
* and 256x256 can be returned in the .png format and sizes of 32x32, 94x94, 160x160, and 320x320 can be returned
* in the .jpg format.
- * @param fileType either PNG of JPG
- * @param minWidth minimum width
- * @param minHeight minimum height
- * @param maxWidth maximum width
- * @param maxHeight maximum height
+ *
+ * @param fileType either PNG of JPG
+ * @param minWidth minimum width
+ * @param minHeight minimum height
+ * @param maxWidth maximum width
+ * @param maxHeight maximum height
* @return the byte array of the thumbnail image
*/
public byte[] getThumbnail(ThumbnailFileType fileType, int minWidth, int minHeight, int maxWidth, int maxHeight) {
@@ -588,6 +607,7 @@ public byte[] getThumbnail(ThumbnailFileType fileType, int minWidth, int minHeig
/**
* Gets a list of any comments on this file.
+ *
* @return a list of comments on this file.
*/
public List getComments() {
@@ -611,6 +631,7 @@ public List getComments() {
/**
* Gets a list of any tasks on this file.
+ *
* @return a list of tasks on this file.
*/
public List getTasks() {
@@ -634,6 +655,7 @@ public List getTasks() {
/**
* Creates metadata on this file in the global properties template.
+ *
* @param metadata The new metadata values.
* @return the metadata returned from the server.
*/
@@ -643,6 +665,7 @@ public Metadata createMetadata(Metadata metadata) {
/**
* Creates metadata on this file in the specified template type.
+ *
* @param typeName the metadata template type name.
* @param metadata the new metadata values.
* @return the metadata returned from the server.
@@ -654,8 +677,9 @@ public Metadata createMetadata(String typeName, Metadata metadata) {
/**
* Creates metadata on this file in the specified template type.
+ *
* @param typeName the metadata template type name.
- * @param scope the metadata scope (global or enterprise).
+ * @param scope the metadata scope (global or enterprise).
* @param metadata the new metadata values.
* @return the metadata returned from the server.
*/
@@ -670,6 +694,7 @@ public Metadata createMetadata(String typeName, String scope, Metadata metadata)
/**
* Locks a file.
+ *
* @param expiresAt expiration date of the lock.
* @return the lock returned from the server.
*/
@@ -679,7 +704,8 @@ public BoxLock lock(Date expiresAt) {
/**
* Locks a file.
- * @param expiresAt expiration date of the lock.
+ *
+ * @param expiresAt expiration date of the lock.
* @param isDownloadPrevented is downloading of file prevented when locked.
* @return the lock returned from the server.
*/
@@ -723,15 +749,17 @@ public void unlock() {
/**
* Used to retrieve all metadata associated with the file.
+ *
* @param fields the optional fields to retrieve.
* @return An iterable of metadata instances associated with the file.
*/
- public Iterable getAllMetadata(String ... fields) {
+ public Iterable getAllMetadata(String... fields) {
return Metadata.getAllMetadata(this, fields);
}
/**
* Gets the file properties metadata.
+ *
* @return the metadata returned from the server.
*/
public Metadata getMetadata() {
@@ -740,6 +768,7 @@ public Metadata getMetadata() {
/**
* Gets the file metadata of specified template type.
+ *
* @param typeName the metadata template type name.
* @return the metadata returned from the server.
*/
@@ -750,8 +779,9 @@ public Metadata getMetadata(String typeName) {
/**
* Gets the file metadata of specified template type.
+ *
* @param typeName the metadata template type name.
- * @param scope the metadata scope (global or enterprise).
+ * @param scope the metadata scope (global or enterprise).
* @return the metadata returned from the server.
*/
public Metadata getMetadata(String typeName, String scope) {
@@ -763,6 +793,7 @@ public Metadata getMetadata(String typeName, String scope) {
/**
* Updates the file metadata.
+ *
* @param metadata the new metadata values.
* @return the metadata returned from the server.
*/
@@ -775,7 +806,7 @@ public Metadata updateMetadata(Metadata metadata) {
}
URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(),
- scope, metadata.getTemplateName());
+ scope, metadata.getTemplateName());
BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "PUT");
request.addHeader("Content-Type", "application/json-patch+json");
request.setBody(metadata.getPatch());
@@ -792,6 +823,7 @@ public void deleteMetadata() {
/**
* Deletes the file metadata of specified template type.
+ *
* @param typeName the metadata template type name.
*/
public void deleteMetadata(String typeName) {
@@ -801,8 +833,9 @@ public void deleteMetadata(String typeName) {
/**
* Deletes the file metadata of specified template type.
+ *
* @param typeName the metadata template type name.
- * @param scope the metadata scope (global or enterprise).
+ * @param scope the metadata scope (global or enterprise).
*/
public void deleteMetadata(String typeName, String scope) {
URL url = METADATA_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID(), scope, typeName);
@@ -813,6 +846,7 @@ public void deleteMetadata(String typeName, String scope) {
/**
* Used to retrieve the watermark for the file.
* If the file does not have a watermark applied to it, a 404 Not Found will be returned by API.
+ *
* @param fields the fields to retrieve.
* @return the watermark associated with the file.
*/
@@ -822,6 +856,7 @@ public BoxWatermark getWatermark(String... fields) {
/**
* Used to apply or update the watermark for the file.
+ *
* @return the watermark associated with the file.
*/
public BoxWatermark applyWatermark() {
@@ -883,7 +918,8 @@ public Info() {
/**
* Constructs an Info object by parsing information from a JSON string.
- * @param json the JSON string to parse.
+ *
+ * @param json the JSON string to parse.
*/
public Info(String json) {
super(json);
@@ -891,7 +927,8 @@ public Info(String json) {
/**
* Constructs an Info object using an already parsed JSON object.
- * @param jsonObject the parsed JSON object.
+ *
+ * @param jsonObject the parsed JSON object.
*/
Info(JsonObject jsonObject) {
super(jsonObject);
@@ -904,6 +941,7 @@ public BoxFile getResource() {
/**
* Gets the SHA1 hash of the file.
+ *
* @return the SHA1 hash of the file.
*/
public String getSha1() {
@@ -912,6 +950,7 @@ public String getSha1() {
/**
* Gets the lock of the file.
+ *
* @return the lock of the file.
*/
public BoxLock getLock() {
@@ -920,6 +959,7 @@ public BoxLock getLock() {
/**
* Gets the current version number of the file.
+ *
* @return the current version number of the file.
*/
public String getVersionNumber() {
@@ -928,6 +968,7 @@ public String getVersionNumber() {
/**
* Gets the number of comments on the file.
+ *
* @return the number of comments on the file.
*/
public long getCommentCount() {
@@ -936,6 +977,7 @@ public long getCommentCount() {
/**
* Gets the permissions that the current user has on the file.
+ *
* @return the permissions that the current user has on the file.
*/
public EnumSet getPermissions() {
@@ -944,6 +986,7 @@ public EnumSet getPermissions() {
/**
* Gets the extension suffix of the file, excluding the dot.
+ *
* @return the extension of the file.
*/
public String getExtension() {
@@ -952,6 +995,7 @@ public String getExtension() {
/**
* Gets whether or not the file is an OSX package.
+ *
* @return true if the file is an OSX package; otherwise false.
*/
public boolean getIsPackage() {
@@ -960,6 +1004,7 @@ public boolean getIsPackage() {
/**
* Gets the current version details of the file.
+ *
* @return the current version details of the file.
*/
public BoxFileVersion getVersion() {
@@ -968,6 +1013,7 @@ public BoxFileVersion getVersion() {
/**
* Gets the current expiring preview link.
+ *
* @return the expiring preview link
*/
public URL getPreviewLink() {
@@ -976,6 +1022,7 @@ public URL getPreviewLink() {
/**
* Gets flag indicating whether this file is Watermarked.
+ *
* @return whether the file is watermarked or not
*/
public boolean getIsWatermarked() {
@@ -1064,42 +1111,42 @@ public enum Permission {
/**
* The user can download the file.
*/
- CAN_DOWNLOAD ("can_download"),
+ CAN_DOWNLOAD("can_download"),
/**
* The user can upload new versions of the file.
*/
- CAN_UPLOAD ("can_upload"),
+ CAN_UPLOAD("can_upload"),
/**
* The user can rename the file.
*/
- CAN_RENAME ("can_rename"),
+ CAN_RENAME("can_rename"),
/**
* The user can delete the file.
*/
- CAN_DELETE ("can_delete"),
+ CAN_DELETE("can_delete"),
/**
* The user can share the file.
*/
- CAN_SHARE ("can_share"),
+ CAN_SHARE("can_share"),
/**
* The user can set the access level for shared links to the file.
*/
- CAN_SET_SHARE_ACCESS ("can_set_share_access"),
+ CAN_SET_SHARE_ACCESS("can_set_share_access"),
/**
* The user can preview the file.
*/
- CAN_PREVIEW ("can_preview"),
+ CAN_PREVIEW("can_preview"),
/**
* The user can comment on the file.
*/
- CAN_COMMENT ("can_comment");
+ CAN_COMMENT("can_comment");
private final String jsonValue;
@@ -1115,6 +1162,7 @@ String toJSONValue() {
return this.jsonValue;
}
}
+
private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxCollaboration.Role role) {
BoxAPIConnection api = this.getAPI();
URL url = ADD_COLLABORATION_URL.build(api.getBaseURL());
@@ -1137,11 +1185,13 @@ private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxColla
BoxCollaboration.Info info = newCollaboration.new Info(responseJSON);
return info;
}
+
/**
* Adds a collaborator to this file.
- * @param collaborator the collaborator to add.
- * @param role the role of the collaborator.
- * @return info about the new collaboration.
+ *
+ * @param collaborator the collaborator to add.
+ * @param role the role of the collaborator.
+ * @return info about the new collaboration.
*/
public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role) {
JsonObject accessibleByField = new JsonObject();
@@ -1162,9 +1212,10 @@ public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollab
/**
* Adds a collaborator to this folder. An email will be sent to the collaborator if they don't already have a Box
* account.
- * @param email the email address of the collaborator to add.
- * @param role the role of the collaborator.
- * @return info about the new collaboration.
+ *
+ * @param email the email address of the collaborator to add.
+ * @param role the role of the collaborator.
+ * @return info about the new collaboration.
*/
public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role) {
JsonObject accessibleByField = new JsonObject();
@@ -1174,6 +1225,15 @@ public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role rol
return this.collaborate(accessibleByField, role);
}
+ /**
+ * Used to retrieve all collaborations associated with the item.
+ *
+ * @param fields the optional fields to retrieve.
+ * @return An iterable of metadata instances associated with the item.
+ */
+ public BoxResourceIterable getAllFileCollaborations(String... fields) {
+ return BoxCollaboration.getAllFileCollaborations(this.getAPI(), this.getID(),
+ GET_COLLABORATORS_PAGE_SIZE, fields);
-
+ }
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index d07ee7039..0caab0fc7 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -127,6 +127,82 @@ private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxColla
BoxCollaboration.Info info = newCollaboration.new Info(responseJSON);
return info;
}
+ /**
+ * Adds a collaborator to this folder.
+ * @param collaborator the collaborator to add.
+ * @param role the role of the collaborator.
+ * @param notify the user/group should receive email notification of the collaboration or not.
+ * @param canViewPath the view path collaboration feature is enabled or not.
+ * View path collaborations allow the invitee to see the entire ancestral path to the associated folder.
+ * The user will not gain privileges in any ancestral folder.
+ * @return info about the new collaboration.
+ */
+ public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role,
+ Boolean notify, Boolean canViewPath) {
+ JsonObject accessibleByField = new JsonObject();
+ accessibleByField.add("id", collaborator.getID());
+
+ if (collaborator instanceof BoxUser) {
+ accessibleByField.add("type", "user");
+ } else if (collaborator instanceof BoxGroup) {
+ accessibleByField.add("type", "group");
+ } else {
+ throw new IllegalArgumentException("The given collaborator is of an unknown type.");
+ }
+
+ return this.collaborate(accessibleByField, role, notify, canViewPath);
+ }
+
+ /**
+ * Adds a collaborator to this folder. An email will be sent to the collaborator if they don't already have a Box
+ * account.
+ * @param email the email address of the collaborator to add.
+ * @param role the role of the collaborator.
+ * @param notify the user/group should receive email notification of the collaboration or not.
+ * @param canViewPath the view path collaboration feature is enabled or not.
+ * View path collaborations allow the invitee to see the entire ancestral path to the associated folder.
+ * The user will not gain privileges in any ancestral folder.
+ * @return info about the new collaboration.
+ */
+ public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role,
+ Boolean notify, Boolean canViewPath) {
+ JsonObject accessibleByField = new JsonObject();
+ accessibleByField.add("login", email);
+ accessibleByField.add("type", "user");
+
+ return this.collaborate(accessibleByField, role, notify, canViewPath);
+ }
+
+ private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxCollaboration.Role role,
+ Boolean notify, Boolean canViewPath) {
+ BoxAPIConnection api = this.getAPI();
+ URL url = ADD_COLLABORATION_URL.build(api.getBaseURL());
+
+ JsonObject itemField = new JsonObject();
+ itemField.add("id", this.getID());
+ itemField.add("type", "folder");
+
+ JsonObject requestJSON = new JsonObject();
+ requestJSON.add("item", itemField);
+ requestJSON.add("accessible_by", accessibleByField);
+ requestJSON.add("role", role.toJSONString());
+ if (canViewPath != null) {
+ requestJSON.add("can_view_path", canViewPath.booleanValue());
+ }
+
+ BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
+ if (notify != null) {
+ request.addHeader("notify", notify.toString());
+ }
+
+ request.setBody(requestJSON.toString());
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
+
+ BoxCollaboration newCollaboration = new BoxCollaboration(api, responseJSON.get("id").asString());
+ BoxCollaboration.Info info = newCollaboration.new Info(responseJSON);
+ return info;
+ }
@Override
public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
@@ -165,6 +241,8 @@ public Collection getCollaborations() {
return collaborations;
}
+
+
@Override
public BoxFolder.Info getInfo() {
URL url = FOLDER_INFO_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
diff --git a/src/main/java/com/box/sdk/BoxResourceIterable.java b/src/main/java/com/box/sdk/BoxResourceIterable.java
index 9f840e8e7..811781f7b 100644
--- a/src/main/java/com/box/sdk/BoxResourceIterable.java
+++ b/src/main/java/com/box/sdk/BoxResourceIterable.java
@@ -157,7 +157,7 @@ public boolean hasNext() {
if (this.pageCursor < this.page.size()) {
return true;
}
- if (this.markerNext == null) {
+ if (this.markerNext == null || this.markerNext.isEmpty()) {
return false;
}
this.loadNextPage();
diff --git a/src/test/java/com/box/sdk/BoxCollaborationTest.java b/src/test/java/com/box/sdk/BoxCollaborationTest.java
index fd325d4ad..c612f27ea 100644
--- a/src/test/java/com/box/sdk/BoxCollaborationTest.java
+++ b/src/test/java/com/box/sdk/BoxCollaborationTest.java
@@ -1,15 +1,21 @@
package com.box.sdk;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.logging.Logger;
public class BoxCollaborationTest {
@Test
@@ -33,6 +39,14 @@ public void updateInfoSucceeds() {
collab.updateInfo(collabInfo);
assertThat(collabInfo.getRole(), is(equalTo(newRole)));
+ Collection collabCollection = folder.getCollaborations();
+
+ assertEquals(collabCollection.size(), 1);
+
+ Iterator collabs = collabCollection.iterator();
+ BoxCollaboration.Info remoteCollab = collabs.next();
+ assertThat(remoteCollab.getRole(), is(equalTo(newRole)));
+
folder.delete(false);
}
@@ -58,7 +72,7 @@ public void deleteSucceeds() {
@Test
@Category(IntegrationTestDebug.class)
public void singleFileCollabSucceeds() {
- Logger logger = TestConfig.enableLogger("FINE");
+ HashMap collabsMap = new HashMap();
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
BoxFolder rootFolder = BoxFolder.getRootFolder(api);
String fileName = "[singleFileCollabSucceeds] Test File.txt";
@@ -73,6 +87,8 @@ public void singleFileCollabSucceeds() {
BoxCollaboration.Info collabInfo = uploadedFile.collaborate(collaboratorLogin, originalRole);
+ collabsMap.put(collabInfo.getID(), collabInfo);
+
assertThat(collabInfo.getRole(), is(equalTo(originalRole)));
BoxCollaboration collab = collabInfo.getResource();
@@ -81,7 +97,57 @@ public void singleFileCollabSucceeds() {
assertThat(collabInfo.getRole(), is(equalTo(newRole)));
+ BoxCollaboration remoteCollab = new BoxCollaboration(api, collab.getID());
+ BoxCollaboration.Info remoteInfo = remoteCollab.getInfo();
+ assertThat(remoteInfo.getRole(), is(equalTo(newRole)));
+ assertThat(remoteInfo.getCreatedBy().getID(), is(collabInfo.getCreatedBy().getID()));
+
+
+ BoxCollaboration.Info collab2Info = uploadedFile.collaborate("davidsmaynard@gmail.com", originalRole);
+
+ collabsMap.put(collab2Info.getID(), collab2Info);
+
+ BoxResourceIterable collabs = uploadedFile.getAllFileCollaborations();
+ Iterator collabIterator = collabs.iterator();
+ int numCollabs = 0;
+
+ while (collabIterator.hasNext() && (numCollabs < 5)) {
+ numCollabs++;
+ BoxCollaboration.Info fileCollabInfo = collabIterator.next();
+
+ BoxCollaboration.Info localFileCollabInfor = collabsMap.get(fileCollabInfo.getID());
+
+ assertEquals(fileCollabInfo.getID(), localFileCollabInfor.getID());
+ assertEquals(fileCollabInfo.getCreatedBy().getID(), localFileCollabInfor.getCreatedBy().getID());
+ assertEquals(fileCollabInfo.getCreatedBy().getName(), localFileCollabInfor.getCreatedBy().getName());
+
+ assertEquals(fileCollabInfo.getAccessibleBy().getID(), localFileCollabInfor.getAccessibleBy().getID());
+ assertEquals(fileCollabInfo.getAccessibleBy().getName(), localFileCollabInfor.getAccessibleBy().getName());
+
+ assertEquals(fileCollabInfo.getRole(), localFileCollabInfor.getRole());
+ assertEquals(fileCollabInfo.getStatus(), localFileCollabInfor.getStatus());
+
+ }
+
+ BoxCollaboration.Info colInfo = collabIterator.next();
+
+ assertThat(colInfo.getID(), is(equalTo(collab2Info.getID())));
+ assertEquals(colInfo.getID(), collab2Info.getID());
+
+ assertEquals(colInfo.getID(), collabInfo.getID());
+
+ assertEquals(collabs.iterator().hasNext(), true);
+
+ colInfo = collabIterator.next();
+
+ assertEquals(colInfo.getID(), collabInfo.getID());
+
+ assertEquals(collabs.iterator().hasNext(), false);
+ assertEquals(2, numCollabs);
+
uploadedFile.delete();
+
+
}
}
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index fdc7d75d3..c2d296574 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -1,52 +1,31 @@
package com.box.sdk;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+
+
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Scanner;
-import java.util.TimeZone;
+import java.util.*;
+import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.isEmptyOrNullString;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
-
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.containing;
-import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.post;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-
-import com.eclipsesource.json.JsonArray;
-import com.eclipsesource.json.JsonObject;
-import com.github.tomakehurst.wiremock.client.WireMock;
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
/**
* {@link BoxFolder} related tests.
@@ -846,6 +825,8 @@ public void moveFolderSucceeds() {
@Test
@Category(IntegrationTest.class)
public void renameFolderSucceeds() {
+ // For some reason the following call causes a failure (connection already closed)
+ // Logger logger = TestConfig.enableLogger("FINE");
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
final String originalName = "[renameFolderSucceeds] Original Name";
final String newName = "[renameFolderSucceeds] New Name";
@@ -879,12 +860,41 @@ public void addCollaboratorSucceeds() {
folder.delete(false);
}
+ @Test
+ @Category(IntegrationTest.class)
+ public void addCollaborationsWithAttributesSucceeds() {
+ // Logger logger = TestConfig.enableLogger("FINE");
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ String folderName = "[getCollaborationsSucceeds] Test Folder";
+ String collaboratorLogin = "karthik2001123@yahoo.com";
+ BoxCollaboration.Role collaboratorRole = BoxCollaboration.Role.CO_OWNER;
+
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ BoxFolder folder = rootFolder.createFolder(folderName).getResource();
+ BoxCollaboration.Info collabInfo = folder.collaborate(collaboratorLogin, collaboratorRole, true, true);
+ String collabID = collabInfo.getID();
+
+ collaboratorRole = BoxCollaboration.Role.VIEWER;
+ collaboratorLogin = "davidsmaynard@gmail.com";
+ BoxCollaboration.Info collabInfo2 = folder.collaborate(collaboratorLogin, collaboratorRole, true, true);
+
+ collaboratorLogin = TestConfig.getCollaborator();
+ BoxCollaboration.Info collabInfo3 = folder.collaborate(collaboratorLogin, collaboratorRole, true, true);
+
+
+ Collection collaborations = folder.getCollaborations();
+
+ assertThat(collaborations, hasSize(3));
+ assertThat(collaborations, hasItem(Matchers.hasProperty("ID", equalTo(collabID))));
+
+ folder.delete(false);
+ }
@Test
@Category(IntegrationTest.class)
public void getCollaborationsHasCorrectCollaborations() {
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
- String folderName = "[getCollaborationsSucceeds] Test Folder";
+ String folderName = "[getCollaborationsHasCorrectCollaborations] Test Folder";
String collaboratorLogin = TestConfig.getCollaborator();
BoxCollaboration.Role collaboratorRole = BoxCollaboration.Role.CO_OWNER;
From 327004a99f7a884aadf10ed56a5a64cb6fde4c56 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 14 Mar 2017 17:57:22 -0700
Subject: [PATCH 082/119] Fixing checkstyle issues in tests
---
config/checkstyle/suppressions.xml | 4 +++-
src/test/java/com/box/sdk/BoxCollaborationTest.java | 1 -
src/test/java/com/box/sdk/BoxFolderTest.java | 3 ++-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml
index 3913785c9..92ee3f784 100644
--- a/config/checkstyle/suppressions.xml
+++ b/config/checkstyle/suppressions.xml
@@ -8,5 +8,7 @@
+ files="example.*\.java"/>
+
diff --git a/src/test/java/com/box/sdk/BoxCollaborationTest.java b/src/test/java/com/box/sdk/BoxCollaborationTest.java
index c612f27ea..fbe11b3c7 100644
--- a/src/test/java/com/box/sdk/BoxCollaborationTest.java
+++ b/src/test/java/com/box/sdk/BoxCollaborationTest.java
@@ -6,7 +6,6 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index c2d296574..c0b12ba68 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -14,7 +14,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
-import java.util.logging.Logger;
+
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.*;
@@ -31,6 +31,7 @@
* {@link BoxFolder} related tests.
*/
public class BoxFolderTest {
+ @SuppressWarnings("checkstyle:wrongOrder")
@Rule
public final WireMockRule wireMockRule = new WireMockRule(8080);
From 600baea6bce5609258b5ec9e1779e026dec45112 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Mon, 20 Mar 2017 16:16:16 -0700
Subject: [PATCH 083/119] Fixed bug in singleFIleCollabTest and premature
disconect in Folder Rename
---
src/main/java/com/box/sdk/BoxFolder.java | 4 ++--
.../com/box/sdk/BoxCollaborationTest.java | 21 +++----------------
src/test/java/com/box/sdk/BoxFolderTest.java | 2 --
3 files changed, 5 insertions(+), 22 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 0caab0fc7..444989b1d 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -372,8 +372,8 @@ public void rename(String newName) {
updateInfo.add("name", newName);
request.setBody(updateInfo.toString());
- BoxAPIResponse response = request.send();
- response.disconnect();
+ BoxJSONResponse response = (BoxJSONResponse)request.send();
+ response.getJSON();
}
/**
diff --git a/src/test/java/com/box/sdk/BoxCollaborationTest.java b/src/test/java/com/box/sdk/BoxCollaborationTest.java
index fbe11b3c7..4c288e740 100644
--- a/src/test/java/com/box/sdk/BoxCollaborationTest.java
+++ b/src/test/java/com/box/sdk/BoxCollaborationTest.java
@@ -69,7 +69,7 @@ public void deleteSucceeds() {
}
@Test
- @Category(IntegrationTestDebug.class)
+ @Category(IntegrationTest.class)
public void singleFileCollabSucceeds() {
HashMap collabsMap = new HashMap();
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
@@ -110,10 +110,9 @@ public void singleFileCollabSucceeds() {
Iterator collabIterator = collabs.iterator();
int numCollabs = 0;
- while (collabIterator.hasNext() && (numCollabs < 5)) {
+ while (collabIterator.hasNext()) {
numCollabs++;
BoxCollaboration.Info fileCollabInfo = collabIterator.next();
-
BoxCollaboration.Info localFileCollabInfor = collabsMap.get(fileCollabInfo.getID());
assertEquals(fileCollabInfo.getID(), localFileCollabInfor.getID());
@@ -125,23 +124,9 @@ public void singleFileCollabSucceeds() {
assertEquals(fileCollabInfo.getRole(), localFileCollabInfor.getRole());
assertEquals(fileCollabInfo.getStatus(), localFileCollabInfor.getStatus());
-
}
- BoxCollaboration.Info colInfo = collabIterator.next();
-
- assertThat(colInfo.getID(), is(equalTo(collab2Info.getID())));
- assertEquals(colInfo.getID(), collab2Info.getID());
-
- assertEquals(colInfo.getID(), collabInfo.getID());
-
- assertEquals(collabs.iterator().hasNext(), true);
-
- colInfo = collabIterator.next();
-
- assertEquals(colInfo.getID(), collabInfo.getID());
-
- assertEquals(collabs.iterator().hasNext(), false);
+ assertEquals(collabIterator.hasNext(), false);
assertEquals(2, numCollabs);
uploadedFile.delete();
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index c0b12ba68..beab027c6 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -826,8 +826,6 @@ public void moveFolderSucceeds() {
@Test
@Category(IntegrationTest.class)
public void renameFolderSucceeds() {
- // For some reason the following call causes a failure (connection already closed)
- // Logger logger = TestConfig.enableLogger("FINE");
BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
final String originalName = "[renameFolderSucceeds] Original Name";
final String newName = "[renameFolderSucceeds] New Name";
From 0e2d3aa11d13d5fddf54e69a87ed404b06204537 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Mon, 20 Mar 2017 17:01:14 -0700
Subject: [PATCH 084/119] Fix chaeckstyle whitespace issue.
---
src/main/java/com/box/sdk/BoxFolder.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 444989b1d..c3e560c1d 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -372,7 +372,7 @@ public void rename(String newName) {
updateInfo.add("name", newName);
request.setBody(updateInfo.toString());
- BoxJSONResponse response = (BoxJSONResponse)request.send();
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
response.getJSON();
}
From 22ecdba69e68820d32f3366a6886751772d4f586 Mon Sep 17 00:00:00 2001
From: David Maynard
Date: Tue, 21 Mar 2017 15:34:08 -0700
Subject: [PATCH 085/119] Removing extraneous blank lines
---
src/main/java/com/box/sdk/BoxCollaboration.java | 1 -
src/main/java/com/box/sdk/BoxFile.java | 1 -
src/test/java/com/box/sdk/BoxCollaborationTest.java | 4 ----
3 files changed, 6 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxCollaboration.java b/src/main/java/com/box/sdk/BoxCollaboration.java
index 7c1080eb6..0fa86e36c 100644
--- a/src/main/java/com/box/sdk/BoxCollaboration.java
+++ b/src/main/java/com/box/sdk/BoxCollaboration.java
@@ -476,7 +476,6 @@ protected BoxCollaboration.Info factory(JsonObject jsonObject) {
String id = jsonObject.get("id").asString();
return new BoxCollaboration(api, id).new Info(jsonObject);
}
-
};
}
}
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 2be3d1219..478c53f48 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -1204,7 +1204,6 @@ public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollab
} else {
throw new IllegalArgumentException("The given collaborator is of an unknown type.");
}
-
return this.collaborate(accessibleByField, role);
}
diff --git a/src/test/java/com/box/sdk/BoxCollaborationTest.java b/src/test/java/com/box/sdk/BoxCollaborationTest.java
index 4c288e740..ffff8f2fc 100644
--- a/src/test/java/com/box/sdk/BoxCollaborationTest.java
+++ b/src/test/java/com/box/sdk/BoxCollaborationTest.java
@@ -128,10 +128,6 @@ public void singleFileCollabSucceeds() {
assertEquals(collabIterator.hasNext(), false);
assertEquals(2, numCollabs);
-
uploadedFile.delete();
-
-
}
-
}
From 8b50a0933f0bf1821a0c1f717e72fb05f50ef8cd Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 23 Feb 2017 10:42:21 -0800
Subject: [PATCH 086/119] Inital check-in for supercharged file upload create
session implementation
---
.../java/com/box/sdk/BoxAPIConnection.java | 19 +++
src/main/java/com/box/sdk/BoxFile.java | 47 +++++-
.../com/box/sdk/BoxFileUploadSession.java | 146 ++++++++++++++++++
src/main/java/com/box/sdk/BoxFolder.java | 19 +++
src/test/java/com/box/sdk/BoxFileTest.java | 48 ++++++
src/test/java/com/box/sdk/BoxFolderTest.java | 19 +++
6 files changed, 293 insertions(+), 5 deletions(-)
create mode 100644 src/main/java/com/box/sdk/BoxFileUploadSession.java
diff --git a/src/main/java/com/box/sdk/BoxAPIConnection.java b/src/main/java/com/box/sdk/BoxAPIConnection.java
index 2c54aeb6e..10bf2f145 100644
--- a/src/main/java/com/box/sdk/BoxAPIConnection.java
+++ b/src/main/java/com/box/sdk/BoxAPIConnection.java
@@ -26,6 +26,7 @@ public class BoxAPIConnection {
private static final String TOKEN_URL_STRING = "https://api.box.com/oauth2/token";
private static final String DEFAULT_BASE_URL = "https://api.box.com/2.0/";
private static final String DEFAULT_BASE_UPLOAD_URL = "https://upload.box.com/api/2.0/";
+ private static final String DEFAULT_BASE_UPLOAD_SESSION_URL = "https://upload.app.box.com/api/2.1/";
/**
* The amount of buffer time, in milliseconds, to use when determining if an access token should be refreshed. For
@@ -52,6 +53,7 @@ public class BoxAPIConnection {
private String tokenURL;
private String baseURL;
private String baseUploadURL;
+ private String baseUploadSessionURL;
private boolean autoRefresh;
private int maxRequestAttempts;
private List listeners;
@@ -80,6 +82,7 @@ public BoxAPIConnection(String clientID, String clientSecret, String accessToken
this.tokenURL = TOKEN_URL_STRING;
this.baseURL = DEFAULT_BASE_URL;
this.baseUploadURL = DEFAULT_BASE_UPLOAD_URL;
+ this.baseUploadSessionURL = DEFAULT_BASE_UPLOAD_SESSION_URL;
this.autoRefresh = true;
this.maxRequestAttempts = DEFAULT_MAX_ATTEMPTS;
this.refreshLock = new ReentrantReadWriteLock();
@@ -237,6 +240,22 @@ public void setBaseUploadURL(String baseUploadURL) {
this.baseUploadURL = baseUploadURL;
}
+ /**
+ * Gets the base upload session URL that's used when performing supercharged uploads to Box.
+ * @return the base upload session URL.
+ */
+ public String getBaseUploadSessionURL() {
+ return this.baseUploadSessionURL;
+ }
+
+ /**
+ * Sets the base upload URL to be used when performing supercharged uploads to Box.
+ * @param baseUploadSessionURL a base upload URL.
+ */
+ public void setBaseUploadSessionURL(String baseUploadSessionURL) {
+ this.baseUploadSessionURL = baseUploadSessionURL;
+ }
+
/**
* Gets the user agent that's used when sending requests to the Box API.
* @return the user agent.
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 730b38ad9..46620e70f 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -6,11 +6,7 @@
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.List;
+import java.util.*;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
@@ -63,6 +59,11 @@ public enum ThumbnailFileType {
private static final URLTemplate GET_TASKS_URL_TEMPLATE = new URLTemplate("files/%s/tasks");
private static final URLTemplate GET_THUMBNAIL_PNG_TEMPLATE = new URLTemplate("files/%s/thumbnail.png");
private static final URLTemplate GET_THUMBNAIL_JPG_TEMPLATE = new URLTemplate("files/%s/thumbnail.jpg");
+ private static final URLTemplate UPLOAD_SESSION_URL_TEMPLATE = new URLTemplate("files/%s/upload-session");
+ private static final URLTemplate UPLOAD_SESSION_STATUS_URL_TEMPLATE = new URLTemplate(
+ "files/upload-session/%s/status");
+ private static final URLTemplate ABORT_UPLOAD_SESSION_URL_TEMPLATE = new URLTemplate("files/upload-session/%s");
+
private static final int BUFFER_SIZE = 8192;
@@ -856,6 +857,42 @@ public BoxFile.Info setCollections(BoxCollection... collections) {
return new Info(jsonObject);
}
+ public BoxFileUploadSession createUploadSession(long fileSize) {
+ String queryString = new QueryStringBuilder().appendParam("file_size", fileSize).toString();
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
+ queryString, this.getID());
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
+ request.addHeader("Content-Type", "application/json");
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(jsonObject);
+ }
+
+ public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(jsonObject);
+ }
+
+ public void abortUploadSession(String sessionId) {
+ URL url = ABORT_UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "DELETE");
+
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ }
+
/**
* Contains information about a BoxFile.
*/
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
new file mode 100644
index 000000000..0deee7543
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -0,0 +1,146 @@
+package com.box.sdk;
+
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ *
+ */
+public class BoxFileUploadSession extends BoxJSONObject {
+
+ private Date sessionExpiresAt;
+ private String uploadSessionId;
+ private long partSize;
+ private Endpoints sessionEndpoints;
+ private int totalParts;
+ private int partsProcessed;
+
+ public BoxFileUploadSession() {
+ super();
+ }
+
+ public BoxFileUploadSession(String json) {
+ super(json);
+ }
+
+ BoxFileUploadSession(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public Date getSessionExpiresAt() {
+ return sessionExpiresAt;
+ }
+
+ public String getUploadSessionId() {
+ return uploadSessionId;
+ }
+
+ public long getPartSize() {
+ return partSize;
+ }
+
+ public Endpoints getSessionEndpoints() {
+ return sessionEndpoints;
+ }
+
+ public int getTotalParts() {
+ return this.totalParts;
+ }
+
+ public int getPartsProcessed() {
+ return this.partsProcessed;
+ }
+
+ @Override
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("session_expires_at")) {
+ try {
+ String dateStr = value.asString();
+ this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
+ } catch (ParseException pe) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ } else if (memberName.equals("upload_session_id")) {
+ this.uploadSessionId = value.asString();
+ } else if (memberName.equals("part_size")) {
+ this.partSize = Double.valueOf(value.toString()).longValue();
+ } else if (memberName.equals("session_endpoints")) {
+ this.sessionEndpoints = new Endpoints(value.asObject());
+ } else if (memberName.equals("total_parts")) {
+ this.totalParts = value.asInt();
+ } if (memberName.equals("num_parts_processed")) {
+ this.partsProcessed = value.asInt();
+ }
+ }
+
+ public class Endpoints extends BoxJSONObject {
+ private URL listPartsEndpoint;
+ private URL commitEndpoint;
+ private URL uploadPartEndpoint;
+ private URL statusEndpoint;
+ private URL abortEndpoint;
+
+ public Endpoints() {
+ super();
+ }
+
+ public Endpoints(String json) {
+ super(json);
+ }
+
+ Endpoints(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public URL getListPartsEndpoint() {
+ return listPartsEndpoint;
+ }
+
+ public URL getCommitEndpoint() {
+ return commitEndpoint;
+ }
+
+ public URL getUploadPartEndpoint() {
+ return uploadPartEndpoint;
+ }
+
+ public URL getStatusEndpoint() {
+ return statusEndpoint;
+ }
+
+ public URL getAbortEndpoint() {
+ return abortEndpoint;
+ }
+
+ @Override
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ try {
+ if (memberName.equals("list_parts")) {
+ this.listPartsEndpoint = new URL(value.asString());
+ } else if (memberName.equals("commit")) {
+ this.commitEndpoint = new URL(value.asString());
+ } else if (memberName.equals("upload_part")) {
+ this.uploadPartEndpoint = new URL(value.asString());
+ } else if (memberName.equals("status")) {
+ this.statusEndpoint = new URL(value.asString());
+ } else if (memberName.equals("abort")) {
+ this.abortEndpoint = new URL(value.asString());
+ }
+ } catch(MalformedURLException mue) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index d07ee7039..13d6f0cc1 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -42,6 +42,7 @@ public class BoxFolder extends BoxItem implements Iterable {
private static final URLTemplate GET_ITEMS_URL = new URLTemplate("folders/%s/items/");
private static final URLTemplate SEARCH_URL_TEMPLATE = new URLTemplate("search");
private static final URLTemplate METADATA_URL_TEMPLATE = new URLTemplate("folders/%s/metadata/%s/%s");
+ private static final URLTemplate UPLOAD_SESSION_URL_TEMPLATE = new URLTemplate("files/upload-session");
/**
* Constructs a BoxFolder for a folder with a given ID.
@@ -728,6 +729,24 @@ public void deleteMetadata(String templateName, String scope) {
response.disconnect();
}
+ public BoxFileUploadSession createUploadSession(String folderId, long fileSize, String fileName) {
+
+ String queryString = new QueryStringBuilder()
+ .appendParam("folder_id", folderId)
+ .appendParam("file_size", fileSize)
+ .appendParam("file_name", fileName)
+ .toString();
+
+ URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
+ queryString);
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(jsonObject);
+ }
+
/**
* Contains information about a BoxFolder.
*/
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index ca1a1ace3..2a87411e6 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -966,6 +966,54 @@ public void setCollectionsWithInfoSucceeds() {
uploadedFile.delete();
}
+ @Test
+ @Category(IntegrationTest.class)
+ public void uploadSessionSucceeds() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ String fileName = "[createUploadSessionSucceeds] Test File.txt";
+ String fileContent = "Test file";
+ byte[] fileBytes = fileContent.getBytes(StandardCharsets.UTF_8);
+
+ InputStream uploadStream = new ByteArrayInputStream(fileBytes);
+ BoxFile uploadedFile = rootFolder.uploadFile(uploadStream, fileName).getResource();
+ try {
+ BoxFileUploadSession session = uploadedFile.createUploadSession(10000000);
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+
+ //Verify the status of the session
+ getUploadSessionStatusSucceeds(uploadedFile, session.getUploadSessionId());
+
+ //Verify the delete session
+ abortUploadSessionStatusSucceeds(uploadedFile, session.getUploadSessionId());
+ } finally {
+ uploadedFile.delete();
+ }
+ }
+
+ private void getUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
+ BoxFileUploadSession session = file.getUploadSessionStatus(sessionId);
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+ Assert.assertNotNull(session.getTotalParts());
+ Assert.assertNotNull(session.getPartsProcessed());
+ }
+
+ private void abortUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
+ file.abortUploadSession(sessionId);
+
+ }
+
private static byte[] readAllBytes(String fileName) throws IOException {
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int) f.length()];
diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java
index fdc7d75d3..c24f22642 100644
--- a/src/test/java/com/box/sdk/BoxFolderTest.java
+++ b/src/test/java/com/box/sdk/BoxFolderTest.java
@@ -1065,4 +1065,23 @@ public void sharedLinkInfoHasEffectiveAccess() {
folder.delete(true);
}
+
+ @Test
+ @Category(IntegrationTest.class)
+ public void createUploadSessionSucceeds() {
+ BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken());
+ BoxFolder rootFolder = BoxFolder.getRootFolder(api);
+ BoxFileUploadSession session = rootFolder.createUploadSession("0", 1000000, "Test_File.txt");
+ Assert.assertNotNull(session.getUploadSessionId());
+ Assert.assertNotNull(session.getSessionExpiresAt());
+ Assert.assertNotNull(session.getPartSize());
+
+ BoxFileUploadSession.Endpoints endpoints = session.getSessionEndpoints();
+ Assert.assertNotNull(endpoints);
+ Assert.assertNotNull(endpoints.getUploadPartEndpoint());
+ Assert.assertNotNull(endpoints.getStatusEndpoint());
+ Assert.assertNotNull(endpoints.getListPartsEndpoint());
+ Assert.assertNotNull(endpoints.getCommitEndpoint());
+ Assert.assertNotNull(endpoints.getAbortEndpoint());
+ }
}
From 43c935bc0c024fd590d9b1bb3239510e400a0c85 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Thu, 23 Feb 2017 11:14:29 -0800
Subject: [PATCH 087/119] Abort session implementation
---
src/main/java/com/box/sdk/BoxFile.java | 6 +++---
src/test/java/com/box/sdk/BoxFileTest.java | 8 ++++++++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 46620e70f..835b52414 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -873,7 +873,7 @@ public BoxFileUploadSession createUploadSession(long fileSize) {
}
public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
- URL url = UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
+ URL url = UPLOAD_SESSION_STATUS_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
@@ -889,8 +889,8 @@ public void abortUploadSession(String sessionId) {
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "DELETE");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ BoxAPIResponse response = (BoxAPIResponse) request.send();
+ System.out.println("Abort session status: " + response.getResponseCode());
}
/**
diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java
index 2a87411e6..19ad7a168 100644
--- a/src/test/java/com/box/sdk/BoxFileTest.java
+++ b/src/test/java/com/box/sdk/BoxFileTest.java
@@ -1012,6 +1012,14 @@ private void getUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
private void abortUploadSessionStatusSucceeds(BoxFile file, String sessionId) {
file.abortUploadSession(sessionId);
+ try {
+ BoxFileUploadSession session = file.getUploadSessionStatus(sessionId);
+
+ //If the session is aborted, this line should not be executed.
+ Assert.assertFalse("Upload session is not deleted", true);
+ } catch(BoxAPIException apiEx) {
+ Assert.assertEquals(apiEx.getResponseCode(), 404);
+ }
}
private static byte[] readAllBytes(String fileName) throws IOException {
From 98bc132f445b4a26a2918ecf42da823562f1e655 Mon Sep 17 00:00:00 2001
From: Harish Gokavarapu
Date: Thu, 23 Feb 2017 17:32:48 -0800
Subject: [PATCH 088/119] First attempt at generalising FileUploadSession
---
src/main/java/com/box/sdk/BoxAPIRequest.java | 6 +
src/main/java/com/box/sdk/BoxFile.java | 23 +---
.../com/box/sdk/BoxFileUploadSession.java | 108 +++++++++++++-----
src/main/java/com/box/sdk/BoxFolder.java | 2 +-
.../java/com/box/sdk/http/ContentType.java | 8 ++
.../java/com/box/sdk/http/HttpHeaders.java | 12 ++
.../java/com/box/sdk/http/HttpMethod.java | 8 ++
7 files changed, 113 insertions(+), 54 deletions(-)
create mode 100644 src/main/java/com/box/sdk/http/ContentType.java
create mode 100644 src/main/java/com/box/sdk/http/HttpHeaders.java
create mode 100644 src/main/java/com/box/sdk/http/HttpMethod.java
diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java
index 11e779cfa..5e15bd372 100644
--- a/src/main/java/com/box/sdk/BoxAPIRequest.java
+++ b/src/main/java/com/box/sdk/BoxAPIRequest.java
@@ -1,5 +1,7 @@
package com.box.sdk;
+import com.box.sdk.http.HttpMethod;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -76,6 +78,10 @@ public BoxAPIRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Accept-Charset", "utf-8");
}
+ public BoxAPIRequest(BoxAPIConnection api, URL uploadPartEndpoint, HttpMethod post) {
+ this(api, uploadPartEndpoint, post.name());
+ }
+
/**
* Adds an HTTP header to this request.
* @param key the header key.
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 835b52414..0eda0637c 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -869,28 +869,7 @@ public BoxFileUploadSession createUploadSession(long fileSize) {
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(jsonObject);
- }
-
- public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
- URL url = UPLOAD_SESSION_STATUS_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
-
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET");
-
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- System.out.println("Response: " + jsonObject);
-
- return new BoxFileUploadSession(jsonObject);
- }
-
- public void abortUploadSession(String sessionId) {
- URL url = ABORT_UPLOAD_SESSION_URL_TEMPLATE.build(this.getAPI().getBaseUploadSessionURL(), sessionId);
-
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "DELETE");
-
- BoxAPIResponse response = (BoxAPIResponse) request.send();
- System.out.println("Abort session status: " + response.getResponseCode());
+ return new BoxFileUploadSession(this.getAPI(), jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 0deee7543..fc8032f71 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -1,36 +1,51 @@
package com.box.sdk;
+import com.box.sdk.http.ContentType;
+import com.box.sdk.http.HttpHeaders;
+import com.box.sdk.http.HttpMethod;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.Date;
-import java.util.Map;
/**
*
*/
public class BoxFileUploadSession extends BoxJSONObject {
+ private BoxAPIConnection api;
private Date sessionExpiresAt;
private String uploadSessionId;
- private long partSize;
private Endpoints sessionEndpoints;
+ private long partSize;
private int totalParts;
private int partsProcessed;
- public BoxFileUploadSession() {
- super();
+ private BoxAPIConnection getAPI() {
+ return api;
}
- public BoxFileUploadSession(String json) {
- super(json);
+ private void setAPI(BoxAPIConnection api) {
+ this.api = api;
}
- BoxFileUploadSession(JsonObject jsonObject) {
- super(jsonObject);
+ public BoxFileUploadSession getResource() {
+ return BoxFileUploadSession.this;
+ }
+
+ public int getTotalParts() {
+ return this.totalParts;
+ }
+
+ public int getPartsProcessed() {
+ return this.partsProcessed;
}
public Date getSessionExpiresAt() {
@@ -41,31 +56,27 @@ public String getUploadSessionId() {
return uploadSessionId;
}
- public long getPartSize() {
- return partSize;
- }
-
public Endpoints getSessionEndpoints() {
return sessionEndpoints;
}
- public int getTotalParts() {
- return this.totalParts;
+ public long getPartSize() {
+ return partSize;
}
- public int getPartsProcessed() {
- return this.partsProcessed;
+ public BoxFileUploadSession(BoxAPIConnection api, JsonObject jsonObject) {
+ super(jsonObject);
+ this.api = api;
}
- @Override
protected void parseJSONMember(JsonObject.Member member) {
String memberName = member.getName();
JsonValue value = member.getValue();
if (memberName.equals("session_expires_at")) {
- try {
+ try {
String dateStr = value.asString();
- this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
+ this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
} catch (ParseException pe) {
assert false : "A ParseException indicates a bug in the SDK.";
}
@@ -83,23 +94,23 @@ protected void parseJSONMember(JsonObject.Member member) {
}
public class Endpoints extends BoxJSONObject {
- private URL listPartsEndpoint;
- private URL commitEndpoint;
- private URL uploadPartEndpoint;
- private URL statusEndpoint;
- private URL abortEndpoint;
+ private URL listPartsEndpoint;
+ private URL commitEndpoint;
+ private URL uploadPartEndpoint;
+ private URL statusEndpoint;
+ private URL abortEndpoint;
public Endpoints() {
- super();
- }
+ super();
+ }
- public Endpoints(String json) {
+ public Endpoints(String json) {
super(json);
- }
+ }
- Endpoints(JsonObject jsonObject) {
+ Endpoints(JsonObject jsonObject) {
super(jsonObject);
- }
+ }
public URL getListPartsEndpoint() {
return listPartsEndpoint;
@@ -128,7 +139,7 @@ protected void parseJSONMember(JsonObject.Member member) {
JsonValue value = member.getValue();
try {
if (memberName.equals("list_parts")) {
- this.listPartsEndpoint = new URL(value.asString());
+ this.listPartsEndpoint = new URL(value.asString());
} else if (memberName.equals("commit")) {
this.commitEndpoint = new URL(value.asString());
} else if (memberName.equals("upload_part")) {
@@ -143,4 +154,39 @@ protected void parseJSONMember(JsonObject.Member member) {
}
}
}
+
+ /**
+ *
+ */
+ public void uploadPart(String xBoxPartId, byte[] bytes, long offset, Long partSize, long totalSizeOfFile, String contentRangeUnits) throws MalformedURLException, NoSuchAlgorithmException {
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), this.getSessionEndpoints().getUploadPartEndpoint(), HttpMethod.POST);
+ request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
+ request.addHeader(HttpHeaders.X_BOX_PART_ID, xBoxPartId);
+ byte[] digestBytes = MessageDigest.getInstance("SHA1").digest(bytes);
+ String digest = Base64.encode(digestBytes);
+ request.addHeader("Digest", "sha=" + digest);
+ if(null == contentRangeUnits){
+ contentRangeUnits = "bytes";
+ }
+ request.addHeader(HttpHeaders.CONTENT_RANGE, contentRangeUnits+" "+offset+"-"+(offset+partSize-1)+"/"+totalSizeOfFile);
+ request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
+ request.setBody(new ByteArrayInputStream(bytes));
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ }
+
+ public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getStatusEndpoint(), "GET");
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+ System.out.println("Response: " + jsonObject);
+
+ return new BoxFileUploadSession(this.getAPI(), jsonObject);
+ }
+
+
+ public void abortUploadSession(String sessionId) {
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getAbortEndpoint(), "DELETE");
+ BoxAPIResponse response = (BoxAPIResponse) request.send();
+ System.out.println("Abort session status: " + response.getResponseCode());
+ }
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index 13d6f0cc1..c6df62074 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -744,7 +744,7 @@ public BoxFileUploadSession createUploadSession(String folderId, long fileSize,
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(jsonObject);
+ return new BoxFileUploadSession(this.getAPI(), jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/http/ContentType.java b/src/main/java/com/box/sdk/http/ContentType.java
new file mode 100644
index 000000000..4f6b4ebb4
--- /dev/null
+++ b/src/main/java/com/box/sdk/http/ContentType.java
@@ -0,0 +1,8 @@
+package com.box.sdk.http;
+
+/**
+ *
+ */
+public class ContentType {
+ public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+}
diff --git a/src/main/java/com/box/sdk/http/HttpHeaders.java b/src/main/java/com/box/sdk/http/HttpHeaders.java
new file mode 100644
index 000000000..fa9b12404
--- /dev/null
+++ b/src/main/java/com/box/sdk/http/HttpHeaders.java
@@ -0,0 +1,12 @@
+package com.box.sdk.http;
+
+/**
+ *
+ */
+public class HttpHeaders {
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String CONTENT_LENGTH = "Content-Length";
+ public static final String CONTENT_RANGE = "Content-Range";
+ public static final String DIGEST = "Digest";
+ public static final String X_BOX_PART_ID = "X-Box-Part-Id";
+}
diff --git a/src/main/java/com/box/sdk/http/HttpMethod.java b/src/main/java/com/box/sdk/http/HttpMethod.java
new file mode 100644
index 000000000..4121191b5
--- /dev/null
+++ b/src/main/java/com/box/sdk/http/HttpMethod.java
@@ -0,0 +1,8 @@
+package com.box.sdk.http;
+
+/**
+ *
+ */
+public enum HttpMethod {
+ GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
+}
From f6a4d1a696785f6b880db6bfd26f45023d61dbcc Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Sun, 26 Feb 2017 19:20:42 -0800
Subject: [PATCH 089/119] Upload implementation changes & code refactoring to
match existing code style
---
src/main/java/com/box/sdk/BoxAPIRequest.java | 8 +-
src/main/java/com/box/sdk/BoxFile.java | 12 +-
.../com/box/sdk/BoxFileUploadSession.java | 436 +++++++++++-------
src/main/java/com/box/sdk/BoxFolder.java | 7 +-
src/main/java/com/box/sdk/BoxJSONRequest.java | 14 +
src/main/java/com/box/sdk/BoxResource.java | 2 +
.../java/com/box/sdk/http/ContentType.java | 10 +-
.../java/com/box/sdk/http/HttpHeaders.java | 17 +-
.../java/com/box/sdk/http/HttpMethod.java | 3 +-
9 files changed, 314 insertions(+), 195 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java
index 5e15bd372..de7b3585a 100644
--- a/src/main/java/com/box/sdk/BoxAPIRequest.java
+++ b/src/main/java/com/box/sdk/BoxAPIRequest.java
@@ -1,7 +1,5 @@
package com.box.sdk;
-import com.box.sdk.http.HttpMethod;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -16,6 +14,8 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import com.box.sdk.http.HttpMethod;
+
/**
* Used to make HTTP requests to the Box API.
*
@@ -78,8 +78,8 @@ public BoxAPIRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Accept-Charset", "utf-8");
}
- public BoxAPIRequest(BoxAPIConnection api, URL uploadPartEndpoint, HttpMethod post) {
- this(api, uploadPartEndpoint, post.name());
+ public BoxAPIRequest(BoxAPIConnection api, URL uploadPartEndpoint, HttpMethod method) {
+ this(api, uploadPartEndpoint, method.name());
}
/**
diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java
index 0eda0637c..bda7859e5 100644
--- a/src/main/java/com/box/sdk/BoxFile.java
+++ b/src/main/java/com/box/sdk/BoxFile.java
@@ -6,7 +6,11 @@
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.List;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
@@ -857,7 +861,7 @@ public BoxFile.Info setCollections(BoxCollection... collections) {
return new Info(jsonObject);
}
- public BoxFileUploadSession createUploadSession(long fileSize) {
+ public BoxFileUploadSession.Info createUploadSession(long fileSize) {
String queryString = new QueryStringBuilder().appendParam("file_size", fileSize).toString();
URL url = UPLOAD_SESSION_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseUploadSessionURL(),
queryString, this.getID());
@@ -869,7 +873,9 @@ public BoxFileUploadSession createUploadSession(long fileSize) {
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(this.getAPI(), jsonObject);
+ String sessionId = jsonObject.get("upload_session_id").asString();
+ BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId);
+ return session.new Info(jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index fc8032f71..7cae4c53f 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -1,11 +1,5 @@
package com.box.sdk;
-import com.box.sdk.http.ContentType;
-import com.box.sdk.http.HttpHeaders;
-import com.box.sdk.http.HttpMethod;
-import com.eclipsesource.json.JsonObject;
-import com.eclipsesource.json.JsonValue;
-
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -15,178 +9,266 @@
import java.text.ParseException;
import java.util.Date;
+import com.box.sdk.http.ContentType;
+import com.box.sdk.http.HttpHeaders;
+import com.box.sdk.http.HttpMethod;
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
/**
*
*/
-public class BoxFileUploadSession extends BoxJSONObject {
-
- private BoxAPIConnection api;
- private Date sessionExpiresAt;
- private String uploadSessionId;
- private Endpoints sessionEndpoints;
- private long partSize;
- private int totalParts;
- private int partsProcessed;
-
- private BoxAPIConnection getAPI() {
- return api;
- }
-
- private void setAPI(BoxAPIConnection api) {
- this.api = api;
- }
-
- public BoxFileUploadSession getResource() {
- return BoxFileUploadSession.this;
- }
-
- public int getTotalParts() {
- return this.totalParts;
- }
-
- public int getPartsProcessed() {
- return this.partsProcessed;
- }
-
- public Date getSessionExpiresAt() {
- return sessionExpiresAt;
- }
-
- public String getUploadSessionId() {
- return uploadSessionId;
- }
-
- public Endpoints getSessionEndpoints() {
- return sessionEndpoints;
- }
-
- public long getPartSize() {
- return partSize;
- }
-
- public BoxFileUploadSession(BoxAPIConnection api, JsonObject jsonObject) {
- super(jsonObject);
- this.api = api;
- }
-
- protected void parseJSONMember(JsonObject.Member member) {
-
- String memberName = member.getName();
- JsonValue value = member.getValue();
- if (memberName.equals("session_expires_at")) {
- try {
- String dateStr = value.asString();
- this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length()-1) + "-00:00");
- } catch (ParseException pe) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- } else if (memberName.equals("upload_session_id")) {
- this.uploadSessionId = value.asString();
- } else if (memberName.equals("part_size")) {
- this.partSize = Double.valueOf(value.toString()).longValue();
- } else if (memberName.equals("session_endpoints")) {
- this.sessionEndpoints = new Endpoints(value.asObject());
- } else if (memberName.equals("total_parts")) {
- this.totalParts = value.asInt();
- } if (memberName.equals("num_parts_processed")) {
- this.partsProcessed = value.asInt();
- }
- }
-
- public class Endpoints extends BoxJSONObject {
- private URL listPartsEndpoint;
- private URL commitEndpoint;
- private URL uploadPartEndpoint;
- private URL statusEndpoint;
- private URL abortEndpoint;
-
- public Endpoints() {
- super();
- }
-
- public Endpoints(String json) {
- super(json);
- }
-
- Endpoints(JsonObject jsonObject) {
- super(jsonObject);
- }
-
- public URL getListPartsEndpoint() {
- return listPartsEndpoint;
- }
-
- public URL getCommitEndpoint() {
- return commitEndpoint;
- }
-
- public URL getUploadPartEndpoint() {
- return uploadPartEndpoint;
- }
-
- public URL getStatusEndpoint() {
- return statusEndpoint;
- }
-
- public URL getAbortEndpoint() {
- return abortEndpoint;
- }
-
- @Override
- protected void parseJSONMember(JsonObject.Member member) {
-
- String memberName = member.getName();
- JsonValue value = member.getValue();
- try {
- if (memberName.equals("list_parts")) {
- this.listPartsEndpoint = new URL(value.asString());
- } else if (memberName.equals("commit")) {
- this.commitEndpoint = new URL(value.asString());
- } else if (memberName.equals("upload_part")) {
- this.uploadPartEndpoint = new URL(value.asString());
- } else if (memberName.equals("status")) {
- this.statusEndpoint = new URL(value.asString());
- } else if (memberName.equals("abort")) {
- this.abortEndpoint = new URL(value.asString());
- }
- } catch(MalformedURLException mue) {
- assert false : "A ParseException indicates a bug in the SDK.";
- }
- }
- }
-
- /**
- *
- */
- public void uploadPart(String xBoxPartId, byte[] bytes, long offset, Long partSize, long totalSizeOfFile, String contentRangeUnits) throws MalformedURLException, NoSuchAlgorithmException {
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), this.getSessionEndpoints().getUploadPartEndpoint(), HttpMethod.POST);
- request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
- request.addHeader(HttpHeaders.X_BOX_PART_ID, xBoxPartId);
- byte[] digestBytes = MessageDigest.getInstance("SHA1").digest(bytes);
- String digest = Base64.encode(digestBytes);
- request.addHeader("Digest", "sha=" + digest);
- if(null == contentRangeUnits){
- contentRangeUnits = "bytes";
- }
- request.addHeader(HttpHeaders.CONTENT_RANGE, contentRangeUnits+" "+offset+"-"+(offset+partSize-1)+"/"+totalSizeOfFile);
- request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
- request.setBody(new ByteArrayInputStream(bytes));
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- }
-
- public BoxFileUploadSession getUploadSessionStatus(String sessionId) {
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getStatusEndpoint(), "GET");
- BoxJSONResponse response = (BoxJSONResponse) request.send();
- JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
- System.out.println("Response: " + jsonObject);
-
- return new BoxFileUploadSession(this.getAPI(), jsonObject);
- }
-
-
- public void abortUploadSession(String sessionId) {
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), this.getSessionEndpoints().getAbortEndpoint(), "DELETE");
- BoxAPIResponse response = (BoxAPIResponse) request.send();
- System.out.println("Abort session status: " + response.getResponseCode());
- }
+public class BoxFileUploadSession extends BoxResource {
+
+ private static final String DIGEST_HEADER_PREFIX_SHA = "sha=";
+ private static final String DIGEST_ALGORITHM_SHA1 = "SHA1";
+
+ private static final String MARKER_QUERY_STRING = "marker";
+ private static final String LIMIT_QUERY_STRING = "limit";
+
+ private Info sessionInfo;
+
+ BoxFileUploadSession(BoxAPIConnection api, String id) {
+ super(api, id);
+ }
+
+ public class Info extends BoxResource.Info {
+ private BoxAPIConnection api;
+ private Date sessionExpiresAt;
+ private String uploadSessionId;
+ private Endpoints sessionEndpoints;
+ private long partSize;
+ private int totalParts;
+ private int partsProcessed;
+
+ /**
+ * Constructs an empty Info object.
+ */
+ public Info() {
+ super();
+ BoxFileUploadSession.this.sessionInfo = this;
+ }
+
+ /**
+ * Constructs an Info object by parsing information from a JSON string.
+ * @param json the JSON string to parse.
+ */
+ public Info(String json) {
+ super(json);
+ BoxFileUploadSession.this.sessionInfo = this;
+ }
+
+ /**
+ * Constructs an Info object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ Info(JsonObject jsonObject) {
+ super(jsonObject);
+ BoxFileUploadSession.this.sessionInfo = this;
+ }
+
+ private BoxAPIConnection getAPI() {
+ return this.api;
+ }
+
+ private void setAPI(BoxAPIConnection api) {
+ this.api = api;
+ }
+
+ public BoxFileUploadSession getResource() {
+ return BoxFileUploadSession.this;
+ }
+
+ public int getTotalParts() {
+ return this.totalParts;
+ }
+
+ public int getPartsProcessed() {
+ return this.partsProcessed;
+ }
+
+ public Date getSessionExpiresAt() {
+ return this.sessionExpiresAt;
+ }
+
+ public String getUploadSessionId() {
+ return this.uploadSessionId;
+ }
+
+ public Endpoints getSessionEndpoints() {
+ return this.sessionEndpoints;
+ }
+
+ public long getPartSize() {
+ return this.partSize;
+ }
+
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("session_expires_at")) {
+ try {
+ String dateStr = value.asString();
+ this.sessionExpiresAt = BoxDateFormat.parse(dateStr.substring(0, dateStr.length() - 1) + "-00:00");
+ } catch (ParseException pe) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ } else if (memberName.equals("upload_session_id")) {
+ this.uploadSessionId = value.asString();
+ } else if (memberName.equals("part_size")) {
+ this.partSize = Double.valueOf(value.toString()).longValue();
+ } else if (memberName.equals("session_endpoints")) {
+ this.sessionEndpoints = new Endpoints(value.asObject());
+ } else if (memberName.equals("total_parts")) {
+ this.totalParts = value.asInt();
+ } else if (memberName.equals("num_parts_processed")) {
+ this.partsProcessed = value.asInt();
+ }
+ }
+ }
+
+ public class Endpoints extends BoxJSONObject {
+ private URL listPartsEndpoint;
+ private URL commitEndpoint;
+ private URL uploadPartEndpoint;
+ private URL statusEndpoint;
+ private URL abortEndpoint;
+
+ public Endpoints() {
+ super();
+ }
+
+ public Endpoints(String json) {
+ super(json);
+ }
+
+ Endpoints(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public URL getListPartsEndpoint() {
+ return this.listPartsEndpoint;
+ }
+
+ public URL getCommitEndpoint() {
+ return this.commitEndpoint;
+ }
+
+ public URL getUploadPartEndpoint() {
+ return this.uploadPartEndpoint;
+ }
+
+ public URL getStatusEndpoint() {
+ return this.statusEndpoint;
+ }
+
+ public URL getAbortEndpoint() {
+ return this.abortEndpoint;
+ }
+
+ @Override
+ protected void parseJSONMember(JsonObject.Member member) {
+
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ try {
+ if (memberName.equals("list_parts")) {
+ this.listPartsEndpoint = new URL(value.asString());
+ } else if (memberName.equals("commit")) {
+ this.commitEndpoint = new URL(value.asString());
+ } else if (memberName.equals("upload_part")) {
+ this.uploadPartEndpoint = new URL(value.asString());
+ } else if (memberName.equals("status")) {
+ this.statusEndpoint = new URL(value.asString());
+ } else if (memberName.equals("abort")) {
+ this.abortEndpoint = new URL(value.asString());
+ }
+ } catch (MalformedURLException mue) {
+ assert false : "A ParseException indicates a bug in the SDK.";
+ }
+ }
+ }
+
+ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSize, long totalSizeOfFile)
+ throws MalformedURLException, NoSuchAlgorithmException {
+
+ URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), uploadPartURL, HttpMethod.POST);
+ request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
+ request.addHeader(HttpHeaders.X_BOX_PART_ID, partId);
+
+ byte[] digestBytes = MessageDigest.getInstance(DIGEST_ALGORITHM_SHA1).digest(bytes);
+ String digest = Base64.encode(digestBytes);
+ request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
+ request.addHeader(HttpHeaders.CONTENT_RANGE,
+ "bytes " + startRange + "-" + (startRange + partSize - 1) + "/" + totalSizeOfFile);
+ request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
+
+ request.setBody(new ByteArrayInputStream(bytes));
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ }
+
+ public int listParts(String sessionId, int marker, int limit) {
+ URL listPartsURL = this.sessionInfo.getSessionEndpoints().getListPartsEndpoint();
+ URLTemplate template = new URLTemplate(listPartsURL.toString());
+
+ String queryString = new QueryStringBuilder()
+ .appendParam(MARKER_QUERY_STRING, marker)
+ .appendParam(LIMIT_QUERY_STRING, limit)
+ .toString();
+ URL url = template.buildWithQuery("", queryString);
+
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, HttpMethod.GET);
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+// System.out.println("Response: " + jsonObject);
+
+ return response.getResponseCode();
+ }
+
+ public int commit(String sessionId, String digest, JsonObject jsonObject, String ifMatch, String ifNonMatch) {
+ URL commitURL = this.sessionInfo.getSessionEndpoints().getCommitEndpoint();
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), commitURL, HttpMethod.POST);
+ request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
+ request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON);
+
+ request.setBody(jsonObject.toString());
+
+ BoxAPIResponse response = request.send();
+ //System.out.println("Response: " + response.getResponseCode());
+
+ try {
+ InputStream stream = response.getBody();
+ int value = stream.read();
+ StringBuffer buffer = new StringBuffer();
+ while (value != -1) {
+ buffer.append(value);
+ value = stream.read();
+ }
+ //System.out.println("Response: " + buffer.toString());
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ return response.getResponseCode();
+ }
+
+ public BoxFileUploadSession.Info getUploadSessionStatus() {
+ URL statusURL = this.sessionInfo.getSessionEndpoints().getStatusEndpoint();
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), statusURL, HttpMethod.GET);
+ BoxJSONResponse response = (BoxJSONResponse) request.send();
+ JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
+
+ this.sessionInfo.update(jsonObject);
+
+ return this.sessionInfo;
+ }
+
+ public void abortUploadSession() {
+ URL abortURL = this.sessionInfo.getSessionEndpoints().getAbortEndpoint();
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), abortURL, "DELETE");
+ BoxAPIResponse response = request.send();
+ //System.out.println("Abort session status: " + response.getResponseCode());
+ }
}
diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java
index c6df62074..c2d933c78 100644
--- a/src/main/java/com/box/sdk/BoxFolder.java
+++ b/src/main/java/com/box/sdk/BoxFolder.java
@@ -729,7 +729,7 @@ public void deleteMetadata(String templateName, String scope) {
response.disconnect();
}
- public BoxFileUploadSession createUploadSession(String folderId, long fileSize, String fileName) {
+ public BoxFileUploadSession.Info createUploadSession(String folderId, long fileSize, String fileName) {
String queryString = new QueryStringBuilder()
.appendParam("folder_id", folderId)
@@ -744,7 +744,10 @@ public BoxFileUploadSession createUploadSession(String folderId, long fileSize,
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
System.out.println("Response: " + jsonObject);
- return new BoxFileUploadSession(this.getAPI(), jsonObject);
+ String sessionId = jsonObject.get("upload_session_id").asString();
+ BoxFileUploadSession session = new BoxFileUploadSession(this.getAPI(), sessionId);
+
+ return session.new Info(jsonObject);
}
/**
diff --git a/src/main/java/com/box/sdk/BoxJSONRequest.java b/src/main/java/com/box/sdk/BoxJSONRequest.java
index c67e51a40..1c86b1241 100644
--- a/src/main/java/com/box/sdk/BoxJSONRequest.java
+++ b/src/main/java/com/box/sdk/BoxJSONRequest.java
@@ -2,6 +2,8 @@
import java.net.URL;
+import com.box.sdk.http.HttpMethod;
+
/**
* Used to make HTTP requests containing JSON to the Box API.
*
@@ -23,6 +25,18 @@ public BoxJSONRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Content-Type", "application/json");
}
+ /**
+ * Constructs an authenticated BoxJSONRequest using a provided BoxAPIConnection.
+ * @param api an API connection for authenticating the request.
+ * @param url the URL of the request.
+ * @param method the HTTP method of the request.
+ */
+ public BoxJSONRequest(BoxAPIConnection api, URL url, HttpMethod method) {
+ super(api, url, method);
+
+ this.addHeader("Content-Type", "application/json");
+ }
+
/**
* Sets the body of this request to a given JSON string.
* @param body the JSON string to use as the body.
diff --git a/src/main/java/com/box/sdk/BoxResource.java b/src/main/java/com/box/sdk/BoxResource.java
index 1dc4299bb..4deb7343e 100644
--- a/src/main/java/com/box/sdk/BoxResource.java
+++ b/src/main/java/com/box/sdk/BoxResource.java
@@ -60,6 +60,8 @@ private static Map> initResourceClassByType
result.put(getResourceType(BoxLegalHoldPolicy.class), BoxLegalHoldPolicy.class);
result.put(getResourceType(BoxLegalHoldAssignment.class), BoxLegalHoldAssignment.class);
result.put(getResourceType(BoxFileVersionLegalHold.class), BoxFileVersionLegalHold.class);
+ result.put(getResourceType(BoxFileUploadSession.class), BoxFileUploadSession.class);
+
return Collections.unmodifiableMap(result);
}
diff --git a/src/main/java/com/box/sdk/http/ContentType.java b/src/main/java/com/box/sdk/http/ContentType.java
index 4f6b4ebb4..c16312e1d 100644
--- a/src/main/java/com/box/sdk/http/ContentType.java
+++ b/src/main/java/com/box/sdk/http/ContentType.java
@@ -3,6 +3,12 @@
/**
*
*/
-public class ContentType {
- public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+public final class ContentType {
+
+ public static final String APPLICATION_JSON = "application/json";
+ public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+
+ //Prevents instantiation
+ private ContentType() {
+ }
}
diff --git a/src/main/java/com/box/sdk/http/HttpHeaders.java b/src/main/java/com/box/sdk/http/HttpHeaders.java
index fa9b12404..ecb942aa1 100644
--- a/src/main/java/com/box/sdk/http/HttpHeaders.java
+++ b/src/main/java/com/box/sdk/http/HttpHeaders.java
@@ -3,10 +3,15 @@
/**
*
*/
-public class HttpHeaders {
- public static final String CONTENT_TYPE = "Content-Type";
- public static final String CONTENT_LENGTH = "Content-Length";
- public static final String CONTENT_RANGE = "Content-Range";
- public static final String DIGEST = "Digest";
- public static final String X_BOX_PART_ID = "X-Box-Part-Id";
+public final class HttpHeaders {
+
+ public static final String CONTENT_LENGTH = "Content-Length";
+ public static final String CONTENT_RANGE = "Content-Range";
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String DIGEST = "Digest";
+ public static final String X_BOX_PART_ID = "X-Box-Part-Id";
+
+ //Prevents instantiation
+ private HttpHeaders() {
+ }
}
diff --git a/src/main/java/com/box/sdk/http/HttpMethod.java b/src/main/java/com/box/sdk/http/HttpMethod.java
index 4121191b5..062b94f54 100644
--- a/src/main/java/com/box/sdk/http/HttpMethod.java
+++ b/src/main/java/com/box/sdk/http/HttpMethod.java
@@ -4,5 +4,6 @@
*
*/
public enum HttpMethod {
- GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
+
+ GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
}
From 29940b495faeacff9030f026cfeb8a60f8a0891d Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Sun, 26 Feb 2017 23:05:02 -0800
Subject: [PATCH 090/119] Upload session list parts and commit are added
---
.../com/box/sdk/BoxFileUploadSessionPart.java | 73 +++++++++++++++++++
.../box/sdk/BoxFileUploadSessionPartList.java | 57 +++++++++++++++
2 files changed, 130 insertions(+)
create mode 100644 src/main/java/com/box/sdk/BoxFileUploadSessionPart.java
create mode 100644 src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSessionPart.java b/src/main/java/com/box/sdk/BoxFileUploadSessionPart.java
new file mode 100644
index 000000000..dad0d21be
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxFileUploadSessionPart.java
@@ -0,0 +1,73 @@
+package com.box.sdk;
+
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ *
+ */
+public class BoxFileUploadSessionPart extends BoxJSONObject {
+
+ private String partId;
+ private long offset;
+ private long size;
+
+ /**
+ * Constructs an empty BoxFileUploadSessionPart object.
+ */
+ public BoxFileUploadSessionPart() {
+ super();
+ }
+
+ /**
+ * Constructs an BoxFileUploadSessionPart object by parsing information from a JSON string.
+ * @param json the JSON string to parse.
+ */
+ public BoxFileUploadSessionPart(String json) {
+ super(json);
+ }
+
+ /**
+ * Constructs an BoxFileUploadSessionPart object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ BoxFileUploadSessionPart(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public String getPartId() {
+ return this.partId;
+ }
+
+ public long getOffset() {
+ return this.offset;
+ }
+
+ public long getSize() {
+ return this.size;
+ }
+
+ public void setPartId(String partId) {
+ this.partId = partId;
+ }
+
+ public void setOffset(long offset) {
+ this.offset = offset;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ protected void parseJSONMember(JsonObject.Member member) {
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("part_id")) {
+ this.partId = value.asString();
+ } else if (memberName.equals("offset")) {
+ this.offset = Double.valueOf(value.toString()).longValue();
+ } else if (memberName.equals("size")) {
+ this.size = Double.valueOf(value.toString()).longValue();
+ }
+ }
+}
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java b/src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java
new file mode 100644
index 000000000..76ca989a1
--- /dev/null
+++ b/src/main/java/com/box/sdk/BoxFileUploadSessionPartList.java
@@ -0,0 +1,57 @@
+package com.box.sdk;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.eclipsesource.json.JsonValue;
+
+/**
+ *
+ */
+public class BoxFileUploadSessionPartList extends BoxJSONObject {
+
+ private List parts;
+ private int marker;
+
+ /**
+ * Constructs an BoxFileUploadSessionPart object using an already parsed JSON object.
+ * @param jsonObject the parsed JSON object.
+ */
+ BoxFileUploadSessionPartList(JsonObject jsonObject) {
+ super(jsonObject);
+ }
+
+ public List getParts() {
+ return this.parts;
+ }
+
+ public int getMarker() {
+ return this.marker;
+ }
+
+ protected void parseJSONMember(JsonObject.Member member) {
+ String memberName = member.getName();
+ JsonValue value = member.getValue();
+ if (memberName.equals("parts")) {
+ JsonArray array = (JsonArray) value;
+
+ if (array.size() > 0) {
+ this.parts = this.getParts(array);
+ }
+ } else if (memberName.equals("marker")) {
+ this.marker = Double.valueOf(value.toString()).intValue();
+ }
+ }
+
+ private List getParts(JsonArray partsArray) {
+ List parts = new ArrayList();
+ for (JsonValue value: partsArray) {
+ BoxFileUploadSessionPart part = new BoxFileUploadSessionPart((JsonObject) value);
+ parts.add(part);
+ }
+
+ return parts;
+ }
+}
From 692868b16436a758fa24ae4011a34a670ecc10a5 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram
Date: Sun, 26 Feb 2017 23:05:25 -0800
Subject: [PATCH 091/119] Upload session list parts and commit are added
---
.../com/box/sdk/BoxFileUploadSession.java | 62 +++++++++++++------
1 file changed, 42 insertions(+), 20 deletions(-)
diff --git a/src/main/java/com/box/sdk/BoxFileUploadSession.java b/src/main/java/com/box/sdk/BoxFileUploadSession.java
index 7cae4c53f..396f35042 100644
--- a/src/main/java/com/box/sdk/BoxFileUploadSession.java
+++ b/src/main/java/com/box/sdk/BoxFileUploadSession.java
@@ -8,16 +8,18 @@
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
import com.box.sdk.http.ContentType;
import com.box.sdk.http.HttpHeaders;
import com.box.sdk.http.HttpMethod;
+import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
-/**
- *
- */
+@BoxResourceType("upload-session")
public class BoxFileUploadSession extends BoxResource {
private static final String DIGEST_HEADER_PREFIX_SHA = "sha=";
@@ -135,14 +137,6 @@ public class Endpoints extends BoxJSONObject {
private URL statusEndpoint;
private URL abortEndpoint;
- public Endpoints() {
- super();
- }
-
- public Endpoints(String json) {
- super(json);
- }
-
Endpoints(JsonObject jsonObject) {
super(jsonObject);
}
@@ -194,7 +188,8 @@ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSi
throws MalformedURLException, NoSuchAlgorithmException {
URL uploadPartURL = this.sessionInfo.getSessionEndpoints().getUploadPartEndpoint();
- BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), uploadPartURL, HttpMethod.POST);
+
+ BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), uploadPartURL, HttpMethod.PUT);
request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_OCTET_STREAM);
request.addHeader(HttpHeaders.X_BOX_PART_ID, partId);
@@ -203,13 +198,12 @@ public void uploadPart(String partId, byte[] bytes, long startRange, Long partSi
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
request.addHeader(HttpHeaders.CONTENT_RANGE,
"bytes " + startRange + "-" + (startRange + partSize - 1) + "/" + totalSizeOfFile);
- request.addHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(bytes.length));
request.setBody(new ByteArrayInputStream(bytes));
- BoxJSONResponse response = (BoxJSONResponse) request.send();
+ BoxAPIResponse response = (BoxAPIResponse) request.send();
}
- public int listParts(String sessionId, int marker, int limit) {
+ public BoxFileUploadSessionPartList listParts(int marker, int limit) {
URL listPartsURL = this.sessionInfo.getSessionEndpoints().getListPartsEndpoint();
URLTemplate template = new URLTemplate(listPartsURL.toString());
@@ -222,18 +216,21 @@ public int listParts(String sessionId, int marker, int limit) {
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, HttpMethod.GET);
BoxJSONResponse response = (BoxJSONResponse) request.send();
JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
-// System.out.println("Response: " + jsonObject);
+ //System.out.println("List parts: " + jsonObject);
- return response.getResponseCode();
+ return new BoxFileUploadSessionPartList(jsonObject);
}
- public int commit(String sessionId, String digest, JsonObject jsonObject, String ifMatch, String ifNonMatch) {
+ public int commit(String digest, List parts,
+ Map attributes, String ifMatch, String ifNonMatch) {
+
URL commitURL = this.sessionInfo.getSessionEndpoints().getCommitEndpoint();
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), commitURL, HttpMethod.POST);
request.addHeader(HttpHeaders.DIGEST, DIGEST_HEADER_PREFIX_SHA + digest);
request.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON);
- request.setBody(jsonObject.toString());
+ String body = this.getCommitBody(parts, attributes);
+ request.setBody(body);
BoxAPIResponse response = request.send();
//System.out.println("Response: " + response.getResponseCode());
@@ -254,6 +251,31 @@ public int commit(String sessionId, String digest, JsonObject jsonObject, String
return response.getResponseCode();
}
+ private String getCommitBody(List parts, Map attributes) {
+ JsonObject jsonObject = new JsonObject();
+
+ JsonArray array = new JsonArray();
+ for (BoxFileUploadSessionPart part: parts) {
+ JsonObject partObj = new JsonObject();
+ partObj.add("part_id", part.getPartId());
+ partObj.add("offset", part.getOffset());
+ partObj.add("size", part.getSize());
+
+ array.add(partObj);
+ }
+ jsonObject.add("parts", array);
+
+ if (attributes != null) {
+ JsonObject attrObj = new JsonObject();
+ for (String key: attributes.keySet()) {
+ attrObj.add(key, attributes.get(key));
+ }
+ jsonObject.add("attributes", attrObj);
+ }
+
+ return jsonObject.toString();
+ }
+
public BoxFileUploadSession.Info getUploadSessionStatus() {
URL statusURL = this.sessionInfo.getSessionEndpoints().getStatusEndpoint();
BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), statusURL, HttpMethod.GET);
@@ -267,7 +289,7 @@ public BoxFileUploadSession.Info getUploadSessionStatus() {
public void abortUploadSession() {
URL abortURL = this.sessionInfo.getSessionEndpoints().getAbortEndpoint();
- BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), abortURL, "DELETE");
+ BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), abortURL, HttpMethod.DELETE);
BoxAPIResponse response = request.send();
//System.out.println("Abort session status: " + response.getResponseCode());
}
From 042b49e7d0ea908487d78c73e92433bc5ac0d0f7 Mon Sep 17 00:00:00 2001
From: Karthik Shanmugasundaram