001package gu.dtalk; 002 003import java.io.ByteArrayOutputStream; 004import java.io.PrintStream; 005import java.io.UnsupportedEncodingException; 006import java.util.ArrayList; 007import java.util.Arrays; 008import java.util.Collections; 009import java.util.HashSet; 010import java.util.LinkedHashMap; 011import java.util.List; 012import java.util.Map; 013import java.util.Map.Entry; 014import java.util.Set; 015 016import com.alibaba.fastjson.TypeReference; 017import com.alibaba.fastjson.annotation.JSONField; 018import com.google.common.base.Function; 019import com.google.common.base.MoreObjects; 020import com.google.common.base.Predicate; 021import com.google.common.base.Predicates; 022import com.google.common.collect.Iterables; 023import com.google.common.collect.Lists; 024import com.google.common.collect.Sets; 025 026import static com.google.common.base.Preconditions.*; 027/** 028 * 多选列表选项 029 * @author guyadong 030 * 031 * @param <E> 032 */ 033public class CheckOption<E> extends BaseOption<Set<Integer>> { 034 @JSONField(serialize = false,deserialize = false) 035 private final Predicate<Set<Integer>> checkValidator = new Predicate<Set<Integer>>() { 036 037 @Override 038 public boolean apply(Set<Integer> set) { 039 boolean findInvalid = Iterables.tryFind(set, new Predicate<Integer>() { 040 @Override 041 public boolean apply(Integer index) { 042 return index < 0 || index >= options.size(); 043 } 044 }).isPresent(); 045 return !findInvalid; 046 } 047 }; 048 protected final LinkedHashMap<E, String> options = new LinkedHashMap<>(); 049 public CheckOption() { 050 super(new TypeReference<Set<Integer>>() {}.getType()); 051 super.setValidator(checkValidator); 052 } 053 054 public CheckOption<E> addOption(E opt,String desc){ 055 options.put(checkNotNull(opt), MoreObjects.firstNonNull(desc, "")); 056 return this; 057 } 058 059 @Override 060 public OptionType getType() { 061 return OptionType.MULTICHECK; 062 } 063 064 @Override 065 public BaseOption<Set<Integer>> setValidator(Predicate<Set<Integer>> validator) { 066 return super.setValidator(Predicates.and(checkValidator, validator)); 067 } 068 069 @JSONField(serialize = false,deserialize = false) 070 public List<E> getSelected(){ 071 ArrayList<Integer> indexs = Lists.newArrayList((Set<Integer>) getValue()); 072 final ArrayList<E> opts = Lists.newArrayList(options.keySet()); 073 return Lists.transform(indexs, new Function<Integer, E>() { 074 075 @Override 076 public E apply(Integer input) { 077 return opts.get(input); 078 } 079 }); 080 } 081 @JSONField(serialize = false,deserialize = false) 082 public CheckOption<E> setSelected(List<E> sel){ 083 sel = MoreObjects.firstNonNull(sel, Collections.<E>emptyList()); 084 Iterable<E> itor = Iterables.filter(sel, new Predicate<E>() { 085 086 @Override 087 public boolean apply(E input) { 088 return options.containsKey(input); 089 } 090 }); 091 final ArrayList<E> opts = Lists.newArrayList(options.keySet()); 092 093 HashSet<Integer> indexSet = Sets.newHashSet(Iterables.transform(itor, new Function<E,Integer>(){ 094 095 @Override 096 public Integer apply(E input) { 097 return opts.indexOf(input); 098 }})); 099 setValue(indexSet); 100 return this; 101 } 102 @SuppressWarnings("unchecked") 103 public CheckOption<E> setSelected(E... sel){ 104 return setSelected(Arrays.asList(sel)); 105 } 106 public String contentOfOptions(){ 107 ByteArrayOutputStream bytestream = new ByteArrayOutputStream(); 108 PrintStream stream = new PrintStream(bytestream); 109 int index=0; 110 stream.printf("\tavailable options:\n"); 111 for(Entry<E, String> entry:options.entrySet()){ 112 String desc = entry.getValue(); 113 stream.printf("\t<%d>%s -- %s\n", index++,entry.getKey().toString(), desc.isEmpty() ? "NO DESC" : desc); 114 } 115 try { 116 return new String(bytestream.toByteArray(),"utf-8"); 117 } catch (UnsupportedEncodingException e) { 118 throw new RuntimeException(e); 119 } 120 } 121 122 public Map<E, String> getOptions() { 123 return options; 124 } 125 public void setOptions(Map<E, String> options) { 126 this.options.clear(); 127 this.options.putAll(options); 128 } 129 public BaseOption<Set<Integer>> setValue(Integer ...selects){ 130 return setValue(Sets.newHashSet(selects)); 131 } 132}