001package com.box.sdk;
002import java.util.List;
003
004import com.eclipsesource.json.JsonArray;
005import com.eclipsesource.json.JsonObject;
006
007/**
008 * Used to Setup Box Search Parameters
009 *
010 * <p>Advanced Search support here allows a number of parameters be specified to take full advantage of
011 * box search capabilities. Query parameter is required in all cases except when Metadata templates
012 * searching is being used.</p>
013 *
014 */
015public class BoxSearchParameters {
016    private String query;
017    private List<String> fields;
018    private String scope;
019    private List<String> fileExtensions;
020    private DateRange createdRange;
021    private DateRange updatedRange;
022    private SizeRange sizeRange;
023    private List<String> ownerUserIds;
024    private List<String> ancestorFolderIds;
025    private List<String> contentTypes;
026    private String type;
027    private String trashContent;
028    private BoxMetadataFilter metadataFilter;
029    private String sort;
030    private String direction;
031    /**
032     * Creates a Box Search Parameters Objects without query set, specific for Metadata Only Searches.
033     */
034    public BoxSearchParameters() {
035    }
036    /**
037     * Creates a Box Search Parameters Objects with a query initiated.
038     * @param query parameter.
039     */
040    public BoxSearchParameters(String query) {
041        this.query = query;
042    }
043    /**
044     * Clears the Parameters before performing a new search.
045     * @return this.true;
046     */
047    public boolean clearParameters() {
048        this.query = null;
049        this.fields = null;
050        this.scope = null;
051        this.fileExtensions = null;
052        this.createdRange = null;
053        this.updatedRange = null;
054        this.sizeRange = null;
055        this.ownerUserIds = null;
056        this.ancestorFolderIds = null;
057        this.contentTypes = null;
058        this.type = null;
059        this.trashContent = null;
060        this.metadataFilter = null;
061        this.sort = null;
062        this.direction = null;
063        return true;
064    }
065    /**
066     * Get existing query String that is being used.
067     * @return this.query string.
068     */
069    public String getQuery() {
070        return this.query;
071    }
072    /**
073     * Set query string for that will be used to search.
074     * @param query is a String value.
075     */
076    public void setQuery(String query) {
077        this.query = query;
078    }
079    /**
080     * Get the existing fields that are used for the search criteria.
081     * @return this.List of fields.
082     */
083    public List<String> getFields() {
084        return this.fields;
085    }
086    /**
087     * Set the existing fields that are used for the search criteria.
088     * @param fields specify what fields to be returned.
089     */
090    public void setFields(List<String> fields) {
091        this.fields = fields;
092    }
093    /**
094     * Get the scope on which you want to search, ["enterprise","scope"].
095     * @return this.current scope that is set.
096     */
097    public String getScope() {
098        return this.scope;
099    }
100    /**
101     * Set the scope for how you want to search, ["enterprise","scope"].
102     * @param scope set scope you want to search.
103     */
104    public void setScope(String scope) {
105        this.scope = scope;
106    }
107    /**
108     * Get file extension filter (jpg,docx).
109     * @return this.list of extensions.
110     */
111    public List<String> getFileExtensions() {
112        return this.fileExtensions;
113    }
114    /**
115     * Set file extension by providing a list of strings [jpg,docx].
116     * @param fileExtensions applied as a filter for extensions.
117     */
118    public void setFileExtensions(List<String> fileExtensions) {
119        this.fileExtensions = fileExtensions;
120    }
121    /**
122     * Get the DateRange filter to specify the when a file was created.
123     * @return this.createdRange DateRange.
124     */
125    public DateRange getCreatedRange() {
126        return this.createdRange;
127    }
128    /**
129     * Set the from DateRange filter to specify when a file was created.
130     * @param createdRange a start and end date on which a file was created.
131     */
132    public void setCreatedRange(DateRange createdRange) {
133        this.createdRange = createdRange;
134    }
135    /**
136     * Get the DateRange filter to specify the when a file was updated.
137     * @return this.updatedRange DateRange.
138     */
139    public DateRange getUpdatedRange() {
140        return this.updatedRange;
141    }
142    /**
143     * Set the from DateRange filter to specify when a file was updated.
144     * @param updatedRange a start and end date on which a file was updated.
145     */
146    public void setUpdatedRange(DateRange updatedRange) {
147        this.updatedRange = updatedRange;
148    }
149    /**
150     * Set the file size range for lower and upper bounds Bytes.
151     * @param sizeRange a size filter.
152     */
153    public void setSizeRange(SizeRange sizeRange) {
154        this.sizeRange = sizeRange;
155    }
156    /**
157     * Return the size range that is being used as a filter.
158     * @return this.sizeRange.
159     */
160    public SizeRange getSizeRange() {
161        return this.sizeRange;
162    }
163    /**
164     * Return the list of owner id's that are being applied as a search filter on the results.
165     * @return ownerUserIds.
166     */
167    public List<String> getOwnerUserIds() {
168        return this.ownerUserIds;
169    }
170    /**
171     * Set the owner id's to be applied as a filter to restrict the results on specific file owners.
172     * @param ownerUserIds applied ownerId's.
173     */
174    public void setOwnerUserIds(List<String> ownerUserIds) {
175        this.ownerUserIds = ownerUserIds;
176    }
177    /**
178     * Return the list of folder ids that is currently being used as applied filter.
179     * @return  ancestorFolderIds.
180     */
181    public List<String> getAncestorFolderIds() {
182        return this.ancestorFolderIds;
183    }
184    /**
185     * Set the list of folder id's to be applied as a filter on the search filters.
186     * @param ancestorFolderIds a list of folder ids that will contain results to specific folders.
187     */
188    public void setAncestorFolderIds(List<String> ancestorFolderIds) {
189        this.ancestorFolderIds = ancestorFolderIds;
190    }
191    /**
192     * Return content types that or being applied as a filter (name,description,tags,file_content).
193     * @return  contentTypes.
194     */
195    public List<String> getContentTypes() {
196        return this.contentTypes;
197    }
198    /**
199     * Set list of content types that will be used as a filters.
200     * @param contentTypes a list of content types such as (name,description,tags,file_content).
201     */
202    public void setContentTypes(List<String> contentTypes) {
203        this.contentTypes = contentTypes;
204    }
205    /**
206     * Return the type you want to return in your search.
207     * @return String type.
208     */
209    public String getType() {
210        return this.type;
211    }
212    /**
213     * Set the type you want to search for can be file, folder, or web_link.
214     * @param type can be file, folder, or web_link.
215     */
216    public void setType(String type) {
217        this.type = type;
218    }
219    /**
220     * Return the specified trash search preference.
221     * @return String trashContent.
222     */
223    public String getTrashContent() {
224        return this.trashContent;
225    }
226    /**
227     * Set trash filter. Can be trashed_only or non_trashed_only, without this parameter default to non_trashed_only.
228     * @param trashContent Can be trashed_only or non_trashed_only.
229     */
230    public void setTrashContent(String trashContent) {
231        this.trashContent = trashContent;
232    }
233    /**
234     * Retrieve the existing BoxMetaDataFilter.
235     * @return this.BoxMetaDataFilter
236     */
237    public BoxMetadataFilter getMetadataFilter() {
238        return this.metadataFilter;
239    }
240    /**
241     * Set the current list of Metadata Filters.
242     * @param metadataFilter a list of the current metadata filters.
243     */
244    public void setMetadataFilter(BoxMetadataFilter metadataFilter) {
245        this.metadataFilter = metadataFilter;
246    }
247
248    /**
249     * Set the sort field for Box Search.
250     * @param sortBy the field to sort the Box Search results by.
251     */
252    public void setSort(String sortBy) {
253        this.sort = sortBy;
254    }
255
256    /**
257     * Retrieve the sort field for Box Search.
258     * @return String identifier for Sort.
259     */
260    public String getSort() {
261        return this.sort;
262    }
263
264    /**
265     * Set the direction of the sort for the Box Search results.
266     * @param direction can be DESC or ASC.
267     */
268    public void setDirection(String direction) {
269        this.direction = direction;
270    }
271
272    /**
273     * Retrieves the sort direction for Box Search results.
274     * @return The direction of the Box Search sort.
275     */
276    public String getDirection() {
277        return this.direction;
278    }
279
280    /**
281     * Checks String to see if the parameter is null.
282     * @param    paramValue Object that will be checked if null.
283     * @return this.true if the parameter that is being checked is not null
284     */
285    private boolean isNullOrEmpty(Object paramValue) {
286        boolean isNullOrEmpty = false;
287        if (paramValue == null) {
288            isNullOrEmpty = true;
289        }
290        if (paramValue instanceof String) {
291            if (((String) paramValue).trim().equalsIgnoreCase("")) {
292                isNullOrEmpty = true;
293            }
294        } else if (paramValue instanceof List) {
295            return ((List) paramValue).isEmpty();
296        }
297        return isNullOrEmpty;
298    }
299    /**
300     * Add BoxMetaDataFilter to the JsonArray boxMetadataFilterRequestArray.
301     * @param @param bmf accepts a filter that has templateKey, scope, and filters populated.
302     * @return JsonArray that is formated Json request
303     */
304    private JsonArray formatBoxMetadataFilterRequest() {
305        JsonArray boxMetadataFilterRequestArray = new JsonArray();
306
307        JsonObject boxMetadataFilter = new JsonObject()
308                .add("templateKey", this.metadataFilter.getTemplateKey())
309                .add("scope", this.metadataFilter.getScope())
310                .add("filters", this.metadataFilter.getFiltersList());
311        boxMetadataFilterRequestArray.add(boxMetadataFilter);
312
313        return boxMetadataFilterRequestArray;
314    }
315
316    /**
317     * Concat a List into a CSV String.
318     * @param list list to concat
319     * @return csv string
320     */
321    private String listToCSV(List<String> list) {
322        String csvStr = "";
323        for (String item : list) {
324            csvStr += "," + item;
325        }
326
327        return csvStr.length() > 1 ? csvStr.substring(1) : csvStr;
328    }
329    /**
330     * Get the Query Paramaters to be used for search request.
331     * @return this.QueryStringBuilder.
332     */
333    public QueryStringBuilder getQueryParameters() {
334        QueryStringBuilder builder = new QueryStringBuilder();
335
336        if (this.isNullOrEmpty(this.query) && this.metadataFilter == null) {
337            throw new BoxAPIException(
338                "BoxSearchParameters requires either a search query or Metadata filter to be set."
339            );
340        }
341
342        //Set the query of the search
343        if (!this.isNullOrEmpty(this.query)) {
344            builder.appendParam("query", this.query);
345        }
346        //Set the scope of the search
347        if (!this.isNullOrEmpty(this.scope)) {
348            builder.appendParam("scope", this.scope);
349        }
350        //Acceptable Value: "jpg,png"
351        if (!this.isNullOrEmpty(this.fileExtensions)) {
352            builder.appendParam("file_extensions", this.listToCSV(this.fileExtensions));
353        }
354        //Created Date Range: From Date - To Date
355        if ((this.createdRange != null)) {
356            builder.appendParam("created_at_range", this.createdRange.buildRangeString());
357        }
358        //Updated Date Range: From Date - To Date
359        if ((this.updatedRange != null)) {
360            builder.appendParam("updated_at_range", this.updatedRange.buildRangeString());
361        }
362        //Filesize Range
363        if ((this.sizeRange != null)) {
364            builder.appendParam("size_range", this.sizeRange.buildRangeString());
365        }
366        //Owner Id's
367        if (!this.isNullOrEmpty(this.ownerUserIds)) {
368            builder.appendParam("owner_user_ids", this.listToCSV(this.ownerUserIds));
369        }
370        //Ancestor ID's
371        if (!this.isNullOrEmpty(this.ancestorFolderIds)) {
372            builder.appendParam("ancestor_folder_ids", this.listToCSV(this.ancestorFolderIds));
373        }
374        //Content Types: "name, description"
375        if (!this.isNullOrEmpty(this.contentTypes)) {
376            builder.appendParam("content_types", this.listToCSV(this.contentTypes));
377        }
378        //Type of File: "file,folder,web_link"
379        if (this.type != null) {
380            builder.appendParam("type", this.type);
381        }
382        //Trash Content
383        if (!this.isNullOrEmpty(this.trashContent)) {
384            builder.appendParam("trash_content", this.trashContent);
385        }
386        //Metadata filters
387        if (this.metadataFilter != null) {
388            builder.appendParam("mdfilters", this.formatBoxMetadataFilterRequest().toString());
389        }
390        //Fields
391        if (!this.isNullOrEmpty(this.fields)) {
392            builder.appendParam("fields", this.listToCSV(this.fields));
393        }
394        //Sort
395        if (!this.isNullOrEmpty(this.sort)) {
396            builder.appendParam("sort", this.sort);
397        }
398        //Direction
399        if (!this.isNullOrEmpty(this.direction)) {
400            builder.appendParam("direction", this.direction);
401        }
402        return builder;
403    }
404}