001package com.box.sdk; 002 003import java.net.URL; 004import java.util.ArrayList; 005import java.util.Collection; 006import java.util.Iterator; 007 008import com.box.sdk.BoxGroupMembership.Role; 009import com.eclipsesource.json.JsonArray; 010import com.eclipsesource.json.JsonObject; 011import com.eclipsesource.json.JsonValue; 012 013/** 014 * Represents a set of Box users. 015 * 016 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked 017 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error 018 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p> 019 */ 020@BoxResourceType("group") 021public class BoxGroup extends BoxCollaborator { 022 023 /** 024 * @see #getAllGroups(BoxAPIConnection, String...) 025 */ 026 private static final URLTemplate GROUPS_URL_TEMPLATE = new URLTemplate("groups"); 027 028 /** 029 * @see #getInfo() 030 */ 031 private static final URLTemplate GROUP_URL_TEMPLATE = new URLTemplate("groups/%s"); 032 033 /** 034 * @see #getMemberships() 035 */ 036 private static final URLTemplate MEMBERSHIPS_URL_TEMPLATE = new URLTemplate("groups/%s/memberships"); 037 038 /** 039 * @see #addMembership(BoxUser) 040 */ 041 private static final URLTemplate ADD_MEMBERSHIP_URL_TEMPLATE = new URLTemplate("group_memberships"); 042 043 /** 044 * @see #getCollaborations() 045 */ 046 private static final URLTemplate COLLABORATIONS_URL_TEMPLATE = new URLTemplate("groups/%s/collaborations"); 047 048 /** 049 * Constructs a BoxGroup for a group with a given ID. 050 * @param api the API connection to be used by the group. 051 * @param id the ID of the group. 052 */ 053 public BoxGroup(BoxAPIConnection api, String id) { 054 super(api, id); 055 } 056 057 /** 058 * Creates a new group with a specified name. 059 * @param api the API connection to be used by the group. 060 * @param name the name of the new group. 061 * @return info about the created group. 062 */ 063 public static BoxGroup.Info createGroup(BoxAPIConnection api, String name) { 064 return createGroup(api, name, null, null, null, null, null); 065 } 066 067 /** 068 * Creates a new group with a specified name. 069 * @param api the API connection to be used by the group. 070 * @param name the name of the new group. 071 * @param provenance the provenance of the new group 072 * @param externalSyncIdentifier the external_sync_identifier of the new group 073 * @param description the description of the new group 074 * @param invitabilityLevel the invitibility_level of the new group 075 * @param memberViewabilityLevel the member_viewability_level of the new group 076 * @return info about the created group. 077 */ 078 public static BoxGroup.Info createGroup(BoxAPIConnection api, String name, String provenance, 079 String externalSyncIdentifier, String description, 080 String invitabilityLevel, String memberViewabilityLevel) { 081 JsonObject requestJSON = new JsonObject(); 082 requestJSON.add("name", name); 083 084 if (provenance != null) { 085 requestJSON.add("provenance", provenance); 086 } 087 if (externalSyncIdentifier != null) { 088 requestJSON.add("external_sync_identifier", externalSyncIdentifier); 089 } 090 if (description != null) { 091 requestJSON.add("description", description); 092 } 093 if (invitabilityLevel != null) { 094 requestJSON.add("invitability_level", invitabilityLevel); 095 } 096 if (memberViewabilityLevel != null) { 097 requestJSON.add("member_viewability_level", memberViewabilityLevel); 098 } 099 100 URL url = GROUPS_URL_TEMPLATE.build(api.getBaseURL()); 101 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 102 request.setBody(requestJSON.toString()); 103 BoxJSONResponse response = (BoxJSONResponse) request.send(); 104 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 105 106 BoxGroup group = new BoxGroup(api, responseJSON.get("id").asString()); 107 return group.new Info(responseJSON); 108 } 109 110 /** 111 * Gets an iterable of all the groups in the enterprise. 112 * @param api the API connection to be used when retrieving the groups. 113 * @return an iterable containing info about all the groups. 114 */ 115 public static Iterable<BoxGroup.Info> getAllGroups(final BoxAPIConnection api) { 116 return new Iterable<BoxGroup.Info>() { 117 public Iterator<BoxGroup.Info> iterator() { 118 URL url = GROUPS_URL_TEMPLATE.build(api.getBaseURL()); 119 return new BoxGroupIterator(api, url); 120 } 121 }; 122 } 123 124 /** 125 * Gets an iterable of all the groups in the enterprise. 126 * @param api the API connection to be used when retrieving the groups. 127 * @param fields the fields to retrieve. 128 * @return an iterable containing info about all the groups. 129 */ 130 public static Iterable<BoxGroup.Info> getAllGroups(final BoxAPIConnection api, String ... fields) { 131 final QueryStringBuilder builder = new QueryStringBuilder(); 132 if (fields.length > 0) { 133 builder.appendParam("fields", fields); 134 } 135 return new Iterable<BoxGroup.Info>() { 136 public Iterator<BoxGroup.Info> iterator() { 137 URL url = GROUPS_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString()); 138 return new BoxGroupIterator(api, url); 139 } 140 }; 141 } 142 143 /** 144 * Gets information about this group. 145 * @return info about this group. 146 */ 147 public Info getInfo() { 148 URL url = GROUP_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 149 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 150 BoxJSONResponse response = (BoxJSONResponse) request.send(); 151 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 152 return new Info(responseJSON); 153 } 154 155 /** 156 * Gets information about this group. 157 * @param fields the fields to retrieve. 158 * @return info about this group. 159 */ 160 public Info getInfo(String ... fields) { 161 QueryStringBuilder builder = new QueryStringBuilder(); 162 if (fields.length > 0) { 163 builder.appendParam("fields", fields); 164 } 165 URL url = GROUP_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), builder.toString(), this.getID()); 166 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 167 BoxJSONResponse response = (BoxJSONResponse) request.send(); 168 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 169 return new Info(responseJSON); 170 } 171 172 /** 173 * Gets information about all of the group memberships for this group. 174 * Does not support paging. 175 * @return a collection of information about the group memberships for this group. 176 */ 177 public Collection<BoxGroupMembership.Info> getMemberships() { 178 final BoxAPIConnection api = this.getAPI(); 179 final String groupID = this.getID(); 180 181 Iterable<BoxGroupMembership.Info> iter = new Iterable<BoxGroupMembership.Info>() { 182 public Iterator<BoxGroupMembership.Info> iterator() { 183 URL url = MEMBERSHIPS_URL_TEMPLATE.build(api.getBaseURL(), groupID); 184 return new BoxGroupMembershipIterator(api, url); 185 } 186 }; 187 188 // We need to iterate all results because this method must return a Collection. This logic should be removed in 189 // the next major version, and instead return the Iterable directly. 190 Collection<BoxGroupMembership.Info> memberships = new ArrayList<BoxGroupMembership.Info>(); 191 for (BoxGroupMembership.Info membership : iter) { 192 memberships.add(membership); 193 } 194 return memberships; 195 } 196 197 /** 198 * Gets information about all of the group memberships for this group as iterable with paging support. 199 * @param fields the fields to retrieve. 200 * @return an iterable with information about the group memberships for this group. 201 */ 202 public Iterable<BoxGroupMembership.Info> getAllMemberships(String ... fields) { 203 final QueryStringBuilder builder = new QueryStringBuilder(); 204 if (fields.length > 0) { 205 builder.appendParam("fields", fields); 206 } 207 return new Iterable<BoxGroupMembership.Info>() { 208 public Iterator<BoxGroupMembership.Info> iterator() { 209 URL url = MEMBERSHIPS_URL_TEMPLATE.buildWithQuery( 210 BoxGroup.this.getAPI().getBaseURL(), builder.toString(), BoxGroup.this.getID()); 211 return new BoxGroupMembershipIterator(BoxGroup.this.getAPI(), url); 212 } 213 }; 214 } 215 216 /** 217 * Adds a member to this group with the default role. 218 * @param user the member to be added to this group. 219 * @return info about the new group membership. 220 */ 221 public BoxGroupMembership.Info addMembership(BoxUser user) { 222 return this.addMembership(user, null); 223 } 224 225 /** 226 * Adds a member to this group with the specified role. 227 * @param user the member to be added to this group. 228 * @param role the role of the user in this group. Can be null to assign the default role. 229 * @return info about the new group membership. 230 */ 231 public BoxGroupMembership.Info addMembership(BoxUser user, Role role) { 232 BoxAPIConnection api = this.getAPI(); 233 234 JsonObject requestJSON = new JsonObject(); 235 requestJSON.add("user", new JsonObject().add("id", user.getID())); 236 requestJSON.add("group", new JsonObject().add("id", this.getID())); 237 if (role != null) { 238 requestJSON.add("role", role.toJSONString()); 239 } 240 241 URL url = ADD_MEMBERSHIP_URL_TEMPLATE.build(api.getBaseURL()); 242 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 243 request.setBody(requestJSON.toString()); 244 BoxJSONResponse response = (BoxJSONResponse) request.send(); 245 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 246 247 BoxGroupMembership membership = new BoxGroupMembership(api, responseJSON.get("id").asString()); 248 return membership.new Info(responseJSON); 249 } 250 251 /** 252 * Gets information about all of the collaborations for this group. 253 * @return a collection of information about the collaborations for this group. 254 */ 255 public Collection<BoxCollaboration.Info> getCollaborations() { 256 BoxAPIConnection api = this.getAPI(); 257 URL url = COLLABORATIONS_URL_TEMPLATE.build(api.getBaseURL(), this.getID()); 258 259 BoxAPIRequest request = new BoxAPIRequest(api, url, "GET"); 260 BoxJSONResponse response = (BoxJSONResponse) request.send(); 261 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 262 263 int entriesCount = responseJSON.get("total_count").asInt(); 264 Collection<BoxCollaboration.Info> collaborations = new ArrayList<BoxCollaboration.Info>(entriesCount); 265 JsonArray entries = responseJSON.get("entries").asArray(); 266 for (JsonValue entry : entries) { 267 JsonObject entryObject = entry.asObject(); 268 BoxCollaboration collaboration = new BoxCollaboration(api, entryObject.get("id").asString()); 269 BoxCollaboration.Info info = collaboration.new Info(entryObject); 270 collaborations.add(info); 271 } 272 273 return collaborations; 274 } 275 276 /** 277 * Deletes this group. 278 */ 279 public void delete() { 280 URL url = GROUP_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 281 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 282 BoxAPIResponse response = request.send(); 283 response.disconnect(); 284 } 285 286 /** 287 * Updates the information about this group with any info fields that have been modified locally. 288 * @param info the updated info. 289 */ 290 public void updateInfo(BoxGroup.Info info) { 291 URL url = GROUP_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 292 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 293 request.setBody(info.getPendingChanges()); 294 BoxJSONResponse response = (BoxJSONResponse) request.send(); 295 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 296 info.update(jsonObject); 297 } 298 299 /** 300 * Contains information about a BoxGroup. 301 */ 302 public class Info extends BoxCollaborator.Info { 303 304 /** 305 * @see #getProvenance() 306 */ 307 private String provenance; 308 309 /** 310 * @see #getExternalSyncIdentifier() 311 */ 312 private String externalSyncIdentifier; 313 314 /** 315 * @see #getDescription() 316 */ 317 private String description; 318 319 /** 320 * @see #getInvitabilityLevel() 321 */ 322 private String invitabilityLevel; 323 324 /** 325 * @see #getMemberViewabilityLevel() 326 */ 327 private String memberViewabilityLevel; 328 329 /** 330 * Constructs an empty Info object. 331 */ 332 public Info() { 333 super(); 334 } 335 336 /** 337 * Constructs an Info object by parsing information from a JSON string. 338 * @param json the JSON string to parse. 339 */ 340 public Info(String json) { 341 super(json); 342 } 343 344 /** 345 * Constructs an Info object using an already parsed JSON object. 346 * @param jsonObject the parsed JSON object. 347 */ 348 Info(JsonObject jsonObject) { 349 super(jsonObject); 350 } 351 352 /** 353 * {@inheritDoc} 354 */ 355 @Override 356 public BoxGroup getResource() { 357 return BoxGroup.this; 358 } 359 360 /** 361 * {@inheritDoc} 362 */ 363 @Override 364 protected void parseJSONMember(JsonObject.Member member) { 365 super.parseJSONMember(member); 366 367 String memberName = member.getName(); 368 JsonValue value = member.getValue(); 369 if (memberName.equals("description")) { 370 this.description = value.asString(); 371 } else if (memberName.equals("external_sync_identifier")) { 372 this.externalSyncIdentifier = value.asString(); 373 } else if (memberName.equals("invitability_level")) { 374 this.invitabilityLevel = value.asString(); 375 } else if (memberName.equals("member_viewability_level")) { 376 this.memberViewabilityLevel = value.asString(); 377 } else if (memberName.equals("provenance")) { 378 this.provenance = value.asString(); 379 } 380 } 381 382 /** 383 * Gets the description for the group. 384 * @return the description for the group. 385 */ 386 public String getDescription() { 387 return this.description; 388 } 389 390 /** 391 * Sets the description for the group. 392 * @param description the description for the group. 393 */ 394 public void setDescription(String description) { 395 this.description = description; 396 addPendingChange("description", description); 397 } 398 399 /** 400 * Gets the external_sync_identifier for the group. 401 * @return the external_sync_identifier for the group. 402 */ 403 public String getExternalSyncIdentifier() { 404 return this.externalSyncIdentifier; 405 } 406 407 /** 408 * Sets the external_sync_identifier for the group. 409 * @param externalSyncIdentifier the external_sync_identifier for the group. 410 */ 411 public void setExternalSyncIdentifier(String externalSyncIdentifier) { 412 this.externalSyncIdentifier = externalSyncIdentifier; 413 addPendingChange("external_sync_identifier", externalSyncIdentifier); 414 } 415 416 /** 417 * Gets the invitability_level for the group. 418 * @return the invitability_level for the group. 419 */ 420 public String getInvitabilityLevel() { 421 return this.invitabilityLevel; 422 } 423 424 /** 425 * Sets the invitability_level for the group. 426 * @param invitabilityLevel the invitability_level for the group. 427 */ 428 public void setInvitabilityLevel(String invitabilityLevel) { 429 this.invitabilityLevel = invitabilityLevel; 430 addPendingChange("invitability_level", invitabilityLevel); 431 } 432 433 /** 434 * Gets the member_viewability_level for the group. 435 * @return the member_viewability_level for the group. 436 */ 437 public String getMemberViewabilityLevel() { 438 return this.memberViewabilityLevel; 439 } 440 441 /** 442 * Sets the member_viewability_level for the group. 443 * @param memberViewabilityLevel the member_viewability_level for the group. 444 */ 445 public void setMemberViewabilityLevel(String memberViewabilityLevel) { 446 this.memberViewabilityLevel = memberViewabilityLevel; 447 addPendingChange("member_viewability_level", memberViewabilityLevel); 448 } 449 450 /** 451 * Gets the provenance for the group. 452 * @return the provenance for the group. 453 */ 454 public String getProvenance() { 455 return this.provenance; 456 } 457 458 /** 459 * Sets the provenance for the group. 460 * @param provenance the provenance for the group. 461 */ 462 public void setProvenance(String provenance) { 463 this.provenance = provenance; 464 addPendingChange("provenance", provenance); 465 } 466 } 467}