/** * */ package org.activejpa.entity; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Order; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.activejpa.entity.Condition.Operator; /** * @author ganeshs * */ public class Filter { private List<Condition> conditions = new ArrayList<Condition>(); private List<SortField> sortFields = new ArrayList<SortField>(); private Integer pageNo; private Integer perPage; private boolean cacheable; private boolean shouldPage; public Filter(int perPage, int pageNo, Condition... conditions) { this.pageNo = pageNo > 0 ? pageNo : 1; this.shouldPage = perPage > 0; this.perPage = (perPage < 1) ? Integer.MAX_VALUE : perPage; if (conditions != null && conditions.length > 0) { this.conditions.addAll(Arrays.asList(conditions)); } } public Filter() { this(0, 0); } public Filter(Condition... conditions) { this(0, 0, conditions); } public Integer getPageNo() { return pageNo; } public void setPageNo(Integer pageNo) { this.pageNo = pageNo; } public Integer getPerPage() { return perPage; } public void setPerPage(Integer perPage) { this.perPage = perPage; } public Integer getStart() { return (pageNo - 1) * perPage; } public Integer getLimit() { return perPage; } public boolean shouldPage() { return shouldPage; } /** * @return the conditions */ public List<Condition> getConditions() { return conditions; } /** * @param conditions the conditions to set */ public void setConditions(List<Condition> conditions) { this.conditions = conditions; } public void addCondition(String name, Object value) { addCondition(name, Operator.eq, value); } public void addCondition(String name, Operator operator, Object value) { this.conditions.add(new Condition(name, operator, value)); } public String constructQuery() { StringWriter writer = new StringWriter(); if (conditions != null || !conditions.isEmpty()) { for (int i = 0; i < conditions.size() - 1; i++) { writer.append(conditions.get(i).constructQuery()).append(" and "); } writer.append(conditions.get(conditions.size() - 1).constructQuery()); } return writer.toString(); } /** * Constructs the select criteria query * * @param builder * @param query * @param root */ public <T extends Model> void constructQuery(CriteriaBuilder builder, CriteriaQuery<?> query, Root<T> root) { if (conditions != null || !conditions.isEmpty()) { List<Predicate> predicates = new ArrayList<Predicate>(); for (Condition condition : conditions) { predicates.add(condition.constructQuery(builder, root)); } query.where(predicates.toArray(new Predicate[0])); } if (sortFields != null && !sortFields.isEmpty()) { List<Order> orders = new ArrayList<Order>(); for (SortField sortField : sortFields) { orders.add(sortField.getOrder(builder, root)); } query.orderBy(orders); } } /** * Constructs the delete criteria query * * @param builder * @param query * @param root */ public <T extends Model> void constructQuery(CriteriaBuilder builder, CriteriaDelete<?> query, Root<T> root) { if (conditions != null || !conditions.isEmpty()) { List<Predicate> predicates = new ArrayList<Predicate>(); for (Condition condition : conditions) { predicates.add(condition.constructQuery(builder, root)); } query.where(predicates.toArray(new Predicate[0])); } } public void setParameters(Query query) { if (conditions != null && !conditions.isEmpty()) { for (Condition condition : conditions) { condition.setParameters(query, condition.getValue()); } } } public void setPage(Query query) { if (shouldPage()) { query.setFirstResult(getStart()); query.setMaxResults(getPerPage()); } } /** * @return the cacheable */ public boolean isCacheable() { return cacheable; } /** * @param cacheable the cacheable to set */ public void setCacheable(boolean cacheable) { this.cacheable = cacheable; } /** * Adds the sort field * * @param name * @param asc */ public void addSortField(String name, boolean asc) { this.sortFields.add(new SortField(name, asc)); } /** * Adds the sort field * * @param sortField */ public void addSortField(SortField sortField) { this.sortFields.add(sortField); } /** * @return the sortFields */ public List<SortField> getSortFields() { return sortFields; } /** * @param sortFields the sortFields to set */ public void setSortFields(List<SortField> sortFields) { this.sortFields = sortFields; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((conditions == null) ? 0 : conditions.hashCode()); result = prime * result + ((pageNo == null) ? 0 : pageNo.hashCode()); result = prime * result + ((perPage == null) ? 0 : perPage.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Filter other = (Filter) obj; if (conditions == null) { if (other.conditions != null) return false; } else if (!conditions.containsAll(other.conditions)) return false; if (pageNo == null) { if (other.pageNo != null) return false; } else if (!pageNo.equals(other.pageNo)) return false; if (perPage == null) { if (other.perPage != null) return false; } else if (!perPage.equals(other.perPage)) return false; return true; } public Filter clone(boolean paginate) { Filter filter = new Filter(conditions.toArray(new Condition[0])); if (paginate) { filter.perPage = perPage; filter.pageNo = pageNo; filter.shouldPage = shouldPage; } return filter; } }