From 683612dcf437ccbb0189c25e0f0ee2f1c948dca3 Mon Sep 17 00:00:00 2001 From: Shihyu Date: Wed, 20 Dec 2023 15:01:51 +0800 Subject: [PATCH 1/3] style: switch formatter (#72) --- .editorconfig | 10 +- Makefile | 2 +- ide-config/eclipse-format.xml | 321 ------------------ ide-config/eclipse.importorder | 4 - mapper/pom.xml | 14 +- .../com/softleader/data/jpa/spec/ASTNode.java | 31 +- .../softleader/data/jpa/spec/Databind.java | 13 +- .../spec/JoinFetchSpecificationResolver.java | 27 +- .../jpa/spec/JoinSpecificationResolver.java | 48 ++- .../jpa/spec/NestedSpecificationResolver.java | 45 +-- .../data/jpa/spec/ReflectionDatabind.java | 23 +- .../jpa/spec/SimpleSpecificationResolver.java | 42 +-- .../data/jpa/spec/SkippingStrategy.java | 3 +- .../com/softleader/data/jpa/spec/SpecAST.java | 1 - .../softleader/data/jpa/spec/SpecCodec.java | 18 +- .../softleader/data/jpa/spec/SpecContext.java | 4 +- .../data/jpa/spec/SpecJoinContext.java | 12 +- .../softleader/data/jpa/spec/SpecMapper.java | 56 +-- .../data/jpa/spec/SpecificationResolver.java | 5 +- .../data/jpa/spec/annotation/And.java | 5 +- .../data/jpa/spec/annotation/Join.java | 19 +- .../data/jpa/spec/annotation/JoinFetch.java | 7 +- .../data/jpa/spec/annotation/NestedSpec.java | 6 +- .../data/jpa/spec/annotation/Or.java | 5 +- .../data/jpa/spec/annotation/Spec.java | 10 +- .../data/jpa/spec/domain/After.java | 3 +- .../softleader/data/jpa/spec/domain/And.java | 7 +- .../data/jpa/spec/domain/Before.java | 3 +- .../data/jpa/spec/domain/Between.java | 11 +- .../jpa/spec/domain/BooleanSpecification.java | 4 +- .../spec/domain/ComparableSpecification.java | 6 +- .../spec/domain/CompoundSpecification.java | 19 +- .../data/jpa/spec/domain/Conjunction.java | 7 +- .../data/jpa/spec/domain/Disjunction.java | 7 +- .../data/jpa/spec/domain/EndingWith.java | 3 +- .../data/jpa/spec/domain/Equals.java | 4 +- .../data/jpa/spec/domain/False.java | 4 +- .../jpa/spec/domain/GreaterThanEqual.java | 3 +- .../data/jpa/spec/domain/HasLength.java | 11 +- .../data/jpa/spec/domain/HasText.java | 11 +- .../softleader/data/jpa/spec/domain/In.java | 4 +- .../data/jpa/spec/domain/IsNull.java | 4 +- .../softleader/data/jpa/spec/domain/Join.java | 27 +- .../data/jpa/spec/domain/JoinContext.java | 5 +- .../data/jpa/spec/domain/JoinFetch.java | 11 +- .../softleader/data/jpa/spec/domain/Like.java | 3 +- .../softleader/data/jpa/spec/domain/Not.java | 12 +- .../data/jpa/spec/domain/NotEquals.java | 4 +- .../data/jpa/spec/domain/NotLike.java | 3 +- .../data/jpa/spec/domain/NotNull.java | 4 +- .../softleader/data/jpa/spec/domain/Or.java | 7 +- .../jpa/spec/domain/SimpleSpecification.java | 18 +- .../data/jpa/spec/domain/StartingWith.java | 3 +- .../softleader/data/jpa/spec/domain/True.java | 4 +- .../spec/domain/TypeMismatchException.java | 35 +- .../data/jpa/spec/ArchitectureCheckTest.java | 70 ++-- .../data/jpa/spec/CustomizeResolverTest.java | 137 ++++---- .../jpa/spec/CustomizeSimpleSpecTest.java | 87 +++-- .../data/jpa/spec/IntegrationTest.java | 2 - .../spec/JoinFetchElementCollectionTest.java | 133 ++++---- .../JoinFetchSpecificationResolverTest.java | 108 +++--- .../spec/JoinSpecificationResolverTest.java | 120 ++++--- .../spec/NestedSpecificationResolverTest.java | 274 +++++++-------- .../data/jpa/spec/ReflectionDatabindTest.java | 38 +-- .../spec/SimpleSpecificationResolverTest.java | 206 ++++++----- .../data/jpa/spec/domain/AfterTest.java | 5 +- .../data/jpa/spec/domain/BeforeTest.java | 5 +- .../data/jpa/spec/domain/BetweenTest.java | 12 +- .../data/jpa/spec/domain/EndingWithTest.java | 4 +- .../data/jpa/spec/domain/EqualsTest.java | 4 +- .../data/jpa/spec/domain/FalseTest.java | 4 +- .../jpa/spec/domain/GreaterThanEqualTest.java | 5 +- .../data/jpa/spec/domain/GreaterThanTest.java | 5 +- .../data/jpa/spec/domain/HasLengthTest.java | 5 +- .../data/jpa/spec/domain/HasTextTest.java | 5 +- .../data/jpa/spec/domain/InTest.java | 5 +- .../data/jpa/spec/domain/IsNullTest.java | 5 +- .../jpa/spec/domain/LessThanEqualTest.java | 5 +- .../data/jpa/spec/domain/LessThanTest.java | 5 +- .../data/jpa/spec/domain/LikeTest.java | 4 +- .../data/jpa/spec/domain/NotEqualsTest.java | 4 +- .../data/jpa/spec/domain/NotInTest.java | 5 +- .../data/jpa/spec/domain/NotLikeTest.java | 4 +- .../data/jpa/spec/domain/NotNullTest.java | 5 +- .../jpa/spec/domain/StartingWithTest.java | 4 +- .../data/jpa/spec/domain/TrueTest.java | 4 +- .../ConstructSimpleSpecificationTest.java | 89 +++-- .../data/jpa/spec/usecase/Badge.java | 4 +- .../data/jpa/spec/usecase/Customer.java | 31 +- .../jpa/spec/usecase/CustomerRepository.java | 6 +- .../data/jpa/spec/usecase/Gender.java | 2 - .../data/jpa/spec/usecase/Order.java | 7 +- .../data/jpa/spec/usecase/School.java | 4 +- .../softleader/data/jpa/spec/usecase/Tag.java | 4 +- pom.xml | 49 +-- starter/pom.xml | 14 +- .../SpecificationResolverCodecBuilder.java | 6 +- .../SpecMapperAutoConfiguration.java | 29 +- .../autoconfigure/SpecMapperProperties.java | 10 +- .../spec/repository/QueryBySpecExecutor.java | 17 +- ...JpaRepositoryFactoryBeanPostProcessor.java | 4 +- .../support/QueryBySpecExecutorAdapter.java | 11 +- .../support/QueryBySpecExecutorImpl.java | 15 +- .../SpecificationResolverBuilderTest.java | 8 +- ...SpecificationResolverCodecBuilderTest.java | 8 +- .../repository/CustomizeResolverTest.java | 56 ++- .../CustomizeSkippingStrategyTest.java | 4 +- .../EnsureAllMethodsAreConsidered.java | 15 +- .../repository/QueryBySpecExecutorTest.java | 17 +- .../jpa/spec/repository/usecase/Customer.java | 4 +- .../usecase/CustomerRepository.java | 5 +- 111 files changed, 1066 insertions(+), 1610 deletions(-) delete mode 100644 ide-config/eclipse-format.xml delete mode 100644 ide-config/eclipse.importorder diff --git a/.editorconfig b/.editorconfig index ce72760..770ff7f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,4 @@ +# Editor configuration, see http://editorconfig.org root = true [*] @@ -9,8 +10,15 @@ insert_final_newline = true trim_trailing_whitespace = true [*.md] +max_line_length = off trim_trailing_whitespace = false +[*.{properties,yml,yaml}] +trim_trailing_whitespace = false + +[*.mustache] +insert_final_newline = false + [Makefile] indent_style = tab -intent_size = 4 +indent_size = 4 diff --git a/Makefile b/Makefile index 79393df..04c4646 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ help: ## Display this help. ##@ Develop format: ## Format the source code. - mvn process-sources -e + mvn validate -e clean: ## Remove files generated at build-time. mvn clean -e diff --git a/ide-config/eclipse-format.xml b/ide-config/eclipse-format.xml deleted file mode 100644 index 1743cd5..0000000 --- a/ide-config/eclipse-format.xml +++ /dev/null @@ -1,321 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ide-config/eclipse.importorder b/ide-config/eclipse.importorder deleted file mode 100644 index d14eade..0000000 --- a/ide-config/eclipse.importorder +++ /dev/null @@ -1,4 +0,0 @@ -0=java -1=javax -2=org -3=com diff --git a/mapper/pom.xml b/mapper/pom.xml index 2c522b9..be294d8 100644 --- a/mapper/pom.xml +++ b/mapper/pom.xml @@ -1,13 +1,11 @@ - + + 4.0.0 tw.com.softleader.data.jakarta specification-mapper-parent 3.0.2 - 4.0.0 specification-mapper specification-mapper @@ -74,12 +72,8 @@ - net.revelc.code.formatter - formatter-maven-plugin - - - net.revelc.code - impsort-maven-plugin + com.diffplug.spotless + spotless-maven-plugin org.apache.maven.plugins diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ASTNode.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ASTNode.java index 73f52a5..c3aa61a 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ASTNode.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ASTNode.java @@ -20,30 +20,33 @@ */ package tw.com.softleader.data.jpa.spec; +import lombok.NonNull; import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.Nullable; -import lombok.NonNull; - /** * @author Matt Ho */ public interface ASTNode { default void preVisit(@NonNull SpecInvocation node) { - node.getAst().add(node.getDepth(), "| +-[%s.%s]: %s (%s)", - node.getTargetType().getSimpleName(), - node.getFieldName(), - node.getFieldType().getName(), - node.getResolverType().getSimpleName()); + node.getAst() + .add( + node.getDepth(), + "| +-[%s.%s]: %s (%s)", + node.getTargetType().getSimpleName(), + node.getFieldName(), + node.getFieldType().getName(), + node.getResolverType().getSimpleName()); } - default void postVisit( - @NonNull SpecInvocation node, - @Nullable Specification resolved) { - node.getAst().add(node.getDepth(), "| \\-[%s.%s]: %s", - node.getTargetType().getSimpleName(), - node.getFieldName(), - resolved); + default void postVisit(@NonNull SpecInvocation node, @Nullable Specification resolved) { + node.getAst() + .add( + node.getDepth(), + "| \\-[%s.%s]: %s", + node.getTargetType().getSimpleName(), + node.getFieldName(), + resolved); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/Databind.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/Databind.java index 162f8e8..5f9f31f 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/Databind.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/Databind.java @@ -22,7 +22,6 @@ import java.lang.reflect.Field; import java.util.Optional; - import org.springframework.lang.NonNull; /** @@ -32,20 +31,14 @@ */ public interface Databind { - /** - * 欄位所在的物件 - */ + /** 欄位所在的物件 */ @NonNull Object getTarget(); - /** - * 欄位 - */ + /** 欄位 */ @NonNull Field getField(); - /** - * 欄位值 - */ + /** 欄位值 */ Optional getFieldValue(); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolver.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolver.java index eca9624..50c478a 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolver.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolver.java @@ -25,11 +25,9 @@ import java.util.Objects; import java.util.stream.Stream; - +import lombok.extern.slf4j.Slf4j; import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.NonNull; - -import lombok.extern.slf4j.Slf4j; import tw.com.softleader.data.jpa.spec.annotation.JoinFetch; import tw.com.softleader.data.jpa.spec.annotation.JoinFetch.JoinFetches; import tw.com.softleader.data.jpa.spec.domain.Conjunction; @@ -48,19 +46,18 @@ public boolean supports(@NonNull Databind databind) { } @Override - public Specification buildSpecification(@NonNull Context context, - @NonNull Databind databind) { + public Specification buildSpecification( + @NonNull Context context, @NonNull Databind databind) { var handled = handledKey(databind); if (context.containsKey(handled)) { log.trace("Already handled [{}], skipping", handled); return null; } try { - var specs = Stream.concat( - joinFetchDef(databind.getTarget()), - joinFetchesDef(databind.getTarget())) - .filter(Objects::nonNull) - .collect(toList()); + var specs = + Stream.concat(joinFetchDef(databind.getTarget()), joinFetchesDef(databind.getTarget())) + .filter(Objects::nonNull) + .collect(toList()); if (specs.size() == 1) { return specs.get(0); } @@ -74,8 +71,7 @@ private Stream> joinFetchesDef(Object obj) { if (!obj.getClass().isAnnotationPresent(JoinFetches.class)) { return Stream.empty(); } - return stream(obj.getClass().getAnnotation(JoinFetches.class).value()) - .map(this::newJoinFetch); + return stream(obj.getClass().getAnnotation(JoinFetches.class).value()).map(this::newJoinFetch); } private Stream> joinFetchDef(Object obj) { @@ -87,13 +83,12 @@ private Stream> joinFetchDef(Object obj) { Specification newJoinFetch(@NonNull JoinFetch def) { return new tw.com.softleader.data.jpa.spec.domain.JoinFetch<>( - def.paths(), - def.joinType(), - def.distinct()); + def.paths(), def.joinType(), def.distinct()); } private String handledKey(Databind databind) { - return String.join("/", + return String.join( + "/", JoinFetchSpecificationResolver.class.getName(), databind.getField().getDeclaringClass().getName(), "" + databind.getTarget().hashCode()); diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolver.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolver.java index 3928fb8..e2563cb 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolver.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolver.java @@ -26,11 +26,9 @@ import java.lang.reflect.Field; import java.util.Objects; import java.util.stream.Stream; - +import lombok.extern.slf4j.Slf4j; import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.NonNull; - -import lombok.extern.slf4j.Slf4j; import tw.com.softleader.data.jpa.spec.annotation.Join; import tw.com.softleader.data.jpa.spec.annotation.Join.Joins; import tw.com.softleader.data.jpa.spec.domain.Conjunction; @@ -49,45 +47,43 @@ public boolean supports(@NonNull Databind databind) { } @Override - public Specification buildSpecification(@NonNull Context context, - @NonNull Databind databind) { - return databind.getFieldValue() - .map(value -> { - var specs = Stream.concat( - joinDef(context, databind.getField()), - joinsDef(context, databind.getField())) - .filter(Objects::nonNull) - .collect(toList()); - if (specs.size() == 1) { - return specs.get(0); - } - return new Conjunction<>(specs); - }).orElse(null); + public Specification buildSpecification( + @NonNull Context context, @NonNull Databind databind) { + return databind + .getFieldValue() + .map( + value -> { + var specs = + Stream.concat( + joinDef(context, databind.getField()), + joinsDef(context, databind.getField())) + .filter(Objects::nonNull) + .collect(toList()); + if (specs.size() == 1) { + return specs.get(0); + } + return new Conjunction<>(specs); + }) + .orElse(null); } private Stream> joinsDef(Context context, Field field) { if (!field.isAnnotationPresent(Joins.class)) { return Stream.empty(); } - return stream(field.getAnnotation(Joins.class).value()) - .map(def -> newJoin(context, def)); + return stream(field.getAnnotation(Joins.class).value()).map(def -> newJoin(context, def)); } private Stream> joinDef(Context context, Field field) { if (!field.isAnnotationPresent(Join.class)) { return Stream.empty(); } - return Stream.of( - newJoin(context, field.getAnnotation(Join.class))); + return Stream.of(newJoin(context, field.getAnnotation(Join.class))); } Specification newJoin(@NonNull Context context, @NonNull Join def) { return new tw.com.softleader.data.jpa.spec.domain.Join<>( - context, - def.path(), - def.alias(), - def.joinType(), - def.distinct()); + context, def.path(), def.alias(), def.joinType(), def.distinct()); } @Override diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolver.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolver.java index a6dae76..84dff9c 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolver.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolver.java @@ -22,11 +22,10 @@ import static tw.com.softleader.data.jpa.spec.AST.CTX_DEPTH; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.lang.NonNull; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.lang.NonNull; import tw.com.softleader.data.jpa.spec.annotation.And; import tw.com.softleader.data.jpa.spec.annotation.NestedSpec; import tw.com.softleader.data.jpa.spec.annotation.Or; @@ -47,25 +46,27 @@ public boolean supports(@NonNull Databind databind) { } @Override - public Specification buildSpecification(@NonNull Context context, - @NonNull Databind databind) { - return databind.getFieldValue() - .map(nested -> { - var depth = (int) context.get(CTX_DEPTH).get(); - context.put(CTX_DEPTH, depth + 1); - var spec = codec.toSpec(context, nested); - if (spec == null) { - return null; - } - var field = databind.getField(); - if (field.isAnnotationPresent(And.class)) { - return new tw.com.softleader.data.jpa.spec.domain.And<>(spec); - } - if (field.isAnnotationPresent(Or.class)) { - return new tw.com.softleader.data.jpa.spec.domain.Or<>(spec); - } - return spec; - }) + public Specification buildSpecification( + @NonNull Context context, @NonNull Databind databind) { + return databind + .getFieldValue() + .map( + nested -> { + var depth = (int) context.get(CTX_DEPTH).get(); + context.put(CTX_DEPTH, depth + 1); + var spec = codec.toSpec(context, nested); + if (spec == null) { + return null; + } + var field = databind.getField(); + if (field.isAnnotationPresent(And.class)) { + return new tw.com.softleader.data.jpa.spec.domain.And<>(spec); + } + if (field.isAnnotationPresent(Or.class)) { + return new tw.com.softleader.data.jpa.spec.domain.Or<>(spec); + } + return spec; + }) .orElse(null); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ReflectionDatabind.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ReflectionDatabind.java index fd3f62f..d676795 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ReflectionDatabind.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/ReflectionDatabind.java @@ -23,7 +23,6 @@ import static java.util.Collections.unmodifiableList; import static java.util.Optional.ofNullable; import static java.util.function.Predicate.not; - import static org.springframework.util.ReflectionUtils.doWithLocalFields; import static org.springframework.util.ReflectionUtils.makeAccessible; @@ -33,13 +32,11 @@ import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; - -import org.springframework.util.ReflectionUtils; - import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import org.springframework.util.ReflectionUtils; /** * Databind implementation using Spring's {@code ReflectionUtils} @@ -49,16 +46,11 @@ @RequiredArgsConstructor class ReflectionDatabind implements Databind { - @Getter - @NonNull - private final Object target; + @Getter @NonNull private final Object target; - @Getter - @NonNull - private final Field field; + @Getter @NonNull private final Field field; - @NonNull - private final SkippingStrategy skippingStrategy; + @NonNull private final SkippingStrategy skippingStrategy; private final AtomicBoolean loaded = new AtomicBoolean(); private final CountDownLatch latch = new CountDownLatch(1); @@ -68,12 +60,13 @@ static List of(@NonNull Object target, @NonNull SkippingStrategy skipp return of(target, skippingStrategy, ReflectionDatabind::new); } - static List of(@NonNull Object target, + static List of( + @NonNull Object target, @NonNull SkippingStrategy skippingStrategy, @NonNull ReflectionDatabindFactory factory) { var lookup = new ArrayList(); - doWithLocalFields(target.getClass(), - field -> lookup.add(factory.apply(target, field, skippingStrategy))); + doWithLocalFields( + target.getClass(), field -> lookup.add(factory.apply(target, field, skippingStrategy))); return unmodifiableList(lookup); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolver.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolver.java index 088303f..9f94cea 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolver.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolver.java @@ -21,15 +21,13 @@ package tw.com.softleader.data.jpa.spec; import static java.util.Optional.of; - import static tw.com.softleader.data.jpa.spec.AST.CTX_AST; import static tw.com.softleader.data.jpa.spec.AST.CTX_DEPTH; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.NonNull; import org.springframework.util.StringUtils; - -import lombok.extern.slf4j.Slf4j; import tw.com.softleader.data.jpa.spec.annotation.And; import tw.com.softleader.data.jpa.spec.annotation.Or; import tw.com.softleader.data.jpa.spec.annotation.Spec; @@ -49,15 +47,19 @@ public boolean supports(@NonNull Databind databind) { } @Override - public Specification buildSpecification(@NonNull Context context, - @NonNull Databind databind) { + public Specification buildSpecification( + @NonNull Context context, @NonNull Databind databind) { var def = databind.getField().getAnnotation(Spec.class); var ast = context.get(CTX_AST).map(AST.class::cast).get(); var depth = (int) context.get(CTX_DEPTH).get(); - var built = databind.getFieldValue() - .map(value -> buildSpecification(context, databind, def, value)) - .orElse(null); - ast.add(depth, "| +-[%s.%s]: @Spec(value=%s, path=%s, not=%s) -> %s", + var built = + databind + .getFieldValue() + .map(value -> buildSpecification(context, databind, def, value)) + .orElse(null); + ast.add( + depth, + "| +-[%s.%s]: @Spec(value=%s, path=%s, not=%s) -> %s", databind.getTarget().getClass().getSimpleName(), databind.getField().getName(), def.value().getSimpleName(), @@ -67,18 +69,16 @@ public Specification buildSpecification(@NonNull Context context, return built; } - private Specification buildSpecification(@NonNull Context context, - @NonNull Databind databind, @NonNull Spec def, - Object value) { - var path = of(def.path()) - .filter(StringUtils::hasText) - .orElseGet(databind.getField()::getName); - Specification spec = SimpleSpecification.builder() - .context(context) - .domainClass(def.value()) - .path(path) - .value(value) - .build(); + private Specification buildSpecification( + @NonNull Context context, @NonNull Databind databind, @NonNull Spec def, Object value) { + var path = of(def.path()).filter(StringUtils::hasText).orElseGet(databind.getField()::getName); + Specification spec = + SimpleSpecification.builder() + .context(context) + .domainClass(def.value()) + .path(path) + .value(value) + .build(); if (def.not()) { spec = new Not<>(spec); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SkippingStrategy.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SkippingStrategy.java index d58e553..aee4e0c 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SkippingStrategy.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SkippingStrategy.java @@ -32,7 +32,8 @@ public interface SkippingStrategy { /** * This method is used to determine whether a given field value should be skipped. * - * @param fieldValue The field value to be checked. It can be an object of any type, and even null. + * @param fieldValue The field value to be checked. It can be an object of any type, and even + * null. * @return True if the field value should be skipped, false otherwise. */ boolean shouldSkip(@Nullable Object fieldValue); diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecAST.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecAST.java index ac69793..35075b7 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecAST.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecAST.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.List; - import lombok.NonNull; /** diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecCodec.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecCodec.java index 9b7a01d..885a892 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecCodec.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecCodec.java @@ -23,11 +23,9 @@ import static java.util.Optional.ofNullable; import java.util.Optional; - import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; - import tw.com.softleader.data.jpa.spec.domain.Context; /** @@ -63,8 +61,8 @@ default Optional> trySpec(@Nullable Object rootObject) { * @return empty if non any {@code Specification} was mapped */ @NonNull - default Optional> trySpec(@Nullable T rootObject, - @Nullable Class rootType) { + default Optional> trySpec( + @Nullable T rootObject, @Nullable Class rootType) { return ofNullable(toSpec(rootObject, rootType)); } @@ -72,8 +70,8 @@ default Optional> trySpec(@Nullable T rootObject, * @return empty if non any {@code Specification} was mapped */ @NonNull - default Optional> trySpec(@NonNull Context context, - @Nullable Object rootObject) { + default Optional> trySpec( + @NonNull Context context, @Nullable Object rootObject) { return ofNullable(toSpec(context, rootObject)); } @@ -81,8 +79,8 @@ default Optional> trySpec(@NonNull Context context, * @return empty if non any {@code Specification} was mapped */ @NonNull - default Optional> trySpec(@NonNull Context context, @Nullable T rootObject, - @Nullable Class rootType) { + default Optional> trySpec( + @NonNull Context context, @Nullable T rootObject, @Nullable Class rootType) { return ofNullable(toSpec(context, rootObject, rootType)); } @@ -97,8 +95,8 @@ default Optional> trySpec(@NonNull Context context, @Nullab */ @Nullable @SuppressWarnings("unchecked") - default Specification toSpec(@NonNull Context context, @Nullable Object rootObject, - @Nullable Class rootType) { + default Specification toSpec( + @NonNull Context context, @Nullable Object rootObject, @Nullable Class rootType) { return (Specification) toSpec(context, rootObject); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecContext.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecContext.java index b8f2814..86020e9 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecContext.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecContext.java @@ -26,10 +26,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; - -import org.springframework.lang.Nullable; - import lombok.NonNull; +import org.springframework.lang.Nullable; import tw.com.softleader.data.jpa.spec.domain.Context; import tw.com.softleader.data.jpa.spec.domain.JoinContext; diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecJoinContext.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecJoinContext.java index af9c368..013ac7f 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecJoinContext.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecJoinContext.java @@ -22,15 +22,13 @@ import static java.util.Collections.synchronizedMap; +import jakarta.persistence.criteria.Join; +import jakarta.persistence.criteria.Root; import java.util.HashMap; import java.util.Map; import java.util.function.Function; - -import org.springframework.data.util.Pair; - -import jakarta.persistence.criteria.Join; -import jakarta.persistence.criteria.Root; import lombok.Synchronized; +import org.springframework.data.util.Pair; import tw.com.softleader.data.jpa.spec.domain.JoinContext; /** @@ -39,8 +37,8 @@ class SpecJoinContext implements JoinContext { private final Map>, Join> joins = synchronizedMap(new HashMap<>()); - private final Map, Join>> lazyJoins = synchronizedMap( - new HashMap<>()); + private final Map, Join>> lazyJoins = + synchronizedMap(new HashMap<>()); @Override @Synchronized diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecMapper.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecMapper.java index bfcb231..5cb3989 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecMapper.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecMapper.java @@ -21,7 +21,6 @@ package tw.com.softleader.data.jpa.spec; import static java.util.stream.Collectors.toList; - import static lombok.AccessLevel.PACKAGE; import static tw.com.softleader.data.jpa.spec.AST.CTX_AST; import static tw.com.softleader.data.jpa.spec.AST.CTX_DEPTH; @@ -34,14 +33,12 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; - -import org.springframework.data.jpa.domain.Specification; -import org.springframework.lang.Nullable; - import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.lang.Nullable; import tw.com.softleader.data.jpa.spec.annotation.Or; import tw.com.softleader.data.jpa.spec.domain.Conjunction; import tw.com.softleader.data.jpa.spec.domain.Context; @@ -54,8 +51,7 @@ @RequiredArgsConstructor(access = PACKAGE) public class SpecMapper implements SpecCodec { - @NonNull - private final SkippingStrategy skippingStrategy; + @NonNull private final SkippingStrategy skippingStrategy; private Collection resolvers; // Order matters public static SpecMapperBuilder builder() { @@ -72,13 +68,13 @@ public Specification toSpec(Object rootObject) { var depth = 0; context.put(CTX_AST, ast); context.put(CTX_DEPTH, depth); - ast.add(depth, "+-[%s]: %s", + ast.add( + depth, + "+-[%s]: %s", rootObject.getClass().getSimpleName(), rootObject.getClass().getName()); var spec = toSpec(context, rootObject); - ast.add(depth, "\\-[%s]: %s", - rootObject.getClass().getSimpleName(), - spec); + ast.add(depth, "\\-[%s]: %s", rootObject.getClass().getSimpleName(), spec); log.debug("--- Spec AST ---\n{}", ast.print()); return spec; } @@ -88,11 +84,11 @@ public Specification toSpec(@NonNull Context context, @Nullable Object r if (rootObject == null) { return null; } - var specs = ReflectionDatabind.of(rootObject, skippingStrategy) - .stream() - .flatMap(databind -> resolveSpec(context, databind)) - .filter(Objects::nonNull) - .collect(toList()); + var specs = + ReflectionDatabind.of(rootObject, skippingStrategy).stream() + .flatMap(databind -> resolveSpec(context, databind)) + .filter(Objects::nonNull) + .collect(toList()); if (specs.isEmpty()) { return null; } @@ -108,13 +104,16 @@ Stream> resolveSpec(@NonNull Context context, @NonNull Dat .map(resolver -> resolveSpec(context, databind, resolver)); } - Specification resolveSpec(@NonNull Context context, @NonNull Databind databind, + Specification resolveSpec( + @NonNull Context context, + @NonNull Databind databind, @NonNull SpecificationResolver resolver) { - var node = new ReflectionSpecInvocation( - context.get(CTX_AST).map(AST.class::cast).get(), - (int) context.get(CTX_DEPTH).get(), - resolver, - databind); + var node = + new ReflectionSpecInvocation( + context.get(CTX_AST).map(AST.class::cast).get(), + (int) context.get(CTX_DEPTH).get(), + resolver, + databind); resolver.preVisit(node); var resolved = resolver.buildSpecification(context, databind); resolver.postVisit(node, resolved); @@ -124,7 +123,8 @@ Specification resolveSpec(@NonNull Context context, @NonNull Databind da @NoArgsConstructor(access = PACKAGE) public static class SpecMapperBuilder { - private final Collection> resolvers = new LinkedList<>(); + private final Collection> resolvers = + new LinkedList<>(); private SkippingStrategy strategy = new DefaultSkippingStrategy(); public SpecMapperBuilder skippingStrategy(@NonNull SkippingStrategy strategy) { @@ -163,11 +163,11 @@ public SpecMapper build() { defaultResolvers(); } var mapper = new SpecMapper(strategy); - mapper.resolvers = this.resolvers.stream() - .map(resolver -> resolver.apply(mapper)) - .collect(Collectors.collectingAndThen( - Collectors.toList(), - Collections::unmodifiableList)); + mapper.resolvers = + this.resolvers.stream() + .map(resolver -> resolver.apply(mapper)) + .collect( + Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); return mapper; } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolver.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolver.java index 59479a9..67e656f 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolver.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolver.java @@ -21,18 +21,15 @@ package tw.com.softleader.data.jpa.spec; import static java.util.Objects.requireNonNull; - import static lombok.AccessLevel.PACKAGE; import java.util.function.BiFunction; import java.util.function.Predicate; - +import lombok.NoArgsConstructor; import org.springframework.core.Ordered; import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; - -import lombok.NoArgsConstructor; import tw.com.softleader.data.jpa.spec.domain.Context; /** diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/And.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/And.java index e74a57d..ddc3bf8 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/And.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/And.java @@ -31,6 +31,5 @@ * @author Matt Ho */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.FIELD }) -public @interface And { -} +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface And {} diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Join.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Join.java index 9d33f44..58d1c00 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Join.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Join.java @@ -20,36 +20,29 @@ */ package tw.com.softleader.data.jpa.spec.annotation; +import jakarta.persistence.criteria.JoinType; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import jakarta.persistence.criteria.JoinType; - @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD }) +@Target({ElementType.FIELD}) public @interface Join { - /** - * Specifies a collection property to join on, e.g. "addresses" - */ + /** Specifies a collection property to join on, e.g. "addresses" */ String path(); - /** - * Specifies an alias for the joined part, e.g. "a" - */ + /** Specifies an alias for the joined part, e.g. "a" */ String alias(); - /** - * Whether the query should return distinct results or not - */ + /** Whether the query should return distinct results or not */ boolean distinct() default true; JoinType joinType() default JoinType.INNER; @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.FIELD }) + @Target({ElementType.FIELD}) @interface Joins { Join[] value(); diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/JoinFetch.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/JoinFetch.java index 4dd1e6c..b0779e5 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/JoinFetch.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/JoinFetch.java @@ -20,15 +20,14 @@ */ package tw.com.softleader.data.jpa.spec.annotation; +import jakarta.persistence.criteria.JoinType; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import jakarta.persistence.criteria.JoinType; - @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) +@Target({ElementType.TYPE}) public @interface JoinFetch { String[] paths(); @@ -38,7 +37,7 @@ boolean distinct() default true; @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.TYPE }) + @Target({ElementType.TYPE}) @interface JoinFetches { JoinFetch[] value(); diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/NestedSpec.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/NestedSpec.java index b7ebb60..db26014 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/NestedSpec.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/NestedSpec.java @@ -31,7 +31,5 @@ * @author Matt Ho */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD }) -public @interface NestedSpec { - -} +@Target({ElementType.FIELD}) +public @interface NestedSpec {} diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Or.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Or.java index 2d65de9..a2111bd 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Or.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Or.java @@ -31,6 +31,5 @@ * @author Matt Ho */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.FIELD }) -public @interface Or { -} +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface Or {} diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Spec.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Spec.java index d7e0207..3696f5e 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Spec.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/annotation/Spec.java @@ -20,14 +20,12 @@ */ package tw.com.softleader.data.jpa.spec.annotation; +import jakarta.persistence.criteria.Path; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - import org.springframework.data.jpa.domain.Specification; - -import jakarta.persistence.criteria.Path; import tw.com.softleader.data.jpa.spec.domain.Equals; import tw.com.softleader.data.jpa.spec.domain.SimpleSpecification; @@ -35,7 +33,7 @@ * @author Matt Ho */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD }) +@Target({ElementType.FIELD}) public @interface Spec { /** @@ -45,9 +43,7 @@ */ String path() default ""; - /** - * {@code Specification} domain class - */ + /** {@code Specification} domain class */ Class value() default Equals.class; /** diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/After.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/After.java index f72c7e2..0e1f35a 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/After.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/After.java @@ -29,8 +29,7 @@ */ public class After extends GreaterThan { - public After(@NonNull Context context, @NonNull String path, - @NonNull Object value) { + public After(@NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/And.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/And.java index fa98b85..93a3732 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/And.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/And.java @@ -20,12 +20,11 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import org.springframework.data.jpa.domain.Specification; - import lombok.AllArgsConstructor; import lombok.NonNull; import lombok.ToString; import lombok.experimental.Delegate; +import org.springframework.data.jpa.domain.Specification; /** * @author Matt Ho @@ -34,7 +33,5 @@ @AllArgsConstructor public class And implements Specification { - @NonNull - @Delegate - Specification spec; + @NonNull @Delegate Specification spec; } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Before.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Before.java index ce495f2..c0136cf 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Before.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Before.java @@ -29,8 +29,7 @@ */ public class Before extends LessThan { - public Before(@NonNull Context context, @NonNull String path, - @NonNull Object value) { + public Before(@NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Between.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Between.java index d369de4..3c47aa3 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Between.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Between.java @@ -46,12 +46,11 @@ public Between(@NonNull Context context, @NonNull String path, @NonNull Object v } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { - var args = stream(((Iterable) value).spliterator(), false) - .map(arg -> (Comparable) arg) - .toArray(Comparable[]::new); + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { + var args = + stream(((Iterable) value).spliterator(), false) + .map(arg -> (Comparable) arg) + .toArray(Comparable[]::new); return builder.between(getPath(root), args[0], args[1]); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/BooleanSpecification.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/BooleanSpecification.java index d4000fb..32f9ebf 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/BooleanSpecification.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/BooleanSpecification.java @@ -29,8 +29,8 @@ */ abstract class BooleanSpecification extends SimpleSpecification { - protected BooleanSpecification(@NonNull Context context, @NonNull String path, - @NonNull Object value) { + protected BooleanSpecification( + @NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); if (!(value instanceof Boolean)) { throw new TypeMismatchException(value, Boolean.class); diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/ComparableSpecification.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/ComparableSpecification.java index 498e9d8..94b0047 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/ComparableSpecification.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/ComparableSpecification.java @@ -29,15 +29,15 @@ */ abstract class ComparableSpecification extends SimpleSpecification { - protected ComparableSpecification(@NonNull Context context, @NonNull String path, - @NonNull Object value) { + protected ComparableSpecification( + @NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); if (!(value instanceof Comparable)) { throw new TypeMismatchException(value, Comparable.class); } } - @SuppressWarnings({ "rawtypes" }) + @SuppressWarnings({"rawtypes"}) protected Comparable getValue() { return (Comparable) value; } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/CompoundSpecification.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/CompoundSpecification.java index 5d456d3..da8eb02 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/CompoundSpecification.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/CompoundSpecification.java @@ -20,17 +20,15 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import java.util.Collection; -import java.util.StringJoiner; - -import org.springframework.data.jpa.domain.Specification; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import java.util.Collection; +import java.util.StringJoiner; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import org.springframework.data.jpa.domain.Specification; /** * @author Matt Ho @@ -38,13 +36,10 @@ @RequiredArgsConstructor abstract class CompoundSpecification implements Specification { - @NonNull - protected final transient Collection> specs; + @NonNull protected final transient Collection> specs; @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { return specs.stream() .reduce(this::combine) .map(spec -> spec.toPredicate(root, query, builder)) @@ -55,9 +50,7 @@ public Predicate toPredicate(Root root, * @param result 到目前 Combine 的結果 * @param element 下一個元素 */ - protected abstract Specification combine( - Specification result, - Specification element); + protected abstract Specification combine(Specification result, Specification element); @Override public String toString() { diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Conjunction.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Conjunction.java index 38be01e..5388dd9 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Conjunction.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Conjunction.java @@ -21,10 +21,8 @@ package tw.com.softleader.data.jpa.spec.domain; import java.util.Collection; - -import org.springframework.data.jpa.domain.Specification; - import lombok.NonNull; +import org.springframework.data.jpa.domain.Specification; /** * @author Matt Ho @@ -36,8 +34,7 @@ public Conjunction(@NonNull Collection> specs) { } @Override - protected Specification combine(Specification result, - Specification element) { + protected Specification combine(Specification result, Specification element) { if (element instanceof Or) { return result.or(element); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Disjunction.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Disjunction.java index fc79540..5b9f719 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Disjunction.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Disjunction.java @@ -21,10 +21,8 @@ package tw.com.softleader.data.jpa.spec.domain; import java.util.Collection; - -import org.springframework.data.jpa.domain.Specification; - import lombok.NonNull; +import org.springframework.data.jpa.domain.Specification; /** * @author Matt Ho @@ -36,8 +34,7 @@ public Disjunction(@NonNull Collection> specs) { } @Override - protected Specification combine(Specification result, - Specification element) { + protected Specification combine(Specification result, Specification element) { if (element instanceof And) { return result.and(element); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/EndingWith.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/EndingWith.java index 09fb6c5..2e0e87a 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/EndingWith.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/EndingWith.java @@ -20,12 +20,11 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import java.util.Objects; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import java.util.Objects; import lombok.NonNull; /** diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Equals.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Equals.java index 8ea36a5..acf82f5 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Equals.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Equals.java @@ -38,9 +38,7 @@ public Equals(@NonNull Context context, @NonNull String path, @NonNull Object va } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { return builder.equal(getPath(root), value); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/False.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/False.java index 1d37594..251ffba 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/False.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/False.java @@ -40,9 +40,7 @@ public False(@NonNull Context context, @NonNull String path, @NonNull Object val } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { return ofNullable(super.toPredicate(root, query, builder)).map(Predicate::not).orElse(null); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqual.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqual.java index 77508fe..f60ba52 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqual.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqual.java @@ -33,8 +33,7 @@ */ public class GreaterThanEqual extends ComparableSpecification { - public GreaterThanEqual(@NonNull Context context, @NonNull String path, - @NonNull Object value) { + public GreaterThanEqual(@NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasLength.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasLength.java index ec60450..c71fa0b 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasLength.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasLength.java @@ -38,12 +38,11 @@ public HasLength(@NonNull Context context, @NonNull String path, @NonNull Object } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { - var predicate = builder.and( - builder.isNotNull(getPath(root)), - builder.greaterThan(builder.length(getPath(root)), 0)); + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { + var predicate = + builder.and( + builder.isNotNull(getPath(root)), + builder.greaterThan(builder.length(getPath(root)), 0)); if (getValue()) { return predicate; } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasText.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasText.java index f6d4d94..2857df5 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasText.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/HasText.java @@ -38,12 +38,11 @@ public HasText(@NonNull Context context, @NonNull String path, @NonNull Object v } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { - var predicate = builder.and( - builder.isNotNull(getPath(root)), - builder.greaterThan(builder.length(builder.trim(getPath(root))), 0)); + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { + var predicate = + builder.and( + builder.isNotNull(getPath(root)), + builder.greaterThan(builder.length(builder.trim(getPath(root))), 0)); if (getValue()) { return predicate; } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/In.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/In.java index a6a4fc6..8cda252 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/In.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/In.java @@ -44,7 +44,7 @@ public In(@NonNull Context context, @NonNull String path, @NonNull Object value) @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return getPath(root).in( - stream(((Iterable) value).spliterator(), false).toArray(Object[]::new)); + return getPath(root) + .in(stream(((Iterable) value).spliterator(), false).toArray(Object[]::new)); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/IsNull.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/IsNull.java index 93c74fd..e657f27 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/IsNull.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/IsNull.java @@ -38,9 +38,7 @@ public IsNull(@NonNull Context context, @NonNull String path, @NonNull Object va } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { if (getValue()) { return builder.isNull(getPath(root)); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Join.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Join.java index d665df3..a5cafc7 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Join.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Join.java @@ -20,13 +20,12 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import org.springframework.data.jpa.domain.Specification; - import jakarta.persistence.criteria.*; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.ToString; import lombok.ToString.Exclude; +import org.springframework.data.jpa.domain.Specification; /** * @author Matt Ho @@ -35,15 +34,10 @@ @RequiredArgsConstructor public class Join implements Specification { - @Exclude - @NonNull - private final transient Context context; - @NonNull - private final String pathToJoinOn; - @NonNull - private final String alias; - @NonNull - private final JoinType joinType; + @Exclude @NonNull private final transient Context context; + @NonNull private final String pathToJoinOn; + @NonNull private final String alias; + @NonNull private final JoinType joinType; private final boolean distinct; @Override @@ -64,9 +58,14 @@ private void join(Root root) { var joined = context.join().get(extractedAlias, root); if (joined == null) { throw new IllegalArgumentException( - "Join definition with alias: '" + extractedAlias + "' not found! " + - "Make sure that join with the alias '" + extractedAlias - + "' is defined before the join with path: '" + pathToJoinOn + "'"); + "Join definition with alias: '" + + extractedAlias + + "' not found! " + + "Make sure that join with the alias '" + + extractedAlias + + "' is defined before the join with path: '" + + pathToJoinOn + + "'"); } var extractedPathToJoin = byDot[1]; diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinContext.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinContext.java index 99cd6d8..2fdfcfb 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinContext.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinContext.java @@ -20,10 +20,9 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import java.util.function.Function; - import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.Root; +import java.util.function.Function; /** * Share data between specifications @@ -32,7 +31,7 @@ */ public interface JoinContext { - @SuppressWarnings({ "rawtypes" }) + @SuppressWarnings({"rawtypes"}) Join get(String key, Root root); void putLazy(String key, Function, Join> function); diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinFetch.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinFetch.java index 767f145..7b939c8 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinFetch.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/JoinFetch.java @@ -20,14 +20,12 @@ */ package tw.com.softleader.data.jpa.spec.domain; +import jakarta.persistence.criteria.*; import java.util.Arrays; import java.util.List; - -import org.springframework.data.jpa.domain.Specification; - -import jakarta.persistence.criteria.*; import lombok.NonNull; import lombok.ToString; +import org.springframework.data.jpa.domain.Specification; /** * @author Matt Ho @@ -39,10 +37,7 @@ public class JoinFetch implements Specification { private final JoinType joinType; private final boolean distinct; - public JoinFetch( - @NonNull String[] pathsToFetch, - @NonNull JoinType joinType, - boolean distinct) { + public JoinFetch(@NonNull String[] pathsToFetch, @NonNull JoinType joinType, boolean distinct) { this.pathsToFetch = Arrays.asList(pathsToFetch); this.joinType = joinType; this.distinct = distinct; diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Like.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Like.java index 94654e0..d6203df 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Like.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Like.java @@ -20,12 +20,11 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import java.util.Objects; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import java.util.Objects; import lombok.NonNull; /** diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Not.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Not.java index 25bec06..868c8e8 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Not.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Not.java @@ -22,15 +22,14 @@ import static org.springframework.data.jpa.domain.Specification.not; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.lang.Nullable; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; import lombok.AllArgsConstructor; import lombok.ToString; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.lang.Nullable; /** * Negates the given Specification. @@ -47,13 +46,10 @@ @AllArgsConstructor public class Not implements Specification { - @Nullable - final Specification spec; + @Nullable final Specification spec; @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { return not(spec).toPredicate(root, query, builder); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotEquals.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotEquals.java index 46ef14d..96d6180 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotEquals.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotEquals.java @@ -38,9 +38,7 @@ public NotEquals(@NonNull Context context, @NonNull String path, @NonNull Object } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { return builder.notEqual(getPath(root), value); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotLike.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotLike.java index c07cc12..2748ec2 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotLike.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotLike.java @@ -20,12 +20,11 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import java.util.Objects; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import java.util.Objects; import lombok.NonNull; /** diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotNull.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotNull.java index d537401..6a71f9e 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotNull.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/NotNull.java @@ -40,9 +40,7 @@ public NotNull(@NonNull Context context, @NonNull String path, @NonNull Object v } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { return ofNullable(super.toPredicate(root, query, builder)).map(Predicate::not).orElse(null); } } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Or.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Or.java index 83009b5..33eba04 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Or.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/Or.java @@ -20,12 +20,11 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import org.springframework.data.jpa.domain.Specification; - import lombok.AllArgsConstructor; import lombok.NonNull; import lombok.ToString; import lombok.experimental.Delegate; +import org.springframework.data.jpa.domain.Specification; /** * @author Matt Ho @@ -34,7 +33,5 @@ @AllArgsConstructor public class Or implements Specification { - @NonNull - @Delegate - Specification spec; + @NonNull @Delegate Specification spec; } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/SimpleSpecification.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/SimpleSpecification.java index 19a63bf..ccd6ba8 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/SimpleSpecification.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/SimpleSpecification.java @@ -21,18 +21,15 @@ package tw.com.softleader.data.jpa.spec.domain; import static java.util.Optional.ofNullable; - import static org.springframework.util.ReflectionUtils.accessibleConstructor; -import java.util.StringJoiner; - -import org.springframework.data.jpa.domain.Specification; - import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Root; +import java.util.StringJoiner; import lombok.Builder; import lombok.NonNull; import lombok.SneakyThrows; +import org.springframework.data.jpa.domain.Specification; /** * To constraint the constructor, the implementations must provide accessible constructor. @@ -45,8 +42,8 @@ public abstract class SimpleSpecification implements Specification { protected final String path; protected final transient Object value; - protected SimpleSpecification(@NonNull Context context, @NonNull String path, - @NonNull Object value) { + protected SimpleSpecification( + @NonNull Context context, @NonNull String path, @NonNull Object value) { this.context = context; this.path = path; this.value = value; @@ -71,9 +68,10 @@ protected Path getPath(Root root) { Path expr = null; for (String field : split) { if (expr == null) { - expr = ofNullable(context.join().get(field, root)) - .map(joined -> (Path) joined) - .orElseGet(() -> root.get(field)); + expr = + ofNullable(context.join().get(field, root)) + .map(joined -> (Path) joined) + .orElseGet(() -> root.get(field)); continue; } expr = expr.get(field); diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/StartingWith.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/StartingWith.java index 2031605..e7d12f9 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/StartingWith.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/StartingWith.java @@ -20,12 +20,11 @@ */ package tw.com.softleader.data.jpa.spec.domain; -import java.util.Objects; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import java.util.Objects; import lombok.NonNull; /** diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/True.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/True.java index d87b51e..9859d0d 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/True.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/True.java @@ -38,9 +38,7 @@ public True(@NonNull Context context, @NonNull String path, @NonNull Object valu } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { if (getValue()) { return builder.isTrue(getPath(root)); } diff --git a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/TypeMismatchException.java b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/TypeMismatchException.java index 50be4ff..68d2c11 100644 --- a/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/TypeMismatchException.java +++ b/mapper/src/main/java/tw/com/softleader/data/jpa/spec/domain/TypeMismatchException.java @@ -23,38 +23,41 @@ import static java.util.stream.Collectors.joining; import java.util.stream.Stream; - +import lombok.Getter; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; -import lombok.Getter; - /** * @author Matt Ho */ @Getter public class TypeMismatchException extends RuntimeException { - @Nullable - private final transient Object value; + @Nullable private final transient Object value; - @Nullable - private final Class requiredType; + @Nullable private final Class requiredType; - public TypeMismatchException(@Nullable Object value, @Nullable Class requiredType, - Class... requiredTypes) { + public TypeMismatchException( + @Nullable Object value, @Nullable Class requiredType, Class... requiredTypes) { this(null, value, requiredType, requiredTypes); } - public TypeMismatchException(@Nullable Throwable cause, @Nullable Object value, + public TypeMismatchException( + @Nullable Throwable cause, + @Nullable Object value, @Nullable Class requiredType, Class... requiredTypes) { - super("Failed to convert value of type '" + ClassUtils.getDescriptiveType(value) + "'" + - (requiredType != null ? " to required type '" - + Stream.concat(Stream.of(requiredType), Stream.of(requiredTypes)) - .map(ClassUtils::getQualifiedName).collect( - joining(" or ")) - + "'" : ""), + super( + "Failed to convert value of type '" + + ClassUtils.getDescriptiveType(value) + + "'" + + (requiredType != null + ? " to required type '" + + Stream.concat(Stream.of(requiredType), Stream.of(requiredTypes)) + .map(ClassUtils::getQualifiedName) + .collect(joining(" or ")) + + "'" + : ""), cause); this.value = value; this.requiredType = requiredType; diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ArchitectureCheckTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ArchitectureCheckTest.java index 59fdb8a..2305023 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ArchitectureCheckTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ArchitectureCheckTest.java @@ -36,14 +36,12 @@ import com.tngtech.archunit.junit.ArchTest; import com.tngtech.archunit.junit.ArchTests; import com.tngtech.archunit.lang.ArchRule; - import tw.com.softleader.data.jpa.spec.annotation.Spec; import tw.com.softleader.data.jpa.spec.domain.SimpleSpecification; -@AnalyzeClasses(packagesOf = SpecCodec.class, importOptions = { - DoNotIncludeTests.class, - DoNotIncludeJars.class -}) +@AnalyzeClasses( + packagesOf = SpecCodec.class, + importOptions = {DoNotIncludeTests.class, DoNotIncludeJars.class}) class ArchitectureCheckTest { static final DescribedPredicate BUILDER = simpleNameEndingWith("Builder"); @@ -57,47 +55,59 @@ class ArchitectureCheckTest { static final String ANNOTATION_PACKAGE = Spec.class.getPackage().getName(); @ArchTest - static final ArchRule layerDependency = layeredArchitecture() - .consideringAllDependencies() - .layer(DOMAIN).definedBy(DOMAIN_PACKAGE) - .layer(INFRA).definedBy(INFRA_PACKAGE) - .layer(ANNOTATION).definedBy(ANNOTATION_PACKAGE) - .whereLayer(ANNOTATION).mayOnlyBeAccessedByLayers(INFRA) - .whereLayer(DOMAIN).mayOnlyBeAccessedByLayers(INFRA, ANNOTATION) - .whereLayer(INFRA).mayNotBeAccessedByAnyLayer(); + static final ArchRule layerDependency = + layeredArchitecture() + .consideringAllDependencies() + .layer(DOMAIN) + .definedBy(DOMAIN_PACKAGE) + .layer(INFRA) + .definedBy(INFRA_PACKAGE) + .layer(ANNOTATION) + .definedBy(ANNOTATION_PACKAGE) + .whereLayer(ANNOTATION) + .mayOnlyBeAccessedByLayers(INFRA) + .whereLayer(DOMAIN) + .mayOnlyBeAccessedByLayers(INFRA, ANNOTATION) + .whereLayer(INFRA) + .mayNotBeAccessedByAnyLayer(); @ArchTest - static final ArchRule domainClassesShouldBePublic = classes() - .that().resideInAPackage(DOMAIN_PACKAGE) - .and(doNot(modifier(ABSTRACT))) - .should().bePublic(); + static final ArchRule domainClassesShouldBePublic = + classes() + .that() + .resideInAPackage(DOMAIN_PACKAGE) + .and(doNot(modifier(ABSTRACT))) + .should() + .bePublic(); @ArchTest - static final ArchRule annotationClassesShouldBePublic = classes() - .that().resideInAPackage(ANNOTATION_PACKAGE) - .should().bePublic(); + static final ArchRule annotationClassesShouldBePublic = + classes().that().resideInAPackage(ANNOTATION_PACKAGE).should().bePublic(); @ArchTest - static final ArchRule classesExceptSpecMapperShouldNotBePublicResideInInfra = classes() - .that().resideInAPackage(INFRA_PACKAGE) - .and(doNot(INTERFACES.or(BUILDER).or(assignableTo(SpecMapper.class)))) - .should().notBePublic(); + static final ArchRule classesExceptSpecMapperShouldNotBePublicResideInInfra = + classes() + .that() + .resideInAPackage(INFRA_PACKAGE) + .and(doNot(INTERFACES.or(BUILDER).or(assignableTo(SpecMapper.class)))) + .should() + .notBePublic(); - @ArchTest - static final ArchTests generalCodingRules = ArchTests.in(GeneralCodingRules.class); + @ArchTest static final ArchTests generalCodingRules = ArchTests.in(GeneralCodingRules.class); static class GeneralCodingRules { @ArchTest - static final ArchRule noClassesShouldThrowGenericExceptions = NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS; + static final ArchRule noClassesShouldThrowGenericExceptions = + NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS; - @ArchTest - static final ArchRule noClassesShouldUseJodaTime = NO_CLASSES_SHOULD_USE_JODATIME; + @ArchTest static final ArchRule noClassesShouldUseJodaTime = NO_CLASSES_SHOULD_USE_JODATIME; @ArchTest static final ArchRule noClassesShouldUseFieldInjection = NO_CLASSES_SHOULD_USE_FIELD_INJECTION; @ArchTest - static final ArchRule noClassesShouldUseJavaUtilLogging = NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING; + static final ArchRule noClassesShouldUseJavaUtilLogging = + NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING; } } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeResolverTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeResolverTest.java index 192c1ba..d72473c 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeResolverTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeResolverTest.java @@ -21,7 +21,6 @@ package tw.com.softleader.data.jpa.spec; import static java.util.concurrent.TimeUnit.MICROSECONDS; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -32,17 +31,15 @@ import java.lang.annotation.Target; import java.time.LocalDate; import java.time.LocalDateTime; - +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; +import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; - -import lombok.Builder; -import lombok.Data; -import lombok.NonNull; -import lombok.SneakyThrows; import tw.com.softleader.data.jpa.spec.annotation.NestedSpec; import tw.com.softleader.data.jpa.spec.annotation.Spec; import tw.com.softleader.data.jpa.spec.domain.Context; @@ -53,8 +50,7 @@ @IntegrationTest class CustomizeResolverTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; SpecMapper mapper; SimpleSpecificationResolver simpleResolver; @@ -67,26 +63,52 @@ class CustomizeResolverTest { @BeforeEach void setup() { - mapper = SpecMapper.builder() - .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) - .resolver(maxCreatedTimeResolver = spy(MaxCreatedTimeSpecificationResolver.class)) - .build(); + mapper = + SpecMapper.builder() + .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) + .resolver(maxCreatedTimeResolver = spy(MaxCreatedTimeSpecificationResolver.class)) + .build(); save( - Customer.builder().name("matt").gender(Gender.MALE).createdTime(LocalDateTime.now()).build()); - save(Customer.builder().name("matt").gender(Gender.MALE).createdTime(LocalDateTime.now()) - .build()); - matt = save(Customer.builder().name("matt").gender(Gender.MALE) - .createdTime(LocalDateTime.now()) - .birthday(LocalDate.now()) - .build()); + Customer.builder() + .name("matt") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + save( + Customer.builder() + .name("matt") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + matt = + save( + Customer.builder() + .name("matt") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .birthday(LocalDate.now()) + .build()); save( - Customer.builder().name("bob").gender(Gender.MALE).createdTime(LocalDateTime.now()).build()); - bob = save(Customer.builder().name("bob").gender(Gender.MALE).createdTime(LocalDateTime.now()) - .build()); - mary = save( - Customer.builder().name("mary").gender(Gender.FEMALE).createdTime(LocalDateTime.now()) + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) .build()); + bob = + save( + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + mary = + save( + Customer.builder() + .name("mary") + .gender(Gender.FEMALE) + .createdTime(LocalDateTime.now()) + .build()); } @SneakyThrows @@ -108,12 +130,12 @@ void customizeResolver() { var actual = repository.findAll(spec); assertThat(actual).hasSize(2).contains(matt, bob); - var inOrder = inOrder( - simpleResolver, - maxCreatedTimeResolver); - inOrder.verify(simpleResolver, times(1)) + var inOrder = inOrder(simpleResolver, maxCreatedTimeResolver); + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(maxCreatedTimeResolver, times(1)) + inOrder + .verify(maxCreatedTimeResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); } @@ -121,37 +143,35 @@ void customizeResolver() { @Test void customizeResolverOnTypeAndNested() { CustomizeOnTypeSpecificationResolver customizeOnTypeResolver; - mapper = SpecMapper.builder() - .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) - .resolver(codec -> nestedResolver = spy(new NestedSpecificationResolver(codec))) - .resolver(customizeOnTypeResolver = spy(CustomizeOnTypeSpecificationResolver.class)) - .build(); - - var criteria = OuterCriteria.builder() - .gender(Gender.FEMALE) - .inner(InnerCriteria.builder() + mapper = + SpecMapper.builder() + .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) + .resolver(codec -> nestedResolver = spy(new NestedSpecificationResolver(codec))) + .resolver(customizeOnTypeResolver = spy(CustomizeOnTypeSpecificationResolver.class)) + .build(); + + var criteria = + OuterCriteria.builder() .gender(Gender.FEMALE) - .build()) - .build(); + .inner(InnerCriteria.builder().gender(Gender.FEMALE).build()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); assertThat(actual).hasSize(1).contains(mary); - verify(nestedResolver, times(1)) - .buildSpecification(any(Context.class), any(Databind.class)); + verify(nestedResolver, times(1)).buildSpecification(any(Context.class), any(Databind.class)); // 跟掛 annotation 的 class fields 數一樣 verify(customizeOnTypeResolver, times(2)) .buildSpecification(any(Context.class), any(Databind.class)); - verify(customizeOnTypeResolver, times(1)) - .buildSpecification(); + verify(customizeOnTypeResolver, times(1)).buildSpecification(); } @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.FIELD }) + @Target({ElementType.FIELD}) public @interface MaxCreatedTime { Class from(); @@ -161,18 +181,15 @@ void customizeResolverOnTypeAndNested() { @Data public static class MyCriteria { - @Spec - Gender gender; + @Spec Gender gender; @MaxCreatedTime(from = Customer.class) String maxBy; } @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.TYPE }) - public @interface CustomizeOnType { - - } + @Target({ElementType.TYPE}) + public @interface CustomizeOnType {} public static class MaxCreatedTimeSpecificationResolver implements SpecificationResolver { @@ -184,7 +201,8 @@ public boolean supports(@NonNull Databind databind) { @Override public Specification buildSpecification(Context context, Databind databind) { var def = databind.getField().getAnnotation(MaxCreatedTime.class); - return databind.getFieldValue() + return databind + .getFieldValue() .map(value -> subquery(def.from(), value.toString())) .orElse(null); } @@ -193,7 +211,8 @@ Specification subquery(Class entityClass, String by) { return (root, query, builder) -> { var subquery = query.subquery(LocalDateTime.class); var subroot = subquery.from(entityClass); - subquery.select(builder.greatest(subroot.get("createdTime").as(LocalDateTime.class))) + subquery + .select(builder.greatest(subroot.get("createdTime").as(LocalDateTime.class))) .where(builder.equal(root.get(by), subroot.get(by))); return builder.equal(root.get("createdTime"), subquery); }; @@ -204,18 +223,15 @@ Specification subquery(Class entityClass, String by) { @CustomizeOnType static class OuterCriteria { - @Spec - Gender gender; + @Spec Gender gender; - @NestedSpec - InnerCriteria inner; + @NestedSpec InnerCriteria inner; } @Builder static class InnerCriteria { - @Spec - Gender gender; + @Spec Gender gender; } public static class CustomizeOnTypeSpecificationResolver implements SpecificationResolver { @@ -243,5 +259,4 @@ Specification buildSpecification() { return (root, query, builder) -> builder.isNotNull(root.get("gender")); } } - } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeSimpleSpecTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeSimpleSpecTest.java index d981b7b..e7d2c69 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeSimpleSpecTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/CustomizeSimpleSpecTest.java @@ -21,26 +21,23 @@ package tw.com.softleader.data.jpa.spec; import static java.util.concurrent.TimeUnit.MICROSECONDS; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; -import java.time.LocalDateTime; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import java.time.LocalDateTime; import lombok.Builder; import lombok.Data; import lombok.NonNull; import lombok.SneakyThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import tw.com.softleader.data.jpa.spec.annotation.Spec; import tw.com.softleader.data.jpa.spec.domain.Context; import tw.com.softleader.data.jpa.spec.domain.SimpleSpecification; @@ -51,8 +48,7 @@ @IntegrationTest class CustomizeSimpleSpecTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; SpecMapper mapper; SimpleSpecificationResolver simpleResolver; @@ -62,19 +58,49 @@ class CustomizeSimpleSpecTest { @BeforeEach void setup() { - mapper = SpecMapper.builder() - .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) - .build(); - - save(Customer.builder().name("matt").gender(Gender.MALE).createdTime(LocalDateTime.now()).build()); - save(Customer.builder().name("matt").gender(Gender.MALE).createdTime(LocalDateTime.now()) - .build()); - matt = save(Customer.builder().name("matt").gender(Gender.MALE).createdTime(LocalDateTime.now()).build()); - save(Customer.builder().name("bob").gender(Gender.MALE).createdTime(LocalDateTime.now()).build()); - bob = save(Customer.builder().name("bob").gender(Gender.MALE).createdTime(LocalDateTime.now()) - .build()); - save(Customer.builder().name("mary").gender(Gender.FEMALE).createdTime(LocalDateTime.now()) - .build()); + mapper = + SpecMapper.builder() + .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) + .build(); + + save( + Customer.builder() + .name("matt") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + save( + Customer.builder() + .name("matt") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + matt = + save( + Customer.builder() + .name("matt") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + save( + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + bob = + save( + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .createdTime(LocalDateTime.now()) + .build()); + save( + Customer.builder() + .name("mary") + .gender(Gender.FEMALE) + .createdTime(LocalDateTime.now()) + .build()); } @SneakyThrows @@ -96,8 +122,7 @@ void customizeSimpleSpec() { var actual = repository.findAll(spec); assertThat(actual).hasSize(2).contains(matt, bob); - verify(simpleResolver, times(2)) - .buildSpecification(any(Context.class), any(Databind.class)); + verify(simpleResolver, times(2)).buildSpecification(any(Context.class), any(Databind.class)); } public static class MaxCustomerCreatedTime extends SimpleSpecification { @@ -107,13 +132,12 @@ public MaxCustomerCreatedTime(Context context, String path, Object value) { } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder builder) { + public Predicate toPredicate( + Root root, CriteriaQuery query, CriteriaBuilder builder) { var subquery = query.subquery(LocalDateTime.class); var subroot = subquery.from(Customer.class); - subquery.select( - builder.greatest(subroot.get("createdTime").as(LocalDateTime.class))) + subquery + .select(builder.greatest(subroot.get("createdTime").as(LocalDateTime.class))) .where(builder.equal(root.get((String) value), subroot.get((String) value))); return builder.equal(root.get("createdTime"), subquery); } @@ -123,8 +147,7 @@ public Predicate toPredicate(Root root, @Data public static class MyCriteria { - @Spec - Gender gender; + @Spec Gender gender; @Spec(MaxCustomerCreatedTime.class) String simpleMaxBy; diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/IntegrationTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/IntegrationTest.java index c54769b..c9ce9ea 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/IntegrationTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/IntegrationTest.java @@ -22,11 +22,9 @@ import java.lang.annotation.*; import java.util.Optional; - import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - import tw.com.softleader.data.jpa.spec.domain.Context; import tw.com.softleader.data.jpa.spec.domain.JoinContext; diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchElementCollectionTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchElementCollectionTest.java index 908538c..d11a0ff 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchElementCollectionTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchElementCollectionTest.java @@ -26,16 +26,14 @@ import static org.mockito.Mockito.*; import java.util.Set; - +import lombok.Builder; +import lombok.Data; +import lombok.Singular; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; - -import lombok.Builder; -import lombok.Data; -import lombok.Singular; import tw.com.softleader.data.jpa.spec.annotation.Join; import tw.com.softleader.data.jpa.spec.annotation.JoinFetch; import tw.com.softleader.data.jpa.spec.annotation.NestedSpec; @@ -50,8 +48,7 @@ @IntegrationTest class JoinFetchElementCollectionTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; SpecMapper mapper; NestedSpecificationResolver nestedResolver; @@ -60,31 +57,33 @@ class JoinFetchElementCollectionTest { @BeforeEach void setup() { - mapper = SpecMapper.builder() - .resolver(codec -> nestedResolver = spy(new NestedSpecificationResolver(codec))) - .resolver(joinFetchResolver = spy(new JoinFetchSpecificationResolver())) - .resolver(spy(new JoinSpecificationResolver())) - .resolver(simpleResolver = spy(new SimpleSpecificationResolver())) - .build(); + mapper = + SpecMapper.builder() + .resolver(codec -> nestedResolver = spy(new NestedSpecificationResolver(codec))) + .resolver(joinFetchResolver = spy(new JoinFetchSpecificationResolver())) + .resolver(spy(new JoinSpecificationResolver())) + .resolver(simpleResolver = spy(new SimpleSpecificationResolver())) + .build(); } @DisplayName("@JoinFetch 遇上 @ElementCollection") @Test void joinFetchWithElementCollection() { - var matt = repository.save(Customer.builder().name("matt") - .phone("taiwanmobile", "0911222333") - .phone("cht", "0944555666") - .build()); - repository.save(Customer.builder().name("mary") - .phone("cht", "0955666777") - .phone("fetnet", "0966777888") - .build()); - - var spec = mapper.toSpec( - CustomerFetchPhone.builder() - .name("matt") - .build(), - Customer.class); + var matt = + repository.save( + Customer.builder() + .name("matt") + .phone("taiwanmobile", "0911222333") + .phone("cht", "0944555666") + .build()); + repository.save( + Customer.builder() + .name("mary") + .phone("cht", "0955666777") + .phone("fetnet", "0966777888") + .build()); + + var spec = mapper.toSpec(CustomerFetchPhone.builder().name("matt").build(), Customer.class); assertThat(spec) .isNotNull() .extracting("specs", LIST) @@ -101,44 +100,36 @@ void joinFetchWithElementCollection() { @DisplayName("巢狀的 @JoinFetch") @Test void nestedJoinFetch() { - var matt = repository.save(Customer.builder().name("matt") - .phone("taiwanmobile", "0911222333") - .phone("cht", "0944555666") - .school(School.builder() - .city("Taipei") - .name("A") - .build()) - .build()); - repository.save(Customer.builder().name("mary") - .phone("cht", "0955666777") - .phone("fetnet", "0966777888") - .school(School.builder() - .city("Taipei") - .name("B") - .build()) - .build()); - repository.save(Customer.builder().name("bob") - .phone("cht", "0955666777") - .phone("taiwanmobile", "0977888999") - .school(School.builder() - .city("Taichung") - .name("B") - .build()) - .build()); - var criteria = CustomerFetchPhone.builder() - .school(CustomerFetchSchool.builder() - .name("A") - .city("Taipei") - .build()) - .build(); + var matt = + repository.save( + Customer.builder() + .name("matt") + .phone("taiwanmobile", "0911222333") + .phone("cht", "0944555666") + .school(School.builder().city("Taipei").name("A").build()) + .build()); + repository.save( + Customer.builder() + .name("mary") + .phone("cht", "0955666777") + .phone("fetnet", "0966777888") + .school(School.builder().city("Taipei").name("B").build()) + .build()); + repository.save( + Customer.builder() + .name("bob") + .phone("cht", "0955666777") + .phone("taiwanmobile", "0977888999") + .school(School.builder().city("Taichung").name("B").build()) + .build()); + var criteria = + CustomerFetchPhone.builder() + .school(CustomerFetchSchool.builder().name("A").city("Taipei").build()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); - var specs = assertThat(spec) - .isNotNull() - .extracting("specs", LIST) - .map(Specification.class::cast); - specs - .filteredOn(tw.com.softleader.data.jpa.spec.domain.JoinFetch.class::isInstance) - .hasSize(1); + var specs = + assertThat(spec).isNotNull().extracting("specs", LIST).map(Specification.class::cast); + specs.filteredOn(tw.com.softleader.data.jpa.spec.domain.JoinFetch.class::isInstance).hasSize(1); specs .filteredOn(Conjunction.class::isInstance) .hasSize(1) @@ -146,8 +137,9 @@ void nestedJoinFetch() { .extracting("specs", LIST) .filteredOn(tw.com.softleader.data.jpa.spec.domain.JoinFetch.class::isInstance) .hasSize(1); - var totalFields = CustomerFetchPhone.class.getDeclaredFields().length - + CustomerFetchSchool.class.getDeclaredFields().length; + var totalFields = + CustomerFetchPhone.class.getDeclaredFields().length + + CustomerFetchSchool.class.getDeclaredFields().length; verify(joinFetchResolver, times(totalFields)).buildSpecification(any(), any()); verify(nestedResolver, times(1)).buildSpecification(any(), any()); var actual = repository.findAll(spec); @@ -159,14 +151,11 @@ void nestedJoinFetch() { @JoinFetch(paths = "phones") public static class CustomerFetchPhone { - @Spec - String name; + @Spec String name; - @Spec - Gender gender; + @Spec Gender gender; - @NestedSpec - CustomerFetchSchool school; + @NestedSpec CustomerFetchSchool school; } @Data diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolverTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolverTest.java index 66bce8c..79f245f 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolverTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinFetchSpecificationResolverTest.java @@ -23,13 +23,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.spy; +import lombok.AllArgsConstructor; +import lombok.Data; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - -import lombok.AllArgsConstructor; -import lombok.Data; import tw.com.softleader.data.jpa.spec.annotation.JoinFetch; import tw.com.softleader.data.jpa.spec.annotation.JoinFetch.JoinFetches; import tw.com.softleader.data.jpa.spec.annotation.Spec; @@ -41,8 +40,7 @@ @IntegrationTest class JoinFetchSpecificationResolverTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; SpecMapper mapper; JoinFetchSpecificationResolver joinFetchResolver; @@ -50,30 +48,29 @@ class JoinFetchSpecificationResolverTest { @BeforeEach void setup() { - mapper = SpecMapper.builder() - .resolver(joinFetchResolver = spy(new JoinFetchSpecificationResolver())) - .resolver(simpleResolver = spy(new SimpleSpecificationResolver())) - .build(); + mapper = + SpecMapper.builder() + .resolver(joinFetchResolver = spy(new JoinFetchSpecificationResolver())) + .resolver(simpleResolver = spy(new SimpleSpecificationResolver())) + .build(); } @DisplayName("單一層級的 Join Fetch") @Test void joinFetch() { - var matt = repository.save(Customer.builder().name("matt") - .order(Order.builder() - .itemName("Pizza") - .build()) - .build()); - repository.save(Customer.builder().name("mary") - .order(Order.builder() - .itemName("Hamburger") - .build()) - .build()); - repository.save(Customer.builder().name("bob") - .order(Order.builder() - .itemName("Coke") - .build()) - .build()); + var matt = + repository.save( + Customer.builder() + .name("matt") + .order(Order.builder().itemName("Pizza").build()) + .build()); + repository.save( + Customer.builder() + .name("mary") + .order(Order.builder().itemName("Hamburger").build()) + .build()); + repository.save( + Customer.builder().name("bob").order(Order.builder().itemName("Coke").build()).build()); var spec = mapper.toSpec(new CustomerOrder(matt.getName()), Customer.class); assertThat(spec).isNotNull(); @@ -84,29 +81,34 @@ void joinFetch() { @DisplayName("多層級的 Join Fetch") @Test void joinFetches() { - var matt = repository.save(Customer.builder().name("matt") - .order(Order.builder() - .itemName("Pizza").tag(Tag.builder() - .name("Food") - .build()) - .build()) - .build()); - repository.save(Customer.builder().name("mary") - .order(Order.builder() - .itemName("Hamburger") - .tag(Tag.builder() - .name("Food") - .build()) - .build()) - .build()); - repository.save(Customer.builder().name("bob") - .order(Order.builder() - .itemName("Coke") - .tag(Tag.builder() - .name("Beverage") - .build()) - .build()) - .build()); + var matt = + repository.save( + Customer.builder() + .name("matt") + .order( + Order.builder() + .itemName("Pizza") + .tag(Tag.builder().name("Food").build()) + .build()) + .build()); + repository.save( + Customer.builder() + .name("mary") + .order( + Order.builder() + .itemName("Hamburger") + .tag(Tag.builder().name("Food").build()) + .build()) + .build()); + repository.save( + Customer.builder() + .name("bob") + .order( + Order.builder() + .itemName("Coke") + .tag(Tag.builder().name("Beverage").build()) + .build()) + .build()); var spec = mapper.toSpec(new CustomerOrderTag(matt.getName()), Customer.class); assertThat(spec).isNotNull(); @@ -119,20 +121,14 @@ void joinFetches() { @Data public static class CustomerOrder { - @Spec - String name; + @Spec String name; } - @JoinFetches({ - @JoinFetch(paths = "orders"), - @JoinFetch(paths = "orders.tags") - }) + @JoinFetches({@JoinFetch(paths = "orders"), @JoinFetch(paths = "orders.tags")}) @Data @AllArgsConstructor public static class CustomerOrderTag { - @Spec - String name; + @Spec String name; } - } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolverTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolverTest.java index c395240..431c4b9 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolverTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/JoinSpecificationResolverTest.java @@ -24,15 +24,13 @@ import static org.mockito.Mockito.spy; import java.util.Collection; - +import lombok.Builder; +import lombok.Data; +import lombok.Singular; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - -import lombok.Builder; -import lombok.Data; -import lombok.Singular; import tw.com.softleader.data.jpa.spec.annotation.Join; import tw.com.softleader.data.jpa.spec.annotation.Join.Joins; import tw.com.softleader.data.jpa.spec.annotation.Spec; @@ -45,8 +43,7 @@ @IntegrationTest class JoinSpecificationResolverTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; SpecMapper mapper; JoinSpecificationResolver joinResolver; @@ -54,35 +51,32 @@ class JoinSpecificationResolverTest { @BeforeEach void setup() { - mapper = SpecMapper.builder() - .resolver(joinResolver = spy(new JoinSpecificationResolver())) - .resolver(simpleResolver = spy(new SimpleSpecificationResolver())) - .build(); + mapper = + SpecMapper.builder() + .resolver(joinResolver = spy(new JoinSpecificationResolver())) + .resolver(simpleResolver = spy(new SimpleSpecificationResolver())) + .build(); } @DisplayName("單一層級的 Join") @Test void join() { - var matt = repository.save(Customer.builder().name("matt") - .order(Order.builder() - .itemName("Pizza") - .build()) - .build()); - var mary = repository.save(Customer.builder().name("mary") - .order(Order.builder() - .itemName("Hamburger") - .build()) - .build()); - repository.save(Customer.builder().name("bob") - .order(Order.builder() - .itemName("Coke") - .build()) - .build()); - - var criteria = CustomerOrder.builder() - .item("Pizza") - .item("Hamburger") - .build(); + var matt = + repository.save( + Customer.builder() + .name("matt") + .order(Order.builder().itemName("Pizza").build()) + .build()); + var mary = + repository.save( + Customer.builder() + .name("mary") + .order(Order.builder().itemName("Hamburger").build()) + .build()); + repository.save( + Customer.builder().name("bob").order(Order.builder().itemName("Coke").build()).build()); + + var criteria = CustomerOrder.builder().item("Pizza").item("Hamburger").build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); @@ -93,33 +87,37 @@ void join() { @DisplayName("多層級的 Join") @Test void joins() { - var matt = repository.save(Customer.builder().name("matt") - .order(Order.builder() - .itemName("Pizza").tag(Tag.builder() - .name("Food") - .build()) - .build()) - .build()); - var mary = repository.save(Customer.builder().name("mary") - .order(Order.builder() - .itemName("Hamburger") - .tag(Tag.builder() - .name("Food") - .build()) - .build()) - .build()); - repository.save(Customer.builder().name("bob") - .order(Order.builder() - .itemName("Coke") - .tag(Tag.builder() - .name("Beverage") - .build()) - .build()) - .build()); - - var criteria = CustomerOrder.builder() - .tag("Food") - .build(); + var matt = + repository.save( + Customer.builder() + .name("matt") + .order( + Order.builder() + .itemName("Pizza") + .tag(Tag.builder().name("Food").build()) + .build()) + .build()); + var mary = + repository.save( + Customer.builder() + .name("mary") + .order( + Order.builder() + .itemName("Hamburger") + .tag(Tag.builder().name("Food").build()) + .build()) + .build()); + repository.save( + Customer.builder() + .name("bob") + .order( + Order.builder() + .itemName("Coke") + .tag(Tag.builder().name("Beverage").build()) + .build()) + .build()); + + var criteria = CustomerOrder.builder().tag("Food").build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); @@ -137,12 +135,8 @@ public static class CustomerOrder { Collection items; @Singular - @Joins({ - @Join(path = "orders", alias = "o"), - @Join(path = "o.tags", alias = "t") - }) + @Joins({@Join(path = "orders", alias = "o"), @Join(path = "o.tags", alias = "t")}) @Spec(path = "t.name", value = In.class) Collection tags; } - } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java index 46b1b43..2ed8c06 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java @@ -25,15 +25,13 @@ import static org.mockito.Mockito.*; import java.time.LocalDate; - +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import tw.com.softleader.data.jpa.spec.annotation.And; import tw.com.softleader.data.jpa.spec.annotation.NestedSpec; import tw.com.softleader.data.jpa.spec.annotation.Or; @@ -48,8 +46,7 @@ @IntegrationTest class NestedSpecificationResolverTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; SpecMapper mapper; SimpleSpecificationResolver simpleResolver; @@ -61,27 +58,36 @@ class NestedSpecificationResolverTest { @BeforeEach void setup() { - mapper = SpecMapper.builder() - .resolver(codec -> nestedResolver = spy(new NestedSpecificationResolver(codec))) - .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) - .build(); - - matt = repository.save(Customer.builder() - .name("matt") - .gold(true) - .gender(Gender.MALE) - .birthday(LocalDate.now()) - .build()); - bob = repository.save(Customer.builder().name("bob") - .gold(false) - .gender(Gender.MALE) - .birthday(LocalDate.now().plusDays(1)) - .build()); - mary = repository.save(Customer.builder().name("mary") - .gold(true) - .gender(Gender.FEMALE) - .birthday(LocalDate.now()) - .build()); + mapper = + SpecMapper.builder() + .resolver(codec -> nestedResolver = spy(new NestedSpecificationResolver(codec))) + .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) + .build(); + + matt = + repository.save( + Customer.builder() + .name("matt") + .gold(true) + .gender(Gender.MALE) + .birthday(LocalDate.now()) + .build()); + bob = + repository.save( + Customer.builder() + .name("bob") + .gold(false) + .gender(Gender.MALE) + .birthday(LocalDate.now().plusDays(1)) + .build()); + mary = + repository.save( + Customer.builder() + .name("mary") + .gold(true) + .gender(Gender.FEMALE) + .birthday(LocalDate.now()) + .build()); // Data will be: // matt, gold, male, today is birthday @@ -92,68 +98,72 @@ void setup() { @DisplayName("全部都用 AND 組合多個條件") @Test void allAnd() { - var criteria = AllAnd.builder() - .name(matt.getName()) - .nestedAnd(new NestedAnd(matt.getName(), new NestedInNestedAnd(matt.getName()))) - .build(); + var criteria = + AllAnd.builder() + .name(matt.getName()) + .nestedAnd(new NestedAnd(matt.getName(), new NestedInNestedAnd(matt.getName()))) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); assertThat(actual).hasSize(1).contains(matt); - var inOrder = inOrder( - nestedResolver, - simpleResolver); - inOrder.verify(simpleResolver, times(1)) + var inOrder = inOrder(nestedResolver, simpleResolver); + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(nestedResolver, times(1)) + inOrder + .verify(nestedResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(simpleResolver, times(1)) + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); } @DisplayName("全部都用 OR 組合多個條件") @Test void allOr() { - var criteria = AllOr.builder() - .name(matt.getName()) - .nestedOr( - new NestedOr(bob.getName(), new NestedInNestedOr(mary.getName()))) - .build(); + var criteria = + AllOr.builder() + .name(matt.getName()) + .nestedOr(new NestedOr(bob.getName(), new NestedInNestedOr(mary.getName()))) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); assertThat(actual).hasSize(3).contains(matt, bob, mary); - var inOrder = inOrder( - nestedResolver, - simpleResolver); - inOrder.verify(simpleResolver, times(1)) + var inOrder = inOrder(nestedResolver, simpleResolver); + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(nestedResolver, times(1)) + inOrder + .verify(nestedResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(simpleResolver, times(1)) + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); } @DisplayName("混合 AND 或 OR 組合多個條件") @Test void mix() { - var criteria = Mix.builder() - .name(matt.getName()) - .nestedMix( - NestedMix.builder() - .gender(bob.getGender()) - .birthday(bob.getBirthday()) - .nin( - NestedInNestedMix.builder() - .gold(mary.isGold()) - .gender(bob.getGender()) - .build()) - .build()) - .build(); + var criteria = + Mix.builder() + .name(matt.getName()) + .nestedMix( + NestedMix.builder() + .gender(bob.getGender()) + .birthday(bob.getBirthday()) + .nin( + NestedInNestedMix.builder() + .gold(mary.isGold()) + .gender(bob.getGender()) + .build()) + .build()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); System.out.println(spec); @@ -161,70 +171,70 @@ void mix() { var actual = repository.findAll(spec); assertThat(actual).hasSize(1).contains(matt); - var inOrder = inOrder( - nestedResolver, - simpleResolver); - inOrder.verify(simpleResolver, times(1)) + var inOrder = inOrder(nestedResolver, simpleResolver); + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(nestedResolver, times(1)) + inOrder + .verify(nestedResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(simpleResolver, times(1)) + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); } @DisplayName("強制使用 Or 串連") @Test void forceOr() { - var criteria = ForceOr.builder() - .name("m") - .gold(true) - .nestedOr(NestedForceOr.builder() - .birthday(LocalDate.now()) - .gender(Gender.MALE) - .build()) - .build(); + var criteria = + ForceOr.builder() + .name("m") + .gold(true) + .nestedOr(NestedForceOr.builder().birthday(LocalDate.now()).gender(Gender.MALE).build()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); assertThat(actual).hasSize(3).contains(matt, mary, bob); - var inOrder = inOrder( - nestedResolver, - simpleResolver); - inOrder.verify(simpleResolver, times(1)) + var inOrder = inOrder(nestedResolver, simpleResolver); + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(nestedResolver, times(1)) + inOrder + .verify(nestedResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(simpleResolver, times(1)) + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); } @DisplayName("強制使用 And 串連") @Test void forceAnd() { - var criteria = ForceAnd.builder() - .name("m") - .gold(true) - .nestedAnd(NestedForceAnd.builder() - .birthday(LocalDate.now()) - .gender(Gender.MALE) - .build()) - .build(); + var criteria = + ForceAnd.builder() + .name("m") + .gold(true) + .nestedAnd( + NestedForceAnd.builder().birthday(LocalDate.now()).gender(Gender.MALE).build()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); assertThat(actual).hasSize(1).contains(matt); - var inOrder = inOrder( - nestedResolver, - simpleResolver); - inOrder.verify(simpleResolver, times(1)) + var inOrder = inOrder(nestedResolver, simpleResolver); + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(nestedResolver, times(1)) + inOrder + .verify(nestedResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); - inOrder.verify(simpleResolver, times(1)) + inOrder + .verify(simpleResolver, times(1)) .buildSpecification(any(Context.class), any(Databind.class)); } @@ -236,12 +246,9 @@ public static class ForceAnd { @Spec(StartingWith.class) String name; - @Spec - Boolean gold; + @Spec Boolean gold; - @And - @NestedSpec - NestedForceAnd nestedAnd; + @And @NestedSpec NestedForceAnd nestedAnd; } @Or @@ -252,8 +259,7 @@ public static class NestedForceAnd { @Spec(After.class) LocalDate birthday; - @Spec - Gender gender; + @Spec Gender gender; } @And @@ -264,12 +270,9 @@ public static class ForceOr { @Spec(StartingWith.class) String name; - @Spec - Boolean gold; + @Spec Boolean gold; - @Or - @NestedSpec - NestedForceOr nestedOr; + @Or @NestedSpec NestedForceOr nestedOr; } @And @@ -280,19 +283,16 @@ public static class NestedForceOr { @Spec(After.class) LocalDate birthday; - @Spec - Gender gender; + @Spec Gender gender; } @Builder @Data public static class AllAnd { - @Spec - String name; + @Spec String name; - @NestedSpec - NestedAnd nestedAnd; + @NestedSpec NestedAnd nestedAnd; } @And @@ -300,11 +300,9 @@ public static class AllAnd { @Data public static class NestedAnd { - @Spec - String name; + @Spec String name; - @NestedSpec - NestedInNestedAnd nin; + @NestedSpec NestedInNestedAnd nin; } @And @@ -312,8 +310,7 @@ public static class NestedAnd { @AllArgsConstructor public static class NestedInNestedAnd { - @NestedSpec - String name; + @NestedSpec String name; } @Builder @@ -321,11 +318,9 @@ public static class NestedInNestedAnd { @Or public static class AllOr { - @Spec - String name; + @Spec String name; - @NestedSpec - NestedOr nestedOr; + @NestedSpec NestedOr nestedOr; } @Or @@ -333,11 +328,9 @@ public static class AllOr { @Data public static class NestedOr { - @Spec - String name; + @Spec String name; - @NestedSpec - NestedInNestedOr nin; + @NestedSpec NestedInNestedOr nin; } @Or @@ -345,19 +338,16 @@ public static class NestedOr { @AllArgsConstructor public static class NestedInNestedOr { - @Spec - String name; + @Spec String name; } @Builder @Data public static class Mix { - @Spec - String name; + @Spec String name; - @NestedSpec - NestedMix nestedMix; + @NestedSpec NestedMix nestedMix; } @Or @@ -365,14 +355,11 @@ public static class Mix { @Data public static class NestedMix { - @Spec - Gender gender; + @Spec Gender gender; - @Spec - LocalDate birthday; + @Spec LocalDate birthday; - @NestedSpec - NestedInNestedMix nin; + @NestedSpec NestedInNestedMix nin; } @And @@ -380,11 +367,8 @@ public static class NestedMix { @Data public static class NestedInNestedMix { - @Spec - boolean gold; + @Spec boolean gold; - @Spec - Gender gender; + @Spec Gender gender; } - } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java index c8b7452..7d4de98 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java @@ -21,7 +21,6 @@ package tw.com.softleader.data.jpa.spec; import static java.util.concurrent.Executors.newFixedThreadPool; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -32,11 +31,9 @@ import java.util.Collection; import java.util.Optional; import java.util.concurrent.CountDownLatch; - -import org.junit.jupiter.api.Test; - import lombok.AllArgsConstructor; import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; class ReflectionDatabindTest { @@ -45,32 +42,32 @@ class ReflectionDatabindTest { void fireOnlyOnce() { var object = new MyObject("hello", null, Optional.empty(), Arrays.asList()); - var databind = ReflectionDatabind.of(object, - new DefaultSkippingStrategy(), - (obj, field, strategy) -> spy(new ReflectionDatabind(obj, field, strategy))); + var databind = + ReflectionDatabind.of( + object, + new DefaultSkippingStrategy(), + (obj, field, strategy) -> spy(new ReflectionDatabind(obj, field, strategy))); - assertThat(databind) - .hasSize(4); + assertThat(databind).hasSize(4); var numberOfThreads = 100; var service = newFixedThreadPool(numberOfThreads); var latch = new CountDownLatch(numberOfThreads); for (int i = 0; i < numberOfThreads; i++) { - service.submit(() -> { - databind.forEach(Databind::getFieldValue); - latch.countDown(); - }); + service.submit( + () -> { + databind.forEach(Databind::getFieldValue); + latch.countDown(); + }); } latch.await(); - databind.forEach(bind -> { - assertThat(bind) - .isNotNull() - .isInstanceOf(ReflectionDatabind.class); + databind.forEach( + bind -> { + assertThat(bind).isNotNull().isInstanceOf(ReflectionDatabind.class); - verify((ReflectionDatabind) bind, times(1)) - .getFieldValue(eq(object), any(Field.class)); - }); + verify((ReflectionDatabind) bind, times(1)).getFieldValue(eq(object), any(Field.class)); + }); } @AllArgsConstructor @@ -81,5 +78,4 @@ static class MyObject { Optional c; Collection d; } - } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolverTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolverTest.java index 860f002..50d8592 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolverTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/SimpleSpecificationResolverTest.java @@ -30,16 +30,13 @@ import java.util.Collection; import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; - import javax.annotation.Nonnull; - +import lombok.Builder; +import lombok.Data; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - -import lombok.Builder; -import lombok.Data; import tw.com.softleader.data.jpa.spec.annotation.And; import tw.com.softleader.data.jpa.spec.annotation.Or; import tw.com.softleader.data.jpa.spec.annotation.Spec; @@ -53,24 +50,23 @@ @IntegrationTest class SimpleSpecificationResolverTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; SpecMapper mapper; SimpleSpecificationResolver simpleResolver; @BeforeEach void setup() { - mapper = SpecMapper.builder() - .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) - .build(); + mapper = + SpecMapper.builder() + .resolver(simpleResolver = spy(SimpleSpecificationResolver.class)) + .build(); } @DisplayName("Null Root Object") @Test void nullRootObject() { - assertThat(mapper.toSpec(null)) - .isNull(); + assertThat(mapper.toSpec(null)).isNull(); } @DisplayName("空的 @Spec") @@ -100,9 +96,7 @@ void emptyCriteria() { @DisplayName("Optional Empty") @Test void optionalEmpty() { - var criteria = MyCriteria.builder() - .opt(Optional.empty()) - .build(); + var criteria = MyCriteria.builder().opt(Optional.empty()).build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNull(); } @@ -113,9 +107,7 @@ void optionalPresent() { var matt = repository.save(Customer.builder().name("matt").build()); repository.save(Customer.builder().name("bob").build()); - var criteria = MyCriteria.builder() - .opt(Optional.of("matt")) - .build(); + var criteria = MyCriteria.builder().opt(Optional.of("matt")).build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); @@ -128,9 +120,7 @@ void optionalPresent() { @DisplayName("Iterable Empty") @Test void iterableEmpty() { - var criteria = MyCriteria.builder() - .names(Arrays.asList()) - .build(); + var criteria = MyCriteria.builder().names(Arrays.asList()).build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNull(); } @@ -141,9 +131,7 @@ void iterablePresent() { var matt = repository.save(Customer.builder().name("matt").build()); repository.save(Customer.builder().name("bob").build()); - var criteria = MyCriteria.builder() - .names(Arrays.asList("matt")) - .build(); + var criteria = MyCriteria.builder().names(Arrays.asList("matt")).build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); @@ -158,12 +146,11 @@ void iterablePresent() { void notSpec() { var matt = repository.save(Customer.builder().name("matt").birthday(LocalDate.now()).build()); repository.save(Customer.builder().name("bob").birthday(LocalDate.now().plusDays(1)).build()); - var mary = repository.save( - Customer.builder().name("mary").birthday(LocalDate.now().minusDays(1)).build()); + var mary = + repository.save( + Customer.builder().name("mary").birthday(LocalDate.now().minusDays(1)).build()); - var criteria = MyCriteria.builder() - .birthday(LocalDate.now()) - .build(); + var criteria = MyCriteria.builder().birthday(LocalDate.now()).build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); @@ -176,20 +163,30 @@ void notSpec() { @DisplayName("Force Or") @Test void forceOr() { - var matt = repository.save( - Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); - var bob = repository.save( - Customer.builder().name("bob").gender(Gender.MALE).birthday(LocalDate.now().plusDays(1)) - .build()); - var mary = repository.save( - Customer.builder().name("mary").gender(Gender.FEMALE).birthday(LocalDate.now().minusDays(1)) - .build()); - - var criteria = ForceOr.builder() - .name(bob.getName()) - .gender(bob.getGender()) - .birthday(LocalDate.now()) - .build(); + var matt = + repository.save( + Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); + var bob = + repository.save( + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .birthday(LocalDate.now().plusDays(1)) + .build()); + var mary = + repository.save( + Customer.builder() + .name("mary") + .gender(Gender.FEMALE) + .birthday(LocalDate.now().minusDays(1)) + .build()); + + var criteria = + ForceOr.builder() + .name(bob.getName()) + .gender(bob.getGender()) + .birthday(LocalDate.now()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); @@ -202,20 +199,29 @@ void forceOr() { @DisplayName("Force Or 2") @Test void forceOr2() { - var matt = repository.save( - Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); - var bob = repository.save( - Customer.builder().name("bob").gender(Gender.MALE).birthday(LocalDate.now().plusDays(1)) - .build()); + var matt = + repository.save( + Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); + var bob = + repository.save( + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .birthday(LocalDate.now().plusDays(1)) + .build()); repository.save( - Customer.builder().name("mary").gender(Gender.FEMALE).birthday(LocalDate.now().minusDays(1)) + Customer.builder() + .name("mary") + .gender(Gender.FEMALE) + .birthday(LocalDate.now().minusDays(1)) .build()); - var criteria = ForceOr2.builder() - .name(bob.getName()) - .gender(bob.getGender()) - .birthday(LocalDate.now()) - .build(); + var criteria = + ForceOr2.builder() + .name(bob.getName()) + .gender(bob.getGender()) + .birthday(LocalDate.now()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); @@ -228,20 +234,29 @@ void forceOr2() { @DisplayName("Force And") @Test void forceAnd() { - var matt = repository.save( - Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); + var matt = + repository.save( + Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); repository.save( - Customer.builder().name("bob").gender(Gender.MALE).birthday(LocalDate.now().plusDays(1)) - .build()); - var mary = repository.save( - Customer.builder().name("mary").gender(Gender.FEMALE).birthday(LocalDate.now().minusDays(1)) + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .birthday(LocalDate.now().plusDays(1)) .build()); - - var criteria = ForceAnd.builder() - .name(matt.getName()) - .gender(mary.getGender()) - .birthday(LocalDate.now()) - .build(); + var mary = + repository.save( + Customer.builder() + .name("mary") + .gender(Gender.FEMALE) + .birthday(LocalDate.now().minusDays(1)) + .build()); + + var criteria = + ForceAnd.builder() + .name(matt.getName()) + .gender(mary.getGender()) + .birthday(LocalDate.now()) + .build(); var spec = mapper.toSpec(criteria, Customer.class); assertThat(spec).isNotNull(); var actual = repository.findAll(spec); @@ -260,14 +275,23 @@ int numberOfLocalField(@Nonnull Class clazz) { @DisplayName("Skip if empty text") @Test void skipIfEmptyText() { - var matt = repository.save( - Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); - var bob = repository.save( - Customer.builder().name("bob").gender(Gender.MALE).birthday(LocalDate.now().plusDays(1)) - .build()); - var mary = repository.save( - Customer.builder().name("mary").gender(Gender.FEMALE).birthday(LocalDate.now().minusDays(1)) - .build()); + var matt = + repository.save( + Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); + var bob = + repository.save( + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .birthday(LocalDate.now().plusDays(1)) + .build()); + var mary = + repository.save( + Customer.builder() + .name("mary") + .gender(Gender.FEMALE) + .birthday(LocalDate.now().minusDays(1)) + .build()); var criteria = SkipEmptyText.builder().name("").build(); var spec = mapper.toSpec(criteria, Customer.class); @@ -285,10 +309,16 @@ void notToSkipIfBlackText() { repository.save( Customer.builder().name("matt").gender(Gender.MALE).birthday(LocalDate.now()).build()); repository.save( - Customer.builder().name("bob").gender(Gender.MALE).birthday(LocalDate.now().plusDays(1)) + Customer.builder() + .name("bob") + .gender(Gender.MALE) + .birthday(LocalDate.now().plusDays(1)) .build()); repository.save( - Customer.builder().name("mary").gender(Gender.FEMALE).birthday(LocalDate.now().minusDays(1)) + Customer.builder() + .name("mary") + .gender(Gender.FEMALE) + .birthday(LocalDate.now().minusDays(1)) .build()); var criteria = SkipEmptyText.builder().name(" ").build(); @@ -305,8 +335,7 @@ void notToSkipIfBlackText() { @Data public static class MyCriteria { - @Spec - String name; + @Spec String name; @Spec(path = "name") Optional opt; @@ -322,11 +351,9 @@ public static class MyCriteria { @Data public static class ForceOr { - @Spec - String name; + @Spec String name; - @Spec - Gender gender; + @Spec Gender gender; @Or @Spec(value = After.class, not = true) @@ -337,15 +364,13 @@ public static class ForceOr { @Data public static class ForceOr2 { - @Spec - String name; + @Spec String name; @Or @Spec(value = After.class, not = true) LocalDate birthday; - @Spec - Gender gender; + @Spec Gender gender; } @Or @@ -353,11 +378,9 @@ public static class ForceOr2 { @Data public static class ForceAnd { - @Spec - String name; + @Spec String name; - @Spec - Gender gender; + @Spec Gender gender; @And @Spec(value = After.class, not = true) @@ -368,7 +391,6 @@ public static class ForceAnd { @Data public static class SkipEmptyText { - @Spec - String name; + @Spec String name; } } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/AfterTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/AfterTest.java index ee38f78..3a1d0b5 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/AfterTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/AfterTest.java @@ -24,10 +24,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -35,8 +33,7 @@ @IntegrationTest class AfterTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BeforeTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BeforeTest.java index 16d10c4..38c986f 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BeforeTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BeforeTest.java @@ -24,10 +24,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -35,8 +33,7 @@ @IntegrationTest class BeforeTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BetweenTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BetweenTest.java index 2c27753..15c89d6 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BetweenTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/BetweenTest.java @@ -25,10 +25,8 @@ import java.time.LocalDate; import java.util.Arrays; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,16 +34,18 @@ @IntegrationTest class BetweenTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { var matt = repository.save(Customer.builder().name("matt").birthday(LocalDate.now()).build()); repository.save(Customer.builder().name("matt").birthday(LocalDate.now().minusDays(2)).build()); - var spec = new Between(noopContext(), "birthday", - Arrays.asList(LocalDate.now().minusDays(1), LocalDate.now().plusDays(1))); + var spec = + new Between( + noopContext(), + "birthday", + Arrays.asList(LocalDate.now().minusDays(1), LocalDate.now().plusDays(1))); var actual = repository.findAll(spec); assertThat(actual).hasSize(1).contains(matt); } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EndingWithTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EndingWithTest.java index 0e056e7..ada9f9f 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EndingWithTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EndingWithTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -33,8 +32,7 @@ @IntegrationTest class EndingWithTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EqualsTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EqualsTest.java index 68e78ed..4073ec9 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EqualsTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/EqualsTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -33,8 +32,7 @@ @IntegrationTest class EqualsTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/FalseTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/FalseTest.java index 5a65125..dfa1e24 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/FalseTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/FalseTest.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -34,8 +33,7 @@ @IntegrationTest class FalseTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void isTrue() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqualTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqualTest.java index 03ca2cd..23d9315 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqualTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanEqualTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class GreaterThanEqualTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanTest.java index dcec99e..f2a7a5c 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/GreaterThanTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class GreaterThanTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasLengthTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasLengthTest.java index f1a0d6d..f2ac585 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasLengthTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasLengthTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class HasLengthTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void hasLength() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasTextTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasTextTest.java index fd924ce..3e5edc5 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasTextTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/HasTextTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class HasTextTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void hasText() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/InTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/InTest.java index 2d14e85..d01835e 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/InTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/InTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.util.Arrays; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class InTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/IsNullTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/IsNullTest.java index 5c4d38e..be9970e 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/IsNullTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/IsNullTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class IsNullTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void isNull() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanEqualTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanEqualTest.java index 639647e..514b5da 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanEqualTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanEqualTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class LessThanEqualTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanTest.java index 25f4e2e..90f314e 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LessThanTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class LessThanTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LikeTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LikeTest.java index dd9198b..3da6e05 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LikeTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/LikeTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -33,8 +32,7 @@ @IntegrationTest class LikeTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotEqualsTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotEqualsTest.java index 9435fbe..8f791b4 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotEqualsTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotEqualsTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -33,8 +32,7 @@ @IntegrationTest class NotEqualsTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotInTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotInTest.java index c55ca18..68c3dd5 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotInTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotInTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.util.Arrays; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class NotInTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotLikeTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotLikeTest.java index be005a5..5d555a3 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotLikeTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotLikeTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -33,8 +32,7 @@ @IntegrationTest class NotLikeTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotNullTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotNullTest.java index 9d6c15b..0a856d7 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotNullTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/NotNullTest.java @@ -25,10 +25,8 @@ import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; import java.time.LocalDate; - import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -36,8 +34,7 @@ @IntegrationTest class NotNullTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void isNotNull() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/StartingWithTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/StartingWithTest.java index e6f6196..fe95989 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/StartingWithTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/StartingWithTest.java @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -33,8 +32,7 @@ @IntegrationTest class StartingWithTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void test() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/TrueTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/TrueTest.java index f005e7b..69750d2 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/TrueTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/TrueTest.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; - import tw.com.softleader.data.jpa.spec.IntegrationTest; import tw.com.softleader.data.jpa.spec.usecase.Customer; import tw.com.softleader.data.jpa.spec.usecase.CustomerRepository; @@ -34,8 +33,7 @@ @IntegrationTest class TrueTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void isTrue() { diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/yet_another_package/ConstructSimpleSpecificationTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/yet_another_package/ConstructSimpleSpecificationTest.java index a437d0c..fdde037 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/yet_another_package/ConstructSimpleSpecificationTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/domain/yet_another_package/ConstructSimpleSpecificationTest.java @@ -23,13 +23,12 @@ import static org.assertj.core.api.Assertions.assertThatNoException; import static tw.com.softleader.data.jpa.spec.IntegrationTest.TestApplication.noopContext; -import org.junit.jupiter.api.Test; - import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; import lombok.NonNull; +import org.junit.jupiter.api.Test; import tw.com.softleader.data.jpa.spec.domain.Context; import tw.com.softleader.data.jpa.spec.domain.SimpleSpecification; @@ -38,75 +37,76 @@ class ConstructSimpleSpecificationTest { @Test void newProtectedConstructorSpec() { assertThatNoException() - .isThrownBy(() -> SimpleSpecification.builder() - .context(noopContext()) - .domainClass(ProtectedConstructorSpec.class) - .path("") - .value(new Object()) - .build()); + .isThrownBy( + () -> + SimpleSpecification.builder() + .context(noopContext()) + .domainClass(ProtectedConstructorSpec.class) + .path("") + .value(new Object()) + .build()); } @Test void newDefaultConstructorSpec() { assertThatNoException() - .isThrownBy(() -> SimpleSpecification.builder() - .context(noopContext()) - .domainClass(DefaultConstructorSpec.class) - .path("") - .value(new Object()) - .build()); + .isThrownBy( + () -> + SimpleSpecification.builder() + .context(noopContext()) + .domainClass(DefaultConstructorSpec.class) + .path("") + .value(new Object()) + .build()); } @Test void newPrivateConstructorSpec() { assertThatNoException() - .isThrownBy(() -> SimpleSpecification.builder() - .context(noopContext()) - .domainClass(PrivateConstructorSpec.class) - .path("") - .value(new Object()) - .build()); + .isThrownBy( + () -> + SimpleSpecification.builder() + .context(noopContext()) + .domainClass(PrivateConstructorSpec.class) + .path("") + .value(new Object()) + .build()); } @Test void newDefaultClassSpec() { assertThatNoException() - .isThrownBy(() -> SimpleSpecification.builder() - .context(noopContext()) - .domainClass(DefaultClassSpec.class) - .path("") - .value(new Object()) - .build()); + .isThrownBy( + () -> + SimpleSpecification.builder() + .context(noopContext()) + .domainClass(DefaultClassSpec.class) + .path("") + .value(new Object()) + .build()); } public static class ProtectedConstructorSpec extends SimpleSpecification { protected ProtectedConstructorSpec( - @NonNull Context context, @NonNull String path, - @NonNull Object value) { + @NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder criteriaBuilder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { return null; } } public static class DefaultConstructorSpec extends SimpleSpecification { - DefaultConstructorSpec( - @NonNull Context context, @NonNull String path, - @NonNull Object value) { + DefaultConstructorSpec(@NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder criteriaBuilder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { return null; } } @@ -114,15 +114,12 @@ public Predicate toPredicate(Root root, public static class PrivateConstructorSpec extends SimpleSpecification { private PrivateConstructorSpec( - @NonNull Context context, @NonNull String path, - @NonNull Object value) { + @NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder criteriaBuilder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { return null; } } @@ -130,16 +127,12 @@ public Predicate toPredicate(Root root, class DefaultClassSpec extends SimpleSpecification { - private DefaultClassSpec( - @NonNull Context context, @NonNull String path, - @NonNull Object value) { + private DefaultClassSpec(@NonNull Context context, @NonNull String path, @NonNull Object value) { super(context, path, value); } @Override - public Predicate toPredicate(Root root, - CriteriaQuery query, - CriteriaBuilder criteriaBuilder) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { return null; } } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Badge.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Badge.java index 09cba04..3392e08 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Badge.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Badge.java @@ -37,9 +37,7 @@ @Table(name = "badges") public class Badge { - @Id - @GeneratedValue - Long id; + @Id @GeneratedValue Long id; String badgeType; } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Customer.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Customer.java index ca0a240..801c166 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Customer.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Customer.java @@ -23,16 +23,14 @@ import static jakarta.persistence.CascadeType.ALL; import static jakarta.persistence.FetchType.LAZY; +import jakarta.persistence.*; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Map; import java.util.Set; - -import org.springframework.data.annotation.CreatedDate; - -import jakarta.persistence.*; import lombok.*; +import org.springframework.data.annotation.CreatedDate; @Builder @AllArgsConstructor @@ -41,9 +39,7 @@ @Entity public class Customer { - @Id - @GeneratedValue - Long id; + @Id @GeneratedValue Long id; @Enumerated(EnumType.STRING) Gender gender; @@ -52,8 +48,7 @@ public class Customer { LocalDate birthday; - @CreatedDate - LocalDateTime createdTime; + @CreatedDate LocalDateTime createdTime; Integer weight; int weightInt; @@ -83,16 +78,12 @@ public class Customer { Map phones; @Singular - @ManyToMany(cascade = { - CascadeType.PERSIST, - CascadeType.MERGE, - CascadeType.DETACH, - CascadeType.REFRESH - }, fetch = FetchType.EAGER) - @JoinTable(name = "CCUSTOMER_SCHOOL_MAPPING", joinColumns = { - @JoinColumn(name = "CUSTOMER_ID", nullable = false) - }, inverseJoinColumns = { - @JoinColumn(name = "SCHOOL_ID", nullable = false) - }) + @ManyToMany( + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH}, + fetch = FetchType.EAGER) + @JoinTable( + name = "CCUSTOMER_SCHOOL_MAPPING", + joinColumns = {@JoinColumn(name = "CUSTOMER_ID", nullable = false)}, + inverseJoinColumns = {@JoinColumn(name = "SCHOOL_ID", nullable = false)}) Set schools; } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/CustomerRepository.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/CustomerRepository.java index e8b18c3..f1368a8 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/CustomerRepository.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/CustomerRepository.java @@ -25,7 +25,5 @@ import org.springframework.stereotype.Repository; @Repository -public interface CustomerRepository extends JpaRepository, - JpaSpecificationExecutor { - -} +public interface CustomerRepository + extends JpaRepository, JpaSpecificationExecutor {} diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Gender.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Gender.java index 765aed8..ec7ab73 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Gender.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Gender.java @@ -21,9 +21,7 @@ package tw.com.softleader.data.jpa.spec.usecase; public enum Gender { - MALE, FEMALE, OTHER - } diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Order.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Order.java index 896376c..b60398e 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Order.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Order.java @@ -20,9 +20,8 @@ */ package tw.com.softleader.data.jpa.spec.usecase; -import java.util.Set; - import jakarta.persistence.*; +import java.util.Set; import lombok.*; @Builder @@ -33,9 +32,7 @@ @Table(name = "orders") public class Order { - @Id - @GeneratedValue - Long id; + @Id @GeneratedValue Long id; String itemName; diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/School.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/School.java index 5844573..ee1d82b 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/School.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/School.java @@ -35,9 +35,7 @@ @Entity public class School { - @Id - @GeneratedValue - Long id; + @Id @GeneratedValue Long id; String name; String city; diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Tag.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Tag.java index 88f82da..dceff62 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Tag.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/usecase/Tag.java @@ -37,9 +37,7 @@ @Table(name = "tag") public class Tag { - @Id - @GeneratedValue - Long id; + @Id @GeneratedValue Long id; String name; } diff --git a/pom.xml b/pom.xml index c5241a8..69740ad 100644 --- a/pom.xml +++ b/pom.xml @@ -47,13 +47,12 @@ 3.9.0 3.0.0-M5 - 2.16.0 + 2.41.1 3.2.0 3.3.1 3.8.2 4.1 3.0.1 - 1.9.0 3.2.0 3.0.1 @@ -121,44 +120,24 @@ - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - net.revelc.code.formatter - formatter-maven-plugin - ${formatter-maven-plugin.version} - - ${maven.multiModuleProjectDirectory}/ide-config/eclipse-format.xml - - ${format.skip} - - - - process-sources - - format - - - - - - net.revelc.code - impsort-maven-plugin - ${impsort-maven-plugin.version} + com.diffplug.spotless + spotless-maven-plugin + ${spotless-maven-plugin.version} - LF - java.,javax.,org.,com. - java,* - true - ${skip.formatting} + ${format.skip} + + + + + + - sort-imports + apply + validate - sort + apply diff --git a/starter/pom.xml b/starter/pom.xml index 23e26b1..2382bde 100644 --- a/starter/pom.xml +++ b/starter/pom.xml @@ -1,13 +1,11 @@ - + + 4.0.0 tw.com.softleader.data.jakarta specification-mapper-parent 3.0.2 - 4.0.0 specification-mapper-starter specification-mapper-starter @@ -66,12 +64,8 @@ spring-boot-maven-plugin - net.revelc.code.formatter - formatter-maven-plugin - - - net.revelc.code - impsort-maven-plugin + com.diffplug.spotless + spotless-maven-plugin org.apache.maven.plugins diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilder.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilder.java index 1ebddc2..e16f481 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilder.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilder.java @@ -21,9 +21,7 @@ package tw.com.softleader.data.jpa.spec; import java.util.function.Function; - import org.springframework.core.Ordered; - import tw.com.softleader.data.jpa.spec.autoconfigure.SpecMapperAutoConfiguration; /** @@ -35,8 +33,8 @@ * @see SpecificationResolver * @see SpecMapperAutoConfiguration */ -public interface SpecificationResolverCodecBuilder extends - Function, Ordered { +public interface SpecificationResolverCodecBuilder + extends Function, Ordered { @Override default int getOrder() { return 0; diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java index 024afc3..235ab9e 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java @@ -25,7 +25,9 @@ import java.util.List; import java.util.Optional; - +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -36,10 +38,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; import org.springframework.data.repository.core.support.RepositoryFactoryCustomizer; - -import lombok.RequiredArgsConstructor; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; import tw.com.softleader.data.jpa.spec.SkippingStrategy; import tw.com.softleader.data.jpa.spec.SpecMapper; import tw.com.softleader.data.jpa.spec.SpecificationResolver; @@ -80,12 +78,8 @@ SpecMapper specMapper( } } if (log.isDebugEnabled()) { - concat( - resolvers.orderedStream(), - concat( - builders.stream(), - codecBuilders.stream())) - .forEach(detected -> log.debug("Detected {}", detected.getClass().getName())); + concat(resolvers.orderedStream(), concat(builders.stream(), codecBuilders.stream())) + .forEach(detected -> log.debug("Detected {}", detected.getClass().getName())); } var mapper = SpecMapper.builder().defaultResolvers(); resolvers.orderedStream().forEach(mapper::resolver); @@ -107,20 +101,23 @@ JpaRepositoryFactoryBeanPostProcessor jpaRepositoryFactoryBeanPostProcessor( @Bean RepositoryFactoryCustomizer repositoryBaseClassCustomizer(SpecMapperProperties properties) { - log.debug("Configuring repository-base-class with '{}'", + log.debug( + "Configuring repository-base-class with '{}'", properties.getRepositoryBaseClass().getName()); return factory -> factory.setRepositoryBaseClass(properties.getRepositoryBaseClass()); } @Bean RepositoryFactoryCustomizer specMapperCustomizer(SpecMapper specMapper) { - return factory -> factory.addRepositoryProxyPostProcessor( - (proxyFactory, repositoryInformation) -> getQueryBySpecExecutorAdapter(proxyFactory) - .ifPresent(target -> target.setSpecMapper(specMapper))); + return factory -> + factory.addRepositoryProxyPostProcessor( + (proxyFactory, repositoryInformation) -> + getQueryBySpecExecutorAdapter(proxyFactory) + .ifPresent(target -> target.setSpecMapper(specMapper))); } @SneakyThrows - @SuppressWarnings({ "rawtypes" }) + @SuppressWarnings({"rawtypes"}) private Optional getQueryBySpecExecutorAdapter( ProxyFactory factory) { return ofNullable(factory.getTargetSource().getTarget()) diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperProperties.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperProperties.java index 8fd2586..808ad8d 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperProperties.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperProperties.java @@ -20,9 +20,8 @@ */ package tw.com.softleader.data.jpa.spec.autoconfigure; -import org.springframework.boot.context.properties.ConfigurationProperties; - import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; import tw.com.softleader.data.jpa.spec.repository.support.QueryBySpecExecutorAdapter; import tw.com.softleader.data.jpa.spec.repository.support.QueryBySpecExecutorImpl; @@ -33,14 +32,11 @@ @ConfigurationProperties(prefix = "spec.mapper") public class SpecMapperProperties { - /** - * Whether to enable the spec mapper - */ + /** Whether to enable the spec mapper */ boolean enabled = true; /** - * Configures the repository base class. the given class must implement - * QueryBySpecExecutorAdapter + * Configures the repository base class. the given class must implement QueryBySpecExecutorAdapter * * @see QueryBySpecExecutorAdapter * @see QueryBySpecExecutorImpl diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutor.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutor.java index 5228154..ab8d836 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutor.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutor.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; - import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -34,7 +33,6 @@ import org.springframework.data.repository.query.FluentQuery; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; - import tw.com.softleader.data.jpa.spec.SpecMapper; /** @@ -46,7 +44,8 @@ public interface QueryBySpecExecutor { /** - * Returns a single entity matching the given {@code spec} or {@link Optional#empty()} if none found. + * Returns a single entity matching the given {@code spec} or {@link Optional#empty()} if none + * found. * * @param spec the object will be mapped into {@link Specification} by {@link SpecMapper} * @return never {@literal null}. @@ -95,20 +94,22 @@ public interface QueryBySpecExecutor { * Checks whether the data store contains elements that match the given {@code spec}. * * @param spec the object will be mapped into {@link Specification} by {@link SpecMapper} - * @return {@code true} if the data store contains elements that match the given {@link Specification} otherwise - * {@code false}. + * @return {@code true} if the data store contains elements that match the given {@link + * Specification} otherwise {@code false}. * @see JpaSpecificationExecutor#exists(Specification) */ boolean existsBySpec(@Nullable Object spec); /** - * Returns entities matching the given {@code spec} applying the {@code queryFunction} that defines the query - * and its result type. + * Returns entities matching the given {@code spec} applying the {@code queryFunction} that + * defines the query and its result type. * * @param spec the object will be mapped into {@link Specification} by {@link SpecMapper} * @param queryFunction the query function defining projection, sorting, and the result type * @return all entities matching the given Example. * @see JpaSpecificationExecutor#findBy(Specification, Function) */ - R findBySpec(@Nullable Object spec, @NonNull Function, R> queryFunction); + R findBySpec( + @Nullable Object spec, + @NonNull Function, R> queryFunction); } diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/JpaRepositoryFactoryBeanPostProcessor.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/JpaRepositoryFactoryBeanPostProcessor.java index 901f122..57378e2 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/JpaRepositoryFactoryBeanPostProcessor.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/JpaRepositoryFactoryBeanPostProcessor.java @@ -21,14 +21,12 @@ package tw.com.softleader.data.jpa.spec.repository.support; import java.util.List; - +import lombok.RequiredArgsConstructor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; import org.springframework.data.repository.core.support.RepositoryFactoryCustomizer; -import lombok.RequiredArgsConstructor; - /** * RepositoryFactoryCustomizer injector, which somehow Spring Data doesn't do the injection... * diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorAdapter.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorAdapter.java index 4bd6fdc..10c0d4d 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorAdapter.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorAdapter.java @@ -25,7 +25,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; - +import lombok.NonNull; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -33,8 +33,6 @@ import org.springframework.data.repository.query.FluentQuery; import org.springframework.lang.Nullable; import org.springframework.transaction.annotation.Transactional; - -import lombok.NonNull; import tw.com.softleader.data.jpa.spec.SpecMapper; import tw.com.softleader.data.jpa.spec.repository.QueryBySpecExecutor; @@ -43,8 +41,8 @@ * * @author Matt Ho */ -public interface QueryBySpecExecutorAdapter extends JpaSpecificationExecutor, - QueryBySpecExecutor { +public interface QueryBySpecExecutorAdapter + extends JpaSpecificationExecutor, QueryBySpecExecutor { @Override @Transactional(readOnly = true) @@ -108,7 +106,8 @@ default Optional findOneBySpec(@Nullable Object spec) { @Override @Transactional(readOnly = true) - default R findBySpec(@Nullable Object spec, + default R findBySpec( + @Nullable Object spec, @NonNull Function, R> queryFunction) { var mapper = getSpecMapper(); var domainClass = getDomainClass(); diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorImpl.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorImpl.java index 8e9554e..64078e5 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorImpl.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorImpl.java @@ -20,15 +20,13 @@ */ package tw.com.softleader.data.jpa.spec.repository.support; -import java.io.Serializable; - -import org.springframework.data.jpa.repository.support.JpaEntityInformation; -import org.springframework.data.jpa.repository.support.SimpleJpaRepository; - import jakarta.persistence.EntityManager; +import java.io.Serializable; import lombok.Getter; import lombok.NonNull; import lombok.Setter; +import org.springframework.data.jpa.repository.support.JpaEntityInformation; +import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import tw.com.softleader.data.jpa.spec.SpecMapper; /** @@ -39,13 +37,10 @@ public class QueryBySpecExecutorImpl extends SimpleJpaRepository implements QueryBySpecExecutorAdapter { - @Setter - @Getter - private SpecMapper specMapper; + @Setter @Getter private SpecMapper specMapper; public QueryBySpecExecutorImpl( - @NonNull JpaEntityInformation entityInformation, - @NonNull EntityManager entityManager) { + @NonNull JpaEntityInformation entityInformation, @NonNull EntityManager entityManager) { super(entityInformation, entityManager); } diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverBuilderTest.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverBuilderTest.java index ef4f305..e61dae7 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverBuilderTest.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverBuilderTest.java @@ -25,6 +25,8 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import lombok.AllArgsConstructor; +import lombok.NonNull; import org.assertj.core.api.Condition; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -36,9 +38,6 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; - -import lombok.AllArgsConstructor; -import lombok.NonNull; import tw.com.softleader.data.jpa.spec.SpecificationResolver.SpecificationResolverBuilder; import tw.com.softleader.data.jpa.spec.domain.Context; @@ -50,8 +49,7 @@ class SpecificationResolverBuilderTest { static SpecificationResolverBuilder myBuilder; static SpecificationResolver myResolver; - @Autowired - SpecMapper mapper; + @Autowired SpecMapper mapper; @BeforeAll static void setup() { diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilderTest.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilderTest.java index d6014f2..ce5abf0 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilderTest.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/SpecificationResolverCodecBuilderTest.java @@ -23,6 +23,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.InstanceOfAssertFactories.LIST; +import lombok.AllArgsConstructor; +import lombok.NonNull; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -32,9 +34,6 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; - -import lombok.AllArgsConstructor; -import lombok.NonNull; import tw.com.softleader.data.jpa.spec.domain.Context; @EnableAutoConfiguration @@ -42,8 +41,7 @@ @SpringBootTest class SpecificationResolverCodecBuilderTest { - @Autowired - SpecMapper mapper; + @Autowired SpecMapper mapper; @Test void customizeCodecBuilder() { diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeResolverTest.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeResolverTest.java index 697a500..05a6fae 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeResolverTest.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeResolverTest.java @@ -27,7 +27,10 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.function.Supplier; - +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectFactory; @@ -40,11 +43,6 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.transaction.annotation.Transactional; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NonNull; import tw.com.softleader.data.jpa.spec.Databind; import tw.com.softleader.data.jpa.spec.SpecMapper; import tw.com.softleader.data.jpa.spec.SpecificationResolver; @@ -63,33 +61,18 @@ @SpringBootTest class CustomizeResolverTest { - @Autowired - SpecMapper mapper; + @Autowired SpecMapper mapper; - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void customizeResolver() { - var matt = repository.save(Customer.builder() - .name("matt") - .age(20) - .build()); - repository.save(Customer.builder() - .name("mary") - .age(10) - .build()); - repository.save(Customer.builder() - .name("bob") - .age(10) - .build()); - - var criteria = MyCriteria.builder() - .age(18) - .profile(Profile.builder() - .name("m") - .build()) - .build(); + var matt = repository.save(Customer.builder().name("matt").age(20).build()); + repository.save(Customer.builder().name("mary").age(10).build()); + repository.save(Customer.builder().name("bob").age(10).build()); + + var criteria = + MyCriteria.builder().age(18).profile(Profile.builder().name("m").build()).build(); var spec = mapper.toSpec(criteria); assertThat(spec) .isNotNull() @@ -103,13 +86,15 @@ void customizeResolver() { assertThat(actual).hasSize(1).contains(matt); // SQL will be: - // select customer0_.id as id1_0_, customer0_.age as age2_0_, customer0_.name as name3_0_ from customer customer0_ + // select customer0_.id as id1_0_, customer0_.age as age2_0_, customer0_.name as name3_0_ from + // customer customer0_ // where customer0_.age>=18 - // and (exists (select customer1_.id from customer customer1_ where customer0_.id=customer1_.id and (customer1_.name like ?))) + // and (exists (select customer1_.id from customer customer1_ where + // customer0_.id=customer1_.id and (customer1_.name like ?))) } @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.FIELD }) + @Target({ElementType.FIELD}) public @interface ProfileExists { /** @@ -164,16 +149,15 @@ public boolean supports(@NonNull Databind databind) { @Override public Specification buildSpecification(Context context, Databind databind) { var def = databind.getField().getAnnotation(ProfileExists.class); - return databind.getFieldValue() + return databind + .getFieldValue() .map(mapper.get()::toSpec) .map(spec -> buildExistsSubquery(def.entity(), def.on(), spec)) .orElse(null); } private Specification buildExistsSubquery( - Class entityClass, - String on, - Specification subquerySpec) { + Class entityClass, String on, Specification subquerySpec) { return (root, query, builder) -> { var subquery = query.subquery(entityClass); var subroot = subquery.from(entityClass); diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeSkippingStrategyTest.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeSkippingStrategyTest.java index 9981da1..a942f43 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeSkippingStrategyTest.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/CustomizeSkippingStrategyTest.java @@ -30,7 +30,6 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.transaction.annotation.Transactional; - import tw.com.softleader.data.jpa.spec.SkippingStrategy; import tw.com.softleader.data.jpa.spec.SpecMapper; @@ -40,8 +39,7 @@ @SpringBootTest class CustomizeSkippingStrategyTest { - @Autowired - SpecMapper mapper; + @Autowired SpecMapper mapper; @Test void customizeSkippingStrategy() { diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/EnsureAllMethodsAreConsidered.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/EnsureAllMethodsAreConsidered.java index e429e90..7ad0bd2 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/EnsureAllMethodsAreConsidered.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/EnsureAllMethodsAreConsidered.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; - import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -32,13 +31,12 @@ import org.springframework.data.repository.query.FluentQuery; /** - * This class is meant to ensure that all methods in {@link JpaSpecificationExecutor} are either used or considered in - * {@link QueryBySpecExecutor}. + * This class is meant to ensure that all methods in {@link JpaSpecificationExecutor} are either + * used or considered in {@link QueryBySpecExecutor}. * - *

- *
- * If methods in {@link JpaSpecificationExecutor} change in the future, this class will trigger a compilation error, - * alerting the maintainers that some adjustments are required. + *


+ * If methods in {@link JpaSpecificationExecutor} change in the future, this class will trigger a + * compilation error, alerting the maintainers that some adjustments are required. * * @author Matt Ho */ @@ -79,7 +77,8 @@ public long delete(Specification spec) { } @Override - public R findBy(Specification spec, Function, R> queryFunction) { + public R findBy( + Specification spec, Function, R> queryFunction) { return null; } } diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutorTest.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutorTest.java index 1775526..acc20d6 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutorTest.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/QueryBySpecExecutorTest.java @@ -23,6 +23,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import lombok.Builder; +import lombok.Data; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -34,9 +36,6 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.transaction.annotation.Transactional; - -import lombok.Builder; -import lombok.Data; import tw.com.softleader.data.jpa.spec.annotation.Spec; import tw.com.softleader.data.jpa.spec.repository.usecase.Customer; import tw.com.softleader.data.jpa.spec.repository.usecase.CustomerRepository; @@ -47,8 +46,7 @@ @SpringBootTest class QueryBySpecExecutorTest { - @Autowired - CustomerRepository repository; + @Autowired CustomerRepository repository; @Test void findBySpec() { @@ -117,11 +115,12 @@ void findOneBySpec() { repository.save(Customer.builder().name("bob").build()); repository.save(Customer.builder().name("mary").build()); - assertThat( - repository.findOneBySpec(MyCriteria.builder().hello("matt").build())).isNotEmpty().get().isEqualTo(matt); + assertThat(repository.findOneBySpec(MyCriteria.builder().hello("matt").build())) + .isNotEmpty() + .get() + .isEqualTo(matt); - assertThat( - repository.findOneBySpec(MyCriteria.builder().hello("no-one").build())).isEmpty(); + assertThat(repository.findOneBySpec(MyCriteria.builder().hello("no-one").build())).isEmpty(); assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class) .isThrownBy(() -> repository.findOneBySpec(MyCriteria.builder().build())); diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/Customer.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/Customer.java index c7d5c83..e95f83f 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/Customer.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/Customer.java @@ -35,9 +35,7 @@ @Entity public class Customer { - @Id - @GeneratedValue - Long id; + @Id @GeneratedValue Long id; String name; diff --git a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/CustomerRepository.java b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/CustomerRepository.java index 0e3d14e..eb4b1b7 100644 --- a/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/CustomerRepository.java +++ b/starter/src/test/java/tw/com/softleader/data/jpa/spec/repository/usecase/CustomerRepository.java @@ -22,11 +22,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; - import tw.com.softleader.data.jpa.spec.repository.QueryBySpecExecutor; @Repository public interface CustomerRepository - extends JpaRepository, QueryBySpecExecutor { - -} + extends JpaRepository, QueryBySpecExecutor {} From cb3522d8cbc5d86a7a0c908e7e721faee4a80145 Mon Sep 17 00:00:00 2001 From: Shihyu Ho Date: Wed, 20 Dec 2023 15:02:19 +0800 Subject: [PATCH 2/3] ci: update bump-spring pipeline --- .github/workflows/bump-spring.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bump-spring.yml b/.github/workflows/bump-spring.yml index cf6b324..42843e9 100644 --- a/.github/workflows/bump-spring.yml +++ b/.github/workflows/bump-spring.yml @@ -35,12 +35,24 @@ jobs: outputs: spring-boot: ${{ steps.get-latest-version.outputs.spring-boot }} + compare-version: + runs-on: ubuntu-latest + needs: [latest-version, current-version] + steps: + - id: semver-compare + uses: madhead/semver-utils@latest + with: + version: ${{ needs.latest-version.outputs.spring-boot }} + compare-to: ${{ needs.current-version.outputs.spring-boot }} + outputs: + comparison-result: ${{ steps.semver-compare.outputs.comparison-result }} + bump-spring: runs-on: ubuntu-latest permissions: contents: write pull-requests: write - needs: [current-version, latest-version] + needs: [current-version, latest-version, compare-version] if: "${{ needs.current-version.outputs.spring-boot != needs.latest-version.outputs.spring-boot }}" steps: - uses: actions/checkout@v3 From 48549de1c72762885195ce983bfa6cd90598c48a Mon Sep 17 00:00:00 2001 From: Shihyu Date: Wed, 20 Dec 2023 15:13:14 +0800 Subject: [PATCH 3/3] fix: warning message about "not eligible ..." (#73) --- .../SpecMapperAutoConfiguration.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java b/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java index 235ab9e..9b85e70 100644 --- a/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java +++ b/starter/src/main/java/tw/com/softleader/data/jpa/spec/autoconfigure/SpecMapperAutoConfiguration.java @@ -22,6 +22,8 @@ import static java.util.Optional.ofNullable; import static java.util.stream.Stream.concat; +import static org.springframework.beans.factory.config.BeanDefinition.ROLE_INFRASTRUCTURE; +import static org.springframework.util.Assert.notNull; import java.util.List; import java.util.Optional; @@ -36,6 +38,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Role; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; import org.springframework.data.repository.core.support.RepositoryFactoryCustomizer; import tw.com.softleader.data.jpa.spec.SkippingStrategy; @@ -89,6 +92,7 @@ SpecMapper specMapper( return mapper.build(); } + @Role(ROLE_INFRASTRUCTURE) @ConditionalOnBean(JpaRepositoryFactoryBean.class) static class RepositoryFactoryCustomizerAutoConfiguration { @@ -100,20 +104,31 @@ JpaRepositoryFactoryBeanPostProcessor jpaRepositoryFactoryBeanPostProcessor( } @Bean - RepositoryFactoryCustomizer repositoryBaseClassCustomizer(SpecMapperProperties properties) { - log.debug( - "Configuring repository-base-class with '{}'", - properties.getRepositoryBaseClass().getName()); - return factory -> factory.setRepositoryBaseClass(properties.getRepositoryBaseClass()); + @Role(ROLE_INFRASTRUCTURE) + RepositoryFactoryCustomizer repositoryBaseClassCustomizer( + ObjectProvider propertiesProvider) { + return factory -> { + var properties = propertiesProvider.getIfAvailable(); + notNull(properties, "SpecMapperProperties must not be null"); + log.debug( + "Configuring repository-base-class with '{}'", + properties.getRepositoryBaseClass().getName()); + factory.setRepositoryBaseClass(properties.getRepositoryBaseClass()); + }; } @Bean - RepositoryFactoryCustomizer specMapperCustomizer(SpecMapper specMapper) { - return factory -> - factory.addRepositoryProxyPostProcessor( - (proxyFactory, repositoryInformation) -> - getQueryBySpecExecutorAdapter(proxyFactory) - .ifPresent(target -> target.setSpecMapper(specMapper))); + @Role(ROLE_INFRASTRUCTURE) + RepositoryFactoryCustomizer specMapperCustomizer( + ObjectProvider specMapperProvider) { + return factory -> { + var specMapper = specMapperProvider.getIfAvailable(); + notNull(specMapper, "SpecMapper must not be null"); + factory.addRepositoryProxyPostProcessor( + (proxyFactory, repositoryInformation) -> + getQueryBySpecExecutorAdapter(proxyFactory) + .ifPresent(target -> target.setSpecMapper(specMapper))); + }; } @SneakyThrows