YmlProvider

This commit is contained in:
redkale
2024-08-14 15:32:00 +08:00
parent 66806d60a5
commit d69412b1f8
6 changed files with 171 additions and 30 deletions

View File

@@ -42,6 +42,7 @@ module org.redkale {
exports org.redkale.util; exports org.redkale.util;
exports org.redkale.watch; exports org.redkale.watch;
uses org.redkale.util.YmlProvider;
uses org.redkale.props.spi.PropertiesAgentProvider; uses org.redkale.props.spi.PropertiesAgentProvider;
uses org.redkale.cached.spi.CachedManagerProvider; uses org.redkale.cached.spi.CachedManagerProvider;
uses org.redkale.cluster.spi.ClusterAgentProvider; uses org.redkale.cluster.spi.ClusterAgentProvider;

View File

@@ -357,18 +357,31 @@ class AppConfig {
String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf"); String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf");
URI appConfFile; URI appConfFile;
boolean fromCache = false; boolean fromCache = false;
boolean yml = false;
if (confDir.contains("://")) { // jar内部资源 if (confDir.contains("://")) { // jar内部资源
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml"); appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml");
try { try {
appConfFile.toURL().openStream().close(); appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties } catch (IOException e) { // 没有application.xml就尝试读application.yml
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.yml");
try {
appConfFile.toURL().openStream().close();
yml = true;
} catch (IOException e2) { // 没有application.xml就尝试读application.properties
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties"); appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties");
} }
}
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { // 绝对路径 } else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { // 绝对路径
File f = new File(confDir, "application.xml"); File f = new File(confDir, "application.xml");
if (f.isFile() && f.canRead()) { if (f.isFile() && f.canRead()) {
appConfFile = f.toURI(); appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath(); confDir = f.getParentFile().getCanonicalPath();
} else {
f = new File(confDir, "application.yml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
yml = true;
} else { } else {
f = new File(confDir, "application.properties"); f = new File(confDir, "application.properties");
if (f.isFile() && f.canRead()) { if (f.isFile() && f.canRead()) {
@@ -378,21 +391,35 @@ class AppConfig {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try { try {
appConfFile.toURL().openStream().close(); appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties } catch (IOException e) { // 没有application.xml就尝试读application.yml
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.yml");
try {
appConfFile.toURL().openStream().close();
yml = true;
} catch (IOException e2) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
} }
}
confDir = appConfFile confDir = appConfFile
.toString() .toString()
.replace("/application.xml", "") .replace("/application.xml", "")
.replace("/application.yml", "")
.replace("/application.properties", ""); .replace("/application.properties", "");
fromCache = true; fromCache = true;
} }
} }
}
} else { // 相对路径 } else { // 相对路径
File f = new File(new File(home, confDir), "application.xml"); File f = new File(new File(home, confDir), "application.xml");
if (f.isFile() && f.canRead()) { if (f.isFile() && f.canRead()) {
appConfFile = f.toURI(); appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath(); confDir = f.getParentFile().getCanonicalPath();
} else {
f = new File(new File(home, confDir), "application.yml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
yml = true;
} else { } else {
f = new File(new File(home, confDir), "application.properties"); f = new File(new File(home, confDir), "application.properties");
if (f.isFile() && f.canRead()) { if (f.isFile() && f.canRead()) {
@@ -402,21 +429,31 @@ class AppConfig {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try { try {
appConfFile.toURL().openStream().close(); appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties } catch (IOException e) { // 没有application.xml就尝试读application.yml
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.yml");
try {
appConfFile.toURL().openStream().close();
yml = true;
} catch (IOException e2) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
} }
}
confDir = appConfFile confDir = appConfFile
.toString() .toString()
.replace("/application.xml", "") .replace("/application.xml", "")
.replace("/application.yml", "")
.replace("/application.properties", ""); .replace("/application.properties", "");
fromCache = true; fromCache = true;
} }
} }
} }
}
System.setProperty(RESNAME_APP_CONF_DIR, confDir); System.setProperty(RESNAME_APP_CONF_DIR, confDir);
String text = Utility.readThenClose(appConfFile.toURL().openStream()); String text = Utility.readThenClose(appConfFile.toURL().openStream());
AnyValue conf; AnyValue conf;
if (text.trim().startsWith("<")) { if (yml) {
conf = AnyValue.loadFromYml(text).getAnyValue("redkale");
} else if (text.trim().startsWith("<")) {
conf = AnyValue.loadFromXml(text, (k, v) -> v.replace("${APP_HOME}", home)) conf = AnyValue.loadFromXml(text, (k, v) -> v.replace("${APP_HOME}", home))
.getAnyValue("application"); .getAnyValue("application");
} else { } else {
@@ -425,7 +462,6 @@ class AppConfig {
if (fromCache) { if (fromCache) {
((AnyValueWriter) conf).addValue("[config-from-cache]", "true"); ((AnyValueWriter) conf).addValue("[config-from-cache]", "true");
} }
return conf; return conf;
} }

View File

@@ -5,14 +5,13 @@
*/ */
package org.redkale.util; package org.redkale.util;
import static org.redkale.util.Utility.isEmpty;
import java.io.*; import java.io.*;
import java.nio.charset.*; import java.nio.charset.*;
import java.util.*; import java.util.*;
import java.util.function.*; import java.util.function.*;
import org.redkale.annotation.ConstructorParameters; import org.redkale.annotation.ConstructorParameters;
import org.redkale.convert.ConvertColumn; import org.redkale.convert.ConvertColumn;
import static org.redkale.util.Utility.isEmpty;
/** /**
* 该类提供类似JSONObject的数据结构主要用于读取xml配置文件和http-header存储 * 该类提供类似JSONObject的数据结构主要用于读取xml配置文件和http-header存储
@@ -222,6 +221,17 @@ public abstract class AnyValue {
return new AnyValueWriter(); return new AnyValueWriter();
} }
/**
* yml内容流转换成AnyValue对象
*
*
* @param text 文本内容
* @return AnyValue
*/
public static AnyValue loadFromYml(String text) {
return new YmlReader(text).read();
}
/** /**
* Properties内容转换成AnyValue对象 层级采用key的.分隔 <br> * Properties内容转换成AnyValue对象 层级采用key的.分隔 <br>
* key中包含[xx]且xx不是数字且不是位于最后的视为name会在对应的节点对象中加入name属性 * key中包含[xx]且xx不是数字且不是位于最后的视为name会在对应的节点对象中加入name属性

View File

@@ -0,0 +1,27 @@
/*
*/
package org.redkale.util;
/**
* 读取yml的解析器
*
* <p>详情见: https://redkale.org
*
* @since 2.8.0
* @author zhangjx
*/
public interface YmlProvider {
public static final YmlProvider NIL = c -> {
throw new UnsupportedOperationException("Not supported yet.");
};
/**
* 将yml内容转换成AnyValue
* @param content yml内容
* @return AnyValue
*/
public AnyValue read(String content);
}

View File

@@ -0,0 +1,67 @@
/*
*/
package org.redkale.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.ServiceLoader;
import org.redkale.annotation.Nonnull;
/**
* 简单的yml读取器
* TODO 待实现
*
* <p>详情见: https://redkale.org
*
* @since 2.8.0
* @author zhangjx
*/
public class YmlReader {
private static YmlProvider currentProvider;
private final String text;
public YmlReader(String text) {
this.text = Objects.requireNonNull(text);
}
public AnyValue read() {
YmlProvider provider = loadProvider();
if (provider == YmlProvider.NIL) {
throw new UnsupportedOperationException("Not supported yml.");
}
return provider.read(text);
}
/**
* 加载解析器的实现对象
*
* @return YmlProvider
*/
private static @Nonnull YmlProvider loadProvider() {
if (currentProvider == null) {
Iterator<YmlProvider> it = ServiceLoader.load(YmlProvider.class).iterator();
RedkaleClassLoader.putServiceLoader(YmlProvider.class);
List<YmlProvider> providers = new ArrayList<>();
while (it.hasNext()) {
YmlProvider provider = it.next();
if (provider != null) {
RedkaleClassLoader.putReflectionPublicConstructors(
provider.getClass(), provider.getClass().getName());
providers.add(provider);
}
}
for (YmlProvider provider : Utility.sortPriority(providers)) {
currentProvider = provider;
return provider;
}
currentProvider = YmlProvider.NIL;
}
return currentProvider;
}
}