package org.exitsoft.orm.core.hibernate.property; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.exitsoft.common.utils.ServletUtils; import org.exitsoft.orm.core.PropertyFilter; import org.exitsoft.orm.core.PropertyType; import org.exitsoft.orm.core.hibernate.property.impl.restriction.EqRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.GeRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.GtRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.InRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.LLikeRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.LeRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.LikeRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.LtRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.NeRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.NinRestriction; import org.exitsoft.orm.core.hibernate.property.impl.restriction.RLikeRestriction; import org.hibernate.criterion.Criterion; /** * Hibernate属性过滤器约束持有者,帮助HibernateDao对buildCriterion方法创建相对的Criterion对象给Hibernate查询 * * @author vincent * */ public class PropertyFilterRestrictionHolder { private static Map<String, PropertyCriterionBuilder> criterionMap = new HashMap<String, PropertyCriterionBuilder>(); static { PropertyCriterionBuilder eqRestriction = new EqRestriction(); PropertyCriterionBuilder neRestriction = new NeRestriction(); PropertyCriterionBuilder geRestriction = new GeRestriction(); PropertyCriterionBuilder gtRestriction = new GtRestriction(); PropertyCriterionBuilder inRestriction = new InRestriction(); PropertyCriterionBuilder lLikeRestriction = new LLikeRestriction(); PropertyCriterionBuilder leRestriction = new LeRestriction(); PropertyCriterionBuilder likeRestriction = new LikeRestriction(); PropertyCriterionBuilder ltRestriction = new LtRestriction(); PropertyCriterionBuilder notInRestriction = new NinRestriction(); PropertyCriterionBuilder rLikeRestriction = new RLikeRestriction(); criterionMap.put(eqRestriction.getRestrictionName(), eqRestriction); criterionMap.put(neRestriction.getRestrictionName(), neRestriction); criterionMap.put(geRestriction.getRestrictionName(), geRestriction); criterionMap.put(inRestriction.getRestrictionName(), inRestriction); criterionMap.put(gtRestriction.getRestrictionName(), gtRestriction); criterionMap.put(lLikeRestriction.getRestrictionName(), lLikeRestriction); criterionMap.put(leRestriction.getRestrictionName(), leRestriction); criterionMap.put(likeRestriction.getRestrictionName(), likeRestriction); criterionMap.put(ltRestriction.getRestrictionName(), ltRestriction); criterionMap.put(rLikeRestriction.getRestrictionName(), rLikeRestriction); criterionMap.put(notInRestriction.getRestrictionName(), notInRestriction); } /** * 通过{@link PropertyFilter} 创建Hibernate约束标准 * * @param filter 属性过滤器 * * @return {@link Criterion} */ public static Criterion getCriterion(PropertyFilter filter) { PropertyCriterionBuilder criterionBuilder = criterionMap.get(filter.getRestrictionName()); return criterionBuilder.build(filter); } /** * 创建Hibernate约束标准 * * @param propertyName 属性名称 * @param value 值 * @param restrictionName 约束名称 * * @return {@link Criterion} */ public static Criterion getCriterion(String propertyName,Object value,String restrictionName) { PropertyCriterionBuilder restriction = criterionMap.get(restrictionName); return restriction.build(propertyName, value); } /** * 通过表达式和对比值创建条件过滤器集合,要求表达式与值必须相等 * <p> * 如: * </p> * <code> * PropertyFilerRestriction.createrPropertyFilter(new String[]{"EQ_S_propertyName1","NE_I_propertyName2"},new String[]{"vincent","vincent_OR_admin"}) * </code> * <p> * 对比值长度与表达式长度必须相等 * </p> * * @param expressions 表达式 * @param matchValues 对比值 * * @return List */ public static List<PropertyFilter> createPropertyFilter(String[] expressions,String[] matchValues) { if (ArrayUtils.isEmpty(expressions) && ArrayUtils.isEmpty(matchValues)) { return Collections.emptyList(); } if (expressions.length != matchValues.length) { throw new IllegalAccessError("expressions中的值与matchValues不匹配,matchValues的长度为:" + matchValues.length + "而expressions的长度为:" + expressions.length); } List<PropertyFilter> filters = new ArrayList<PropertyFilter>(); for (int i = 0; i < expressions.length; i++) { filters.add(createPropertyFilter(expressions[i], matchValues[i])); } return filters; } /** * 通过表达式和对比值创建条件过滤器 * <p> * 如: * </p> * <code> * PropertyFilerRestriction.createrPropertyFilter("EQ_S_propertyName","vincent") * </code> * * @param expressions 表达式 * @param matchValues 对比值 * * @return {@link PropertyFilter} */ public static PropertyFilter createPropertyFilter(String expression,String matchValue) { String restrictionsName = StringUtils.substringBefore(expression, "_"); if (!criterionMap.containsKey(restrictionsName)) { throw new IllegalAccessError("[" + expression + "]表达式找不到相应的约束名称,获取的值为:" + restrictionsName); } String classType = StringUtils.substringBetween(expression, "_"); PropertyType propertyType = null; try { propertyType = PropertyType.valueOf(classType); } catch (Exception e) { throw new IllegalAccessError("[" + expression + "]表达式找不到相应的属性类型,获取的值为:" + classType); } String[] propertyNames = null; if (StringUtils.contains(expression,"_OR_")) { String temp = StringUtils.substringAfter(expression, restrictionsName + "_" + classType + "_"); propertyNames = StringUtils.splitByWholeSeparator(temp, "_OR_"); } else { propertyNames = new String[1]; propertyNames[0] = StringUtils.substringAfterLast(expression, "_"); } return new PropertyFilter(restrictionsName, propertyType, propertyNames,matchValue); } /** * 获取Criterion的Map * * @return Map */ public static Map<String, PropertyCriterionBuilder> getCriterionMap() { return criterionMap; } /** * 设置Criterion的Map * * @return Map */ public static void setCriterionMap(Map<String, PropertyCriterionBuilder> map) { criterionMap.putAll(map); } /** * 从HttpRequest参数中创建PropertyFilter列表, 默认Filter属性名前缀为filter. * 当参数存在{filter_EQ_S_property1:value,filter_EQ_S_property2:''}该形式的时候,将不会创建filter_EQ_S_property2等于""值的实例 * 参考{@link PropertyFilterRestrictionHolder#buildPropertyFilter(HttpServletRequest, String, boolean)} * * @param request HttpServletRequest */ public static List<PropertyFilter> buildFromHttpRequest(HttpServletRequest request) { return buildFromHttpRequest(request, "filter"); } /** * 从HttpRequest参数中创建PropertyFilter列表,当参数存在{filter_EQ_S_property1:value,filter_EQ_S_property2:''} * 该形式的时候,将不会创建filter_EQ_S_property2等于""值的实例 * 参考{@link PropertyFilterRestrictionHolder#buildPropertyFilter(HttpServletRequest, String, boolean)} * * @param request HttpServletRequest * @param filterPrefix 用于识别是propertyfilter参数的前准 * * @return List */ public static List<PropertyFilter> buildFromHttpRequest(HttpServletRequest request,String filterPrefix) { return buildPropertyFilter(request, "filter",false); } /** * 从HttpRequest参数中创建PropertyFilter列表,当参数存在{filter_EQ_S_property1:value,filter_EQ_S_property2:''} * 该形式的时候,将不会创建filter_EQ_S_property2等于""值的实例 * 参考{@link PropertyFilterRestrictionHolder#buildPropertyFilter(HttpServletRequest, String, boolean)} * * <pre> * 当页面提交的参数为:{filter_EQ_S_property1:value,filter_EQ_S_property2:''} * List filters =buildPropertyFilter(request,"filter",false); * 当前filters:EQ_S_proerpty1="value",EQ_S_proerpty1="" * * 当页面提交的参数为:{filter_EQ_S_property1:value,filter_EQ_S_property2:''} * List filters =buildPropertyFilter(request,"filter",true); * 当前filters:EQ_S_proerpty1="value" * </pre> * * @param request HttpServletRequest * @param ignoreEmptyValue true表示当存在""值时忽略该PropertyFilter * * @return List */ public static List<PropertyFilter> buildFromHttpRequest(HttpServletRequest request,boolean ignoreEmptyValue) { return buildPropertyFilter(request, "filter",ignoreEmptyValue); } /** * 从HttpRequest参数中创建PropertyFilter列表,例子: * * <pre> * 当页面提交的参数为:{filter_EQ_S_property1:value,filter_EQ_S_property2:''} * List filters =buildPropertyFilter(request,"filter",false); * 当前filters:EQ_S_proerpty1="value",EQ_S_proerpty1="" * * 当页面提交的参数为:{filter_EQ_S_property1:value,filter_EQ_S_property2:''} * List filters =buildPropertyFilter(request,"filter",true); * 当前filters:EQ_S_proerpty1="value" * </pre> * * @param request HttpServletRequest * @param filterPrefix 用于识别是propertyfilter参数的前准 * @param ignoreEmptyValue true表示当存在""值时忽略该PropertyFilter * * @return List */ public static List<PropertyFilter> buildPropertyFilter(HttpServletRequest request,String filterPrefix,boolean ignoreEmptyValue) { // 从request中获取含属性前缀名的参数,构造去除前缀名后的参数Map. Map<String, Object> filterParamMap = ServletUtils.getParametersStartingWith(request, filterPrefix + "_"); return buildPropertyFilter(filterParamMap,ignoreEmptyValue); } /** * 从Map中创建PropertyFilter列表,如: * * <pre> * Map o = new HashMap(); * o.put("EQ_S_property1","value"); * o.put("EQ_S_property2",""); * List filters = buildPropertyFilter(o,false); * 当前filters:EQ_S_proerpty1="value",EQ_S_proerpty1="" * * Map o = new HashMap(); * o.put("EQ_S_property1","value"); * o.put("EQ_S_property2",""); * List filters = buildPropertyFilter(o,true); * 当前filters:EQ_S_proerpty1="value" * </pre> * * * @param filters 过滤器信息 * @param ignoreEmptyValue true表示当存在 null或者""值时忽略该PropertyFilter * */ public static List<PropertyFilter> buildPropertyFilter(Map<String, Object> filters,boolean ignoreEmptyValue) { List<PropertyFilter> filterList = new ArrayList<PropertyFilter>(); // 分析参数Map,构造PropertyFilter列表 for (Map.Entry<String, Object> entry : filters.entrySet()) { String expression = entry.getKey(); Object value = entry.getValue(); //如果ignoreEmptyValue为true忽略null或""的值 if (ignoreEmptyValue && (value == null || value.toString().equals(""))) { continue; } //如果ignoreEmptyValue为true忽略null或""的值 PropertyFilter filter = createPropertyFilter(expression, value.toString()); filterList.add(filter); } return filterList; } }