public class FileExtensionUtil {
public static String getFileExtension(String fileName) {
if (fileName != null && fileName.lastIndexOf(".") != -1) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
return "";
}
}
判断JAVA文件类型是CLASS还是INTERFACE或者ENUM或者ABSTRACT_CLASS
这是gradle的方式引入,Maven同理
implementation 'com.github.javaparser:javaparser-core:3.25.3'
public enum FileType {
CLASS,
INTERFACE,
ABSTRACT_CLASS,
ENUM,
UNKNOWN
}
public class JavaFileTypeChecker {
public static FileType getFileType(String filePath) {
try {
CompilationUnit cu = StaticJavaParser.parse(new File(filePath));
if (cu.getType(0) instanceof ClassOrInterfaceDeclaration) {
ClassOrInterfaceDeclaration classOrInterfaceDeclaration =
(ClassOrInterfaceDeclaration) cu.getType(0);
if (classOrInterfaceDeclaration.isInterface()) {
return FileType.INTERFACE;
} else if (classOrInterfaceDeclaration.isAbstract()) {
return FileType.ABSTRACT_CLASS;
} else {
return FileType.CLASS;
}
} else if (cu.getType(0) instanceof EnumDeclaration) {
return FileType.ENUM;
}
} catch (IOException e) {
e.printStackTrace();
}
return FileType.UNKNOWN;
}
}
public class CollectionUtil {
/**
* 判断集合是否为空的
*
* @param collection 集合对象
* @return 是否为空
*/
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
/**
* 判断map是否为空的
*
* @param map map对象
* @return 是否为空
*/
public static boolean isEmpty(Map<?, ?> map) {
return map == null || map.isEmpty();
}
public class CompareFileUtils {
/**
* 显示文件对比框
*
* @param project 项目
* @param leftFile 左边的文件
* @param rightFile 右边的文件
*/
public static void showCompareWindow(Project project, VirtualFile leftFile, VirtualFile rightFile) {
try {
Class<?> cls = Class.forName("com.intellij.diff.actions.impl.MutableDiffRequestChain");
// 新版支持
DiffContentFactory contentFactory = DiffContentFactory.getInstance();
DiffRequestFactory requestFactory = DiffRequestFactory.getInstance();
DiffContent leftContent = contentFactory.create(project, leftFile);
DiffContent rightContent = contentFactory.create(project, rightFile);
DiffRequestChain chain = (DiffRequestChain) cls.getConstructor(DiffContent.class, DiffContent.class).newInstance(leftContent, rightContent);
// MutableDiffRequestChain chain = new MutableDiffRequestChain(leftContent, rightContent);
cls.getMethod("setWindowTitle", String.class).invoke(chain, requestFactory.getTitle(leftFile, rightFile));
cls.getMethod("setTitle1", String.class).invoke(chain, requestFactory.getContentTitle(leftFile));
cls.getMethod("setTitle2", String.class).invoke(chain, requestFactory.getContentTitle(rightFile));
// chain.setWindowTitle(requestFactory.getTitle(leftFile, rightFile));
// chain.setTitle1(requestFactory.getContentTitle(leftFile));
// chain.setTitle2(requestFactory.getContentTitle(rightFile));
DiffManager.getInstance().showDiff(project, chain, DiffDialogHints.MODAL);
} catch (ClassNotFoundException e) {
// 旧版兼容
DiffRequest diffRequest = DiffRequestFactory.getInstance().createFromFiles(project, leftFile, rightFile);
DiffManager.getInstance().showDiff(project, diffRequest, DiffDialogHints.MODAL);
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
ExceptionUtil.rethrow(e);
}
}
}
public class DocCommentUtils {
/**
* 获取注释信息,获取第一条文本类型注释内容,不存在则返回null
*
* @param docComment 文档注释
* @return 注释内容
*/
public static String getComment(@Nullable PsiDocComment docComment) {
if (docComment == null) {
return null;
}
return Arrays.stream(docComment.getDescriptionElements())
.filter(o -> o instanceof PsiDocToken)
.map(PsiElement::getText)
.findFirst()
.map(String::trim)
.orElse(null);
}
}
public class JSON {
private static final ObjectMapper INSTANCE;
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
static {
INSTANCE = new ObjectMapper();
// 禁止将日期序列化成时间戳
INSTANCE.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 禁止属性不存在时报错
INSTANCE.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 允许字符串转换成数组
INSTANCE.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
// 读取到未知的枚举值转换成空
INSTANCE.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL);
// 禁用科学计数法
INSTANCE.enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS);
INSTANCE.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
// 序列化忽略空值
INSTANCE.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 配置时间格式
INSTANCE.setDateFormat(new SimpleDateFormat(DATE_FORMAT));
}
public static ObjectMapper getInstance() {
return INSTANCE;
}
/**
* 将json字符串转换成java对象
*
* @param json json字符串
* @param cls java对象类型
* @param <T> 对象类型
* @return 对象
*/
public static <T> T parse(String json, Class<T> cls) {
try {
return INSTANCE.readValue(json, cls);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
/**
* 将json字符串转换成java对象
*
* @param json json字符串
* @param type java对象类型
* @param <T> 对象类型
* @return 对象
*/
public static <T> T parse(String json, TypeReference<T> type) {
try {
return INSTANCE.readValue(json, type);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
/**
* 将json对象转换成json字符串
*
* @param obj 对象
* @return json字符串
*/
public static String toJson(Object obj) {
try {
return INSTANCE.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}
/**
* 将json对象转换成json字符串
*
* @param obj 对象
* @return json字符串
*/
public static String toJsonByFormat(Object obj) {
try {
return INSTANCE.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}
public static JsonNode readTree(Object obj) {
try {
if (obj instanceof String) {
return INSTANCE.readTree((String) obj);
} else if (obj instanceof byte[]) {
return INSTANCE.readTree((byte[]) obj);
} else if (obj instanceof InputStream) {
return INSTANCE.readTree((InputStream) obj);
} else if (obj instanceof URL) {
return INSTANCE.readTree((URL) obj);
} else if (obj instanceof File) {
return INSTANCE.readTree((File) obj);
} else {
// 其他对象,转字符串再转JsonNode
return INSTANCE.readTree(toJson(obj));
}
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
}
/**
* 消息弹框工具类
* 对message dialog弹框进行兼容处理
*/
public class MessageDialogUtils {
/**
* yes no确认框
*
* @param msg 消息
* @return 是否确认
*/
public static boolean yesNo(String msg) {
return yesNo(null, msg);
}
/**
* yes no确认框
*
* @param project 项目对象
* @param msg 消息
* @return 是否确认
*/
public static boolean yesNo(Project project, String msg) {
Object[] options = new Object[]{"Yes", "No"};
return JOptionPane.showOptionDialog(null,
msg, GlobalDict.TITLE_INFO,
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
UIUtil.getQuestionIcon(),
options, options[0]) == 0;
}
/**
* 显示确认框
*
* @param msg 确认框消息
* @param project 项目
* @return 点击按钮
*/
public static int yesNoCancel(Project project, String msg, String yesText, String noText, String cancelText) {
Object[] options = new Object[]{yesText, noText, cancelText};
return JOptionPane.showOptionDialog(null,
msg, GlobalDict.TITLE_INFO,
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
UIUtil.getQuestionIcon(),
options, options[0]);
}
}
public final class ModuleUtils {
/**
* 禁用构造方法
*/
private ModuleUtils() {
throw new UnsupportedOperationException();
}
/**
* 获取module路径
*
* @param module 模块
* @return 路径
*/
public static VirtualFile getModuleDir(@NotNull Module module) {
// 优先使用ModuleRootManager来获取module路径
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
for (VirtualFile contentRoot : moduleRootManager.getContentRoots()) {
if (contentRoot.isDirectory() && contentRoot.getName().equals(module.getName())) {
return contentRoot;
}
}
String modulePath = ModuleUtil.getModuleDirPath(module);
// 统一路径分割符号
modulePath = modulePath.replace("\\", "/");
// 尝试消除不正确的路径
if (modulePath.contains(".idea/modules/")) {
modulePath = modulePath.replace(".idea/modules/","");
}
if (modulePath.contains(".idea/modules")) {
modulePath = modulePath.replace(".idea/modules","");
}
if (modulePath.contains("/.idea")) {
modulePath = modulePath.replace("/.idea","");
}
VirtualFile dir = VirtualFileManager.getInstance().findFileByUrl(String.format("file://%s", modulePath));
if (dir == null) {
Messages.showInfoMessage("无法获取Module路径, path=" + modulePath, GlobalDict.TITLE_INFO);
}
return dir;
}
/**
* 获取模块的源代码文件夹,不存在
*
* @param module 模块对象
* @return 文件夹路径
*/
public static VirtualFile getSourcePath(@NotNull Module module) {
List<VirtualFile> virtualFileList = ModuleRootManager.getInstance(module).getSourceRoots(JavaSourceRootType.SOURCE);
if (CollectionUtil.isEmpty(virtualFileList)) {
VirtualFile modulePath = getModuleDir(module);
// 尝试智能识别源代码路径(通过上面的方式,IDEA不能百分百拿到源代码路径)
VirtualFile srcDir = VfsUtil.findRelativeFile(modulePath, "src", "main", "java");
if (srcDir != null && srcDir.isDirectory()) {
return srcDir;
}
return modulePath;
}
if (virtualFileList.size() > 1) {
for (VirtualFile file : virtualFileList) {
String tmpPath = file.getPath();
if (!tmpPath.contains("build") && !tmpPath.contains("generated")) {
return file;
}
}
}
return virtualFileList.get(0);
}
/**
* 判断模块是否存在源代码文件夹
*
* @param module 模块对象
* @return 是否存在
*/
public static boolean existsSourcePath(Module module) {
return !CollectionUtil.isEmpty(ModuleRootManager.getInstance(module).getSourceRoots(JavaSourceRootType.SOURCE));
}
}
public class NameUtils {
private volatile static NameUtils nameUtils;
/**
* 单例模式
*/
public static NameUtils getInstance() {
if (nameUtils == null) {
synchronized (NameUtils.class) {
if (nameUtils == null) {
nameUtils = new NameUtils();
}
}
}
return nameUtils;
}
/**
* 私有构造方法
*/
NameUtils() {
}
/**
* 转驼峰命名正则匹配规则
*/
private static final Pattern TO_HUMP_PATTERN = Pattern.compile("[-_]([a-z0-9])");
private static final Pattern TO_LINE_PATTERN = Pattern.compile("[A-Z]+");
/**
* 首字母大写方法
*
* @param name 名称
* @return 结果
*/
public String firstUpperCase(String name) {
return StringUtils.capitalize(name);
}
/**
* 首字母小写方法
*
* @param name 名称
* @return 结果
*/
public String firstLowerCase(String name) {
return StringUtils.uncapitalize(name);
}
/**
* 驼峰转下划线,全小写
*
* @param str 驼峰字符串
* @return 下划线字符串
*/
public String hump2Underline(String str) {
if (StringUtils.isEmpty(str)) {
return str;
}
Matcher matcher = TO_LINE_PATTERN.matcher(str);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
if (matcher.start() > 0) {
matcher.appendReplacement(buffer, "_" + matcher.group(0).toLowerCase());
} else {
matcher.appendReplacement(buffer, matcher.group(0).toLowerCase());
}
}
matcher.appendTail(buffer);
return buffer.toString();
}
/**
* 通过java全名获取类名
*
* @param fullName 全名
* @return 类名
*/
public String getClsNameByFullName(String fullName) {
int genericIdx = fullName.indexOf('<');
if (genericIdx == -1) {
return fullName.substring(fullName.lastIndexOf('.') + 1);
}
String className = fullName.substring(0, genericIdx);
return fullName.substring(className.lastIndexOf('.') + 1);
}
/**
* 通过java全名获取类名
*
* @param fullName 全名
* @return 类名
*/
public String getClsFullNameRemoveGeneric(String fullName) {
int genericIdx = fullName.indexOf('<');
if (genericIdx == -1) {
return fullName;
}
return fullName.substring(0, genericIdx);
}
/**
* 下划线中横线命名转驼峰命名(属性名)
*
* @param name 名称
* @return 结果
*/
public String getJavaName(String name) {
if (StringUtils.isEmpty(name)) {
return name;
}
// 强转全小写
name = name.toLowerCase();
Matcher matcher = TO_HUMP_PATTERN.matcher(name.toLowerCase());
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(buffer, matcher.group(1).toUpperCase());
}
matcher.appendTail(buffer);
return buffer.toString();
}
/**
* 下划线中横线命名转驼峰命名(类名)
*
* @param name 名称
* @return 结果
*/
public String getClassName(String name) {
return firstUpperCase(getJavaName(name));
}
/**
* 任意对象合并工具类
*
* @param objects 任意对象
* @return 合并后的字符串结果
*/
public String append(Object... objects) {
if (objects == null || objects.length == 0) {
return null;
}
StringBuilder builder = new StringBuilder();
for (Object s : objects) {
if (s != null) {
builder.append(s);
}
}
return builder.toString();
}
}
public class ProjectUtils {
/**
* 获取当前项目对象
*
* @return 当前项目对象
*/
public static Project getCurrProject() {
ProjectManager projectManager = ProjectManager.getInstance();
Project[] openProjects = projectManager.getOpenProjects();
if (openProjects.length == 0) {
// 在未打开任何项目,进入到设置页面时会出现
return projectManager.getDefaultProject();
} else if (openProjects.length == 1) {
// 只存在一个打开的项目则使用打开的项目
return openProjects[0];
}
//如果有项目窗口处于激活状态
try {
WindowManager wm = WindowManager.getInstance();
for (Project project : openProjects) {
Window window = wm.suggestParentWindow(project);
if (window != null && window.isActive()) {
return project;
}
}
} catch (Exception ignored) {
}
//否则使用默认项目
return projectManager.getDefaultProject();
}
/**
* 进行旧版本兼容,该方法已经存在 @see {@link com.intellij.openapi.project.ProjectUtil#guessProjectDir(Project)}
*
* @param project 项目对象
* @return 基本目录
*/
public static VirtualFile getBaseDir(Project project) {
if (project.isDefault()) {
return null;
}
Module[] modules = ModuleManager.getInstance(project).getModules();
Module module = null;
if (modules.length == 1) {
module = modules[0];
} else {
for (Module item : modules) {
if (item.getName().equals(project.getName())) {
module = item;
break;
}
}
}
if (module != null) {
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
for (VirtualFile contentRoot : moduleRootManager.getContentRoots()) {
if (contentRoot.isDirectory() && contentRoot.getName().equals(module.getName())) {
return contentRoot;
}
}
}
String basePath = project.getBasePath();
if (basePath == null) {
throw new NullPointerException();
}
return LocalFileSystem.getInstance().findFileByPath(basePath);
}
}
/**
* 反射工具
*/
public class ReflectionUtils {
/**
* 获取泛型类型的类型
* @param obj
* @param index
* @return
*/
public static Class<?> getGenericClass(Object obj, int index) {
// 获取泛型接口
Type type = obj.getClass().getGenericInterfaces()[0];
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type targetType = parameterizedType.getActualTypeArguments()[index];
return (Class<?>) targetType;
} else {
// 不存在泛型
throw new IllegalArgumentException(obj.getClass() + " not found generic");
}
}
/**
* 获取声明的方法
* @param clazz
* @param name
* @param parameterTypes
* @return
*/
public static Method getDeclaredMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
Class<?> searchType = clazz;
while (searchType != null) {
Method[] methods = (searchType.isInterface() ? searchType.getMethods() : getDeclaredMethods(searchType));
for (Method method : methods) {
if (!Objects.equals(name, method.getName())) {
continue;
}
if (parameterTypes == null || Arrays.equals(parameterTypes, method.getParameterTypes())) {
return method;
}
}
searchType = searchType.getSuperclass();
}
return null;
}
/**
* 获取类的所有public方法
* @param clazz
* @return
*/
private static Method[] getDeclaredMethods(Class<?> clazz) {
Method[] result;
try {
Method[] declaredMethods = clazz.getDeclaredMethods();
List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz);
if (defaultMethods != null) {
result = new Method[declaredMethods.length + defaultMethods.size()];
System.arraycopy(declaredMethods, 0, result, 0, declaredMethods.length);
int index = declaredMethods.length;
for (Method defaultMethod : defaultMethods) {
result[index] = defaultMethod;
index++;
}
} else {
result = declaredMethods;
}
} catch (Throwable ex) {
throw new IllegalStateException("Failed to introspect Class [" + clazz.getName() +
"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
}
return result;
}
/**
* 查找接口上的具体方法
* @param clazz
* @return
*/
private static List<Method> findConcreteMethodsOnInterfaces(Class<?> clazz) {
List<Method> result = null;
for (Class<?> ifc : clazz.getInterfaces()) {
for (Method ifcMethod : ifc.getMethods()) {
if (!Modifier.isAbstract(ifcMethod.getModifiers())) {
if (result == null) {
result = new ArrayList<>();
}
result.add(ifcMethod);
}
}
}
return result;
}
}
添加字符串工具类,为了兼容JB的各种产品,尽量不要用第三方工具包
public class StringUtils {
/**
* 首字母处理方法
*/
private static final BiFunction<String, Function<Integer, Integer>, String> FIRST_CHAR_HANDLER_FUN = (str, firstCharFun) -> {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return str;
}
final int firstCodepoint = str.codePointAt(0);
final int newCodePoint = firstCharFun.apply(firstCodepoint);
if (firstCodepoint == newCodePoint) {
// already capitalized
return str;
}
// cannot be longer than the char array
final int[] newCodePoints = new int[strLen];
int outOffset = 0;
// copy the first codepoint
newCodePoints[outOffset++] = newCodePoint;
for (int inOffset = Character.charCount(firstCodepoint); inOffset < strLen; ) {
final int codepoint = str.codePointAt(inOffset);
// copy the remaining ones
newCodePoints[outOffset++] = codepoint;
inOffset += Character.charCount(codepoint);
}
return new String(newCodePoints, 0, outOffset);
};
/**
* 判断是空字符串
*
* @param cs 字符串
* @return 是否为空
*/
public static boolean isEmpty(final CharSequence cs) {
return cs == null || cs.length() == 0;
}
/**
* 首字母大写方法
* @param str 字符串
* @return 首字母大写结果
*/
public static String capitalize(final String str) {
return FIRST_CHAR_HANDLER_FUN.apply(str, Character::toTitleCase);
}
/**
* 首字母小写方法
* @param str 字符串
* @return 首字母小写结果
*/
public static String uncapitalize(final String str) {
return FIRST_CHAR_HANDLER_FUN.apply(str, Character::toLowerCase);
}
}
Velocity工具类,主要用于代码生成
public class VelocityUtils {
/**
* velocity配置
*/
private static final Properties INIT_PROP;
static {
// 设置初始化配置
INIT_PROP = new Properties();
// 修复部分用户的velocity日志记录无权访问velocity.log文件问题
INIT_PROP.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.Log4JLogChute");
INIT_PROP.setProperty("runtime.log.logsystem.log4j.logger", "velocity");
}
/**
* 禁止创建实例对象
*/
private VelocityUtils() {
throw new UnsupportedOperationException();
}
/**
* 渲染模板
*
* @param template 模板字符串
* @param map 参数集合
* @return 渲染结果
*/
public static String generate(String template, Map<String, Object> map) {
// 每次创建一个新实例,防止velocity缓存宏定义
VelocityEngine velocityEngine = new VelocityEngine(INIT_PROP);
// 创建上下文对象
VelocityContext velocityContext = new VelocityContext();
if (map != null) {
map.forEach(velocityContext::put);
}
StringWriter stringWriter = new StringWriter();
try {
// 生成代码
velocityEngine.evaluate(velocityContext, stringWriter, "Velocity Code Generate", template);
} catch (Exception e) {
// 将异常全部捕获,直接返回,用于写入模板
StringBuilder builder = new StringBuilder("在生成代码时,模板发生了如下语法错误:\n");
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
builder.append(writer.toString());
return builder.toString().replace("\r", "");
}
String code = stringWriter.toString();
// 清除前面空格
StringBuilder sb = new StringBuilder(code);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
}
// 返回结果
return sb.toString();
}
}