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

org.onetwo.common.propconf.JFishProperties Maven / Gradle / Ivy

There is a newer version: 4.7.2
Show newest version
package org.onetwo.common.propconf;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

import org.onetwo.apache.io.IOUtils;
import org.onetwo.common.date.DateUtils;
import org.onetwo.common.exception.BaseException;
import org.onetwo.common.expr.Expression;
import org.onetwo.common.expr.ExpressionFacotry;
import org.onetwo.common.file.FileUtils;
import org.onetwo.common.reflect.ReflectUtils;
import org.onetwo.common.utils.EnumUtils;
import org.onetwo.common.utils.LangUtils;
import org.onetwo.common.utils.StringUtils;
import org.onetwo.common.utils.func.ReturnableClosure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Splitter;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

@SuppressWarnings({"unchecked", "rawtypes", "serial"})
public class JFishProperties extends Properties implements VariableSupporter {
	
	public static final JFishProperties wrap(Properties properties){
		return new JFishProperties(true, properties);
	}
	
	private static Comparator NAME_LENGTH_COMPARATOR = new Comparator() {

		@Override
		public int compare(String o1, String o2) {
			return o1.compareTo(o2);
		}
		
	};

	private ReturnableClosure> startWithBlock = new ReturnableClosure>() {
		@Override
		public Map execute(String keyStartWith) {
			Map values = LangUtils.newHashMap();
			for(Enumeration ekey = configNames(); ekey.hasMoreElements();){
				String key = ekey.nextElement();
				if(key.startsWith(keyStartWith)){
					String val = getVariable(key);
					key = key.substring(keyStartWith.length());
					values.put(key, val);
				}
			}
//			return values;
			return ImmutableMap.copyOf(values);
		}
	};
	
	private ReturnableClosure> splitBlock = new ReturnableClosure>() {

		@Override
		public List execute(String[] key) {
			List listValue = LangUtils.newArrayList();
			String value = getVariable(key[0]);
			if(StringUtils.isBlank(value)){
				listValue = Collections.EMPTY_LIST;
			}else{
				listValue = new ArrayList();
				String[] strs = StringUtils.split(value, key[1]);
				for(String str : strs){
					if(StringUtils.isBlank(str))
						continue;
					listValue.add(str.trim());
				}
			}
			return ImmutableList.copyOf(listValue);
		}
		
	};
	
	private ReturnableClosure> classBlock = new ReturnableClosure>() {

		@Override
		public List execute(String object) {
			List classes = new ArrayList();
			String strs = getVariable(object);
			for(String clsName : Splitter.on(',').omitEmptyStrings().trimResults().split(strs)){
				Class clazz = ReflectUtils.loadClass(clsName);
				if(!classes.contains(clazz))
					classes.add(clazz);
			}
			return classes;
		}
		
	};
	
	private static final Logger logger = LoggerFactory.getLogger(JFishProperties.class);
	
//	protected Properties config = new Properties();

	protected VariableExpositor expositor;
	
	protected Expression expression = ExpressionFacotry.AT;

//	private Map cache = new HashMap();
	private Cache cache = CacheBuilder.newBuilder().build();
	

	public JFishProperties(Properties... configs) {
		this(true, configs);
	}
	public JFishProperties(boolean cacheable, Properties... configs) {
//		Assert.notEmpty(configs);
		setConfigs(configs);
		this.expositor = new VariableExpositor(this, cacheable);
	}
	
	final public void setConfigs(Properties...configs){
		clear();
		for(Properties conf : configs){
//			this.config.putAll(conf);
			Enumeration names = (Enumeration)conf.propertyNames();
			String qname = null;
			while(names.hasMoreElements()){
				qname = names.nextElement();
				/*if(this.config.containsKey(qname)){
					throw new BaseException("query name ["+qname+"] has already exist!");
				}*/
				setProperty(qname, conf.getProperty(qname));
			}
		}
	}


	public boolean load(String srcpath){
		File file = null;
		boolean succeed = false;
		String filepath = srcpath;
		try {
			/*if (filepath.indexOf(".")==-1)
				filepath += PropUtils.CONFIG_POSTFIX;*/
			file = new File(filepath);
			/*if (!file.exists()) {
				if (filepath.indexOf(':') == -1) {
					filepath = FileUtils.getResourcePath(this.getClass().getClassLoader(), filepath);
					file = new File(filepath);
				}
			}*/
			if(!file.exists()){
				logger.info("1. file not exist : " + (file==null?"null":file.getPath()));
				filepath = FileUtils.getResourcePath(this.getClass().getClassLoader(), filepath);
				InputStream fin = getInputStream(filepath);
				if(fin==null){
					throw new FileNotFoundException("no stream: " + filepath);
				}
				PropUtils.loadProperties(fin, this);
			}else{
				PropUtils.loadProperties(file, this);
			}
			succeed = true;
		} catch (Exception e) {
			InputStream in = null;
			try {
				if(logger.isInfoEnabled()){
					logger.error("load config error: " + e.getMessage());
					logger.info("try to load config by stream : " + filepath);
				}
				in = this.getClass().getClassLoader().getResourceAsStream(srcpath);
				load(in);
				succeed = true;
			} catch (Exception e1) {
				throw new BaseException("load config error: " + filepath, e);
			} finally{
				IOUtils.closeQuietly(in);
			}
		}finally{
			logger.info("load config finished : "+succeed);
		}
		return succeed;
	}
	
	protected InputStream getInputStream(String path) throws Exception{
		if(FileUtils.isJarURL(path)){
			URL url = new URL(path);
			URLConnection con = url.openConnection();
			try {
				return con.getInputStream();
			}
			catch (IOException ex) {
				if (con instanceof HttpURLConnection) {
					((HttpURLConnection) con).disconnect();
				}
				throw ex;
			}
		}else{
			return new FileInputStream(new File(path));
		}
	}

	public List sortedKeys(){
		List keys = new ArrayList();
		Enumeration keyNames = (Enumeration)configNames();
		while(keyNames.hasMoreElements()){
			keys.add(keyNames.nextElement());
		}
		Collections.sort(keys, NAME_LENGTH_COMPARATOR);
		return keys;
	}
	
	public Object remove(Object key){
//		this.cache.remove(key);
		this.cache.invalidate(key);
		return super.remove(key);
	}
	
	protected void putInCache(String key, Object value){
		this.cache.put(key, value);
	}
	
	protected Object getFromCache(String key){
		return cache.getIfPresent(key);
	}

	public List getStringList(String key, String split) {
		return getPropertyWithSplit(key, split);
	}

	public String[] getStringArray(String key, String split) {
		return getPropertyWithSplit(key, split).toArray(new String[0]);
	}

	
	public Map getPropertiesStartWith(String keyStartWith) {
		return getFromCache(keyStartWith, startWithBlock, keyStartWith);
	}

	protected  T getFromCache(String key, final ReturnableClosure block, final K k) {
		try {
			return (T)this.cache.get(key, new Callable() {

				@Override
				public T call() throws Exception {
					return block.execute(k);
				}
				
			});
		} catch (ExecutionException e) {
			throw new BaseException("get cache error.", e);
		}
		
		/*T cacheValue = (T)getFromCache(key);
		
		cacheValue = block.execute(k);
		
		putInCache(key, cacheValue);
		return cacheValue;*/
		
	}

	public List getPropertyWithSplit(String key, String split) {
		return getFromCache(key, splitBlock, new String[]{key, split});
		/*List listValue = (List)getFromCache(key);
		if(listValue!=null)
			return listValue;
		
//		String value = getProperty(key);
		String value = getVariable(key);
		if(StringUtils.isBlank(value)){
			listValue = Collections.EMPTY_LIST;
		}else{
			listValue = new ArrayList();
			String[] strs = StringUtils.split(value, split);
			for(String str : strs){
				if(StringUtils.isBlank(str))
					continue;
				listValue.add(str.trim());
			}
		}
		putInCache(key, listValue);
		return listValue;*/
	}


	public  List getEnums(String key, Class clazz){
		List strs = getPropertyWithSplit(key, ",");
		List enumObj = EnumUtils.asEnumList(clazz, strs.toArray(new String[0]));
		return enumObj;
	}

	public  T getEnum(String key, Class clazz){
		String enumStr = getProperty(key);
		if(StringUtils.isBlank(enumStr))
			return null;
		return (T)Enum.valueOf(clazz, enumStr);
	}
	public  Optional getOptionalEnum(String key, Class clazz){
		String enumStr = getProperty(key);
		if(StringUtils.isBlank(enumStr))
			return Optional.empty();
		return Optional.of(Enum.valueOf(clazz, enumStr));
	}

	public String getProperty(String key, String defaultValue) {
		String value = this.getProperty(key);
		return StringUtils.isBlank(value) ? defaultValue : value;
	}

	public String getPath(String key, String def){
		String path = getProperty(key, def);
		path = FileUtils.replaceBackSlashToSlash(path);
		return path;
	}

	public String getDir(String key, String def){
		String path = getPath(key, def);
		path = FileUtils.convertDir(path);
		return path;
	}
	/*public Enumeration keys() {
		return (Enumeration) config.propertyNames();
	}*/

	public String getVariable(String key) {
		return getVariable(key, false);
	}

	public String getVariable(String key, boolean checkCache) {
		String value = super.getProperty(key);
		//
		if (StringUtils.isNotBlank(value) && expositor!=null) {
			value = this.expositor.explainVariable(value, checkCache);
		}
		return StringUtils.trimToEmpty(value);
	}
	
	public String formatVariable(String key, Object...values){
		String str = getVariable(key);
		if(this.expression.isExpresstion(str))
			str = this.expression.parse(str, values);
		return str;
	}

	/*public String getProperty(String key) {
		return super.getProperty(key);
	}*/

	public String getAndThrowIfEmpty(String key) {
		String val = getProperty(key);
		if(StringUtils.isBlank(val))
			LangUtils.throwBaseException("can find the value for key: " + key);
		return val;
	}

    public String getProperty(String key) {
    	return StringUtils.trimToEmpty(super.getProperty(key));
    }
	/*public String getProperty(String key, boolean checkCache) {
		return this.getVariable(key, checkCache);
	}*/

	public Integer getInteger(String key, Integer def) {
		if (!containsKey(key)) {
			return def;
		}
		Integer integer = null;
		try {
			integer = new Integer(getVariable(key));
		} catch (Exception e) {
			integer = def;
		}
		return integer;
	}
	
	public int getInt(String key){
		return this.getInteger(key);
	}
	
	public int getInt(String key, int def){
		return this.getInteger(key, def);
	}

	public Integer getInteger(String key) {
		return getInteger(key, Integer.valueOf(0));
	}

	public Class getClass(String key, Class cls) {
		Collection clses =  this.getClasses(key, cls);
		if(clses!=null){
			Iterator it = clses.iterator();
			if(it.hasNext())
				return it.next();
		}
		return null;
	}

	public Collection getClasses(final String key, Class... defClasses) {
		if(!this.containsKey(key))
			return Arrays.asList(defClasses);
		
		return this.getFromCache(key, classBlock, key);
		/*//cache
		List classes = (List) getFromCache(key);
		if(classes!=null)
			return classes;
		
		classes = new ArrayList();
		this.putInCache(key, classes);

		String strs = this.getVariable(key);
		if(StringUtils.isBlank(strs)){
			return MyUtils.asList(defClasses);
		}
		
		String[] classNames = StringUtils.split(strs, ",");
		Class clazz = null;
		for(String clsName : classNames){
			clazz = ReflectUtils.loadClass(clsName.trim());
			if(!classes.contains(clazz))
				classes.add(clazz);
		}
		for(String clsName : Splitter.on(',').omitEmptyStrings().trimResults().split(strs)){
			Class clazz = ReflectUtils.loadClass(clsName);
			if(!classes.contains(clazz))
				classes.add(clazz);
		}
		
//		this.putInCache(key, classes);
		
		return classes;*/
	}

	public List getClassList(String key) {
		if(!this.containsKey(key))
			return Collections.EMPTY_LIST;
		
		return this.getFromCache(key, classBlock, key);
	}

	public Long getLong(String key, Long def) {
		if (!containsKey(key)) {
			return def;
		}
		Long longValue = null;
		try {
			longValue = new Long(getVariable(key));
		} catch (Exception e) {
			longValue = def;
		}
		return longValue;
	}

	public Double getDouble(String key, Double def) {
		if (!containsKey(key)) {
			return def;
		}
		try {
			return new Double(getVariable(key));
		} catch (Exception e) {
			return def;
		}
	}
	

	public Boolean getBoolean(String key) {
		return getBoolean(key, false);
	}

	public Boolean getBoolean(String key, boolean def) {
		if (!containsKey(key)) {
			return def;
		}
		Boolean booleanValue = false;
		try {
			booleanValue = Boolean.parseBoolean(getVariable(key));
		} catch (Exception e) {
			booleanValue = def;
		}
		return booleanValue;
	}

	public Date getDate(String key, Date def) {
		if (!containsKey(key)) {
			return def;
		}
		Date date = DateUtils.parse(getVariable(key));
		if(date==null)
			date = def;
		return date;
	}

	public synchronized void clear() {
		super.clear();
		if(expositor!=null)
			this.expositor.clear();
		if(cache!=null)
			this.cache.cleanUp();
	}
	
	public Enumeration configNames() {
		return keys();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy