Skip to content

Commit 135850d

Browse files
authored
fix: BoxCollaboration.getItem() returns BoxItem.Info not BoxFolder.Info (#1102)
* fix: BoxCollaboration.getItem() should return BoxItem.Info not BoxFolder.Info Fixes #1101 * fix: Added details on retrying failed requests. Fixes #1100
1 parent 45e9906 commit 135850d

12 files changed

Lines changed: 418 additions & 261 deletions

File tree

doc/configuration.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ api.setProxyPassword("proxyPassword");
3131
```
3232

3333
# Configure retries of calls and timeouts
34+
SDK can retry failed calls when:
35+
- failed writting request body
36+
- when recieved HTTP response code:
37+
- 429 - rate limit exceeded
38+
- 5XX - internal server error
39+
- 400 error with error that `exp` claim has expired. This usially means there is a clock skew.
40+
41+
SDK is using exponnetial strategy to calculate time between retries.
42+
If response contains `Retry-After` header its value will be used as a wait time between calls.
43+
You can check details in `com.box.sdk.BoxAPIRequest.send(com.box.sdk.ProgressListener)` method.
3444

3545
## Maximum retries
3646

@@ -140,4 +150,4 @@ BoxAPIConnection api = new BoxAPIConnection("YOUR-DEVELOPER-TOKEN");
140150
api.setRevokeURL("https://example.com/revoke");
141151
```
142152

143-
If you use `setRevokeUrl` this URL will be used over the one coming from`setBaseUrl` when doing authentication.
153+
If you use `setRevokeUrl` this URL will be used over the one coming from`setBaseUrl` when doing authentication.

doc/users.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ user.updateInfo(info);
159159

160160
## Delete User
161161

162-
To delete a user call the [`delete(boolean notifyUser, boolean force)`][delete] method.
162+
To delete a user call the [`delete(boolean notifyUser, boolean force)`][deleteWithParams] method or one that
163+
uses API default parameters [`delete()][delete]
163164

164165
The `notifyUser` determines whether the user should receive an email about the deletion,
165166
and the `force` parameter will cause the user to be deleted even if they still have files
@@ -171,7 +172,8 @@ BoxUser user = new BoxUser(api, "0");
171172
user.delete(false, false);
172173
```
173174

174-
[delete]: https://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#delete-boolean-boolean-
175+
[deleteWithParams]: https://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#delete-boolean-boolean-
176+
[delete]: https://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxUser.html#delete--
175177

176178
## Invite User
177179

src/intTest/java/com/box/sdk/BoxUserIT.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public void getCurrentUserInfoIsCorrect() {
5454
}
5555

5656
@Test(timeout = 10000)
57-
public void createAndDeleteEnterpriseUserSucceeds() {
57+
public void createAndForcefullyDeleteEnterpriseUser() {
5858
BoxAPIConnection api = jwtApiForServiceAccount();
5959
// Since deleting users happens in a separate process in the backend
6060
// it is really an asynchronous call. So we have to use a new user in
@@ -66,7 +66,26 @@ public void createAndDeleteEnterpriseUserSucceeds() {
6666
assertEquals(NEW_USER_NAME, createdUserInfo.getName());
6767
assertEquals(NEW_USER_LOGIN, createdUserInfo.getLogin());
6868

69-
createdUserInfo.getResource().delete(false, false);
69+
createdUserInfo.getResource().delete(false, true);
70+
71+
Iterable<BoxUser.Info> users = BoxUser.getAllEnterpriseUsers(api, NEW_USER_LOGIN);
72+
assertThat(createListFrom(users), Matchers.hasSize(0));
73+
}
74+
75+
@Test(timeout = 10000)
76+
public void createAndDeleteEnterpriseUser() {
77+
BoxAPIConnection api = jwtApiForServiceAccount();
78+
// Since deleting users happens in a separate process in the backend
79+
// it is really an asynchronous call. So we have to use a new user in
80+
// this test in case the previous user's deletion hasn't completed.
81+
82+
BoxUser.Info createdUserInfo = BoxUser.createEnterpriseUser(api, NEW_USER_LOGIN, NEW_USER_NAME);
83+
84+
assertNotNull(createdUserInfo.getID());
85+
assertEquals(NEW_USER_NAME, createdUserInfo.getName());
86+
assertEquals(NEW_USER_LOGIN, createdUserInfo.getLogin());
87+
88+
createdUserInfo.getResource().delete();
7089

7190
Iterable<BoxUser.Info> users = BoxUser.getAllEnterpriseUsers(api, NEW_USER_LOGIN);
7291
assertThat(createListFrom(users), Matchers.hasSize(0));
@@ -92,7 +111,7 @@ public void getMembershipsHasCorrectMemberships() {
92111
}
93112

94113
@Test(timeout = 10000)
95-
public void updateInfoSucceeds() {
114+
public void updateUserInfo() {
96115
BoxAPIConnection api = jwtApiForServiceAccount();
97116
final String login = "login3+" + Calendar.getInstance().getTimeInMillis() + "@boz.com";
98117
final String originalName = "original name";

src/main/java/com/box/sdk/BoxCollaboration.java

Lines changed: 95 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -331,24 +331,25 @@ public enum Role {
331331
}
332332

333333
static Role fromJSONString(String jsonValue) {
334-
if (jsonValue.equals("editor")) {
335-
return EDITOR;
336-
} else if (jsonValue.equals("viewer")) {
337-
return VIEWER;
338-
} else if (jsonValue.equals("previewer")) {
339-
return PREVIEWER;
340-
} else if (jsonValue.equals("uploader")) {
341-
return UPLOADER;
342-
} else if (jsonValue.equals("previewer uploader")) {
343-
return PREVIEWER_UPLOADER;
344-
} else if (jsonValue.equals("viewer uploader")) {
345-
return VIEWER_UPLOADER;
346-
} else if (jsonValue.equals("co-owner")) {
347-
return CO_OWNER;
348-
} else if (jsonValue.equals("owner")) {
349-
return OWNER;
350-
} else {
351-
throw new IllegalArgumentException("The provided JSON value isn't a valid Role.");
334+
switch (jsonValue) {
335+
case "editor":
336+
return EDITOR;
337+
case "viewer":
338+
return VIEWER;
339+
case "previewer":
340+
return PREVIEWER;
341+
case "uploader":
342+
return UPLOADER;
343+
case "previewer uploader":
344+
return PREVIEWER_UPLOADER;
345+
case "viewer uploader":
346+
return VIEWER_UPLOADER;
347+
case "co-owner":
348+
return CO_OWNER;
349+
case "owner":
350+
return OWNER;
351+
default:
352+
throw new IllegalArgumentException("The provided JSON value isn't a valid Role.");
352353
}
353354
}
354355

@@ -360,7 +361,7 @@ String toJSONString() {
360361
/**
361362
* Contains information about a BoxCollaboration.
362363
*/
363-
public class Info extends BoxResource.Info {
364+
public class Info extends BoxResource.Info {
364365
private BoxUser.Info createdBy;
365366
private Date createdAt;
366367
private Date modifiedAt;
@@ -369,8 +370,7 @@ public class Info extends BoxResource.Info {
369370
private BoxCollaborator.Info accessibleBy;
370371
private Role role;
371372
private Date acknowledgedAt;
372-
private BoxFolder.Info item;
373-
private BoxFile.Info fileItem;
373+
private BoxItem.Info item;
374374
private String inviteEmail;
375375
private boolean canViewPath;
376376

@@ -532,7 +532,7 @@ public Date getAcknowledgedAt() {
532532
*
533533
* @return the folder the collaboration is related to.
534534
*/
535-
public BoxFolder.Info getItem() {
535+
public BoxItem.Info getItem() {
536536
return this.item;
537537
}
538538

@@ -541,70 +541,92 @@ public BoxCollaboration getResource() {
541541
return BoxCollaboration.this;
542542
}
543543

544+
@SuppressWarnings("checkstyle:MissingSwitchDefault")
544545
@Override
545546
protected void parseJSONMember(JsonObject.Member member) {
546547
super.parseJSONMember(member);
547548

548549
String memberName = member.getName();
549550
JsonValue value = member.getValue();
550551
try {
551-
if (memberName.equals("created_by")) {
552-
JsonObject userJSON = value.asObject();
553-
if (this.createdBy == null) {
554-
String userID = userJSON.get("id").asString();
555-
BoxUser user = new BoxUser(getAPI(), userID);
556-
this.createdBy = user.new Info(userJSON);
557-
} else {
558-
this.createdBy.update(userJSON);
559-
}
560-
561-
} else if (memberName.equals("created_at")) {
562-
this.createdAt = BoxDateFormat.parse(value.asString());
563-
564-
} else if (memberName.equals("modified_at")) {
565-
this.modifiedAt = BoxDateFormat.parse(value.asString());
566-
567-
} else if (memberName.equals("expires_at")) {
568-
this.expiresAt = BoxDateFormat.parse(value.asString());
569-
570-
} else if (memberName.equals("status")) {
571-
String statusString = value.asString().toUpperCase();
572-
this.status = Status.valueOf(statusString);
573-
574-
} else if (memberName.equals("accessible_by")) {
575-
JsonObject accessibleByJSON = value.asObject();
576-
if (this.accessibleBy == null) {
577-
this.accessibleBy = this.parseAccessibleBy(accessibleByJSON);
578-
} else {
579-
this.updateAccessibleBy(accessibleByJSON);
580-
}
581-
} else if (memberName.equals("role")) {
582-
this.role = Role.fromJSONString(value.asString());
583-
584-
} else if (memberName.equals("acknowledged_at")) {
585-
this.acknowledgedAt = BoxDateFormat.parse(value.asString());
586-
587-
} else if (memberName.equals("can_view_path")) {
588-
this.canViewPath = value.asBoolean();
589-
590-
} else if (memberName.equals("invite_email")) {
591-
this.inviteEmail = value.asString();
592-
593-
} else if (memberName.equals("item")) {
594-
JsonObject folderJSON = value.asObject();
595-
if (this.item == null) {
596-
String folderID = folderJSON.get("id").asString();
597-
BoxFolder folder = new BoxFolder(getAPI(), folderID);
598-
this.item = folder.new Info(folderJSON);
599-
} else {
600-
this.item.update(folderJSON);
601-
}
552+
switch (memberName) {
553+
case "created_by":
554+
JsonObject userJSON = value.asObject();
555+
if (this.createdBy == null) {
556+
String userID = userJSON.get("id").asString();
557+
BoxUser user = new BoxUser(getAPI(), userID);
558+
this.createdBy = user.new Info(userJSON);
559+
} else {
560+
this.createdBy.update(userJSON);
561+
}
562+
break;
563+
case "created_at":
564+
this.createdAt = BoxDateFormat.parse(value.asString());
565+
566+
break;
567+
case "modified_at":
568+
this.modifiedAt = BoxDateFormat.parse(value.asString());
569+
break;
570+
case "expires_at":
571+
this.expiresAt = BoxDateFormat.parse(value.asString());
572+
break;
573+
case "status":
574+
String statusString = value.asString().toUpperCase();
575+
this.status = Status.valueOf(statusString);
576+
577+
break;
578+
case "accessible_by":
579+
JsonObject accessibleByJSON = value.asObject();
580+
if (this.accessibleBy == null) {
581+
this.accessibleBy = this.parseAccessibleBy(accessibleByJSON);
582+
} else {
583+
this.updateAccessibleBy(accessibleByJSON);
584+
}
585+
break;
586+
case "role":
587+
this.role = Role.fromJSONString(value.asString());
588+
break;
589+
case "acknowledged_at":
590+
this.acknowledgedAt = BoxDateFormat.parse(value.asString());
591+
break;
592+
case "can_view_path":
593+
this.canViewPath = value.asBoolean();
594+
break;
595+
case "invite_email":
596+
this.inviteEmail = value.asString();
597+
break;
598+
case "item":
599+
JsonObject itemJson = value.asObject();
600+
if (this.item == null) {
601+
this.item = selectCollaborationItem(itemJson);
602+
} else {
603+
this.item.update(itemJson);
604+
}
605+
break;
602606
}
603607
} catch (Exception e) {
604608
throw new BoxDeserializationException(memberName, value.toString(), e);
605609
}
606610
}
607611

612+
private BoxItem.Info selectCollaborationItem(JsonObject itemJson) {
613+
String itemId = itemJson.get("id").asString();
614+
String itemType = itemJson.get("type").asString();
615+
switch (itemType) {
616+
case BoxFile.TYPE:
617+
return new BoxFile(getAPI(), itemId).new Info(itemJson);
618+
case BoxFolder.TYPE:
619+
return new BoxFolder(getAPI(), itemId).new Info(itemJson);
620+
default:
621+
throw new IllegalStateException(
622+
String.format(
623+
"Unsupported collaboration item type '%s': JSON %n%s",
624+
itemType,
625+
itemJson
626+
));
627+
}
628+
}
629+
608630
private void updateAccessibleBy(JsonObject json) {
609631
String type = json.get("type").asString();
610632
if ((type.equals("user") && this.accessibleBy instanceof BoxUser.Info)

0 commit comments

Comments
 (0)