package io.robe.common.service.search.model; import com.fasterxml.jackson.annotation.JsonIgnore; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; /** * A data class for holding search query parameters as a auto * filled easy to access data structure. */ public class SearchModel { /** * Full text search parameter */ private String q; /** * Starting index for the paged fetches. */ private Integer offset; /** * Maximum number of results per page. */ private Integer limit; /** * on response fields */ private String[] fields; /** * Fieds for sorting + for asc and - for desc ordering followed by field name Forex. +fieldName */ private String[] sort; private String[][] filter; private long totalCount; private HttpServletResponse response; public SearchModel() { } private static String[][] parseFilterExp(String filters) { String[] filterArr = filters.split(","); String[][] parsed = new String[filterArr.length][3]; int parsedIndex = 0; for (String filter : filterArr) { char[] chars = filter.toCharArray(); char[] name = new char[chars.length]; char[] op = new char[2]; char[] value = new char[chars.length]; int nIndex = 0; int oIndex = 0; int vIndex = 0; short part = 0; for (int i = 0; i < chars.length; i++) { switch (part) { case 0://Filling name switch (chars[i]) { case '=': case '!': case '<': case '>': case '~': case '|': //Jump to operation op[oIndex++] = chars[i]; part = 1; break; default: name[nIndex++] = chars[i]; } break; case 1://Filling op switch (chars[i]) { case '=': op[oIndex++] = chars[i]; break; default: //Jump to value value[vIndex++] = chars[i]; part = 2; } break; case 2://Filling value value[vIndex++] = chars[i]; break; } } parsed[parsedIndex++] = new String[]{ new String(name, 0, nIndex), new String(op, 0, oIndex), new String(value, 0, vIndex)}; } return parsed; } public String getQ() { return q; } public void setQ(String q) { this.q = q; } public Integer getOffset() { return offset; } public void setOffset(Integer offset) { this.offset = offset; } public Integer getLimit() { return limit; } public void setLimit(Integer limit) { this.limit = limit; } public String[] getFields() { return fields; } public void setFields(String[] fields) { this.fields = fields; } public String[] getSort() { return sort; } public void setSort(String[] sort) { this.sort = sort; } public String[][] getFilter() { return filter; } public void setFilter(String[][] filter) { this.filter = filter; } public void setFilterExpression(String filter) { this.filter = parseFilterExp(filter); } public long getTotalCount() { return totalCount; } public void setTotalCount(long totalCount) { this.totalCount = totalCount; } public HttpServletResponse getResponse() { return response; } public void setResponse(HttpServletResponse response) { this.response = response; } @JsonIgnore public void addFilter(String field, String operator, String value) { if (this.filter == null || this.filter.length == 0) { this.filter = new String[][]{new String[]{field, operator, value}}; } else { this.filter = Arrays.copyOf(this.filter, this.filter.length + 1); this.filter[filter.length - 1] = new String[]{field, operator, value}; } } @JsonIgnore public void addSort(String field, String operator) { if (this.sort == null) { this.sort = new String[1]; this.sort[0] = operator + field; } else { boolean find = false; for (int i = 0; i < this.sort.length; i++) { String f = this.sort[i]; if (field.equals(f.substring(1, f.length()))) { this.sort[i] = operator + field; find = true; break; } } if (!find) { String[] array = Arrays.copyOf(this.sort, this.sort.length + 1); array[this.sort.length] = operator + field; this.sort = array; } } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SearchModel model = (SearchModel) o; if (totalCount != model.totalCount) return false; if (q != null ? !q.equals(model.q) : model.q != null) return false; if (offset != null ? !offset.equals(model.offset) : model.offset != null) return false; if (limit != null ? !limit.equals(model.limit) : model.limit != null) return false; // Probably incorrect - comparing Object[] arrays with Arrays.equals if (!Arrays.equals(fields, model.fields)) return false; // Probably incorrect - comparing Object[] arrays with Arrays.equals if (!Arrays.equals(sort, model.sort)) return false; return Arrays.deepEquals(filter, model.filter); } @Override public int hashCode() { int result = q != null ? q.hashCode() : 0; result = 31 * result + (offset != null ? offset.hashCode() : 0); result = 31 * result + (limit != null ? limit.hashCode() : 0); result = 31 * result + Arrays.hashCode(fields); result = 31 * result + Arrays.hashCode(sort); result = 31 * result + Arrays.deepHashCode(filter); result = 31 * result + (int) (totalCount ^ (totalCount >>> 32)); return result; } }