Java tutorial
/** * Copyright (c) 2014-2016 https://github.com/playersun * * Licensed under the Apache License, Version 2.0 (the "License"); */ package com.playersun.jbf.common.persistence.search; import java.lang.reflect.Field; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.commons.lang3.ArrayUtils; import org.apache.shiro.util.CollectionUtils; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.reflect.Reflection; import com.opensymphony.module.sitemesh.Page; import com.playersun.jbf.common.persistence.mybatis.pagination.PageRequest; import com.playersun.jbf.common.persistence.pagination.Pageable; import com.playersun.jbf.common.persistence.search.exception.InvalidSearchPropertyException; import com.playersun.jbf.common.persistence.search.exception.InvalidSearchValueException; import com.playersun.jbf.common.persistence.search.exception.SearchException; import com.playersun.jbf.common.utils.reflex.Reflections; /** * * @author PlayerSun * @date Dec 20, 2015 */ public class SearchRequest implements Searchable { private final Map<String, Condition> conditionMap = Maps.newHashMap(); //??sql?? private final List<Condition> conditions = Lists.newArrayList(); //? private Pageable page; //?? private Sort sort; //Mybatis? private Object paramObj; /** * @param searchParams * @see SearchRequest#SearchRequest(java.util.Map<java.lang.String,java.lang.Object>, Pageable, sort) */ public SearchRequest() { this(null, null, null); } /** * @param searchParams * @see SearchRequest#SearchRequest(java.util.Map<java.lang.String,java.lang.Object>, Pageable, sort) */ public SearchRequest(Pageable page) { this(null, page, null); } /** * @param searchParams * @see SearchRequest#SearchRequest(java.util.Map<java.lang.String,java.lang.Object>, Pageable, sort) */ public SearchRequest(final Map<String, Object> searchParams) { this(searchParams, null, null); } /** * @param searchParams * @see SearchRequest#SearchRequest(java.util.Map<java.lang.String,java.lang.Object>, Pageable, sort) */ public SearchRequest(final Map<String, Object> searchParams, final Pageable page) { this(searchParams, page, null); } /** * @param searchParams * @see SearchRequest#SearchRequest(java.util.Map<java.lang.String,java.lang.Object>, Pageable, sort) */ public SearchRequest(final Map<String, Object> searchParams, final Sort sort) throws SearchException { this(searchParams, null, sort); } /** * <p>??Search<br/> * ??property_op=value customerProperty=value<br/> * customerProperty1?domain2??domainSearchPropertyMappings * ??_op??/custom??custom??<br/> * op=customproperty???domain?, * </p> * * @param searchParams ? * @param page * @param sort ? */ public SearchRequest(final Map<String, Object> searchParams, final Pageable page, final Sort sort) throws SearchException { toSearchConditions(searchParams); merge(sort, page); } private void toSearchConditions(final Map<String, Object> searchParams) throws SearchException { if (searchParams == null || searchParams.size() == 0) { return; } for (Map.Entry<String, Object> entry : searchParams.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); addCondition(CommonCondition.newCondition(key, value)); } } private void merge(Sort sort, Pageable page) { if (sort == null) { sort = this.sort; } if (page == null) { page = this.page; } //?? if (sort == null) { this.sort = page != null ? page.getSort() : null; } else { this.sort = (page != null ? sort.and(page.getSort()) : sort); } //??page if (page != null) { this.page = new PageRequest(page.getPageNumber(), page.getPageSize(), this.sort); setParamObject(page.getParmObject()); } else { this.page = null; } } @Override public Searchable addSearchParam(String key, Object value) throws SearchException { addCondition(CommonCondition.newCondition(key, value)); return this; } @Override public Searchable addSearchParams(Map<String, Object> searchParams) throws SearchException { toSearchConditions(searchParams); return this; } @Override public Searchable addCondition(String searchProperty, SearchOperator operator, Object value) throws SearchException { addCondition(CommonCondition.newCondition(searchProperty, operator, value)); return null; } @Override public Searchable addCondition(Condition condition) { if (condition == null) { return this; } if (condition instanceof CommonCondition) { CommonCondition commonCondition = (CommonCondition) condition; String key = commonCondition.getKey(); conditionMap.put(key, condition); } int index = conditions.indexOf(condition); if (index != -1) { conditions.set(index, condition); } else { conditions.add(condition); } return this; } @Override public Searchable addConditions(Collection<? extends Condition> cdts) { if (CollectionUtils.isEmpty(cdts)) { return this; } for (Condition condition : cdts) { addCondition(condition); } return this; } @Override public Searchable or(Condition first, Condition... others) { OrCondition orCondition = new OrCondition(); orCondition.getOrConditions().add(first); if (ArrayUtils.isNotEmpty(others)) { orCondition.getOrConditions().addAll(Arrays.asList(others)); } return addCondition(orCondition); } @Override public Searchable and(Condition first, Condition... others) { AndCondition andCondition = new AndCondition(); andCondition.getAndConditions().add(first); if (ArrayUtils.isNotEmpty(others)) { andCondition.getAndConditions().addAll(Arrays.asList(others)); } return addCondition(andCondition); } @Override public Searchable removeCondition(String key) { if (key == null) { return this; } Condition condition = conditionMap.remove(key); if (condition == null) { condition = conditionMap.remove(getCustomKey(key)); } if (condition == null) { return this; } conditions.remove(condition); return this; } @Override public Searchable removeCondition(String searchProperty, SearchOperator operator) { this.removeCondition(searchProperty + CommonCondition.separator + operator); return this; } @Override public Searchable setPage(Pageable page) { merge(sort, page); return this; } @Override public Searchable setPage(int pageNumber, int pageSize) { merge(sort, new PageRequest(pageNumber, pageSize)); return this; } @Override public Searchable addSort(Sort sort) { merge(sort, page); return this; } @Override public Searchable addSort(Sort.Direction direction, String property) { merge(new Sort(direction, property), page); return this; } @Override public Collection<Condition> getConditions() { return Collections.unmodifiableCollection(conditions); } @Override public boolean hasCondition() { return conditions.size() > 0; } @Override public boolean hashSort() { return this.sort != null && this.sort.iterator().hasNext(); } @Override public void removeSort() { this.sort = null; if (this.page != null) { this.page = new PageRequest(page.getPageNumber(), page.getPageSize(), null); } } @Override public boolean hasPageable() { return this.page != null && this.page.getPageSize() > 0; } @Override public void removePageable() { this.page = null; } @Override public Pageable getPage() { return page; } @Override public Sort getSort() { return sort; } @Override public boolean containsSearchKey(String key) { boolean contains = conditionMap.containsKey(key) || conditionMap.containsKey(getCustomKey(key)); if (contains) { return true; } //?or and return containsSearchKey(conditions, key); } @Override public Object getValue(String key) { Condition cdt = conditionMap.get(key); if (cdt == null) { cdt = conditionMap.get(getCustomKey(key)); } if (cdt == null) { return null; } if (cdt instanceof CommonCondition) { CommonCondition condt = (CommonCondition) cdt; return condt.getValue(); } return null; } private String getCustomKey(String key) { return key + CommonCondition.separator + SearchOperator.eq; } private boolean containsSearchKey(List<Condition> cdts, String key) { boolean contains = false; for (Condition cdt : cdts) { if (cdt instanceof OrCondition) { OrCondition orCondition = (OrCondition) cdt; contains = containsSearchKey(orCondition.getOrConditions(), key); } if (cdt instanceof AndCondition) { AndCondition andCondition = (AndCondition) cdt; contains = containsSearchKey(andCondition.getAndConditions(), key); } if (cdt instanceof CommonCondition) { CommonCondition condition = (CommonCondition) cdt; contains = condition.getKey().equals(key) || condition.getSearchProperty().equals(key); } if (contains) { return true; } } return contains; } @Override public Searchable setParamObject(Object o) { this.paramObj = Reflections.bean2Map(this.paramObj, o); return this; } @Override public Object getParamObject() { return paramObj; } }