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