com.gitee.apanlh.util.setting.ResourceUtils Maven / Gradle / Ivy
package com.gitee.apanlh.util.setting;
import com.gitee.apanlh.exp.NotFoundException;
import com.gitee.apanlh.exp.RuntimeIoException;
import com.gitee.apanlh.exp.StreamReadException;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.StringUtils;
import com.gitee.apanlh.util.encode.CharsetCode;
import com.gitee.apanlh.util.file.FileMatchType;
import com.gitee.apanlh.util.io.IOUtils;
import com.gitee.apanlh.util.reflection.ClassUtils;
import com.gitee.apanlh.util.valid.Assert;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.jar.JarFile;
/**
* 资源加载和路径获取等相关工具类
* 如果需要操作相关资源配置文件等请查看{@link PropertiesUtils}类
*
{@link ConfigLoader}
*
* @author Pan
*/
public class ResourceUtils {
private static final String PATH_ERROR = "path [{}] does not exist";
/**
* 构造函数
*
* @author Pan
*/
private ResourceUtils() {
// 不允许外部实例
super();
}
/**
* 资源地址不限于:"classpath:", "file:", "jar:", "war:"
*
输入流需自行关闭
*
* @author Pan
* @param path 资源地址
* @return InputStream
* @throws StreamReadException 如果获取Stream异常时抛出
*/
public static InputStream getInput(String path) {
return getInput(getUrl(path));
}
/**
* 资源地址不限于:"classpath:", "file:", "jar:", "war:"
*
输入流需自行关闭
*
* @author Pan
* @param url URL地址
* @return InputStream
* @throws StreamReadException 如果获取Stream异常时抛出
*/
public static InputStream getInput(URL url) {
Assert.isNotNull(url);
try {
return url.openStream();
} catch (Exception e) {
throw new StreamReadException(e.getMessage(), e);
}
}
/**
* 资源地址不限于:"classpath:", "file:", "jar:", "war:"
*
默认UTF-8字符集编码
*
输入流需自行关闭
*
* @author Pan
* @param path 资源地址
* @return BufferedReader
* @throws NotFoundException 如果未找到对应资源则抛出
*/
public static BufferedReader getReader(String path) {
return getReader(path, CharsetCode.UTF_8);
}
/**
* 资源地址不限于:"classpath:", "file:", "jar:", "war:"
*
自定义字符集编码
*
输入流需自行关闭
*
* @author Pan
* @param path 资源地址
* @param charset 字符集编码
* @return BufferedReader
* @throws NotFoundException 如果未找到对应资源则抛出
*/
public static BufferedReader getReader(String path, String charset) {
return IOUtils.getReader(getInput(path), CharsetCode.getCharset(charset, CharsetCode.CHARSET_UTF_8));
}
/**
* 资源地址不限于:"classpath:", "file:", "jar:", "war:"
*
默认UTF-8字符集编码
*
输入流需自行关闭
*
* @author Pan
* @param url URL对象
* @return BufferedReader
* @throws NotFoundException 如果未找到对应资源则抛出
*/
public static BufferedReader getReader(URL url) {
return getReader(url, CharsetCode.UTF_8);
}
/**
* 资源地址不限于:"classpath:", "file:", "jar:", "war:"
*
自定义字符集编码
*
输入流需自行关闭
*
* @author Pan
* @param url URL对象
* @param charset 字符集编码
* @return BufferedReader
* @throws NotFoundException 如果未找到对应资源则抛出
*/
public static BufferedReader getReader(URL url, String charset) {
return IOUtils.getReader(getInput(url), CharsetCode.getCharset(charset, CharsetCode.CHARSET_UTF_8));
}
/**
* 资源地址不限于:"classpath:", "classes/", "file:", "jar:", "war:"
*
classes/可以不填写,如果直接a.properties时则自动获取classes下
*
* @author Pan
* @param path 资源地址
* @return URL
* @throws NotFoundException 如果未找到对应资源则抛出
*/
public static URL getUrl(String path) {
return getUrl(null, path);
}
/**
* 基于类位置进行资源加载
*
例如 {@code A.class(假设A.class存在com/pan/util/下), abc.properties. -> 将寻找 com/pan/util/abc.properties}
*
* @author Pan
* @param clazz 类
* @param path 资源地址
* @return URL
* @throws NotFoundException 如果未找到对应资源则抛出
*/
public static URL getUrl(Class clazz, String path) {
Assert.isNotEmpty(path);
if (clazz == null) {
// classpath
if (ResourceType.isPrefix(path, ResourceType.PREFIX_CLASSPATH)) {
return getResource(null, StringUtils.subStr(path, ResourceType.PREFIX_CLASSPATH.getValue().length()));
}
// classes
if (ResourceType.isPrefix(path, ResourceType.PREFIX_CLASSES)) {
return getResource(null, StringUtils.subStr(path, ResourceType.PREFIX_CLASSES.getValue().length()));
}
}
try {
return new URL(path);
} catch (MalformedURLException e) {
try {
// 基于类位置进行资源加载
return getResource(clazz, path);
} catch (Exception e2) {
// 如果出现未能解析URL时,尝试File解析
try {
File file = new File(path);
if (!file.exists()) {
throw new NotFoundException(StringUtils.format(PATH_ERROR, file.toURI().getRawPath().substring(1)));
}
return file.toURI().toURL();
}
catch (Exception e3) {
throw new NotFoundException(e3.getMessage(), e);
}
}
}
}
/**
* 根据资源路径获取资源
*
根据线程类加载器或JVM类加载器
*
* @author Pan
* @param path 地址
* @return URL
* @throws NotFoundException 如果地址未能解析成URL则抛出
*/
public static URL getResource(String path) {
URL resource = ClassUtils.getClassLoader().getResource(path);
if (resource == null) {
throw new NotFoundException(StringUtils.format(PATH_ERROR, path));
}
return resource;
}
/**
* 根据指定类的资源路径获取资源
*
* @author Pan
* @param clazz 类
* @param path 地址
* @return URL
* @throws NotFoundException 如果地址未能解析成URL则抛出
*/
public static URL getResource(Class clazz, String path) {
if (clazz == null) {
return getResource(path);
}
URL resource = clazz.getResource(path);
if (resource == null) {
throw new NotFoundException(StringUtils.format(PATH_ERROR, path));
}
return resource;
}
/**
* 根据资源路径获取多个资源
*
必须为目录路径格式如:config/x
*
根据线程类加载器或JVM类加载器
*
* @author Pan
* @param path 地址
* @return Enumeration
*/
public static List getResources(String path) {
try {
return CollUtils.newArrayList(ClassUtils.getClassLoader().getResources(path));
} catch (Exception e) {
throw new RuntimeIoException(e.getMessage(), e);
}
}
/**
* 获取上下文路径地址
*
* @author Pan
* @return String
*/
public static String getPath() {
URL resource = ClassUtils.getClassLoader().getResource("");
if (resource == null) {
return null;
}
String path = resource.getPath();
if (null != path && path.startsWith("/")) {
return path.substring(1);
}
return path;
}
/**
* 获取指定类所在的目录下的路径地址
*
* @author Pan
* @param clazz 类
* @return String
*/
public static String getPath(Class clazz) {
URL url = clazz.getResource("");
Assert.isNotNull(url);
String protocol = url.getProtocol();
String filePath = url.getFile();
if (protocol.startsWith(ResourceType.PROTOCOL_JAR.getValue())) {
JarFile jarFile = getJarFile(url);
if (jarFile == null) {
return null;
}
return StringUtils.append(jarFile.getName(), "\\", ClassUtils.getPackageName(clazz).replace(".", "\\"));
}
if (protocol.startsWith(FileMatchType.FILE.getValue())) {
if (filePath.charAt(0) == '/') {
return filePath.substring(1);
}
return StringUtils.replace(filePath, "file:/", "");
}
return null;
}
/**
* 根据类获取指定的JarFile对象
*
* @author Pan
* @param clazz URL对象
* @return JarFile
*/
public static JarFile getJarFile(Class clazz) {
try {
URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
URLConnection openConnection = url.openConnection();
if (openConnection == null || !isJarFileUrl(url)) {
return null;
}
return ((JarURLConnection) openConnection).getJarFile();
} catch (Exception e) {
throw new NotFoundException(e.getMessage(), e);
}
}
/**
* 获取JarFile
*
* @author Pan
* @param url URL对象
* @return JarFile
*/
public static JarFile getJarFile(URL url) {
Assert.isNotNull(url);
try {
URLConnection openConnection = url.openConnection();
if (openConnection == null || !isJarFileUrl(url)) {
return null;
}
return ((JarURLConnection) openConnection).getJarFile();
} catch (Exception e) {
throw new NotFoundException(e.getMessage(), e);
}
}
/**
* 验证是否为File资源
*
* @author Pan
* @param url URL对象
* @return boolean
*/
public static boolean isFileUrl(URL url) {
return Eq.strOr(url.getProtocol(), ResourceType.PROTOCOL_FILE, ResourceType.PROTOCOL_VFS, ResourceType.PROTOCOL_VFSFILE);
}
/**
* 验证是否为jar资源
*
协议为"jar"、"war"、"zip"、"vsfzip"、"wsjar"
*
如果只是判断 URL是否指向一个 jar资源使用此方法
*
* @author Pan
* @param url URL对象
* @return boolean
*/
public static boolean isJarURL(URL url) {
return Eq.strOr(url.getProtocol(), ResourceType.PROTOCOL_JAR,
ResourceType.PROTOCOL_WAR, ResourceType.PROTOCOL_ZIP,
ResourceType.PROTOCOL_VFSZIP, ResourceType.PROTOCOL_WSJAR);
}
/**
* 验证是否为jarFile资源
*
协议为"file"及路径以".jar"结尾返回true
*
验证是否为本地jar文件
*
* @author Pan
* @param url URL对象
* @return boolean
*/
public static boolean isJarFileUrl(URL url) {
return Eq.str(ResourceType.PROTOCOL_FILE.getValue(), url.getProtocol()) && url.getPath().toLowerCase().endsWith(FileMatchType.JAR.getValue());
}
}