package com.taobao.tddl.rule.model; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.Set; import org.apache.commons.lang.builder.ToStringBuilder; import com.taobao.tddl.common.utils.TddlToStringStyle; import com.taobao.tddl.rule.Rule.RuleColumn; import com.taobao.tddl.rule.utils.AdvancedParameterParser; /** * 通过{@linkplain AdvancedParameterParser}.getAdvancedParamByParamTokenNew()进行构建 */ public class AdvancedParameter extends RuleColumn { /** * 自增,给枚举器用的 */ public final Comparable<?> atomicIncreateValue; /** * 叠加次数,给枚举器用的 */ public final Integer cumulativeTimes; /** * 决定当前参数是否允许范围查询如>= <= ... */ public final boolean needMergeValueInCloseInterval; /** * 自增的类型,包括 */ public final AtomIncreaseType atomicIncreateType; /** * 起始与结束值对象列表,通过"|"分割 */ public final Range[] rangeArray; public AdvancedParameter(String key, Comparable<?> atomicIncreateValue, Integer cumulativeTimes, boolean needAppear, AtomIncreaseType atomicIncreateType, Range[] rangeObjectArray){ super(key, needAppear); this.atomicIncreateValue = atomicIncreateValue; this.atomicIncreateType = atomicIncreateType; this.cumulativeTimes = cumulativeTimes; this.rangeArray = rangeObjectArray; if (atomicIncreateValue != null) { this.needMergeValueInCloseInterval = true; } else { this.needMergeValueInCloseInterval = false; } } /** * 枚举所有值 * * @param basepoint * @return */ public Set<Object> enumerateRange() { Set<Object> values = new HashSet<Object>(); if (atomicIncreateType.isTime()) { Calendar c = Calendar.getInstance(); for (Range ro : rangeArray) { for (int i = ro.start; i <= ro.end; i++) { values.add(evalTime(c, i)); } } } else { for (Range ro : rangeArray) { for (int i = ro.start; i <= ro.end; i++) { values.add(i); } } } return values; } /** * 枚举所有值 * * @param basepoint * @return */ public Set<Object> enumerateRange(Object basepoint) { if (basepoint instanceof Number) { return enumerateRange(((Number) basepoint).intValue()); } else if (basepoint instanceof Calendar) { return enumerateRange((Calendar) basepoint); } else if (basepoint instanceof Date) { // add by junyu,因为后面evalTime的时候把结果返回了Date类型,所以这边也要增加这个逻辑 Calendar cal = Calendar.getInstance(); cal.setTime((Date) basepoint); return enumerateRange(cal); } else { throw new IllegalArgumentException(basepoint + " applies on atomicIncreateType: " + atomicIncreateType); } } /** * 枚举所有值 * * @param basepoint * @return */ public Set<Object> enumerateRange(int basepoint) { Set<Object> values = new HashSet<Object>(); if (AtomIncreaseType.NUMBER.equals(atomicIncreateType)) { int start = basepoint; int end = start + this.cumulativeTimes; for (int i = start; i <= end; i++) { values.add(i); } } else { throw new IllegalArgumentException("Number applies on atomicIncreateType: " + atomicIncreateType); } return values; } /** * 枚举所有值 * * @param basepoint * @return */ public Set<Object> enumerateRange(Calendar basepoint) { Set<Object> values = new HashSet<Object>(); if (atomicIncreateType.isTime()) { for (int i = 0; i < this.cumulativeTimes; i++) { values.add(evalTime(basepoint, i)); } } else { throw new IllegalArgumentException("Calendar applies on atomicIncreateType: " + atomicIncreateType); } return values; } private Object evalTime(Calendar base, int i) { Calendar c = (Calendar) base.clone(); if (AtomIncreaseType.YEAR.equals(atomicIncreateType)) { c.add(Calendar.YEAR, i); } else if (AtomIncreaseType.MONTH.equals(atomicIncreateType)) { c.add(Calendar.MONTH, i); } else if (AtomIncreaseType.DATE.equals(atomicIncreateType)) { c.add(Calendar.DATE, i); } else if (AtomIncreaseType.HOUR.equals(atomicIncreateType)) { c.add(Calendar.HOUR_OF_DAY, i); } else { throw new IllegalArgumentException("atomicIncreateType:" + atomicIncreateType); } // return c; // modify by junyu,与sql参数保持一致类型 return c.getTime(); } /** * 参数自增类型,现在支持4种(#2011-12-5,modify by junyu,add HOUR type) */ public static enum AtomIncreaseType { HOUR, DATE, MONTH, YEAR, NUMBER; public boolean isTime() { return this.ordinal() < NUMBER.ordinal(); } } public static class Range { public final Integer start; // 起始值 public final Integer end; // 结束值 public Range(Integer start, Integer end){ this.start = start; this.end = end; } } public String toString() { return ToStringBuilder.reflectionToString(this, TddlToStringStyle.DEFAULT_STYLE); } }