diff --git a/.circleci/config.yml b/.circleci/config.yml
index 72a0483..2438ce3 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,12 +2,17 @@ version: 2.1
orbs:
codecov: codecov/codecov@1.0.2
+parameters:
+ jdk-image:
+ type: string
+ default: cimg/openjdk:17.0
+
jobs:
test:
environment:
MAVEN_OPTS: -Xmx3200m
docker:
- - image: circleci/openjdk:11-jdk
+ - image: << pipeline.parameters.jdk-image >>
working_directory: ~/project
steps:
- checkout
diff --git a/.java-version b/.java-version
new file mode 100644
index 0000000..03b6389
--- /dev/null
+++ b/.java-version
@@ -0,0 +1 @@
+17.0
diff --git a/README.md b/README.md
index 9142bad..9ad1e18 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ Please note that providing such a feature on your API does not come without risk
## Getting Started
-**Requirements** : JDK 8 or more.
+**Requirements** : JDK 17 or more.
To get a local copy up and running follow these simple steps.
### Installation
@@ -91,7 +91,7 @@ Add the repo to your project inside your `pom.xml` file
com.sipios
spring-search
- 0.2.0
+ 0.3.0
```
@@ -175,6 +175,40 @@ Request : `/cars?search=options.transmission:Auto`
Request : `/cars?search=creationyear:2018 AND price<300000 AND (color:Yellow OR color:Blue) AND options.transmission:Auto`
![complex example](./docs/images/complex-example.gif)
+
+## Troubleshooting
+
+If you get the following error ⬇️
+
+> No primary or default constructor found for interface org.springframework.data.jpa.domain.Specification
+
+You are free to opt for either of the two following solutions :
+1. Add a `@Configuration` class to add our argument resolver to your project
+```kotlin
+// Kotlin
+@Configuration
+class SpringSearchResolverConf : WebMvcConfigurer {
+ override fun addArgumentResolvers(argumentResolvers: MutableList) {
+ argumentResolvers.add(SearchSpecificationResolver())
+ }
+}
+```
+```java
+// Java
+@Configuration
+public class SpringSearchResolverConf implements WebMvcConfigurer {
+ @Override
+ public void addArgumentResolvers(List argumentResolvers) {
+ argumentResolvers.add(new SearchSpecificationResolver());
+ }
+}
+```
+
+2. Add a `@ComponentScan` annotation to your project configuration class
+```java
+@ComponentScan(basePackages = {"com.your-application", "com.sipios.springsearch"})
+```
+
## Roadmap
diff --git a/pom.xml b/pom.xml
index be0ccda..9e1929b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,22 +4,26 @@
org.springframework.boot
spring-boot-starter-parent
- 2.4.1
+ 3.1.7
com.sipios
spring-search
- 0.2.5
+ 0.2.6
spring-search
API for generating spring boot database queries
- 1.8
- 1.6.20
- 4.9
+ 17
+ 1.9.22
+ 0.8.4
+ 2.2.220
+ 2.16.0
+ 2.0
+ 9.0.7
+ 4.13.1
com.sipios.springsearch.grammar
com/sipios/springsearch/grammar
- 0.8.4
${project.build.directory}/test-results
@@ -32,6 +36,7 @@
com.h2database
h2
+ ${h2.version}
test
@@ -44,6 +49,18 @@
spring-boot-starter-web
provided
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson-databind.version}
+ provided
+
+
+ org.yaml
+ snakeyaml
+ ${snakeyaml.version}
+ provided
+
com.fasterxml.jackson.module
jackson-module-kotlin
@@ -52,10 +69,6 @@
org.jetbrains.kotlin
kotlin-reflect
-
- org.jetbrains.kotlin
- kotlin-stdlib-jdk8
-
org.springframework.boot
@@ -79,11 +92,6 @@
${kotlin.version}
test
-
- org.jetbrains.kotlin
- kotlin-stdlib-jdk8
- ${kotlin.version}
-
@@ -112,10 +120,6 @@
${project.build.directory}/generated-sources/antlr4/${grammar.directory}
-
- maven-compiler-plugin
- 3.8.1
-
org.jetbrains.kotlin
kotlin-maven-plugin
@@ -123,7 +127,7 @@
compile
- compile
+ process-sources
compile
@@ -161,7 +165,7 @@
src/main/kotlin
target/generated-sources/antlr4
- 1.8
+ 17
@@ -291,6 +295,7 @@
org.apache.maven.plugins
maven-compiler-plugin
+ 3.8.1
compile
@@ -351,7 +356,7 @@
org.apache.maven.plugins
maven-gpg-plugin
- 1.5
+ 3.1.0
sign-artifacts
@@ -368,6 +373,18 @@
+
+ org.owasp
+ dependency-check-maven
+ ${dependency-check-maven.version}
+
+
+
+ check
+
+
+
+
diff --git a/src/main/kotlin/com/sipios/springsearch/QueryVisitorImpl.kt b/src/main/kotlin/com/sipios/springsearch/QueryVisitorImpl.kt
index ced091a..8eda3ce 100644
--- a/src/main/kotlin/com/sipios/springsearch/QueryVisitorImpl.kt
+++ b/src/main/kotlin/com/sipios/springsearch/QueryVisitorImpl.kt
@@ -6,7 +6,7 @@ import com.sipios.springsearch.grammar.QueryParser
import org.springframework.data.jpa.domain.Specification
class QueryVisitorImpl(private val searchSpecAnnotation: SearchSpec) : QueryBaseVisitor>() {
- private val ValueRegExp = Regex(pattern = "^(\\*?)(.+?)(\\*?)$")
+ private val valueRegExp = Regex(pattern = "^(\\*?)(.+?)(\\*?)$")
override fun visitOpQuery(ctx: QueryParser.OpQueryContext): Specification {
val left = visit(ctx.left)
val right = visit(ctx.right)
@@ -43,7 +43,7 @@ class QueryVisitorImpl(private val searchSpecAnnotation: SearchSpec) : QueryB
.replace("\\'", "'")
}
- val matchResult = this.ValueRegExp.find(value!!)
+ val matchResult = this.valueRegExp.find(value!!)
val criteria = SearchCriteria(
key,
op,
diff --git a/src/main/kotlin/com/sipios/springsearch/SearchCriteria.kt b/src/main/kotlin/com/sipios/springsearch/SearchCriteria.kt
index dfaa1ee..e87ba7e 100644
--- a/src/main/kotlin/com/sipios/springsearch/SearchCriteria.kt
+++ b/src/main/kotlin/com/sipios/springsearch/SearchCriteria.kt
@@ -10,20 +10,19 @@ class SearchCriteria // Change EQUALS into ENDS_WITH, CONTAINS, STARTS_WITH base
// Change EQUALS into ENDS_WITH, CONTAINS, STARTS_WITH based on the presence of * in the value
val startsWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX)
val endsWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX)
- if (op === SearchOperation.EQUALS && startsWithAsterisk && endsWithAsterisk) {
- op = SearchOperation.CONTAINS
- } else if (op === SearchOperation.EQUALS && startsWithAsterisk) {
- op = SearchOperation.ENDS_WITH
- } else if (op === SearchOperation.EQUALS && endsWithAsterisk) {
- op = SearchOperation.STARTS_WITH
+ op = when {
+ op === SearchOperation.EQUALS && startsWithAsterisk && endsWithAsterisk -> SearchOperation.CONTAINS
+ op === SearchOperation.EQUALS && startsWithAsterisk -> SearchOperation.ENDS_WITH
+ op === SearchOperation.EQUALS && endsWithAsterisk -> SearchOperation.STARTS_WITH
+ else -> op
}
+
// Change NOT_EQUALS into DOESNT_END_WITH, DOESNT_CONTAIN, DOESNT_START_WITH based on the presence of * in the value
- if (op === SearchOperation.NOT_EQUALS && startsWithAsterisk && endsWithAsterisk) {
- op = SearchOperation.DOESNT_CONTAIN
- } else if (op === SearchOperation.NOT_EQUALS && startsWithAsterisk) {
- op = SearchOperation.DOESNT_END_WITH
- } else if (op === SearchOperation.NOT_EQUALS && endsWithAsterisk) {
- op = SearchOperation.DOESNT_START_WITH
+ op = when {
+ op === SearchOperation.NOT_EQUALS && startsWithAsterisk && endsWithAsterisk -> SearchOperation.DOESNT_CONTAIN
+ op === SearchOperation.NOT_EQUALS && startsWithAsterisk -> SearchOperation.DOESNT_END_WITH
+ op === SearchOperation.NOT_EQUALS && endsWithAsterisk -> SearchOperation.DOESNT_START_WITH
+ else -> op
}
}
this.operation = op
diff --git a/src/main/kotlin/com/sipios/springsearch/SpecificationImpl.kt b/src/main/kotlin/com/sipios/springsearch/SpecificationImpl.kt
index 3c4a631..d58ca96 100644
--- a/src/main/kotlin/com/sipios/springsearch/SpecificationImpl.kt
+++ b/src/main/kotlin/com/sipios/springsearch/SpecificationImpl.kt
@@ -2,12 +2,12 @@ package com.sipios.springsearch
import com.sipios.springsearch.anotation.SearchSpec
import com.sipios.springsearch.strategies.ParsingStrategy
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.CriteriaQuery
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
+import jakarta.persistence.criteria.Root
import java.util.ArrayList
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.CriteriaQuery
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
-import javax.persistence.criteria.Root
import org.springframework.data.jpa.domain.Specification
import org.springframework.http.HttpStatus
import org.springframework.web.server.ResponseStatusException
diff --git a/src/main/kotlin/com/sipios/springsearch/SpecificationsBuilder.kt b/src/main/kotlin/com/sipios/springsearch/SpecificationsBuilder.kt
index c0bb5ec..aab0610 100644
--- a/src/main/kotlin/com/sipios/springsearch/SpecificationsBuilder.kt
+++ b/src/main/kotlin/com/sipios/springsearch/SpecificationsBuilder.kt
@@ -1,10 +1,10 @@
package com.sipios.springsearch
import com.sipios.springsearch.anotation.SearchSpec
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.CriteriaQuery
-import javax.persistence.criteria.Predicate
-import javax.persistence.criteria.Root
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.CriteriaQuery
+import jakarta.persistence.criteria.Predicate
+import jakarta.persistence.criteria.Root
import org.springframework.data.jpa.domain.Specification
class SpecificationsBuilder(searchSpecAnnotation: SearchSpec) {
@@ -20,7 +20,7 @@ class SpecificationsBuilder(searchSpecAnnotation: SearchSpec) {
/**
* This function expect a search string to have been provided.
- * The search string has been transformed into a Expression Queue with the format: [OR, value>100, AND, value<1000, label:*MONO*]
+ * The search string has been transformed into an Expression Queue with the format: [OR, value>100, AND, value<1000, label:*MONO*]
*
* @return A list of specification used to filter the underlying object using JPA specifications
*/
diff --git a/src/main/kotlin/com/sipios/springsearch/anotation/SearchSpec.kt b/src/main/kotlin/com/sipios/springsearch/anotation/SearchSpec.kt
index ae51734..dd2a43d 100644
--- a/src/main/kotlin/com/sipios/springsearch/anotation/SearchSpec.kt
+++ b/src/main/kotlin/com/sipios/springsearch/anotation/SearchSpec.kt
@@ -14,7 +14,7 @@ annotation class SearchSpec(
val searchParam: String = "search",
/**
- * A flag to indicate if the search needs to be case sensitive or not
+ * A flag to indicate if the search needs to be case-sensitive or not
*/
val caseSensitiveFlag: Boolean = true
)
diff --git a/src/main/kotlin/com/sipios/springsearch/configuration/SearchSpecificationResolver.kt b/src/main/kotlin/com/sipios/springsearch/configuration/SearchSpecificationResolver.kt
index 578cac4..6ad160d 100644
--- a/src/main/kotlin/com/sipios/springsearch/configuration/SearchSpecificationResolver.kt
+++ b/src/main/kotlin/com/sipios/springsearch/configuration/SearchSpecificationResolver.kt
@@ -44,7 +44,7 @@ class SearchSpecificationResolver : HandlerMethodArgumentResolver {
private fun buildSpecification(specClass: Class, search: String?, searchSpecAnnotation: SearchSpec): Specification? {
logger.debug("Building specification for class {}", specClass)
logger.debug("Search value found is {}", search)
- if (search == null || search.isEmpty()) {
+ if (search.isNullOrEmpty()) {
return null
}
val specBuilder = SpecificationsBuilder(searchSpecAnnotation)
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/DateStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/DateStrategy.kt
index 38368c9..d240e70 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/DateStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/DateStrategy.kt
@@ -2,11 +2,11 @@ package com.sipios.springsearch.strategies
import com.fasterxml.jackson.databind.util.StdDateFormat
import com.sipios.springsearch.SearchOperation
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import java.text.DateFormat
import java.util.Date
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
import kotlin.reflect.KClass
class DateStrategy : ParsingStrategy {
@@ -20,8 +20,8 @@ class DateStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as Date)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as Date)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as Date)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as Date)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/DoubleStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/DoubleStrategy.kt
index 4a4452d..135dfb3 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/DoubleStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/DoubleStrategy.kt
@@ -1,9 +1,9 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import kotlin.reflect.KClass
class DoubleStrategy : ParsingStrategy {
@@ -15,8 +15,8 @@ class DoubleStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as Double)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as Double)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as Double)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as Double)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/DurationStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/DurationStrategy.kt
index 05f626d..c35a847 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/DurationStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/DurationStrategy.kt
@@ -1,10 +1,10 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import java.time.Duration
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
import kotlin.reflect.KClass
class DurationStrategy : ParsingStrategy {
@@ -16,8 +16,8 @@ class DurationStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as Duration)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as Duration)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as Duration)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as Duration)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/FloatStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/FloatStrategy.kt
index 0041d0a..65e7525 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/FloatStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/FloatStrategy.kt
@@ -1,9 +1,9 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import kotlin.reflect.KClass
class FloatStrategy : ParsingStrategy {
@@ -15,8 +15,8 @@ class FloatStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as Float)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as Float)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as Float)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as Float)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/InstantStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/InstantStrategy.kt
index 5010a40..95aff1f 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/InstantStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/InstantStrategy.kt
@@ -1,10 +1,10 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import java.time.Instant
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
import kotlin.reflect.KClass
class InstantStrategy : ParsingStrategy {
@@ -16,8 +16,8 @@ class InstantStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as Instant)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as Instant)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as Instant)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as Instant)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/IntStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/IntStrategy.kt
index 171f57e..fc8ceb1 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/IntStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/IntStrategy.kt
@@ -1,9 +1,9 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import kotlin.reflect.KClass
class IntStrategy : ParsingStrategy {
@@ -15,8 +15,8 @@ class IntStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as Int)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as Int)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as Int)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as Int)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateStrategy.kt
index 0b9baea..57e8ae2 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateStrategy.kt
@@ -1,10 +1,10 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import java.time.LocalDate
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
import kotlin.reflect.KClass
class LocalDateStrategy : ParsingStrategy {
@@ -16,8 +16,8 @@ class LocalDateStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as LocalDate)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as LocalDate)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as LocalDate)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as LocalDate)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateTimeStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateTimeStrategy.kt
index 4108016..18e691f 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateTimeStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/LocalDateTimeStrategy.kt
@@ -1,10 +1,10 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import java.time.LocalDateTime
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
import kotlin.reflect.KClass
class LocalDateTimeStrategy : ParsingStrategy {
@@ -16,8 +16,8 @@ class LocalDateTimeStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as LocalDateTime)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as LocalDateTime)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as LocalDateTime)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as LocalDateTime)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/LocalTimeStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/LocalTimeStrategy.kt
index b27725c..998c8de 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/LocalTimeStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/LocalTimeStrategy.kt
@@ -1,10 +1,10 @@
package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import java.time.LocalTime
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
import kotlin.reflect.KClass
class LocalTimeStrategy : ParsingStrategy {
@@ -16,8 +16,8 @@ class LocalTimeStrategy : ParsingStrategy {
value: Any?
): Predicate? {
return when (ops) {
- SearchOperation.GREATER_THAN -> builder.greaterThan(path.get(fieldName), value as LocalTime)
- SearchOperation.LESS_THAN -> builder.lessThan(path.get(fieldName), value as LocalTime)
+ SearchOperation.GREATER_THAN -> builder.greaterThan(path[fieldName], value as LocalTime)
+ SearchOperation.LESS_THAN -> builder.lessThan(path[fieldName], value as LocalTime)
else -> super.buildPredicate(builder, path, fieldName, ops, value)
}
}
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/ParsingStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/ParsingStrategy.kt
index 739adb9..611abff 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/ParsingStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/ParsingStrategy.kt
@@ -2,6 +2,9 @@ package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
import com.sipios.springsearch.anotation.SearchSpec
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
import java.time.Duration
import java.time.Instant
import java.time.LocalDate
@@ -9,9 +12,6 @@ import java.time.LocalDateTime
import java.time.LocalTime
import java.util.Date
import java.util.UUID
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
@@ -47,11 +47,11 @@ interface ParsingStrategy {
return when (ops) {
SearchOperation.EQUALS -> builder.equal(path.get(fieldName), value)
SearchOperation.NOT_EQUALS -> builder.notEqual(path.get(fieldName), value)
- SearchOperation.STARTS_WITH -> builder.like(path.get(fieldName), "$value%")
- SearchOperation.ENDS_WITH -> builder.like(path.get(fieldName), "%$value")
+ SearchOperation.STARTS_WITH -> builder.like(path[fieldName], "$value%")
+ SearchOperation.ENDS_WITH -> builder.like(path[fieldName], "%$value")
SearchOperation.CONTAINS -> builder.like((path.get(fieldName).`as`(String::class.java)), "%$value%")
- SearchOperation.DOESNT_START_WITH -> builder.notLike(path.get(fieldName), "$value%")
- SearchOperation.DOESNT_END_WITH -> builder.notLike(path.get(fieldName), "%$value")
+ SearchOperation.DOESNT_START_WITH -> builder.notLike(path[fieldName], "$value%")
+ SearchOperation.DOESNT_END_WITH -> builder.notLike(path[fieldName], "%$value")
SearchOperation.DOESNT_CONTAIN -> builder.notLike(
(path.get(fieldName).`as`(String::class.java)),
"%$value%"
diff --git a/src/main/kotlin/com/sipios/springsearch/strategies/StringStrategy.kt b/src/main/kotlin/com/sipios/springsearch/strategies/StringStrategy.kt
index 322748a..3498959 100644
--- a/src/main/kotlin/com/sipios/springsearch/strategies/StringStrategy.kt
+++ b/src/main/kotlin/com/sipios/springsearch/strategies/StringStrategy.kt
@@ -2,11 +2,12 @@ package com.sipios.springsearch.strategies
import com.sipios.springsearch.SearchOperation
import com.sipios.springsearch.anotation.SearchSpec
-import javax.persistence.criteria.CriteriaBuilder
-import javax.persistence.criteria.Path
-import javax.persistence.criteria.Predicate
+import jakarta.persistence.criteria.CriteriaBuilder
+import jakarta.persistence.criteria.Path
+import jakarta.persistence.criteria.Predicate
+import java.util.Locale
-class StringStrategy(var searchSpecAnnotation: SearchSpec) : ParsingStrategy {
+data class StringStrategy(var searchSpecAnnotation: SearchSpec) : ParsingStrategy {
override fun buildPredicate(
builder: CriteriaBuilder,
path: Path<*>,
@@ -15,8 +16,8 @@ class StringStrategy(var searchSpecAnnotation: SearchSpec) : ParsingStrategy {
value: Any?
): Predicate? {
if (!searchSpecAnnotation.caseSensitiveFlag) {
- val lowerCasedValue = (value as String).toLowerCase()
- val loweredFieldValue = builder.lower(path.get(fieldName))
+ val lowerCasedValue = (value as String).lowercase(Locale.getDefault())
+ val loweredFieldValue = builder.lower(path[fieldName])
return when (ops) {
SearchOperation.STARTS_WITH -> builder.like(loweredFieldValue, "$lowerCasedValue%")
SearchOperation.ENDS_WITH -> builder.like(loweredFieldValue, "%$lowerCasedValue")
diff --git a/src/test/kotlin/com/sipios/springsearch/Users.kt b/src/test/kotlin/com/sipios/springsearch/Users.kt
index fb6610a..73c506c 100644
--- a/src/test/kotlin/com/sipios/springsearch/Users.kt
+++ b/src/test/kotlin/com/sipios/springsearch/Users.kt
@@ -1,5 +1,11 @@
package com.sipios.springsearch
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.Table
import java.time.Duration
import java.time.Instant
import java.time.LocalDate
@@ -7,12 +13,6 @@ import java.time.LocalDateTime
import java.time.LocalTime
import java.util.Date
import java.util.UUID
-import javax.persistence.Column
-import javax.persistence.Entity
-import javax.persistence.GeneratedValue
-import javax.persistence.GenerationType
-import javax.persistence.Id
-import javax.persistence.Table
@Entity
@Table(name = "USERS")