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