Skip to content

1.3.3版本: #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,33 @@
</div>
<br/>
<div align="center">
<img src="https://img.shields.io/badge/version-v1.3.2-blue">
<img src="https://img.shields.io/badge/version-v1.3.3-blue">
<img src="https://img.shields.io/badge/license-Apache%202-red">
<img src="https://img.shields.io/badge/size-3.96%20MB-yellowgreen">
<img src="https://img.shields.io/badge/download-3.2k-green">
<img src="https://img.shields.io/badge/size-3.94%20MB-yellowgreen">
<img src="https://img.shields.io/badge/download-4.8k-green">
</div>

JetBrains Intellij IDEA ObjectHelper 插件旨在减少开发者重复低效的劳动,使开发者能够更专注于业务逻辑的开发。

该插件包含以下功能:

- 对象拷贝
set模式:

![](https://image.bigcoder.cn/7fce876e-fa94-4780-bb14-584068c35963.gif)

对象拷贝的快捷键默认是 `Alt+Insert`,如果该快捷键无效,可以在settings->keymap中搜索“Generate”关键字查看具体的快捷键:

![](https://image.bigcoder.cn/20220916173117.png)

当对象中包含`builder` 或者 `newBuilder`方法时,则插件默认会采用 builder 模式生成代码:

![](https://image.bigcoder.cn/20240505142735.gif)

如果你的builder类生成的方法名与插件默认生成的不同,可以在设置中更改:

![](https://image.bigcoder.cn/20240505143027.png)

- Java类转JSON

![](https://image.bigcoder.cn/20231224171155.gif)
Expand All @@ -42,7 +51,7 @@ File->Settings->Tools->Object Helper 即可进入插件的配置页面
![](https://image.bigcoder.cn/20231224170305.png)

- `generate field mode = target` 代表以方法返回类型的字段为基础生成对象拷贝;
`generate field mode = source` 代表以方法入参类型的字段为基础生成对象拷贝。
`generate field mode = source` 代表以方法入参类型的字段为基础生成对象拷贝。

- `non-existent field generate annotation = yes` 代表当目标字段在源对象中不存在时,是否以注释的形式生成代码,如果为 `no`,则代表不生成这一个字段拷贝代码。

Expand All @@ -53,6 +62,7 @@ object-helper插件未来功能支持计划:
- [x] Class 转 IDL(Class To Thrift IDL)
- [x] Class 转 XML(Class To XML)
- [x] 个性化配置
- [x] Object Copy Method 功能支持 Builder 模式
- [ ] Object Copy Method 功能支持 Lambda 表达式
- [ ] JSON 转 Class(JSON To Class)
- [ ] Class 转 Protobuf IDL(JSON To Class)
Expand Down
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
}

group 'cn.bigcoder.plugin'
version '1.3.2'
version '1.3.3'

repositories {
mavenCentral()
Expand All @@ -29,8 +29,9 @@ intellij {
}
patchPluginXml {
sinceBuild = '211'
untilBuild = '281'
changeNotes = """
1. fix feature:Resolve version compatibility issues and adapt new versions of the IDE
1. new feature: Object Copy Method support builder mode.
"""
}
test {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cn.bigcoder.plugin.objecthelper.common.enums;

/**
* @author: Jindong.Tian
* @date: 2023-12-24
**/
public enum ObjectCopyStrategyEnum {
/**
* 普通SET模式
*/
SET,
/**
* builder模式
*/
BUILDER,
;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cn.bigcoder.plugin.objecthelper.common.exception;

/**
* @author: Jindong.Tian
* @date: 2024-05-05
**/
public class ObjectHeplerPluginException extends RuntimeException{

public ObjectHeplerPluginException() {
}

public ObjectHeplerPluginException(String message) {
super(message);
}

public ObjectHeplerPluginException(String message, Throwable cause) {
super(message, cause);
}

public ObjectHeplerPluginException(Throwable cause) {
super(cause);
}

public ObjectHeplerPluginException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierList;
Expand All @@ -25,6 +26,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.jetbrains.annotations.Nullable;

/**
* @author: Jindong.Tian
Expand Down Expand Up @@ -153,6 +155,21 @@ public static String getMethodReturnClassName(PsiMethod psiMethod) {
return returnType.getPresentableText();
}

/**
* 获取PsiClass 名称
*
* @param psiClass
* @return
*/
@Nullable
public static String getPsiClassName(PsiClass psiClass) {
PsiIdentifier nameIdentifier = psiClass.getNameIdentifier();
if (nameIdentifier == null) {
return null;
}
return nameIdentifier.getText();
}

/**
* 获取方法的参数列表
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public void apply() {
instance.setObjectCopySwitch(currentConfigModel.getObjectCopySwitch());
instance.setObjectCopyMethodFieldGenerateAnnotation(currentConfigModel.getObjectCopyMethodFieldGenerateAnnotation());
instance.setObjectCopyMethodFieldGenerateMode(currentConfigModel.getObjectCopyMethodFieldGenerateMode());
instance.setBuilderInstanceMethodName(currentConfigModel.getBuilderInstanceMethodName());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public class PluginConfigModel {
*/
private WhetherEnum objectCopyMethodFieldGenerateAnnotation = WhetherEnum.YES;

/**
* Object Copy Method 功能中,使用builder模式生成拷贝代码时的判断依据,当目标对象类中包含正则所指定的方法,则默认按照builder模式生成,否则使用set模式生成
*/
private String builderInstanceMethodName = ".*(builder|newBuilder).*";

public FunctionSwitchEnum getJsonSwitch() {
return jsonSwitch;
}
Expand Down Expand Up @@ -87,6 +92,14 @@ public void setObjectCopyMethodFieldGenerateAnnotation(
this.objectCopyMethodFieldGenerateAnnotation = objectCopyMethodFieldGenerateAnnotation;
}

public String getBuilderInstanceMethodName() {
return builderInstanceMethodName;
}

public void setBuilderInstanceMethodName(String builderInstanceMethodName) {
this.builderInstanceMethodName = builderInstanceMethodName;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand All @@ -97,14 +110,15 @@ public boolean equals(Object o) {
}
PluginConfigModel that = (PluginConfigModel) o;
return jsonSwitch == that.jsonSwitch && thriftSwitch == that.thriftSwitch && xmlSwitch == that.xmlSwitch
&& objectCopySwitch == that.objectCopySwitch
&& objectCopyMethodFieldGenerateMode == that.objectCopyMethodFieldGenerateMode
&& objectCopyMethodFieldGenerateAnnotation == that.objectCopyMethodFieldGenerateAnnotation;
&& objectCopySwitch == that.objectCopySwitch
&& objectCopyMethodFieldGenerateMode == that.objectCopyMethodFieldGenerateMode
&& objectCopyMethodFieldGenerateAnnotation == that.objectCopyMethodFieldGenerateAnnotation
&& Objects.equals(builderInstanceMethodName, that.builderInstanceMethodName);
}

@Override
public int hashCode() {
return Objects.hash(jsonSwitch, thriftSwitch, xmlSwitch, objectCopySwitch, objectCopyMethodFieldGenerateMode,
objectCopyMethodFieldGenerateAnnotation);
objectCopyMethodFieldGenerateAnnotation, builderInstanceMethodName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package cn.bigcoder.plugin.objecthelper.generator.copy;

import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getPsiClassName;

import cn.bigcoder.plugin.objecthelper.common.enums.FieldGenerateModeEnum;
import cn.bigcoder.plugin.objecthelper.common.enums.WhetherEnum;
import cn.bigcoder.plugin.objecthelper.common.util.PsiUtils;
import cn.bigcoder.plugin.objecthelper.common.util.StringUtils;
import cn.bigcoder.plugin.objecthelper.config.PluginConfigState;
import cn.bigcoder.plugin.objecthelper.generator.Generator;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author: Jindong.Tian
* @date: 2024-05-05
**/
public abstract class AbstractObjectCopyStrategy implements Generator {

/**
* 对象拷贝源对象类型
*/
protected PsiClass sourceClass;
/**
* 对象拷贝目标对象类型
*/
protected PsiClass targetClass;
/**
* 对象拷贝源参数名称
*/
protected String sourceParamName;
/**
* 对象拷贝目标参数名称
*/
protected String targetParamName;

public AbstractObjectCopyStrategy(PsiClass sourceClass, PsiClass targetClass, String sourceParamName) {
this.sourceClass = sourceClass;
this.targetClass = targetClass;
this.sourceParamName = sourceParamName;
// 生成参数名
this.targetParamName = StringUtils.firstLowerCase(Objects.requireNonNull(getPsiClassName(targetClass)));
// 防止方法入参和返回参数名称一致
if (sourceParamName.equals(this.targetParamName)) {
this.targetParamName = this.targetParamName + "Res";
}
}

@Override
public String generate() {
StringBuilder result = new StringBuilder();
// 生成前缀
result.append(generatePrefix());

// 字段copy模式
FieldGenerateModeEnum generateModeEnum = PluginConfigState.getInstance().getObjectCopyMethodFieldGenerateMode();

// mainClass 代表以哪个类字段为基础生成字段拷贝代码
PsiClass mainClass = targetClass;
PsiClass secondClass = sourceClass;
if (generateModeEnum == FieldGenerateModeEnum.SOURCE) {
// 字段拷贝使用源字段为蓝本拷贝
mainClass = sourceClass;
secondClass = targetClass;
}

Set<String> secondFieldNames = PsiUtils.getAllPsiFields(secondClass).stream().filter(PsiUtils::isMemberField)
.map(PsiField::getName).collect(Collectors.toSet());

List<String> annotationLine = new LinkedList<>();
for (PsiField field : PsiUtils.getAllPsiFields(mainClass)) {
if (!PsiUtils.isMemberField(field)) {
continue;
}
if (secondFieldNames.contains(field.getName())) {
result.append(generateFiledCopy(field));
} else if (PluginConfigState.getInstance().getObjectCopyMethodFieldGenerateAnnotation()
== WhetherEnum.YES) {
// 如果源对象没有该字段,且开启了以注释模式生成代码的开关,则生成注释
annotationLine.add("// " + generateFiledCopy(field));
}
}
annotationLine.forEach(result::append);
result.append(generateSuffix());
return result.toString();
}

protected abstract String generatePrefix();

protected abstract String generateFiledCopy(PsiField field);

protected abstract String generateSuffix();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package cn.bigcoder.plugin.objecthelper.generator.copy.strategy;

import static cn.bigcoder.plugin.objecthelper.common.constant.JavaKeyWord.BLANK_SEPARATOR;
import static cn.bigcoder.plugin.objecthelper.common.constant.JavaKeyWord.LINE_SEPARATOR;
import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.getPsiClassName;

import cn.bigcoder.plugin.objecthelper.common.util.StringUtils;
import cn.bigcoder.plugin.objecthelper.generator.copy.AbstractObjectCopyStrategy;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;

/**
* @author: Jindong.Tian
* @date: 2024-05-05
**/
public class BuilderObjectCopyStrategy extends AbstractObjectCopyStrategy {

public BuilderObjectCopyStrategy(PsiClass sourceClass, PsiClass targetClass, String sourceParamName) {
super(sourceClass, targetClass, sourceParamName);
}


/**
* 生成类似如下代码:
*
* if (user == null) {
* return null;
* }
* return UserDto.builder()
*
* @return
*/
@Override
protected String generatePrefix() {
return generateNullCheck(sourceParamName) + LINE_SEPARATOR +
"return" + BLANK_SEPARATOR + getPsiClassName(targetClass) + ".builder()" + LINE_SEPARATOR;
}

@Override
protected String generateFiledCopy(PsiField field) {
return "." + field.getName() + "("
+ sourceParamName + ".get" + StringUtils.firstUpperCase(field.getName()) + "())"
+ LINE_SEPARATOR;
}


@Override
protected String generateSuffix() {
return ".build();" + LINE_SEPARATOR;
}

/**
* 生成示例:{@code if (user == null) {return null;}}
*
* @return
*/
private String generateNullCheck(String sourceParamName) {
return "if(" + sourceParamName + "==null){return null;}";
}
}
Loading