去除hutool依赖,用户可以按需引用

This commit is contained in:
linpeilie 2024-03-12 16:14:01 +08:00
parent abe54d84cc
commit 4b97f2bfbd
32 changed files with 682 additions and 76 deletions

View File

@ -20,6 +20,7 @@
<mapstruct.version>1.5.1.Final</mapstruct.version>
<mapstruct-plus.version>1.3.7-SNAPSHOTS</mapstruct-plus.version>
<lombok.version>1.18.22</lombok.version>
<hutool.version>5.8.26</hutool.version>
</properties>
<dependencyManagement>
@ -44,6 +45,11 @@
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -28,6 +28,10 @@
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -46,6 +46,10 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -42,6 +42,10 @@
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -1,6 +1,5 @@
package io.github.linpeilie;
import cn.hutool.core.date.DateUtil;
import io.github.linpeilie.model.Goods;
import io.github.linpeilie.model.GoodsDto;
import io.github.linpeilie.model.MapModelA;
@ -27,14 +26,14 @@ public class QuickStartTest {
private Converter converter;
@Test
public void test() {
public void test() throws ParseException {
Map<String, Object> mapModel1 = new HashMap<>();
mapModel1.put("str", "1jkf1ijkj3f");
mapModel1.put("i1", 111);
mapModel1.put("l2", 11231);
Map<String, Object> mapModel2 = new HashMap<>();
mapModel2.put("date", DateUtil.parse("2023-02-23 01:03:23"));
mapModel2.put("date", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2023-02-23 01:03:23"));
mapModel1.put("mapModelB", mapModel2);
@ -99,7 +98,7 @@ public class QuickStartTest {
}
@Test
public void multiClassConvertTest() {
public void multiClassConvertTest() throws ParseException {
User user = new User();
List<String> list = new ArrayList<>();
list.add("1");
@ -110,7 +109,7 @@ public class QuickStartTest {
user.setUsername("Nick");
user.setAge(12);
user.setYoung(true);
user.setBirthday(DateUtil.parseDateTime("2023-02-23 02:01:43"));
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2023-02-23 02:01:43"));
user.setAssets(123.234);
user.setVoField("vofieldfff");
user.setMoney(12543.123);

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-pom</artifactId>
<version>${mapstruct-plus.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>mapstruct-plus-object-convert</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<optional>true</optional>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -27,10 +27,6 @@
<groupId>com.baidu.lbsyun</groupId>
<artifactId>javapoet</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>

View File

@ -1,9 +1,5 @@
package io.github.linpeilie.processor;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import io.github.linpeilie.ComponentModelConstant;
@ -31,6 +27,10 @@ import io.github.linpeilie.processor.metadata.AutoEnumMapperMetadata;
import io.github.linpeilie.processor.metadata.AutoMapMapperMetadata;
import io.github.linpeilie.processor.metadata.AutoMapperMetadata;
import io.github.linpeilie.processor.metadata.AutoMappingMetadata;
import io.github.linpeilie.processor.utils.ExceptionUtils;
import io.github.linpeilie.processor.utils.ObjectUtils;
import io.github.linpeilie.utils.CollectionUtils;
import io.github.linpeilie.utils.StrUtil;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
@ -149,7 +149,7 @@ public class AutoMapperProcessor extends AbstractProcessor {
try {
doProcess(annotations, roundEnv);
} catch (Exception e) {
messager.printMessage(ERROR, ExceptionUtil.stacktraceToString(e));
messager.printMessage(ERROR, ExceptionUtils.getStackTrace(e));
}
return false;
@ -398,7 +398,7 @@ public class AutoMapperProcessor extends AbstractProcessor {
// load previous mapper config
final List<TypeElement> typeElements = buildCollator.getRecords();
if (CollectionUtil.isNotEmpty(typeElements)) {
if (CollectionUtils.isNotEmpty(typeElements)) {
messager.printMessage(Diagnostic.Kind.NOTE,
"The previous Mapper Config Class was read , class name : " + typeElements.get(0));
loadMapperConfig(typeElements.get(0).getAnnotation(MapperConfig.class));
@ -413,7 +413,7 @@ public class AutoMapperProcessor extends AbstractProcessor {
if (mapperConfigOptional.isPresent()) {
loadMapperConfig(mapperConfigOptional.get().getAnnotation(MapperConfig.class));
// record
buildCollator.writeTypeElements(CollectionUtil.newArrayList((TypeElement) mapperConfigOptional.get()));
buildCollator.writeTypeElements(Collections.singletonList((TypeElement) mapperConfigOptional.get()));
}
}
@ -483,7 +483,7 @@ public class AutoMapperProcessor extends AbstractProcessor {
if (!autoMapperMetadata.isReverseConvertGenerate()) {
return;
}
boolean defineReverseMapping = CollectionUtil.isNotEmpty(autoMapperMetadata.getFieldReverseMappingList());
boolean defineReverseMapping = CollectionUtils.isNotEmpty(autoMapperMetadata.getFieldReverseMappingList());
final AutoMapperMetadata reverseMapperMetadata = reverseMapper(autoMapperMetadata);
if (defineReverseMapping) {
addMapper(reverseMapperMetadata);
@ -544,7 +544,7 @@ public class AutoMapperProcessor extends AbstractProcessor {
reverseMapperMetadata.setSuperClass(
ClassName.get(ContextConstants.BaseMapper.packageName, ContextConstants.BaseMapper.className));
}
if (CollectionUtil.isNotEmpty(autoMapperMetadata.getFieldReverseMappingList())) {
if (CollectionUtils.isNotEmpty(autoMapperMetadata.getFieldReverseMappingList())) {
reverseMapperMetadata.setFieldMappingList(autoMapperMetadata.getFieldReverseMappingList());
} else {
// 需要继承的属性
@ -799,7 +799,7 @@ public class AutoMapperProcessor extends AbstractProcessor {
String elementName = ele.getSimpleName().toString();
if (ele.getKind() == ElementKind.METHOD) {
elementName = ObjectUtil.defaultIfBlank(StrUtil.getGeneralField(elementName), elementName);
elementName = ObjectUtils.defaultIfNull(StrUtil.getGeneralField(elementName), elementName);
}
if (StrUtil.isNotEmpty(autoMapping.source())) {

View File

@ -1,7 +1,7 @@
package io.github.linpeilie.processor;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import io.github.linpeilie.processor.utils.FileUtils;
import io.github.linpeilie.utils.CollectionUtils;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
@ -41,7 +41,7 @@ public class BuildCollator {
ContextConstants.MetaInf.folder + fileName);
this.collatorFile = new File(fileObject.getName());
if (collatorFile.exists()) {
records = FileUtil.readUtf8Lines(collatorFile)
records = FileUtils.readUtf8Lines(collatorFile)
.stream()
.map(line -> processingEnv.getElementUtils().getTypeElement(line))
.filter(Objects::nonNull)
@ -62,7 +62,7 @@ public class BuildCollator {
}
private void write(Collection<String> lines) {
if (CollectionUtil.isEmpty(lines)) {
if (CollectionUtils.isEmpty(lines)) {
return;
}
@ -71,8 +71,8 @@ public class BuildCollator {
.filter(Objects::nonNull)
.collect(Collectors.toList());
FileUtil.mkParentDirs(collatorFile);
FileUtil.writeUtf8Lines(lines, collatorFile);
FileUtils.mkParentDirs(collatorFile);
FileUtils.writeUtf8Lines(lines, collatorFile);
}
private List<String> loadRecords() {
@ -87,7 +87,7 @@ public class BuildCollator {
public void consumeRecords(Consumer<TypeElement> consumer) {
final List<TypeElement> typeElements = getRecords();
if (CollectionUtil.isNotEmpty(typeElements)) {
if (CollectionUtils.isNotEmpty(typeElements)) {
typeElements.forEach(consumer);
}
}

View File

@ -1,7 +1,5 @@
package io.github.linpeilie.processor.generator;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
@ -13,6 +11,8 @@ import com.squareup.javapoet.TypeSpec;
import io.github.linpeilie.processor.ContextConstants;
import io.github.linpeilie.processor.metadata.AutoMapperMetadata;
import io.github.linpeilie.processor.metadata.AutoMappingMetadata;
import io.github.linpeilie.utils.CollectionUtils;
import io.github.linpeilie.utils.StrUtil;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Writer;
@ -25,7 +25,6 @@ import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import org.apache.commons.lang3.StringUtils;
public class AutoMapperGenerator {
@ -58,10 +57,9 @@ public class AutoMapperGenerator {
ParameterSpec.builder(ClassName.get("io.github.linpeilie", "CycleAvoidingMappingContext"), "context")
.addAnnotation(ClassName.get("org.mapstruct", "Context"))
.build();
if (metadata.getFieldMappingList() != null && !metadata.getFieldMappingList().isEmpty()) {
builder.addMethod(addConvertMethodSpec(
metadata.isCycles() ? CollectionUtil.newArrayList(source, context) : Collections.singletonList(source),
metadata.isCycles() ? CollectionUtils.newArrayList(source, context) : Collections.singletonList(source),
metadata.getFieldMappingList(),
targetClassName,
CONVERT_METHOD_NAME));
@ -71,14 +69,14 @@ public class AutoMapperGenerator {
if (targetIsImmutable) {
builder.addMethod(
addEmptyConvertMethodForImmutableEntity(
metadata.isCycles() ? CollectionUtil.newArrayList(source, target,
context) : CollectionUtil.newArrayList(source, target),
metadata.isCycles() ? CollectionUtils.newArrayList(source, target,
context) : CollectionUtils.newArrayList(source, target),
targetClassName,
CONVERT_METHOD_NAME));
} else if (metadata.getFieldMappingList() != null && !metadata.getFieldMappingList().isEmpty()) {
builder.addMethod(addConvertMethodSpec(
metadata.isCycles() ? CollectionUtil.newArrayList(source, target,
context) : CollectionUtil.newArrayList(source, target),
metadata.isCycles() ? CollectionUtils.newArrayList(source, target,
context) : CollectionUtils.newArrayList(source, target),
metadata.getFieldMappingList(),
targetClassName,
CONVERT_METHOD_NAME));
@ -117,7 +115,7 @@ public class AutoMapperGenerator {
.addParameters(parameterSpecs)
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.returns(target);
if (CollectionUtil.isNotEmpty(autoMappingMetadataList)) {
if (CollectionUtils.isNotEmpty(autoMappingMetadataList)) {
methodSpecBuilder.addAnnotations(buildMappingAnnotations(autoMappingMetadataList));
}
return methodSpecBuilder.build();
@ -140,17 +138,17 @@ public class AutoMapperGenerator {
builder.addMember("defaultValue",
CodeBlock.builder().add("$S", autoMappingMetadata.getDefaultValue()).build());
}
if (StringUtils.isNotEmpty(autoMappingMetadata.getExpression())) {
if (StrUtil.isNotEmpty(autoMappingMetadata.getExpression())) {
builder.addMember("expression",
CodeBlock.builder().add("$S", autoMappingMetadata.getExpression()).build());
} else {
builder.addMember("source", CodeBlock.builder().add("$S", autoMappingMetadata.getSource()).build());
}
if (StringUtils.isNotEmpty(autoMappingMetadata.getDefaultExpression())) {
if (StrUtil.isNotEmpty(autoMappingMetadata.getDefaultExpression())) {
builder.addMember("defaultExpression",
CodeBlock.builder().add("$S", autoMappingMetadata.getDefaultExpression()).build());
}
if (StringUtils.isNotEmpty(autoMappingMetadata.getConditionExpression())) {
if (StrUtil.isNotEmpty(autoMappingMetadata.getConditionExpression())) {
builder.addMember("conditionExpression",
CodeBlock.builder().add("$S", autoMappingMetadata.getConditionExpression()).build());
}

View File

@ -1,18 +1,17 @@
package io.github.linpeilie.processor.generator;
import cn.hutool.core.collection.CollectionUtil;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
import io.github.linpeilie.processor.AutoMapperProperties;
import io.github.linpeilie.utils.CollectionUtils;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import static javax.tools.Diagnostic.Kind.ERROR;
@ -44,7 +43,7 @@ public class MapperConfigGenerator {
private AnnotationSpec buildMapperConfigAnnotationSpec(final String adapterClassName, final List<TypeMirror> uses) {
CodeBlock.Builder usesCodeBuilder = CodeBlock.builder().add("{");
usesCodeBuilder.add("$T.class", ClassName.get(AutoMapperProperties.getAdapterPackage(), adapterClassName));
if (CollectionUtil.isNotEmpty(uses)) {
if (CollectionUtils.isNotEmpty(uses)) {
uses.forEach(use -> {
usesCodeBuilder.add(", $T.class", use);
});

View File

@ -1,8 +1,8 @@
package io.github.linpeilie.processor.generator;
import cn.hutool.core.collection.CollectionUtil;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import io.github.linpeilie.utils.CollectionUtils;
import java.util.Collection;
import java.util.List;
@ -25,6 +25,6 @@ public class SolonAdapterMapperGenerator extends IocAdapterMapperGenerator {
@Override
protected List<AnnotationSpec> injectAnnotations() {
return CollectionUtil.newArrayList(inject());
return CollectionUtils.newArrayList(inject());
}
}

View File

@ -1,18 +1,9 @@
package io.github.linpeilie.processor.generator;
import cn.hutool.core.collection.CollectionUtil;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeSpec;
import io.github.linpeilie.processor.AbstractAdapterMapperGenerator;
import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata;
import java.util.Collection;
import io.github.linpeilie.utils.CollectionUtils;
import java.util.List;
import javax.lang.model.element.Modifier;
public class SpringAdapterMapperGenerator extends IocAdapterMapperGenerator {
@ -35,7 +26,7 @@ public class SpringAdapterMapperGenerator extends IocAdapterMapperGenerator {
@Override
protected List<AnnotationSpec> injectAnnotations() {
return CollectionUtil.newArrayList(autowired());
return CollectionUtils.newArrayList(autowired());
}
}

View File

@ -2,14 +2,14 @@ package io.github.linpeilie.processor.metadata;
import com.squareup.javapoet.ClassName;
import io.github.linpeilie.processor.AutoMapperProperties;
import org.apache.commons.lang3.StringUtils;
import io.github.linpeilie.utils.StrUtil;
public abstract class AbstractMapperMetadata {
protected ClassName sourceClassName;
public String mapperPackage() {
return StringUtils.isNotEmpty(AutoMapperProperties.getMapperPackage())
return StrUtil.isNotEmpty(AutoMapperProperties.getMapperPackage())
? AutoMapperProperties.getMapperPackage() : sourceClassName.packageName();
}

View File

@ -1,13 +1,13 @@
package io.github.linpeilie.processor.metadata;
import io.github.linpeilie.processor.AutoMapperProperties;
import org.apache.commons.lang3.StringUtils;
import io.github.linpeilie.utils.StrUtil;
public class AutoMapMapperMetadata extends AutoMapperMetadata {
@Override
public String mapperPackage() {
return StringUtils.isNotEmpty(AutoMapperProperties.getMapperPackage())
? AutoMapperProperties.getMapperPackage() : getTargetClassName().packageName();
return StrUtil.isNotEmpty(
AutoMapperProperties.getMapperPackage()) ? AutoMapperProperties.getMapperPackage() : getTargetClassName().packageName();
}
}

View File

@ -1,8 +1,7 @@
package io.github.linpeilie.processor.solon;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import io.github.linpeilie.ComponentModelConstant;
import io.github.linpeilie.utils.CollectionUtils;
import java.util.List;
import org.mapstruct.ap.internal.model.Annotation;
import org.mapstruct.ap.internal.model.Mapper;
@ -16,7 +15,7 @@ public class SolonComponentProcessor extends AnnotationBasedComponentModelProces
@Override
protected List<Annotation> getTypeAnnotations(final Mapper mapper) {
return CollectionUtil.newArrayList(component());
return CollectionUtils.newArrayList(component());
}
private Annotation component() {
@ -29,7 +28,7 @@ public class SolonComponentProcessor extends AnnotationBasedComponentModelProces
@Override
protected List<Annotation> getMapperReferenceAnnotations() {
return CollectionUtil.newArrayList(inject());
return CollectionUtils.newArrayList(inject());
}
@Override

View File

@ -0,0 +1,15 @@
package io.github.linpeilie.processor.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
public class ExceptionUtils {
public static String getStackTrace(final Throwable throwable) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
}

View File

@ -0,0 +1,61 @@
package io.github.linpeilie.processor.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.util.Collection;
public class FileReader extends FileWrapper {
private static final long serialVersionUID = 1L;
public static FileReader create(File file, Charset charset){
return new FileReader(file, charset);
}
// ------------------------------------------------------- Constructor start
public FileReader(File file, Charset charset) {
super(file, charset);
checkFile();
}
// ------------------------------------------------------- Constructor end
public <T extends Collection<String>> T readLines(T collection) {
BufferedReader reader = null;
try {
reader = FileUtils.getReader(file, charset);
String line;
while (true) {
line = reader.readLine();
if (line == null) {
break;
}
collection.add(line);
}
return collection;
} catch (IOException e) {
throw new UncheckedIOException(e);
} finally {
if (null != reader) {
try {
reader.close();
} catch (Exception e) {
// 静默关闭
}
}
}
}
private void checkFile() {
if (file == null) {
throw new UncheckedIOException(new IOException("File to write content is null !"));
}
if (this.file.exists() && !file.isFile()) {
throw new UncheckedIOException(
new IOException("File [" + this.file.getAbsoluteFile() + "] is not a file !"));
}
}
}

View File

@ -0,0 +1,145 @@
package io.github.linpeilie.processor.utils;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class FileUtils {
public static <T> File writeUtf8Lines(Collection<T> list, File file) {
return writeLines(list, file, StandardCharsets.UTF_8);
}
public static <T> File writeLines(Collection<T> list, File file, Charset charset) {
return writeLines(list, file, charset, false);
}
public static <T> File writeLines(Collection<T> list, File file, Charset charset, boolean isAppend) {
return FileWriter.create(file, charset).writeLines(list, isAppend);
}
public static List<String> readUtf8Lines(File file) {
return readLines(file, StandardCharsets.UTF_8);
}
public static List<String> readLines(File file, Charset charset) {
return readLines(file, charset, new ArrayList<>());
}
public static <T extends Collection<String>> T readLines(File file, Charset charset, T collection) {
return FileReader.create(file, charset).readLines(collection);
}
public static BufferedInputStream getInputStream(File file) throws IOException {
return new BufferedInputStream(Files.newInputStream(file.toPath()));
}
public static BufferedReader getReader(File file, Charset charset) throws IOException {
BufferedInputStream in = getInputStream(file);
InputStreamReader reader;
if (null == charset) {
reader = new InputStreamReader(in);
} else {
reader = new InputStreamReader(in, charset);
}
return new BufferedReader(reader);
}
public static File mkParentDirs(File file) {
if (null == file) {
return null;
}
return mkdir(getParent(file, 1));
}
public static File getParent(File file, int level) {
if (level < 1 || null == file) {
return file;
}
File parentFile;
try {
parentFile = file.getCanonicalFile().getParentFile();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (1 == level) {
return parentFile;
}
return getParent(parentFile, level - 1);
}
public static File mkdir(File dir) {
if (dir == null) {
return null;
}
if (false == dir.exists()) {
mkdirsSafely(dir, 5, 1);
}
return dir;
}
public static boolean mkdirsSafely(File dir, int tryCount, long sleepMillis) {
if (dir == null) {
return false;
}
if (dir.isDirectory()) {
return true;
}
for (int i = 1; i <= tryCount; i++) { // 高并发场景下可以看到 i 处于 1 ~ 3 之间
// 如果文件已存在也会返回 false所以该值不能作为是否能创建的依据因此不对其进行处理
//noinspection ResultOfMethodCallIgnored
dir.mkdirs();
if (dir.exists()) {
return true;
}
ThreadUtils.sleep(sleepMillis);
}
return dir.exists();
}
public static File touch(File file) {
if (null == file) {
return null;
}
if (false == file.exists()) {
mkParentDirs(file);
try {
//noinspection ResultOfMethodCallIgnored
file.createNewFile();
} catch (Exception e) {
throw new UncheckedIOException(new IOException(e));
}
}
return file;
}
public static boolean isNotEmpty(File file) {
return !isEmpty(file);
}
public static boolean isEmpty(File file) {
if (null == file || !file.exists()) {
return true;
}
if (file.isDirectory()) {
String[] subFiles = file.list();
return subFiles == null || subFiles.length == 0;
} else if (file.isFile()) {
return file.length() <= 0;
}
return false;
}
}

View File

@ -0,0 +1,68 @@
package io.github.linpeilie.processor.utils;
import java.io.File;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* 文件包装器扩展文件对象
*
* @author Looly
*
*/
public class FileWrapper implements Serializable {
private static final long serialVersionUID = 1L;
protected File file;
protected Charset charset;
/** 默认编码UTF-8 */
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
// ------------------------------------------------------- Constructor start
public FileWrapper(File file, Charset charset) {
this.file = file;
this.charset = charset;
}
// ------------------------------------------------------- Constructor end
// ------------------------------------------------------- Setters and Getters start start
/**
* 获得文件
* @return 文件
*/
public File getFile() {
return file;
}
/**
* 设置文件
* @param file 文件
* @return 自身
*/
public FileWrapper setFile(File file) {
this.file = file;
return this;
}
/**
* 获得字符集编码
* @return 编码
*/
public Charset getCharset() {
return charset;
}
/**
* 设置字符集编码
* @param charset 编码
* @return 自身
*/
public FileWrapper setCharset(Charset charset) {
this.charset = charset;
return this;
}
// ------------------------------------------------------- Setters and Getters start end
}

View File

@ -0,0 +1,89 @@
package io.github.linpeilie.processor.utils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
public class FileWriter extends FileWrapper {
private static final long serialVersionUID = 1L;
public static FileWriter create(File file, Charset charset) {
return new FileWriter(file, charset);
}
// ------------------------------------------------------- Constructor start
public FileWriter(File file, Charset charset) {
super(file, charset);
checkFile();
}
// ------------------------------------------------------- Constructor end
public <T> File writeLines(Iterable<T> list, boolean isAppend) {
return writeLines(list, null, isAppend);
}
public BufferedWriter getWriter(boolean isAppend) {
try {
return new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(FileUtils.touch(file), isAppend), charset));
} catch (Exception e) {
throw new UncheckedIOException(new IOException(e));
}
}
public PrintWriter getPrintWriter(boolean isAppend) {
return new PrintWriter(getWriter(isAppend));
}
public <T> File writeLines(Iterable<T> list, LineSeparator lineSeparator, boolean isAppend) {
try (PrintWriter writer = getPrintWriter(isAppend)) {
boolean isFirst = true;
for (T t : list) {
if (null != t) {
if (isFirst) {
isFirst = false;
if (isAppend && FileUtils.isNotEmpty(this.file)) {
// 追加模式下且文件非空补充换行符
printNewLine(writer, lineSeparator);
}
} else {
printNewLine(writer, lineSeparator);
}
writer.print(t);
writer.flush();
}
}
}
return this.file;
}
private void printNewLine(PrintWriter writer, LineSeparator lineSeparator) {
if (null == lineSeparator) {
//默认换行符
writer.println();
} else {
//自定义换行符
writer.print(lineSeparator.getValue());
}
}
private void checkFile() {
if (file == null) {
throw new UncheckedIOException(new IOException("File to write content is null !"));
}
if (this.file.exists() && !file.isFile()) {
throw new UncheckedIOException(
new IOException("File [" + this.file.getAbsoluteFile() + "] is not a file !"));
}
}
}

View File

@ -0,0 +1,20 @@
package io.github.linpeilie.processor.utils;
public enum LineSeparator {
/** Mac系统换行符"\r" */
MAC("\r"),
/** Linux系统换行符"\n" */
LINUX("\n"),
/** Windows系统换行符"\r\n" */
WINDOWS("\r\n");
private final String value;
LineSeparator(String lineSeparator) {
this.value = lineSeparator;
}
public String getValue() {
return this.value;
}
}

View File

@ -0,0 +1,9 @@
package io.github.linpeilie.processor.utils;
public class ObjectUtils {
public static <T> T defaultIfNull(final T object, final T defaultValue) {
return object != null ? object : defaultValue;
}
}

View File

@ -0,0 +1,14 @@
package io.github.linpeilie.processor.utils;
public class ThreadUtils {
public static boolean sleep(long millis) {
if (millis > 0) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
return false;
}
}
return true;
}
}

View File

@ -24,8 +24,8 @@
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-object-convert</artifactId>
</dependency>
</dependencies>

View File

@ -1,6 +1,5 @@
package io.github.linpeilie;
import cn.hutool.core.collection.CollectionUtil;
import io.github.linpeilie.annotations.DoIgnore;
import java.util.List;
import java.util.stream.Collectors;

View File

@ -1,9 +1,8 @@
package io.github.linpeilie;
import cn.hutool.core.collection.CollectionUtil;
import io.github.linpeilie.annotations.DoIgnore;
import io.github.linpeilie.utils.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.mapstruct.MappingTarget;
@ -18,7 +17,7 @@ public interface BaseMapper<S, T> {
@DoIgnore
default List<T> convert(List<S> sourceList) {
if (CollectionUtil.isEmpty(sourceList)) {
if (CollectionUtils.isEmpty(sourceList)) {
return new ArrayList<>();
}
return sourceList.stream().map(this::convert).collect(Collectors.toList());

View File

@ -0,0 +1,41 @@
package io.github.linpeilie.utils;
public class CharUtils {
/**
* 是否空白符<br>
* 空白符包括空格制表符全角空格和不间断空格<br>
*
* @param c 字符
* @return 是否空白符
* @see Character#isWhitespace(int)
* @see Character#isSpaceChar(int)
* @since 4.0.10
*/
public static boolean isBlankChar(char c) {
return isBlankChar((int) c);
}
/**
* 是否空白符<br>
* 空白符包括空格制表符全角空格和不间断空格<br>
*
* @param c 字符
* @return 是否空白符
* @see Character#isWhitespace(int)
* @see Character#isSpaceChar(int)
* @since 4.0.10
*/
public static boolean isBlankChar(int c) {
return Character.isWhitespace(c)
|| Character.isSpaceChar(c)
|| c == '\ufeff'
|| c == '\u202a'
|| c == '\u0000'
// issue#I5UGSQHangul Filler
|| c == '\u3164'
// Braille Pattern Blank
|| c == '\u2800'
// MONGOLIAN VOWEL SEPARATOR
|| c == '\u180e';
}
}

View File

@ -0,0 +1,29 @@
package io.github.linpeilie.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class CollectionUtils {
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
}
public static <T> List<T> newArrayList(T... values) {
if (values == null || values.length == 0) {
return new ArrayList<>();
}
List<T> arrayList = new ArrayList<>(values.length);
Collections.addAll(arrayList, values);
return arrayList;
}
}

View File

@ -0,0 +1,86 @@
package io.github.linpeilie.utils;
public class StrUtil {
/**
* 去掉首部指定长度的字符串并将剩余字符串首字母小写<br> 例如str=setName, preLength=3 = return name
*
* @param str 被处理的字符串
* @param preLength 去掉的长度
* @return 处理后的字符串不符合规范返回null
*/
public static String removePreAndLowerFirst(CharSequence str, int preLength) {
if (str == null) {
return null;
}
if (str.length() > preLength) {
char first = Character.toLowerCase(str.charAt(preLength));
if (str.length() > preLength + 1) {
return first + str.toString().substring(preLength + 1);
}
return String.valueOf(first);
} else {
return str.toString();
}
}
/**
* 获得set或get或is方法对应的标准属性名<br> 例如setName 返回 name
*
* <pre>
* getName =name
* setName =name
* isName =name
* </pre>
*
* @param getOrSetMethodName Get或Set方法名
* @return 如果是set或get方法名返回field 否则null
*/
public static String getGeneralField(CharSequence getOrSetMethodName) {
final String getOrSetMethodNameStr = getOrSetMethodName.toString();
if (getOrSetMethodNameStr.startsWith("get") || getOrSetMethodNameStr.startsWith("set")) {
return removePreAndLowerFirst(getOrSetMethodName, 3);
} else if (getOrSetMethodNameStr.startsWith("is")) {
return removePreAndLowerFirst(getOrSetMethodName, 2);
}
return null;
}
public static boolean isEmpty(CharSequence cs) {
return cs == null || cs.length() == 0;
}
public static boolean isNotEmpty(CharSequence cs) {
return !isEmpty(cs);
}
public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
if (null == str1) {
// 只有两个都为null才判断相等
return str2 == null;
}
if (null == str2) {
// 字符串2空字符串1非空直接false
return false;
}
return str1.toString().equalsIgnoreCase(str2.toString());
}
public static boolean isBlank(CharSequence str) {
final int length;
if ((str == null) || ((length = str.length()) == 0)) {
return true;
}
for (int i = 0; i < length; i++) {
// 只要有一个非空字符即为非空字符串
if (false == CharUtils.isBlankChar(str.charAt(i))) {
return false;
}
}
return true;
}
}

13
pom.xml
View File

@ -14,6 +14,7 @@
<module>mapstruct-plus</module>
<module>mapstruct-plus-spring-boot-starter</module>
<module>mapstruct-plus-processor</module>
<module>mapstruct-plus-object-convert</module>
</modules>
<properties>
@ -22,12 +23,17 @@
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mapstruct.version>1.5.5.Final</mapstruct.version>
<hutool.version>5.8.15</hutool.version>
<hutool.version>5.8.26</hutool.version>
<projectUrl>https://github.com/linpeilie/mapstruct-plus.git</projectUrl>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-object-convert</artifactId>
<version>${mapstruct-plus.version}</version>
</dependency>
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus</artifactId>
@ -43,11 +49,6 @@
<artifactId>javapoet</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>