You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2024/06/16 07:29:01 UTC
(causeway) branch master updated: CAUSEWAY-3642: moves matching responsibility into Tokens (SPI polishing)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/master by this push:
new d159f9c60c CAUSEWAY-3642: moves matching responsibility into Tokens (SPI polishing)
d159f9c60c is described below
commit d159f9c60c957a1fc8de25ab198bdc1f8a805462
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Jun 16 09:28:55 2024 +0200
CAUSEWAY-3642: moves matching responsibility into Tokens (SPI polishing)
---
.../services/search/CollectionSearchService.java | 54 +++++++++++++++++-----
.../tabular/interactive/_SearchUtils.java | 5 ++
2 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/search/CollectionSearchService.java b/api/applib/src/main/java/org/apache/causeway/applib/services/search/CollectionSearchService.java
index 860c4c446f..3f5cf0c9c2 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/services/search/CollectionSearchService.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/services/search/CollectionSearchService.java
@@ -22,6 +22,8 @@ import java.io.Serializable;
import java.util.function.BiPredicate;
import java.util.function.Function;
+import org.springframework.lang.Nullable;
+
import org.apache.causeway.applib.services.i18n.TranslatableString;
import org.apache.causeway.applib.services.i18n.TranslationContext;
import org.apache.causeway.commons.internal.base._Strings;
@@ -42,7 +44,12 @@ import lombok.NonNull;
public interface CollectionSearchService {
public static interface Tokens extends Serializable {
-
+ /**
+ * @apiNote for convenience, the searchArg can be pre-processed by
+ * by the {@link CollectionSearchService#matcher(Class)};
+ * The default implementation already handles the empty searchArg case.
+ */
+ boolean match(@Nullable String searchArg);
}
/**
@@ -51,32 +58,55 @@ public interface CollectionSearchService {
*/
boolean handles(@NonNull Class<?> domainType);
- // -- SEARCH ARGUMENT
+ // -- TOKENIZER
/**
- * For given {@code domainType} returns a {@link BiPredicate}
- * that matches {@link Tokens} against a nullable searchString.
+ * Returns a function that for a given domainObject returns {@link Tokens} (words),
+ * that are then matchable by {@link #matcher(Class)}.
* <p>
- * For example, the searchString could be tokenized (parsed into tokens),
- * and then matched against the {@link Tokens} using either OR or AND semantics.
+ * For example the domain object's title could be tokenized (parsed into tokens).
*
* @param domainType - entity or view-model type to be rendered as row in a table
* @apiNote guarded by a call to {@link #handles(Class)}
*/
- <T> BiPredicate<Tokens, String> matcher(
+ <T> Function<T, Tokens> tokenizer(
@NonNull Class<T> domainType);
+ // -- MATCHER
+
/**
- * Returns a function that for a given domainObject returns {@link Tokens} (words),
- * that are then matchable by {@link #matcher(Class)}.
+ * For given {@code domainType} returns a {@link BiPredicate}
+ * that matches {@link Tokens} against a nullable searchString.
* <p>
- * For example the domain object's title could be tokenized (parsed into tokens).
+ * For example, the searchString could be tokenized (parsed into tokens),
+ * and then matched against the {@link Tokens} using either OR or AND semantics.
+ * <p>
+ * The default implementation sanitizes the user input (searchArg)
+ * then strips any leading or trailing blanks and handles the empty searchArg case.
*
* @param domainType - entity or view-model type to be rendered as row in a table
* @apiNote guarded by a call to {@link #handles(Class)}
*/
- <T> Function<T, Tokens> tokenizer(
- @NonNull Class<T> domainType);
+ default <T> BiPredicate<Tokens, String> matcher(
+ final @NonNull Class<T> domainType) {
+ return (tokens, searchArg) -> {
+ var sanitized = _Strings.blankToNullOrTrim(searchArg);
+ return _Strings.isNotEmpty(sanitized)
+ ? tokens.match(sanitized)
+ : true; // empty searchArg means 'unfiltered'
+ };
+ }
+
+ // -- SEARCH ARG SANITIZER
+
+ /**
+ * Pre-process user input before passing it to the matcher.
+ * <p>
+ * Default behavior is to strip leading or trailing blanks (if any).
+ */
+ default String sanitzeSearchArgument(final @Nullable String searchArg) {
+ return _Strings.blankToNullOrTrim(searchArg);
+ }
// -- SEARCH PROMT
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/interactive/_SearchUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/interactive/_SearchUtils.java
index 8b5b41ffbe..03b3a266de 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/interactive/_SearchUtils.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/interactive/_SearchUtils.java
@@ -43,6 +43,11 @@ class _SearchUtils {
@NonNull final BiPredicate<Tokens, String> matcher;
@NonNull final String searchPromptPlaceholderText;
+ /**
+ * @deprecated {@link Tokens} could be stored with the {@link DataRow}
+ * on first request-cycle, such we don't need to re-hydrate pojos
+ * on follow-up partial page updates
+ */
@Deprecated
@NonNull final BiPredicate<Object, String> searchPredicate() {
return (pojo, searchArg) -> {