All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gu.dtalk.BaseOption Maven / Gradle / Ivy

There is a newer version: 0.8.2
Show newest version
package gu.dtalk;

import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Observable;
import com.alibaba.fastjson.annotation.JSONField;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import gu.dtalk.event.ValueChangeEvent;
import gu.dtalk.event.ValueListener;

import static com.google.common.base.Preconditions.*;

/**
 * 用于参数配置和命令参数的选项对象
 * @author guyadong
 *
 * @param  实例封装的数据类型
 */
public abstract class BaseOption extends BaseItem {
	/**
	 * 选项值
	 */
	private T optionValue;
	/**
	 * 选项默认值
	 */
	private T defaultValue;
	/**
	 * 该选项是否为必须的
	 */
	private boolean required;
	/**
	 * 该选项是否为只读的
	 */
	private boolean readOnly;
	/**
	 * 修改此选项值时会不会导致应用重启
	 */
	private boolean needReset;
	/**
	 * 修改此选项值后前端要不要重新获取数据
	 */
	private boolean needRefresh;
	/**
	 * 当前选项的java类型
	 */
	protected final Type type;
	/**
	 * 侦听器管理对象
	 */
	protected final Observable observable = new Observable(){
		@Override
		public void notifyObservers(Object arg) {
			setChanged();
			super.notifyObservers(arg);
		}
	};
	/**
	 * 数据值验证器,默认不验证直接返回true
	 */
	@JSONField(serialize = false,deserialize = false)
	private Predicate valueValidator = Predicates.alwaysTrue();
	/**
	 * 保存已知可用的的值
	 */
	private LinkedHashSet available = Sets.newLinkedHashSet();
	public BaseOption(Type type) {
		super();
		this.type = checkNotNull(type);
	}
	/**
	 * @return 当前选项的java类型
	 */
	public Type javaType(){
		return type;
	}
	/**
	 * @return 当前选项的类型
	 */
	public abstract OptionType getType();
	/**
	 * 设置当前选项的类型,
	 * 默认实现不会修改当前选项的类型
	 * @param type
	 * @return 当前对象
	 */
	BaseOption setType(OptionType type){
		return this;
	}
	/**
	 * @return 该选项是否为只读的
	 */
	public boolean isReadOnly() {
		return readOnly;
	}
	/**
	 * 设置该选项是否为只读的
	 * @param readOnly -
	 * @return 当前对象
	 */
	public BaseOption setReadOnly(boolean readOnly) {
		this.readOnly = readOnly;
		return this;
	}
	/**
	 * @return needReset
	 */
	public boolean isNeedReset() {
		return needReset;
	}
	/**
	 * 设置修改此选项值时会不会导致应用重启
	 * @param needReset 要设置的 needReset
	 * @return 当前对象
	 */
	public BaseOption setNeedReset(boolean needReset) {
		this.needReset = needReset;
		return this;
	}
	
	/**
	 * @return needRefresh
	 */
	public boolean isNeedRefresh() {
		return needRefresh;
	}
	/**
	 * 设置修改此选项值后前端要不要重新获取数据
	 * @param needRefresh 要设置的 needRefresh
	 */
	public void setNeedRefresh(boolean needRefresh) {
		this.needRefresh = needRefresh;
	}
	/**
	 * @return regex
	 */
	public String getRegex() {
		return getType().regex;
	}
	/**
	 * @param regex 要设置的 regex
	 * @return 当前对象
	 */
	public BaseOption setRegex(String regex) {
		return this;
	}
	@Override
	public final boolean isContainer() {
		return false;
	}

	@Override
	public final ItemType getCatalog() {
		return ItemType.OPTION;
	}
	@Override
	public final BaseItem addChilds(Collection childs) {
		// DO NOTHING
		return this;
	}
	/**
	 * 验证value是否有效,该方法不会抛出异常
	 * @param value -
	 * @return 成功返回true,否则返回false
	 */
	@SuppressWarnings("unchecked")
	public boolean validate(Object value){
		try{
			return valueValidator.apply((T) value);
		}catch (Throwable e) {
			return false;
		}
	}
	/**
	 * @return 选项值
	 */
	public final T getValue() {
		return	optionValue;
	}
	/**
	 * 设置指定的值
* 如果值有改变则向observer发送{@link ValueChangeEvent}消息 * @param value - * @return 当前对象 * @throws IllegalArgumentException 数值验证失败 * @see #validate(Object) */ public BaseOption setValue(T value) { if(!Objects.equal(value, optionValue)){ optionValue = value; observable.notifyObservers(new ValueChangeEvent>(this)); } return this; } /** * 更新选项的值,如果选项为只读(readonly)或value不满足条件({@link #validate(Object)})则抛出异常 * @param value 要更新的值 * @see #setValue(Object) */ public void updateFrom(T value){ checkState(!isReadOnly(),"READONLY VALUE"); checkArgument(valueValidator.apply(value),"INVALID VALUE"); setValue(value); } /** * 用选项req的值更新当前选项的值 * @param req 更新源对象 * @see #updateFrom(Object) */ public void updateFrom(BaseOption req){ if(req != null){ // 设置参数 updateFrom(req.getValue()); } } /** * @return 返回缺省值 */ public final T getDefaultValue() { return defaultValue; } /** * 设置默认值,同时验证数据有效性,失败抛出异常 * @param defaultValue 默认值 * @return 当前对象 * @throws IllegalArgumentException 数值验证失败 * @see #validate(Object) */ public BaseOption setDefaultValue(T defaultValue) { checkArgument(null == defaultValue || validate(defaultValue),"INVALID DEFAULT VALUE"); this.defaultValue = defaultValue; return this; } /** * @return 返回选项的值,如果为null则返回默认值 */ public T fetch(){ if(getValue() == null){ return getDefaultValue(); } return getValue(); } /** * 设置数据验证器 * @param validator 为null忽略 * @return 当前对象 */ public synchronized BaseOption setValidator(Predicate validator) { if(validator != null){ this.valueValidator = validator; } return this; } /** * @return 该选项是否为必须的 */ public boolean isRequired() { return required; } /** * 设置该选项是否为必须的 * @param required - * @return 当前对象 */ public BaseOption setRequired(boolean required) { this.required = required; return this; } /** * @return 将选项的值转为用于显示的字符串 */ public String contentOfValue(){ return optionValue == null ? "": optionValue.toString(); } /** * 以字符串形式设置值 * @param input 如果不符合数据类型的格式则抛出异常 * @return 当前对象 * @see OptionType#trans() */ public BaseOption asValue(String input){ return setValue(getType().trans().apply(input)); } /** * 以字符串形式设置默认值 * @param input 如果不符合数据类型的格式则抛出异常 * @return 当前对象 * @see OptionType#trans() */ public BaseOption asDefaultValue(String input){ return setDefaultValue(getType().trans().apply(input)); } /** * 检查value,defaultValue的有效性,无效则抛出异常 * @throws IllegalArgumentException value,defaultValue的值无效 * @return 当前对象 */ public BaseOption compile(){ // 检测value,defaultValue的值是否有效,无效则抛出异常 checkArgument(null == getValue() || validate(getValue()) ,"CHECK:invalid value of %s",getType().name()); checkArgument(null == getDefaultValue() || validate(getDefaultValue()) ,"CHECK:invalid defaultValue of %s",getType().name()); return this; } /** * 添加事件侦听器 * @param listeners 侦听器列表 * @return 当前对象 */ @SuppressWarnings("unchecked") @SafeVarargs public final BaseOption addListener(ValueListener ...listeners) { for (ValueListener listener : MoreObjects.firstNonNull(listeners, new ValueListener[0])) { if(listener != null){ this.observable.addObserver(listener); } } return this; } @SuppressWarnings("unchecked") @SafeVarargs public final BaseOption deleteListener(ValueListener ...listeners) { for (ValueListener listener : MoreObjects.firstNonNull(listeners, new ValueListener[0])) { if(listener != null){ this.observable.deleteObserver(listener); } } return this; } @Override BaseOption setParent(BaseItem parent) { super.setParent(parent); // 父类为CmdItem时,disable,readOnly属性无效 if(parent instanceof CmdItem){ setDisable(false); setReadOnly(false); } return this; } /** * @return 返回所有可用的值 */ public List getAvailable() { return Lists.newArrayList(available); } /** * 设置可用的值 * @param available 要设置的 availableValues * @return 当前对象 */ public BaseOption setAvailable(List available) { this.available.clear(); this.available.addAll(MoreObjects.firstNonNull(available, Collections.emptyList())); return this; } /** * 添加可用的值 * @param values 可用的值列表 * @return 当前对象 */ @SuppressWarnings("unchecked") public BaseOption addAvailable(T... values){ if(values != null){ this.available.addAll(Collections2.filter(Arrays.asList(values), Predicates.notNull())); } return this; } /** * 删除可用的值 * @param values 删除值的列表 * @return 当前对象 */ @SuppressWarnings("unchecked") public BaseOption removeAvailable(T... values){ if(values != null){ this.available.removeAll(Collections2.filter(Arrays.asList(values), Predicates.notNull())); } return this; } public void clearAvailable() { available.clear(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy