This commit is contained in:
Looly 2022-11-13 19:50:05 +08:00
parent a78619502e
commit 7e28a55c75
5 changed files with 121 additions and 25 deletions

View File

@ -8,6 +8,7 @@ import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.classloader.ClassLoaderUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.net.url.URLUtil;
import cn.hutool.core.util.ObjUtil;
import java.io.BufferedReader;
import java.io.File;
@ -174,9 +175,26 @@ public class ResourceUtil {
* @since 4.1.5
*/
public static EnumerationIter<URL> getResourceUrlIter(final String resource) {
return getResourceUrlIter(resource, null);
}
/**
* 获取指定路径下的资源Iterator<br>
* 路径格式必须为目录格式,/分隔例如:
*
* <pre>
* config/a
* spring/xml
* </pre>
*
* @param resource 资源路径
* @param classLoader {@link ClassLoader}
* @return 资源列表
*/
public static EnumerationIter<URL> getResourceUrlIter(final String resource, final ClassLoader classLoader) {
final Enumeration<URL> resources;
try {
resources = ClassLoaderUtil.getClassLoader().getResources(resource);
resources = ObjUtil.defaultIfNull(classLoader, ClassLoaderUtil.getClassLoader()).getResources(resource);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
@ -233,4 +251,30 @@ public class ResourceUtil {
public static Resource getResource(final File file) {
return new FileResource(file);
}
/**
* 获取同名的所有资源
*
* @param resource 资源名
* @return {@link MultiResource}
*/
public static MultiResource getResources(final String resource) {
return getResources(resource, null);
}
/**
* 获取同名的所有资源
*
* @param resource 资源名
* @param classLoader {@link ClassLoader}{@code null}表示使用默认的当前上下文ClassLoader
* @return {@link MultiResource}
*/
public static MultiResource getResources(final String resource, final ClassLoader classLoader) {
final EnumerationIter<URL> iter = getResourceUrlIter(resource, classLoader);
final MultiResource resources = new MultiResource();
for (final URL url : iter) {
resources.add(getResource(url));
}
return resources;
}
}

View File

@ -37,7 +37,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @see #putNode(Object, Object)
*/
@Override
default TreeEntry<K, V> put(K key, TreeEntry<K, V> node) {
default TreeEntry<K, V> put(final K key, final TreeEntry<K, V> node) {
return putNode(key, node.getValue());
}
@ -47,7 +47,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param treeEntryMap 节点集合
*/
@Override
default void putAll(Map<? extends K, ? extends TreeEntry<K, V>> treeEntryMap) {
default void putAll(final Map<? extends K, ? extends TreeEntry<K, V>> treeEntryMap) {
if (CollUtil.isEmpty(treeEntryMap)) {
return;
}
@ -73,7 +73,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param ignoreNullNode 是否获取到的key为null的子节点/父节点
*/
default <C extends Collection<V>> void putAllNode(
C values, Function<V, K> keyGenerator, Function<V, K> parentKeyGenerator, boolean ignoreNullNode) {
final C values, final Function<V, K> keyGenerator, final Function<V, K> parentKeyGenerator, final boolean ignoreNullNode) {
if (CollUtil.isEmpty(values)) {
return;
}
@ -137,7 +137,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param childKey 子节点的key
* @param childValue 子节点的值
*/
default void putLinkedNodes(K parentKey, V parentValue, K childKey, V childValue) {
default void putLinkedNodes(final K parentKey, final V parentValue, final K childKey, final V childValue) {
putNode(parentKey, parentValue);
putNode(childKey, childValue);
linkNodes(parentKey, childKey);
@ -162,7 +162,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param parentKey 父节点的key
* @param childKey 子节点的key
*/
default void linkNodes(K parentKey, K childKey) {
default void linkNodes(final K parentKey, final K childKey) {
linkNodes(parentKey, childKey, null);
}
@ -192,7 +192,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param key 指定节点的key
* @return 节点
*/
default Set<TreeEntry<K, V>> getTreeNodes(K key) {
default Set<TreeEntry<K, V>> getTreeNodes(final K key) {
final TreeEntry<K, V> target = get(key);
if (ObjUtil.isNull(target)) {
return Collections.emptySet();
@ -209,7 +209,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param key 指定节点的key
* @return 节点
*/
default TreeEntry<K, V> getRootNode(K key) {
default TreeEntry<K, V> getRootNode(final K key) {
return Opt.ofNullable(get(key))
.map(TreeEntry::getRoot)
.orElse(null);
@ -222,7 +222,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param key 指定节点的key
* @return 节点
*/
default TreeEntry<K, V> getDeclaredParentNode(K key) {
default TreeEntry<K, V> getDeclaredParentNode(final K key) {
return Opt.ofNullable(get(key))
.map(TreeEntry::getDeclaredParent)
.orElse(null);
@ -235,7 +235,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param parentKey 指定父节点key
* @return 节点
*/
default TreeEntry<K, V> getParentNode(K key, K parentKey) {
default TreeEntry<K, V> getParentNode(final K key, final K parentKey) {
return Opt.ofNullable(get(key))
.map(t -> t.getParent(parentKey))
.orElse(null);
@ -248,7 +248,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param parentKey 指定父节点的key
* @return 是否
*/
default boolean containsParentNode(K key, K parentKey) {
default boolean containsParentNode(final K key, final K parentKey) {
return Opt.ofNullable(get(key))
.map(m -> m.containsParent(parentKey))
.orElse(false);
@ -260,7 +260,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param key 节点的key
* @return 节点值若节点不存在或节点值为null都将返回null
*/
default V getNodeValue(K key) {
default V getNodeValue(final K key) {
return Opt.ofNullable(get(key))
.map(TreeEntry::getValue)
.get();
@ -275,7 +275,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param childKey 子节点
* @return 是否
*/
default boolean containsChildNode(K parentKey, K childKey) {
default boolean containsChildNode(final K parentKey, final K childKey) {
return Opt.ofNullable(get(parentKey))
.map(m -> m.containsChild(childKey))
.orElse(false);
@ -288,7 +288,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param key key
* @return 节点
*/
default Collection<TreeEntry<K, V>> getDeclaredChildNodes(K key) {
default Collection<TreeEntry<K, V>> getDeclaredChildNodes(final K key) {
return Opt.ofNullable(get(key))
.map(TreeEntry::getDeclaredChildren)
.map(Map::values)
@ -302,7 +302,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
* @param key key
* @return 该节点的全部子节点
*/
default Collection<TreeEntry<K, V>> getChildNodes(K key) {
default Collection<TreeEntry<K, V>> getChildNodes(final K key) {
return Opt.ofNullable(get(key))
.map(TreeEntry::getChildren)
.map(Map::values)

View File

@ -697,7 +697,6 @@ public class Setting extends AbsSetting implements Map<String, String> {
*
* @return 默认分组空分组中的所有键列表
*/
@SuppressWarnings("NullableProblems")
@Override
public Set<String> keySet() {
return this.groupedMap.keySet(DEFAULT_GROUP);
@ -708,7 +707,6 @@ public class Setting extends AbsSetting implements Map<String, String> {
*
* @return 默认分组空分组中的所有值列表
*/
@SuppressWarnings("NullableProblems")
@Override
public Collection<String> values() {
return this.groupedMap.values(DEFAULT_GROUP);
@ -719,7 +717,6 @@ public class Setting extends AbsSetting implements Map<String, String> {
*
* @return 默认分组空分组中的所有键值对列表
*/
@SuppressWarnings("NullableProblems")
@Override
public Set<Entry<String, String>> entrySet() {
return this.groupedMap.entrySet(DEFAULT_GROUP);

View File

@ -23,7 +23,6 @@ import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.log.StaticLog;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
@ -190,12 +189,7 @@ public final class Props extends Properties implements TypeGetter<CharSequence>
public void load(final Resource resource) {
Assert.notNull(resource, "Props resource must be not null!");
this.resource = resource;
try (final BufferedReader reader = resource.getReader(charset)) {
super.load(reader);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
PropsLoaderUtil.loadTo(this, resource, this.charset);
}
/**

View File

@ -0,0 +1,61 @@
package cn.hutool.setting.dialect;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.io.resource.ResourceUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Properties;
/**
* {@link Properties} 资源内容加载工具
*
* @author looly
* @since 6.0.0
*/
public class PropsLoaderUtil {
/**
* 加载配置文件内容到{@link Properties}<br>
* 需要注意的是如果资源文件的扩展名是.xml会调用{@link Properties#loadFromXML(InputStream)} 读取
*
* @param properties {@link Properties}文件
* @param resource 资源
* @param charset 编码对XML无效
*/
public static void loadTo(final Properties properties, final Resource resource, final Charset charset) {
final String filename = resource.getName();
if (filename != null && filename.endsWith(".xml")) {
// XML
try (final InputStream in = resource.getStream()) {
properties.loadFromXML(in);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
} else {
// .properties
try (final BufferedReader reader = resource.getReader(charset)) {
properties.load(reader);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
}
/**
* 加载指定名称的所有配置文件内容到{@link Properties}
*
* @param properties {@link Properties}文件
* @param resourceName 资源名可以是相对classpath的路径也可以是绝对路径
* @param classLoader {@link ClassLoader}{@code null}表示使用默认的当前上下文ClassLoader
* @param charset 编码对XML无效
*/
public static void loadAllTo(final Properties properties, final String resourceName, final ClassLoader classLoader, final Charset charset) {
for (final Resource resource : ResourceUtil.getResources(resourceName, classLoader)) {
loadTo(properties, resource, charset);
}
}
}