001package com.box.sdk; 002 003import com.eclipsesource.json.Json; 004import com.eclipsesource.json.JsonArray; 005import com.eclipsesource.json.JsonObject; 006import com.eclipsesource.json.JsonValue; 007import java.net.URL; 008import java.util.Iterator; 009 010/** 011 * Collections contain information about the items contained inside of them, including files and 012 * folders. The only collection available currently is a “Favorites” collection. 013 * 014 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link 015 * BoxAPIException} (unchecked meaning that the compiler won't force you to handle it) if an error 016 * occurs. If you wish to implement custom error handling for errors related to the Box REST API, 017 * you should capture this exception explicitly. 018 */ 019@BoxResourceType("collection") 020public class BoxCollection extends BoxResource implements Iterable<BoxItem.Info> { 021 022 /** Get Collections URL Template. */ 023 public static final URLTemplate GET_COLLECTIONS_URL_TEMPLATE = new URLTemplate("collections/"); 024 /** Get Collection Items URL Template. */ 025 public static final URLTemplate GET_COLLECTION_ITEMS_URL = 026 new URLTemplate("collections/%s/items/"); 027 028 /** 029 * Constructs a BoxCollection for a collection with a given ID. 030 * 031 * @param api the API connection to be used by the collection. 032 * @param id the ID of the collection. 033 */ 034 public BoxCollection(BoxAPIConnection api, String id) { 035 super(api, id); 036 } 037 038 /** 039 * Gets an iterable of all the collections for the given user. 040 * 041 * @param api the API connection to be used when retrieving the collections. 042 * @return an iterable containing info about all the collections. 043 */ 044 public static Iterable<BoxCollection.Info> getAllCollections(final BoxAPIConnection api) { 045 return () -> { 046 URL url = GET_COLLECTIONS_URL_TEMPLATE.build(api.getBaseURL()); 047 return new BoxCollectionIterator(api, url); 048 }; 049 } 050 051 /** 052 * Returns an iterable containing the items in this collection. Iterating over the iterable 053 * returned by this method is equivalent to iterating over this BoxCollection directly. 054 * 055 * @return an iterable containing the items in this collection. 056 */ 057 public Iterable<BoxItem.Info> getItems() { 058 return this; 059 } 060 061 /** 062 * Returns an iterable containing the items in this collection and specifies which attributes to 063 * include in the response. 064 * 065 * @param fields the fields to retrieve. 066 * @return an iterable containing the items in this collection. 067 */ 068 public Iterable<BoxItem.Info> getItems(final String... fields) { 069 return () -> { 070 String queryString = new QueryStringBuilder().appendParam("fields", fields).toString(); 071 URL url = 072 GET_COLLECTION_ITEMS_URL.buildWithQuery(getAPI().getBaseURL(), queryString, getID()); 073 return new BoxItemIterator(getAPI(), url); 074 }; 075 } 076 077 /** 078 * Retrieves a specific range of items in this collection. 079 * 080 * @param offset the index of the first item to retrieve. 081 * @param limit the maximum number of items to retrieve after the offset. 082 * @param fields the fields to retrieve. 083 * @return a partial collection containing the specified range of items. 084 */ 085 public PartialCollection<BoxItem.Info> getItemsRange(long offset, long limit, String... fields) { 086 QueryStringBuilder builder = 087 new QueryStringBuilder().appendParam("offset", offset).appendParam("limit", limit); 088 089 if (fields.length > 0) { 090 builder.appendParam("fields", fields); 091 } 092 093 URL url = 094 GET_COLLECTION_ITEMS_URL.buildWithQuery(getAPI().getBaseURL(), builder.toString(), getID()); 095 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "GET"); 096 try (BoxJSONResponse response = request.send()) { 097 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 098 099 String totalCountString = responseJSON.get("total_count").toString(); 100 long fullSize = Double.valueOf(totalCountString).longValue(); 101 PartialCollection<BoxItem.Info> items = new PartialCollection<>(offset, limit, fullSize); 102 JsonArray entries = responseJSON.get("entries").asArray(); 103 for (JsonValue entry : entries) { 104 BoxItem.Info entryInfo = 105 (BoxItem.Info) BoxResource.parseInfo(this.getAPI(), entry.asObject()); 106 if (entryInfo != null) { 107 items.add(entryInfo); 108 } 109 } 110 return items; 111 } 112 } 113 114 /** 115 * Returns an iterator over the items in this collection. 116 * 117 * @return an iterator over the items in this collection. 118 */ 119 @Override 120 public Iterator<BoxItem.Info> iterator() { 121 URL url = 122 GET_COLLECTION_ITEMS_URL.build(this.getAPI().getBaseURL(), BoxCollection.this.getID()); 123 return new BoxItemIterator(BoxCollection.this.getAPI(), url); 124 } 125 126 /** Contains information about a BoxCollection. */ 127 public class Info extends BoxResource.Info { 128 private String collectionType; 129 private String name; 130 131 /** Constructs an empty Info object. */ 132 public Info() { 133 super(); 134 } 135 136 /** 137 * Constructs an Info object by parsing information from a JSON string. 138 * 139 * @param json the JSON string to parse. 140 */ 141 public Info(String json) { 142 super(json); 143 } 144 145 /** 146 * Constructs an Info object using an already parsed JSON object. 147 * 148 * @param jsonObject the parsed JSON object. 149 */ 150 Info(JsonObject jsonObject) { 151 super(jsonObject); 152 } 153 154 /** 155 * Gets the type of the collection. 156 * 157 * @return the type of the collection. 158 */ 159 public String getCollectionType() { 160 return this.collectionType; 161 } 162 163 /** 164 * Gets the name of the collection. 165 * 166 * @return the name of the collection. 167 */ 168 public String getName() { 169 return this.name; 170 } 171 172 @Override 173 public BoxCollection getResource() { 174 return BoxCollection.this; 175 } 176 177 @Override 178 protected void parseJSONMember(JsonObject.Member member) { 179 super.parseJSONMember(member); 180 181 String memberName = member.getName(); 182 JsonValue value = member.getValue(); 183 if (memberName.equals("collection_type")) { 184 this.collectionType = value.asString(); 185 } else if (memberName.equals("name")) { 186 this.name = value.asString(); 187 } 188 } 189 } 190}