Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cloud.agileframework.common.util.properties.PropertiesUtil Maven / Gradle / Ivy
package cloud.agileframework.common.util.properties;
import cloud.agileframework.common.constant.Constant;
import cloud.agileframework.common.util.array.ArrayUtil;
import cloud.agileframework.common.util.clazz.TypeReference;
import cloud.agileframework.common.util.file.JarUtil;
import cloud.agileframework.common.util.object.ObjectUtil;
import cloud.agileframework.common.util.stream.StreamUtil;
import cloud.agileframework.common.util.string.StringUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* @author 佟盟
* 日期 2019/11/28 15:20
* 描述 配置文件加载工具
* @version 1.0
* @since 1.0
*/
public class PropertiesUtil {
/**
* 越过类文件
*/
private static final String CLASS = ".class";
/**
* 编译文件中的文件夹分隔符
*/
private static final String CLASSES_DIR_SPLIT = "/";
/**
* 文件夹分隔符
*/
private static final String DIR_SPLIT = "\\";
/**
* 配置文件的key值分隔符
*/
private static final String PROPERTIES_KEY_SPLIT = ".";
/**
* 配置文件优先级
*/
private static final String[] OVERRIDE_CONFIG = new String[]{"application"};
/**
* 日志
*/
private static final Log log = LogFactory.getLog(PropertiesUtil.class);
/**
* 最终配置集
*/
private static final Properties PROPERTIES = new Properties();
/**
* 扫描到的配置文件集
*/
private static final Set FILE_NAMES = Sets.newHashSet();
/**
* 初始化静态块
*/
static {
// 获取启动类
String className = ((StackTraceElement) ArrayUtil.last(new RuntimeException().getStackTrace())).getClassName();
// 加载agile系列配置文件
readJar("cloud.agileframework.conf", PropertiesUtil::toProperties);
readJar("com.agile.conf", PropertiesUtil::toProperties);
// 读取jar包配置
readJar(className.substring(0, className.lastIndexOf(".")), PropertiesUtil::toProperties);
// 读取编译目录配置文件
readDir(PropertiesUtil::toProperties);
// 读取环境变量
readEnv();
parsePlaceholder();
}
/**
* 按文件优先级处理文件
*
* @param consumer 处理文件的方法
*/
public static void traverseFile(BiConsumer consumer) {
traverseFile(consumer, null);
}
/**
* 按照文件优先级处理文件
*
* @param consumer 处理文件的方法
* @param packagePath 以点分割的包路径,如com.baidu.xxx
*/
public static void traverseFile(BiConsumer consumer, String packagePath) {
if (packagePath == null) {
// 加载agile系列配置文件
readJar("cloud.agileframework.conf", consumer);
readJar("com.agile.conf", consumer);
// 获取启动类
String className = ((StackTraceElement) ArrayUtil.last(new RuntimeException().getStackTrace())).getClassName();
// 读取jar包配置
readJar(className.substring(0, className.lastIndexOf(".")), consumer);
} else {
readJar(packagePath, consumer);
}
// 读取编译目录配置文件
readDir(consumer);
}
private static void parsePlaceholder() {
for (Map.Entry v : PROPERTIES.entrySet()) {
if (v.getValue() instanceof String) {
PROPERTIES.setProperty(String.valueOf(v.getKey()), StringUtil.parsingPlaceholder("${", "}", String.valueOf(v.getValue()), PROPERTIES));
}
}
}
/**
* 去读编译目录下的配置文件
*/
private static void readDir(BiConsumer consumer) {
Set fileNames = Sets.newHashSet();
Set overrideConfigFileNames = Sets.newHashSet();
try {
Collections.list(PropertiesUtil.class.getClassLoader().getResources(""))
.forEach(url -> {
try {
readDir(fileNames, new File(URLDecoder.decode(url.getPath(), StandardCharsets.UTF_8.name())), consumer);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
});
String classPath = PropertiesUtil.class.getResource(CLASSES_DIR_SPLIT).getPath();
fileNames.stream().filter(filterOverrideConfigName(overrideConfigFileNames)).sorted(getStringComparator()).forEach(toRead(classPath, consumer));
overrideConfigFileNames.stream().sorted(getStringComparator()).forEach(toRead(classPath, consumer));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据编译目录读取配置方法
*
* @param classPath 编译目录
* @return 方法
*/
private static Consumer toRead(String classPath, BiConsumer consumer) {
return fileName -> {
try {
read(fileName.replace(URLDecoder.decode(classPath, StandardCharsets.UTF_8.name()), "").replace(DIR_SPLIT, CLASSES_DIR_SPLIT), new FileInputStream(new File(fileName)), consumer);
} catch (FileNotFoundException | UnsupportedEncodingException e) {
e.printStackTrace();
}
};
}
/**
* 字符串比较方法
*
* @return 方法
*/
private static Comparator getStringComparator() {
return (a, b) -> {
final String regex = "[\\\\/]";
int s = b.split(regex).length - a.split(regex).length;
if (s == 0) {
s = a.compareTo(b);
}
return s;
};
}
/**
* 过滤优先级较高的配置文件名字
*
* @param overrideConfigFileNames 过滤后装填的容器
* @return 方法
*/
private static Predicate filterOverrideConfigName(Set overrideConfigFileNames) {
return name -> {
for (String overrideConfigName : OVERRIDE_CONFIG) {
if (name.contains(overrideConfigName + ".")) {
overrideConfigFileNames.add(name);
return false;
}
}
return true;
};
}
/**
* 读取文件目录
*
* @param dir 文件夹
*/
private static void readDir(Set fileNames, File dir, BiConsumer consumer) {
if (dir.exists() && dir.isDirectory()) {
File[] files = dir.listFiles();
if (files == null) {
return;
}
for (File file : files) {
if (file.isFile() && !file.getName().endsWith(CLASS)) {
try {
fileNames.add(URLDecoder.decode(file.toURI().getPath(), StandardCharsets.UTF_8.name()));
} catch (Exception e) {
e.printStackTrace();
}
} else if (file.isDirectory()) {
readDir(fileNames, file, consumer);
}
}
}
}
public static void readJar(String packagePath) {
readJar(packagePath, PropertiesUtil::toProperties);
}
/**
* 读取jar中的配置文件
*
* @param packagePath 扫描的包名
*/
public static void readJar(String packagePath, BiConsumer consumer) {
Set resourceNames = JarUtil.getFile(packagePath, false, CLASS);
Set overrideConfigFileNames = Sets.newHashSet();
resourceNames.stream()
.filter(filterOverrideConfigName(overrideConfigFileNames))
.sorted(getStringComparator())
.forEach(resourceName -> read(resourceName, PropertiesUtil.class.getResourceAsStream(resourceName), consumer));
overrideConfigFileNames.stream()
.sorted(getStringComparator())
.forEach(resourceName -> read(resourceName, PropertiesUtil.class.getResourceAsStream(resourceName), consumer));
}
public static void read(String fileName, InputStream inputStream) {
read(fileName, inputStream, PropertiesUtil::toProperties);
}
/**
* 读取配置文件
*
* @param fileName 文件名
* @param inputStream 输入流
*/
public static void read(String fileName, InputStream inputStream, BiConsumer consumer) {
if (fileName == null || inputStream == null) {
return;
}
consumer.accept(fileName, inputStream);
}
/**
* 文件内容转换为配置信息
*
* @param fileName 文件名
* @param inputStream 文件流
*/
private static void toProperties(String fileName, InputStream inputStream) {
try {
final String properties = "properties";
if (fileName.endsWith(properties)) {
readProperties(inputStream);
} else {
final String yml = "yml";
final String yaml = "yaml";
if (fileName.endsWith(yml) || fileName.endsWith(yaml)) {
try {
readYml(inputStream);
} catch (Exception e) {
log.debug(fileName + " 文件解析错误:", e);
}
}
}
if (!fileName.endsWith(CLASS)) {
if (!fileName.startsWith(Constant.RegularAbout.SLASH)) {
fileName = Constant.RegularAbout.SLASH + fileName;
}
FILE_NAMES.add(fileName);
}
// System.out.println(fileName);
if (log.isDebugEnabled()) {
log.debug(fileName);
}
} catch (Exception e) {
e.printStackTrace();
log.error(String.format("read file(%s) to properties is error", fileName), e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 读取环境变量
*/
private static void readEnv() {
readProperties(System.getProperties());
readProperties(System.getenv());
}
/**
* 读取properties文件流
*
* @param in 文件流
* @throws IOException 异常
*/
private static void readProperties(InputStream in) throws IOException {
PROPERTIES.load(in);
}
/**
* map数据读取到配置中
*
* @param map map数据
*/
private static void readProperties(Map, ?> map) {
if (map == null) {
return;
}
map.forEach((key, value) -> {
try {
PROPERTIES.setProperty(key.toString(), String.valueOf(value));
} catch (Exception e) {
e.printStackTrace();
}
});
}
/**
* 读取yml文件流
*
* @param in yml文件流
*/
private static void readYml(InputStream in) {
Yaml yaml = new Yaml();
Map dataMap = yaml.load(in);
ymlToMap(PROPERTIES, dataMap, null);
}
/**
* yml转Map
*
* @param allMap 转换后的map容器
* @param map 递归用
* @param parentKey 递归用
*/
private static void ymlToMap(Map allMap, Map map, String parentKey) {
if (map == null) {
return;
}
for (Map.Entry entry : map.entrySet()) {
Object currentKey = entry.getKey();
Object value = entry.getValue();
if (value instanceof Map) {
if (parentKey == null) {
ymlToMap(allMap, (Map) value, currentKey.toString());
} else {
ymlToMap(allMap, (Map) value, parentKey + PROPERTIES_KEY_SPLIT + currentKey.toString());
}
} else if (value != null) {
if (parentKey == null) {
allMap.put(currentKey.toString(), value.toString());
}
if (parentKey != null) {
allMap.put(parentKey + PROPERTIES_KEY_SPLIT + currentKey.toString(), value.toString());
}
}
}
}
/**
* 获取所有配置
*
* @return 配置文件集合
*/
public static Properties getProperties() {
return PROPERTIES;
}
/**
* 获取所有扫描到的配置文件名
*
* @return 文件名集
*/
public static Set getFileNames() {
return FILE_NAMES;
}
/**
* 覆盖配置
*
* @param key key
* @param value value
*/
public static void setProperties(String key, String value) {
if (value == null) {
return;
}
PROPERTIES.setProperty(key, value);
}
/**
* 为配置值叠加
*
* @param key key
* @param value value
*/
public static void appendProperties(String key, String value) {
String v = PROPERTIES.getProperty(key);
if (v == null) {
PROPERTIES.setProperty(key, value);
} else {
PROPERTIES.setProperty(key, v + value);
}
}
/**
* 取配置
*
* @param key key
* @return 值
*/
public static String getProperty(String key) {
Object value = PROPERTIES.get(key);
if (value != null) {
return value.toString();
}
return null;
}
/**
* 获取工程配置信息带默认值
*
* @param key 句柄
* @return 值
*/
public static String getProperty(String key, String defaultValue) {
Object value = getProperty(key);
if (!ObjectUtils.isEmpty(value)) {
return value.toString();
}
return defaultValue;
}
/**
* 根据前缀取配置
*
* @param prefix 前缀
* @return 配置集
*/
public static Properties getPropertyByPrefix(String prefix) {
Properties properties = new Properties();
Set propertyNames = getProperties().stringPropertyNames();
for (String name : propertyNames) {
if (name.startsWith(prefix)) {
properties.put(name, getProperties().get(name));
}
}
return properties;
}
/**
* 取配置,并转换
*
* @param key key
* @param clazz 转换类型
* @param 泛型
* @return 结果
*/
public static T getProperty(String key, Class clazz) {
return ObjectUtil.to(getProperty(key), new TypeReference(clazz));
}
public static T getProperty(String var1, Class var2, String defaultValue) {
return ObjectUtil.to(getProperty(var1, defaultValue), new TypeReference(var2));
}
/**
* 根据文件名取classpath目录下的json数据
*
* @param fileName 不带后缀文件名
* @return JSONObject数据
*/
public static JSON getJson(String fileName) {
try {
InputStream stream = null;
File file = new File(fileName);
if (file.exists()) {
stream = new FileInputStream(file);
} else {
final String suffix = ".json";
if (!fileName.endsWith(suffix)) {
fileName = fileName + suffix;
}
String path = getFileClassPath(fileName);
if (path != null) {
stream = PropertiesUtil.class.getResourceAsStream(path);
}
}
if (stream == null) {
return null;
}
return (JSON) JSON.parse(StreamUtil.toString(stream));
} catch (Exception e) {
return null;
}
}
/**
* 取配置文件内容
*
* @param fileName 文件名字
* @return 文件内容
*/
public static String getFileContent(String fileName) {
InputStream inputStream = getFileStream(fileName);
return StreamUtil.toString(inputStream);
}
/**
* 取配置文件流
*
* @param fileName 文件名字
* @return 文件流
*/
public static InputStream getFileStream(String fileName) {
String path = getFileClassPath(fileName);
if (path == null) {
return null;
}
return PropertiesUtil.class.getResourceAsStream(path);
}
/**
* 取配置文件编译路径
*
* @param fileName 文件名字
* @return 编译路径
*/
public static String getFileClassPath(String fileName) {
final String regex = "[\\\\/]";
Set set = getFilePaths("/" + fileName);
return set.stream().min(Comparator.comparingInt(a -> a.split(regex).length)).orElse(null);
}
/**
* 根据文件名取classpath目录下的json数据
*
* @param fileName 不带后缀文件名
* @return JSONObject数据
*/
public static String getFilePath(String fileName) {
String path = getFileClassPath(fileName);
if (path == null) {
return null;
}
URL absolutePath = PropertiesUtil.class.getResource(path);
if (absolutePath == null) {
return path;
}
try {
return URLDecoder.decode(absolutePath.getPath(), StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return path;
}
public static Set getFilePaths(String fileName) {
return getFileNames().stream().filter(name -> name.endsWith(fileName)).collect(Collectors.toSet());
}
}