001package gu.dtalk; 002 003import com.google.common.base.Predicate; 004import com.google.common.base.Predicates; 005import com.google.common.collect.Iterables; 006import com.google.common.collect.Sets; 007 008import static com.google.common.base.Preconditions.*; 009 010import java.util.Arrays; 011import java.util.Collection; 012import java.util.Comparator; 013import java.util.Iterator; 014import java.util.LinkedHashSet; 015 016/** 017 * 数值验证器 018 * @author guyadong 019 * 020 * @param <T> 数据类型,必须{@link Number}的子类 021 */ 022public class NumberValidator<T> implements Predicate<T> { 023 public static final NumberValidator<Object> DEFAULT_VALIDATOR = new NumberValidator<Object>(); 024 public static final NumberValidator<Object> NORMALIZATION_VALIDATOR = new NumberValidator<Object>((Double)0.0,true,(Double)1.0,true); 025 private T min = null, max = null; 026 private LinkedHashSet<T> values = null; 027 028 private Comparator<T> numCcomparator = new Comparator<T>(){ 029 030 @Override 031 public int compare(T o1, T o2) { 032 if((o1 instanceof Integer) && (o2 instanceof Integer) ){ 033 return ((Integer)o1).compareTo((Integer)o2); 034 } 035 if((o1 instanceof Short) && (o2 instanceof Short) ){ 036 return ((Short)o1).compareTo((Short)o2); 037 } 038 if((o1 instanceof Byte) && (o2 instanceof Byte) ){ 039 return ((Byte)o1).compareTo((Byte)o2); 040 } 041 if((o1 instanceof Float) && (o2 instanceof Float) ){ 042 return ((Float)o1).compareTo((Float)o2); 043 } 044 if((o1 instanceof Float) && (o2 instanceof Float) ){ 045 return ((Float)o1).compareTo((Float)o2); 046 } 047 if((o1 instanceof Double) && (o2 instanceof Double) ){ 048 return ((Double)o1).compareTo((Double)o2); 049 } 050 throw new IllegalArgumentException("UNSUPPORTED TYPE"); 051 }}; 052 private boolean mineq; 053 private boolean maxeq; 054 public NumberValidator() { 055 this(null,true,null,true); 056 } 057 public NumberValidator(T min,boolean mineq,T max,boolean maxeq) { 058 this.min = min; 059 this.max = max; 060 this.mineq = mineq; 061 this.maxeq = maxeq; 062 checkArgument(min == null || Number.class.isAssignableFrom(min.getClass())); 063 checkArgument(max == null || Number.class.isAssignableFrom(max.getClass())); 064 if(min != null && max !=null){ 065 checkArgument(numCcomparator.compare(min, max) < 0,"value of max must less than min"); 066 } 067 } 068 @SafeVarargs 069 public NumberValidator(T ... values) { 070 this.values = Sets.newLinkedHashSet(Iterables.filter(Arrays.asList(checkNotNull(values)),Predicates.notNull())); 071 checkArgument(!this.values.isEmpty(),"EMPTY LIST FOR values"); 072 Iterables.any(this.values, new Predicate<T>() { 073 @Override 074 public boolean apply(T input) { 075 checkArgument(input instanceof Number,"INVALID type of values"); 076 return true; 077 } 078 }); 079 } 080 @Override 081 public boolean apply(T input) { 082 if(input == null){ 083 return false; 084 } 085 if(values != null){ 086 return values.contains(input); 087 }else{ 088 boolean check = true; 089 if(min != null){ 090 int comp = numCcomparator.compare(min, input); 091 check = check && ((mineq && comp <= 0 ) || comp <0); 092 } 093 if(max != null){ 094 int comp = numCcomparator.compare(input,max); 095 check = check && ((maxeq && comp >= 0 ) || comp >0); 096 } 097 return check; 098 } 099 } 100 @Override 101 public String toString() { 102 final int maxLen = 10; 103 StringBuilder builder = new StringBuilder(); 104 builder.append("NumberValidator ["); 105 if (min != null) { 106 builder.append("min="); 107 builder.append(min); 108 builder.append(", "); 109 } 110 if (max != null) { 111 builder.append("max="); 112 builder.append(max); 113 builder.append(", "); 114 } 115 if (values != null) { 116 builder.append("values="); 117 builder.append(toString(values, maxLen)); 118 builder.append(", "); 119 } 120 if (numCcomparator != null) { 121 builder.append("numCcomparator="); 122 builder.append(numCcomparator); 123 } 124 builder.append("]"); 125 return builder.toString(); 126 } 127 private String toString(Collection<?> collection, int maxLen) { 128 StringBuilder builder = new StringBuilder(); 129 builder.append("["); 130 int i = 0; 131 for (Iterator<?> iterator = collection.iterator(); iterator.hasNext() && i < maxLen; i++) { 132 if (i > 0) 133 builder.append(", "); 134 builder.append(iterator.next()); 135 } 136 builder.append("]"); 137 return builder.toString(); 138 } 139 @SuppressWarnings({ "rawtypes", "unchecked" }) 140 @SafeVarargs 141 public static final <T>Predicate<Object> makeValidator(T ...values){ 142 checkArgument(values != null && values.length >1); 143 return new NumberValidator(values); 144 } 145 @SuppressWarnings({ "rawtypes", "unchecked" }) 146 public static final <T>Predicate<Object> makeValidator( T min,boolean mineq,T max,boolean maxeq){ 147 return new NumberValidator(min,mineq,max,maxeq); 148 } 149}