/** * Copyright (c) 2005-20010 springside.org.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * * $Id: PropertyFilter.java 1205 2010-09-09 15:12:17Z calvinxiu $ */ package org.springside.modules.orm; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.springframework.util.Assert; import org.springside.modules.utils.reflection.ConvertUtils; import org.springside.modules.utils.web.ServletUtils; /** * 与具体ORM实现无关的属性过滤条件封装类, 主要记录页面中简单的搜索过滤条件. * * @author calvin */ public class PropertyFilter { /** 多个属性间OR关系的分隔符. */ public static final String OR_SEPARATOR = "_OR_"; /** 属性比较类型. * * NN:not null * IN: is null */ public enum MatchType { EQ, NE, LIKE, LLIKE, RLIKE, LT, GT, LE, GE, NN, IN, BTD; } /** 属性数据类型. */ public enum PropertyType { S(String.class), I(Integer.class), L(Long.class), F(Float.class), N(Double.class), D(Date.class), B(Boolean.class), W(String.class); private Class<?> clazz; private PropertyType(Class<?> clazz) { this.clazz = clazz; } public Class<?> getValue() { return clazz; } } private MatchType matchType = null; private Object matchValue = null; private String originValue = null; private String propertyTypeCode = null; private Class<?> propertyClass = null; private String[] propertyNames = null; public PropertyFilter() { } /** * @param filterName 比较属性字符串,含待比较的比较类型、属性值类型及属性列表. * eg. LIKES_NAME_OR_LOGIN_NAME * @param value 待比较的值. */ public PropertyFilter(final String filterName, final String value) { String firstPart = StringUtils.substringBefore(filterName, "_"); String matchTypeCode = StringUtils.substring(firstPart, 0, firstPart.length() - 1); this.propertyTypeCode = StringUtils.substring(firstPart, firstPart.length() - 1, firstPart.length()); try { matchType = Enum.valueOf(MatchType.class, matchTypeCode); } catch (RuntimeException e) { throw new IllegalArgumentException("filter名称" + filterName + "没有按规则编写,无法得到属性比较类型.", e); } try { propertyClass = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue(); } catch (RuntimeException e) { throw new IllegalArgumentException("filter名称" + filterName + "没有按规则编写,无法得到属性值类型.", e); } String propertyNameStr = StringUtils.substringAfter(filterName, "_"); Assert.isTrue(StringUtils.isNotBlank(propertyNameStr), "filter名称" + filterName + "没有按规则编写,无法得到属性名称."); // propertyNames = StringUtils.splitByWholeSeparator(propertyNameStr, PropertyFilter.OR_SEPARATOR); propertyNames = propertyNameStr.split(PropertyFilter.OR_SEPARATOR); this.originValue = value; if (matchType.equals(MatchType.IN) || matchType.equals(MatchType.NN)) { this.matchValue = null; } else { this.matchValue = ConvertUtils.convertStringToObject(value, propertyClass); } } /** * 从HttpRequest中创建PropertyFilter列表, 默认Filter属性名前缀为filter. * * @see #buildFromHttpRequest(HttpServletRequest, String) */ public static List<PropertyFilter> buildFromHttpRequest(final HttpServletRequest request) { return buildFromHttpRequest(request, "filter"); } /** * 从HttpRequest中创建PropertyFilter列表 * PropertyFilter命名规则为Filter属性前缀_比较类型属性类型_属性名. * * eg. * filter_EQS_name * filter_LIKES_name_OR_email */ public static List<PropertyFilter> buildFromHttpRequest(final HttpServletRequest request, final String filterPrefix) { List<PropertyFilter> filterList = new ArrayList<PropertyFilter>(); //从request中获取含属性前缀名的参数,构造去除前缀名后的参数Map. Map<String, Object> filterParamMap = ServletUtils.getParametersStartingWith(request, filterPrefix + "_"); //分析参数Map,构造PropertyFilter列表 for (Map.Entry<String, Object> entry : filterParamMap.entrySet()) { String filterName = entry.getKey(); String value = null; try { String tempValue = entry.getValue() == null ? "" : entry.getValue().toString(); value = URLDecoder.decode(tempValue, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } String firstPart = StringUtils.substringBefore(filterName, "_"); String matchTypeCode = StringUtils.substring(firstPart, 0, firstPart.length() - 1); //如果value值为空,则忽略此filter. if (matchTypeCode.equals("IN") || StringUtils.isNotBlank(value)) { PropertyFilter filter = new PropertyFilter(filterName, value); filterList.add(filter); } } return filterList; } /** * 获取比较值的类型. */ public Class<?> getPropertyClass() { return propertyClass; } /** * 获取比较方式. */ public MatchType getMatchType() { return matchType; } /** * 获取比较值. */ public Object getMatchValue() { return matchValue; } /** * 获取原始值 * @return */ public String getOriginValue() { return originValue; } /** * 获取比较属性名称列表. */ public String[] getPropertyNames() { return propertyNames; } /** * 获取唯一的比较属性名称. */ public String getPropertyName() { Assert.isTrue(propertyNames.length == 1, "There are not only one property in this filter."); return propertyNames[0]; } /** * 是否比较多个属性. */ public boolean hasMultiProperties() { return (propertyNames.length > 1); } /** * 根据MatchType获取sql比较符号 */ public String getSqlOper() { Map<PropertyFilter.MatchType, String> types = new HashMap<PropertyFilter.MatchType, String>(); types.put(MatchType.EQ, "="); types.put(MatchType.NE, "!="); types.put(MatchType.GT, ">"); types.put(MatchType.LT, "<"); types.put(MatchType.GE, ">="); types.put(MatchType.LE, "<="); types.put(MatchType.IN, "is null"); types.put(MatchType.NN, "is not null"); return types.get(this.getMatchType()); } public void setMatchType(MatchType matchType) { this.matchType = matchType; } public void setMatchValue(Object matchValue) { this.matchValue = matchValue; } public void setOriginValue(String originValue) { this.originValue = originValue; } public void setPropertyClass(Class<?> propertyClass) { this.propertyClass = propertyClass; } public void setPropertyNames(String[] propertyNames) { this.propertyNames = propertyNames; } public String getPropertyTypeCode() { return propertyTypeCode; } public void setPropertyTypeCode(String propertyTypeCode) { this.propertyTypeCode = propertyTypeCode; } }