diff --git a/README.md b/README.md
index 2e927f6..d4be63d 100644
--- a/README.md
+++ b/README.md
@@ -5,55 +5,78 @@
-JetBrains Intellij IDEA ObjectHelper 插件旨在减少开发者重复低效的劳动,使开发者能够更专注于业务逻辑的开发。
+JetBrains Intellij ObjectHelper 插件致力于消除开发者重复性的低效工作,助力开发者将更多精力聚焦于核心业务逻辑开发,显著提升开发效率。
-该插件包含以下功能:
+## 功能介绍
-- 对象拷贝
- set模式:
+### 生成对象拷贝方法(Object Copy Method)
- 
+- **set 模式**:通过直观的操作流程,快速生成对象拷贝代码。默认使用快捷键 `Alt+Insert` 触发,若快捷键冲突,可在 `settings->keymap` 中搜索 “Generate” 关键字,查看并修改对应的快捷键设置。
- 对象拷贝的快捷键默认是 `Alt+Insert`,如果该快捷键无效,可以在settings->keymap中搜索“Generate”关键字查看具体的快捷键:
+
- 
+- **builder 模式**:当对象中包含 builder 或者 newBuilder 方法时,插件会智能识别并采用 builder 模式生成代码,实现更优雅的对象构建。
- 当对象中包含`builder` 或者 `newBuilder`方法时,则插件默认会采用 builder 模式生成代码:
+
- 
+> **使用提示**:使用对象拷贝方法时,需先定义好方法签名,插件将自动生成对应的方法体。适用于对象属性较多且需频繁拷贝的场景,如数据传输对象(DTO)的转换等,但在一些对代码灵活性要求较高的场景中,可能需要额外调整。
- 如果你的builder类生成的方法名与插件默认生成的不同,可以在设置中更改:
+### 对象拷贝(Object Copy)
- 
+支持在业务代码和 Lambda 表达式中直接进行对象拷贝操作,极大提升了代码编写的便利性和效率。无论是处理复杂业务逻辑,还是简化数据处理流程,都能轻松应对。
+
-- Java类转JSON
+### Java类转JSON
- 
+在开发过程中,若需要快速生成一个类的对象的 JSON 示例,只需右键单击目标类名,即可一键生成,方便接口调试、文档编写等场景下快速获取数据结构示例。
-- Java类转Thrift IDL
+
- 
+### Java类转 Thrift IDL
-- Java类转XML
+对于涉及 Thrift 框架的开发场景,通过右键单击目标类名,可快速生成对应的 Thrift IDL 文件,加速服务接口的定义和开发流程。
- 
+
-- 插件配置
+### Java 类转 XML
+
+
+
+## 相关配置
+
+### 插件配置
File->Settings->Tools->Object Helper 即可进入插件的配置页面
-
+
+
+- `Class To Json/Thrift IDL/XML`:控制该功能是否启用。
+- `generate field mode`:
+ - `source`:以源字段类型的字段为基础生成对象拷贝代码。例如在 `Object Copy Method` 功能,方法第一个入参的类型就是源字段类型,方法返回的类型为目标类型字段。
+ - `target`:以目标类为基础生成对象拷贝代码。
+- `non-existent field generate annotation`:
+ - `enable`:当目标字段在源对象中不存在时,以注释的形式生成代码。有助于开发者清晰了解字段缺失情况,方便后续代码维护和修改。
+
+ - `disable`:不生成不存在字段的拷贝代码,适用于对代码简洁性要求较高,且能确保目标字段在源对象中都存在的场景。
+
+> 假设存在两个 Java 类:`ClassA` 与 `ClassB`,`ClassA` 包含 `a`、`b`、`c` 三个字段,`ClassB` 包含 `b`、`c`、`d` 三个字段。当使用 ObjectHelper 插件将 `ClassA` 实例的数据拷贝至 `ClassB` 实例时:
+>
+> - **`generate field mode=source`**:插件以 `ClassA` 的字段 `a`、`b`、`c` 为基础生成拷贝代码。若 `ClassB` 中不存在对应字段(如 `a`),则根据 `non-existent field generate annotation` 配置决定是否处理该字段。
+> - **`generate field mode=target`**:插件以 `ClassB` 的字段 `b`、`c`、`d` 为基准生成代码。若 `ClassA` 中无对应字段(如 `d`),同样由 `non-existent field generate annotation` 配置来决定是否生成相关代码或添加注释。
+
+- `builder instance method`:用于插件判断当前类是否支持builder模式,配置的是一个正则表达式。如果你的builder类生成的方法名与插件默认生成的不同,可以在设置中更改:
+
+### 快捷键配置
-- `generate field mode = target` 代表以方法返回类型的字段为基础生成对象拷贝;
- `generate field mode = source` 代表以方法入参类型的字段为基础生成对象拷贝。
+对象拷贝的快捷键默认是 `Alt+Insert`,如果该快捷键无效,可以在 `settings->keymap` 中搜索 “Generate” 关键字查看具体的快捷键:
-- `non-existent field generate annotation = yes` 代表当目标字段在源对象中不存在时,是否以注释的形式生成代码,如果为 `no`,则代表不生成这一个字段拷贝代码。
+
## 未来功能支持计划
@@ -63,8 +86,8 @@ object-helper插件未来功能支持计划:
- [x] Class 转 XML(Class To XML)
- [x] 个性化配置
- [x] Object Copy Method 功能支持 Builder 模式
-- [ ] Object Copy Method 功能支持 Lambda 表达式
+- [x] Object Copy 功能支持 Lambda 表达式
- [ ] JSON 转 Class(JSON To Class)
-- [ ] Class 转 Protobuf IDL(JSON To Class)
-- [ ] All Setter
-- [ ] 菜单分组显示
+- [ ] Class 转 Protobuf IDL(JSON To Protobuf)
+- [ ] Class 转 Baiji(Class To Baiji)
+- [ ] 菜单分组显示
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 196c339..44ee143 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ plugins {
}
group 'cn.bigcoder.plugin'
-version '1.3.3'
+version '1.4.1'
repositories {
mavenCentral()
@@ -28,10 +28,13 @@ intellij {
plugins = ['com.intellij.java']
}
patchPluginXml {
- sinceBuild = '211'
- untilBuild = '281'
+ sinceBuild = '231'
+ untilBuild = '301.*'
changeNotes = """
- 1. new feature: Object Copy Method support builder mode.
+ 1.Fixed the support for boolean type fields in class to json conversion.
+ 2.Added support for Map type fields in class to json conversion.
+ 3.Optimized the code experience of the Object Copy function.
+ 4.Optimized the plugin compatibility.
"""
}
test {
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java
index 365eeb0..0fe3612 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java
@@ -2,6 +2,7 @@
import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.setActionInvisible;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
@@ -25,4 +26,10 @@ public void update(@NotNull AnActionEvent anActionEvent) {
}
super.update(anActionEvent);
}
+
+ @Override
+ public @NotNull ActionUpdateThread getActionUpdateThread() {
+ return ActionUpdateThread.BGT;
+ }
+
}
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToJsonAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToJsonAction.java
index 8e96e8c..206af16 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToJsonAction.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToJsonAction.java
@@ -1,5 +1,7 @@
package cn.bigcoder.plugin.objecthelper.action;
+import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getOperatePsiClass;
+
import cn.bigcoder.plugin.objecthelper.common.enums.FunctionSwitchEnum;
import cn.bigcoder.plugin.objecthelper.common.util.NotificationUtils;
import cn.bigcoder.plugin.objecthelper.config.PluginConfigState;
@@ -10,15 +12,13 @@
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.psi.PsiClass;
-
import java.awt.datatransfer.StringSelection;
-
-import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getOperatePsiClass;
+import org.jetbrains.annotations.NotNull;
public class ClassToJsonAction extends AbstractClassAnAction {
@Override
- public void actionPerformed(AnActionEvent anAction) {
+ public void actionPerformed(@NotNull AnActionEvent anAction) {
PsiClass psiClass = getOperatePsiClass(anAction);
if (psiClass == null) {
return;
@@ -30,7 +30,7 @@ public void actionPerformed(AnActionEvent anAction) {
@Override
public boolean actionShow(AnActionEvent anActionEvent) {
- return PluginConfigState.getInstance().getJsonSwitch() == FunctionSwitchEnum.OPEN
+ return PluginConfigState.getInstance().getJsonSwitch() == FunctionSwitchEnum.ENABLE
&& getOperatePsiClass(anActionEvent) != null;
}
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToThriftIDLAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToThriftIDLAction.java
index d25b2bd..24f28e1 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToThriftIDLAction.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToThriftIDLAction.java
@@ -31,7 +31,7 @@ public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
@Override
public boolean actionShow(@NotNull AnActionEvent anActionEvent) {
- return PluginConfigState.getInstance().getThriftSwitch() == FunctionSwitchEnum.OPEN
+ return PluginConfigState.getInstance().getThriftSwitch() == FunctionSwitchEnum.ENABLE
&& getOperatePsiClass(anActionEvent) != null;
}
}
\ No newline at end of file
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToXMLAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToXMLAction.java
index 82cb64c..16ca662 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToXMLAction.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ClassToXMLAction.java
@@ -1,5 +1,7 @@
package cn.bigcoder.plugin.objecthelper.action;
+import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getOperatePsiClass;
+
import cn.bigcoder.plugin.objecthelper.common.enums.FunctionSwitchEnum;
import cn.bigcoder.plugin.objecthelper.common.util.NotificationUtils;
import cn.bigcoder.plugin.objecthelper.config.PluginConfigState;
@@ -8,17 +10,13 @@
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.psi.PsiClass;
-
-import groovy.json.StringEscapeUtils;
import java.awt.datatransfer.StringSelection;
import org.jetbrains.annotations.NotNull;
-import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getOperatePsiClass;
-
public class ClassToXMLAction extends AbstractClassAnAction {
@Override
- public void actionPerformed(AnActionEvent anAction) {
+ public void actionPerformed(@NotNull AnActionEvent anAction) {
PsiClass psiClass = getOperatePsiClass(anAction);
if (psiClass == null) {
return;
@@ -30,7 +28,7 @@ public void actionPerformed(AnActionEvent anAction) {
@Override
public boolean actionShow(@NotNull AnActionEvent anActionEvent) {
- return PluginConfigState.getInstance().getXmlSwitch() == FunctionSwitchEnum.OPEN
+ return PluginConfigState.getInstance().getXmlSwitch() == FunctionSwitchEnum.ENABLE
&& getOperatePsiClass(anActionEvent) != null;
}
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyAction.java
new file mode 100644
index 0000000..6e8f918
--- /dev/null
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyAction.java
@@ -0,0 +1,193 @@
+package cn.bigcoder.plugin.objecthelper.action;
+
+import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getOperateFieldName;
+import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getOperatePsiClass;
+import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getPsiClassName;
+
+import cn.bigcoder.plugin.objecthelper.common.util.NotificationUtils;
+import cn.bigcoder.plugin.objecthelper.common.util.StringUtils;
+import cn.bigcoder.plugin.objecthelper.generator.Generator;
+import cn.bigcoder.plugin.objecthelper.generator.copy.SmartObjectCopyGenerator;
+import cn.bigcoder.plugin.objecthelper.ui.ClassSearchDialog;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.CaretModel;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClass;
+import java.util.Objects;
+import org.jetbrains.annotations.NotNull;
+
+public class ObjectCopyAction extends AbstractClassAnAction {
+
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent anAction) {
+ PsiClass sourcePsiClass = getOperatePsiClass(anAction);
+ String operateFieldName = getOperateFieldName(anAction);
+ if (sourcePsiClass == null || StringUtils.isEmpty(operateFieldName)) {
+ NotificationUtils.notifyInfo(anAction.getProject(), "The source object type was not obtained");
+ return;
+ }
+ Project project = anAction.getProject();
+ PsiClass targetPsiClass = null;
+ if (project != null) {
+ ClassSearchDialog dialog = new ClassSearchDialog(project, "Search target object class");
+ if (dialog.showAndGet()) {
+ targetPsiClass = dialog.getSelectedClass();
+ }
+ }
+ if (targetPsiClass == null) {
+ NotificationUtils.notifyInfo(anAction.getProject(), "The target object type was not obtained");
+ return;
+ }
+ String targetParameterName = StringUtils.firstLowerCase(
+ Objects.requireNonNull(getPsiClassName(targetPsiClass)));
+ // 防止方法入参和返回参数名称一致
+ if (operateFieldName.equals(targetParameterName)) {
+ targetParameterName = targetParameterName + "Res";
+ }
+ // 代码生成器
+ Generator generator = new SmartObjectCopyGenerator(sourcePsiClass, targetPsiClass, operateFieldName,
+ targetParameterName);
+
+ insertCode(project, generator.generate());
+ }
+
+ /**
+ * 将代码插入光标处
+ *
+ * @param project
+ * @param copyCodeStr
+ */
+ private void insertCode(Project project, String copyCodeStr) {
+ // 检查代码末尾是否有换行符,没有则添加
+ if (!copyCodeStr.endsWith("\n")) {
+ copyCodeStr += "\n";
+ }
+ Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
+ if (editor == null) {
+ return;
+ }
+ CaretModel caretModel = editor.getCaretModel();
+ int offset = caretModel.getOffset();
+ Document document = editor.getDocument();
+
+ // 获取当前光标所在行号
+ int lineNumber = document.getLineNumber(offset);
+ int lineStartOffset = document.getLineStartOffset(lineNumber);
+ int lineEndOffset = document.getLineEndOffset(lineNumber);
+
+ // 检查当前行在光标之后是否有非空白字符
+ CharSequence lineText = document.getCharsSequence().subSequence(offset, lineEndOffset);
+ boolean hasNonWhitespaceAfterCursor = !lineText.toString().trim().isEmpty();
+
+ // 获取当前行的缩进
+ String indent = getLineIndent(document, lineNumber);
+ // 判断当前行是否为方法头
+ String fullLineText = document.getCharsSequence().subSequence(lineStartOffset, lineEndOffset).toString();
+ if (isMethodHeader(fullLineText)) {
+ // 若是方法头,缩进增加一格,假设一格为 4 个空格
+ indent += " ";
+ }
+
+ // 为插入的代码添加缩进
+ String indentedCopyCodeStr = addIndentToCode(copyCodeStr, indent);
+
+ if (!hasNonWhitespaceAfterCursor) {
+ // 如果光标之后没有非空白字符,删除当前行
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ document.deleteString(lineStartOffset, lineEndOffset);
+ });
+ offset = lineStartOffset;
+ } else {
+ // 如果光标之后有非空白字符,将插入位置移动到下一行开头
+ int nextLineStart = document.getLineStartOffset(lineNumber + 1);
+ offset = nextLineStart;
+ }
+
+ int finalOffset = offset;
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ document.insertString(finalOffset, indentedCopyCodeStr);
+ });
+ }
+
+ /**
+ * 获取指定行的缩进
+ * @param document 文档对象
+ * @param lineNumber 行号
+ * @return 缩进字符串
+ */
+ private String getLineIndent(Document document, int lineNumber) {
+ int lineStartOffset = document.getLineStartOffset(lineNumber);
+ int lineEndOffset = document.getLineEndOffset(lineNumber);
+ CharSequence lineText = document.getCharsSequence().subSequence(lineStartOffset, lineEndOffset);
+ int indentLength = 0;
+ while (indentLength < lineText.length() && Character.isWhitespace(lineText.charAt(indentLength))) {
+ indentLength++;
+ }
+ return lineText.subSequence(0, indentLength).toString();
+ }
+
+ /**
+ * 判断当前行是否为方法头
+ * @param lineText 当前行的文本内容
+ * @return 如果是方法头返回 true,否则返回 false
+ */
+ private boolean isMethodHeader(String lineText) {
+ // 去除注释内容,避免注释中的括号影响判断
+ lineText = removeComments(lineText);
+ // 去除前后空白字符
+ lineText = lineText.trim();
+ // 简单判断,包含 ( 和 ) 且不包含 ; 认为是方法头
+ return lineText.contains("(") && lineText.contains(")") && !lineText.contains(";");
+ }
+
+
+ /**
+ * 移除字符串中的注释内容
+ * @param lineText 包含注释的字符串
+ * @return 移除注释后的字符串
+ */
+ private String removeComments(String lineText) {
+ // 移除单行注释
+ int singleCommentIndex = lineText.indexOf("//");
+ if (singleCommentIndex != -1) {
+ lineText = lineText.substring(0, singleCommentIndex);
+ }
+ // 移除多行注释开始标记之后的内容(简单处理,不处理嵌套情况)
+ int multiCommentStartIndex = lineText.indexOf("/*");
+ if (multiCommentStartIndex != -1) {
+ lineText = lineText.substring(0, multiCommentStartIndex);
+ }
+ return lineText;
+ }
+
+ /**
+ * 为代码的每一行添加缩进
+ * @param code 原始代码
+ * @param indent 缩进字符串
+ * @return 添加缩进后的代码
+ */
+ private String addIndentToCode(String code, String indent) {
+ StringBuilder indentedCode = new StringBuilder();
+ String[] lines = code.split("\\r?\\n");
+ for (int i = 0; i < lines.length; i++) {
+ indentedCode.append(indent).append(lines[i]);
+ if (i < lines.length - 1) {
+ indentedCode.append("\n");
+ }
+ }
+ return indentedCode.toString();
+ }
+
+ @Override
+ public boolean actionShow(AnActionEvent anActionEvent) {
+ PsiClass sourcePsiClass = getOperatePsiClass(anActionEvent);
+ String operateFieldName = getOperateFieldName(anActionEvent);
+ return sourcePsiClass != null && !StringUtils.isEmpty(operateFieldName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyMethodAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyMethodAction.java
index 8b8fe9e..00452f8 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyMethodAction.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyMethodAction.java
@@ -25,7 +25,7 @@ public void actionPerformed(AnActionEvent anActionEvent) {
@Override
public boolean actionShow(AnActionEvent anActionEvent) {
- return PluginConfigState.getInstance().getObjectCopySwitch() == FunctionSwitchEnum.OPEN
+ return PluginConfigState.getInstance().getObjectCopySwitch() == FunctionSwitchEnum.ENABLE
&& check(PsiUtils.getCursorPsiMethod(anActionEvent));
}
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java b/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java
index 297cf03..a1d4c22 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java
@@ -10,6 +10,7 @@ public class JavaClassName {
public static final String LONG_TYPE = "java.lang.Long";
public static final String SHORT_TYPE = "java.lang.Short";
public static final String BYTE_TYPE = "java.lang.Byte";
+ public static final String BOOLEAN_TYPE = "java.lang.Boolean";
public static final String DOUBLE_TYPE = "java.lang.Double";
public static final String FLOAT_TYPE = "java.lang.Float";
public static final String DATE_TYPE = "java.util.Date";
@@ -22,6 +23,7 @@ public class JavaClassName {
public static final String BASE_BYTE_TYPE = "byte";
public static final String BASE_DOUBLE_TYPE = "double";
public static final String BASE_FLOAT_TYPE = "float";
+ public static final String BASE_BOOL_TYPE = "boolean";
public static final String COLLECTION_TYPE = "java.util.Collection";
public static final String MAP_TYPE = "java.util.Map";
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/WhetherEnum.java b/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/EnableEnum.java
similarity index 66%
rename from src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/WhetherEnum.java
rename to src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/EnableEnum.java
index 918c484..52067fa 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/WhetherEnum.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/EnableEnum.java
@@ -4,13 +4,13 @@
* @author: Jindong.Tian
* @date: 2023-12-24
**/
-public enum WhetherEnum implements CommonEnum {
- YES("yes"),
- NO("no"),
+public enum EnableEnum implements CommonEnum {
+ ENABLE("enable"),
+ DISABLE("disable"),
;
private String code;
- WhetherEnum(String code) {
+ EnableEnum(String code) {
this.code = code;
}
@@ -18,11 +18,11 @@ public String getCode() {
return code;
}
- public static WhetherEnum nameOf(String modify) {
+ public static EnableEnum nameOf(String modify) {
if (modify == null) {
return null;
}
- for (WhetherEnum item : values()) {
+ for (EnableEnum item : values()) {
if (modify.equals(item.getCode())) {
return item;
}
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/FunctionSwitchEnum.java b/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/FunctionSwitchEnum.java
index 866c40f..f7a6ebe 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/FunctionSwitchEnum.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/common/enums/FunctionSwitchEnum.java
@@ -5,8 +5,8 @@
* @date: 2023-12-24
**/
public enum FunctionSwitchEnum implements CommonEnum {
- OPEN("open"),
- CLOSE("close"),
+ ENABLE("enable"),
+ DISABLE("disable"),
;
private String code;
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java b/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java
index 9dccef7..ea71389 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java
@@ -43,6 +43,8 @@ public class PsiTypeUtils {
DATA_TYPES.add(LOCAL_DATE_TYPE);
DATA_TYPES.add(LOCAL_DATE_TIME_TYPE);
DATA_TYPES.add(BIG_DECIMAL);
+ DATA_TYPES.add(BOOLEAN_TYPE);
+ DATA_TYPES.add(BASE_BOOL_TYPE);
}
/**
@@ -76,6 +78,9 @@ public static Object getDataTypeDefaultValue(String canonicalText) {
case FLOAT_TYPE:
case BASE_FLOAT_TYPE:
return 1.1f;
+ case BOOLEAN_TYPE:
+ case BASE_BOOL_TYPE:
+ return true;
case DATE_TYPE:
return DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
case LOCAL_DATE_TYPE:
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiUtils.java b/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiUtils.java
index c0cc060..686ba38 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiUtils.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiUtils.java
@@ -9,6 +9,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiFile;
@@ -18,7 +19,9 @@
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.PsiTreeUtil;
import org.apache.commons.compress.utils.Lists;
import org.jetbrains.annotations.NotNull;
@@ -58,6 +61,25 @@ public static PsiClass getOperatePsiClass(AnActionEvent actionEvent) {
PsiElement psiElement = getOperatePsiElement(actionEvent);
if (psiElement instanceof PsiClass) {
return (PsiClass) psiElement;
+ } else if (psiElement instanceof PsiVariable) {
+ PsiType type = ((PsiVariable) psiElement).getType();
+ if (type instanceof PsiClassType) {
+ return ((PsiClassType) type).resolve();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 获取当前操作下的 {@code PsiClass}
+ *
+ * @param actionEvent
+ * @return
+ */
+ public static String getOperateFieldName(AnActionEvent actionEvent) {
+ PsiElement psiElement = getOperatePsiElement(actionEvent);
+ if (psiElement instanceof PsiVariable) {
+ return ((PsiVariable) psiElement).getName();
}
return null;
}
@@ -228,14 +250,54 @@ public static List getAllPsiFields(PsiClass psiClass) {
public static boolean isMemberField(PsiField psiField) {
PsiModifierList modifierList = psiField.getModifierList();
if (modifierList == null ||
- modifierList.hasModifierProperty(PsiModifier.STATIC) ||
- modifierList.hasModifierProperty(PsiModifier.FINAL) ||
- modifierList.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
+ modifierList.hasModifierProperty(PsiModifier.STATIC) ||
+ modifierList.hasModifierProperty(PsiModifier.FINAL) ||
+ modifierList.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
return false;
}
return true;
}
+ /**
+ * 根据类名称模糊匹配项目中的PsiClass
+ *
+ * @param project
+ * @param classNameStr 模糊匹配的类名称(大小写不敏感)
+ * @return
+ */
+ public static @NotNull List matchPsiClassByName(Project project, String classNameStr) {
+ JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(project);
+ List exactMatches = new ArrayList<>();
+ List fuzzyMatches = new ArrayList<>();
+
+ // 处理带包名的情况
+ if (classNameStr.contains(".")) {
+ PsiClass cls = psiFacade.findClass(classNameStr, GlobalSearchScope.allScope(project));
+ if (cls != null) {
+ exactMatches.add(cls);
+ }
+ }
+
+ // 获取所有类名
+ String[] allClassNames = shortNamesCache.getAllClassNames();
+ for (String className : allClassNames) {
+ if (className.equalsIgnoreCase(classNameStr)) {
+ // 完全匹配
+ PsiClass[] classes = shortNamesCache.getClassesByName(className, GlobalSearchScope.allScope(project));
+ exactMatches.addAll(Arrays.asList(classes));
+ } else if (className.toLowerCase().contains(classNameStr.toLowerCase())) {
+ // 模糊匹配
+ PsiClass[] classes = shortNamesCache.getClassesByName(className, GlobalSearchScope.allScope(project));
+ fuzzyMatches.addAll(Arrays.asList(classes));
+ }
+ }
+
+ // 合并结果,优先展示完全匹配的类
+ exactMatches.addAll(fuzzyMatches);
+ return exactMatches;
+ }
+
/**
* 递归获取类中所有字段
*
@@ -249,4 +311,4 @@ private static void recursiveAllFields(PsiClass psiClass, List psiFiel
psiFields.addAll(Arrays.asList(psiClass.getFields()));
recursiveAllFields(psiClass.getSuperClass(), psiFields);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/config/PluginConfigModel.java b/src/main/java/cn/bigcoder/plugin/objecthelper/config/PluginConfigModel.java
index 66fc4b6..8dde736 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/config/PluginConfigModel.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/config/PluginConfigModel.java
@@ -2,7 +2,7 @@
import cn.bigcoder.plugin.objecthelper.common.enums.FieldGenerateModeEnum;
import cn.bigcoder.plugin.objecthelper.common.enums.FunctionSwitchEnum;
-import cn.bigcoder.plugin.objecthelper.common.enums.WhetherEnum;
+import cn.bigcoder.plugin.objecthelper.common.enums.EnableEnum;
import java.util.Objects;
/**
@@ -14,19 +14,19 @@ public class PluginConfigModel {
/**
* 是否开启 Class To Json 功能,默认为开启状态
*/
- private FunctionSwitchEnum jsonSwitch = FunctionSwitchEnum.OPEN;
+ private FunctionSwitchEnum jsonSwitch = FunctionSwitchEnum.ENABLE;
/**
* 是否开启 Class To Thrift IDL 功能,默认为开启状态
*/
- private FunctionSwitchEnum thriftSwitch = FunctionSwitchEnum.OPEN;
+ private FunctionSwitchEnum thriftSwitch = FunctionSwitchEnum.ENABLE;
/**
* 是否开启 Class To XML 功能,默认为开启状态
*/
- private FunctionSwitchEnum xmlSwitch = FunctionSwitchEnum.OPEN;
+ private FunctionSwitchEnum xmlSwitch = FunctionSwitchEnum.ENABLE;
/**
* 是否开启 Object Copy Method 功能,默认为开启状态
*/
- private FunctionSwitchEnum objectCopySwitch = FunctionSwitchEnum.OPEN;
+ private FunctionSwitchEnum objectCopySwitch = FunctionSwitchEnum.ENABLE;
/**
* Object Copy Method 功能中,以Source/Target对象为基础生成字段拷贝
*/
@@ -35,7 +35,7 @@ public class PluginConfigModel {
/**
* Object Copy Method 功能中,Source 和 Target 对象之间差异的字段,是否以代码注释的形式生成代码
*/
- private WhetherEnum objectCopyMethodFieldGenerateAnnotation = WhetherEnum.YES;
+ private EnableEnum objectCopyMethodFieldGenerateAnnotation = EnableEnum.ENABLE;
/**
* Object Copy Method 功能中,使用builder模式生成拷贝代码时的判断依据,当目标对象类中包含正则所指定的方法,则默认按照builder模式生成,否则使用set模式生成
@@ -83,12 +83,12 @@ public void setObjectCopyMethodFieldGenerateMode(
this.objectCopyMethodFieldGenerateMode = objectCopyMethodFieldGenerateMode;
}
- public WhetherEnum getObjectCopyMethodFieldGenerateAnnotation() {
+ public EnableEnum getObjectCopyMethodFieldGenerateAnnotation() {
return objectCopyMethodFieldGenerateAnnotation;
}
public void setObjectCopyMethodFieldGenerateAnnotation(
- WhetherEnum objectCopyMethodFieldGenerateAnnotation) {
+ EnableEnum objectCopyMethodFieldGenerateAnnotation) {
this.objectCopyMethodFieldGenerateAnnotation = objectCopyMethodFieldGenerateAnnotation;
}
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java b/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java
index d490bfe..4d88424 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java
@@ -1,5 +1,6 @@
package cn.bigcoder.plugin.objecthelper.generator;
+import cn.bigcoder.plugin.objecthelper.common.constant.JavaClassName;
import cn.bigcoder.plugin.objecthelper.common.util.PsiTypeUtils;
import cn.bigcoder.plugin.objecthelper.common.util.PsiUtils;
import com.google.common.collect.Maps;
@@ -23,66 +24,91 @@
**/
public abstract class AbstractDataObjectGenerator implements Generator {
- private PsiClass psiClass;
+ private PsiClass psiClass;
- public AbstractDataObjectGenerator(PsiClass psiClass) {
- this.psiClass = psiClass;
- }
-
- /**
- * 保存已经解析过的自定义类型名称,防止出现递归嵌套的情况
- */
- private Set recursiveCache = Sets.newHashSet();
+ public AbstractDataObjectGenerator(PsiClass psiClass) {
+ this.psiClass = psiClass;
+ }
- protected Map processFields() {
- return processFields(psiClass);
- }
+ /**
+ * 保存已经解析过的自定义类型名称,防止出现递归嵌套的情况
+ */
+ private Set recursiveCache = Sets.newHashSet();
- protected Map processFields(PsiClass psiClass) {
- Map result = Maps.newLinkedHashMap();
- // 当前类所有字段
- List allPsiFields = PsiUtils.getAllPsiFields(psiClass);
- if (CollectionUtils.isEmpty(allPsiFields)) {
- return result;
+ protected Map processFields() {
+ return processFields(psiClass);
}
- for (PsiField psiField : allPsiFields) {
- result.put(psiField.getName(), processField(psiField.getType()));
+
+ protected Map processFields(PsiClass psiClass) {
+ Map result = Maps.newLinkedHashMap();
+ // 当前类所有字段
+ List allPsiFields = PsiUtils.getAllPsiFields(psiClass);
+ if (CollectionUtils.isEmpty(allPsiFields)) {
+ return result;
+ }
+ for (PsiField psiField : allPsiFields) {
+ // 过滤掉静态字段
+ if (!psiField.hasModifierProperty(com.intellij.psi.PsiModifier.STATIC)) {
+ result.put(psiField.getName(), processField(psiField.getType()));
+ }
+ }
+ return result;
}
- return result;
- }
- private Object processField(PsiType psiType) {
- Object defaultValue = null;
- if (PsiTypeUtils.isDataType(psiType)) {
- //如果是数据类型
- defaultValue = PsiTypeUtils.getDataTypeDefaultValue(psiType.getCanonicalText());
- } else if (PsiTypeUtils.isArrayType(psiType)) {
- //如果是数组类型
- List