You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/02/28 10:17:17 UTC
[james-project] branch master updated (b7aeaaa -> 370d02c)
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git.
from b7aeaaa MAILBOX-381 Use MemoryMailRepositoryStore POJO config in tests
new dae0bc7 MAILBOX-381 Move Query to search package
new bcf0510 MAILBOX-381 Search models for Query
new 7f96286 MAILBOX-381 Plug search by Query to Memory Vault
new 370d02c MAILBOX-384 Adding a failed test of a conner case locale string search
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../apache/james/vault/DeletedMessageVault.java | 1 +
.../vault/memory/MemoryDeletedMessagesVault.java | 8 +-
.../org/apache/james/vault/search/Criterion.java | 37 +-
.../james/vault/search/CriterionFactory.java | 120 ++++
.../james/vault/search/DeletedMessageField.java | 53 ++
.../org/apache/james/vault/{ => search}/Query.java | 17 +-
.../apache/james/vault/DeletedMessageFixture.java | 1 +
.../james/vault/DeletedMessageVaultContract.java | 2 +-
.../vault/DeletedMessageVaultSearchContract.java | 671 +++++++++++++++++++++
.../memory/MemoryDeletedMessagesVaultTest.java | 3 +-
.../org/apache/mailet/base/MailAddressFixture.java | 2 +
11 files changed, 896 insertions(+), 19 deletions(-)
copy server/protocols/jmap/src/main/java/org/apache/james/jmap/json/FieldNamePropertyFilter.java => mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java (54%)
create mode 100644 mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java
create mode 100644 mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java
rename mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/{ => search}/Query.java (74%)
create mode 100644 mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[james-project] 03/04: MAILBOX-381 Plug search by Query to Memory
Vault
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 7f9628660a25a662bf4b4f01111472a95b4c4954
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue Feb 26 11:02:57 2019 +0700
MAILBOX-381 Plug search by Query to Memory Vault
---
.../vault/memory/MemoryDeletedMessagesVault.java | 8 +-
.../org/apache/james/vault/search/Criterion.java | 18 +-
.../james/vault/search/CriterionFactory.java | 94 +--
.../james/vault/search/DeletedMessageField.java | 16 +-
.../java/org/apache/james/vault/search/Query.java | 4 +-
.../apache/james/vault/search/ValueMatcher.java | 79 ---
.../apache/james/vault/DeletedMessageFixture.java | 1 +
.../vault/DeletedMessageVaultSearchContract.java | 653 +++++++++++++++++++++
.../memory/MemoryDeletedMessagesVaultTest.java | 3 +-
.../org/apache/mailet/base/MailAddressFixture.java | 2 +
10 files changed, 741 insertions(+), 137 deletions(-)
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java
index 172692e..c039218 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/memory/MemoryDeletedMessagesVault.java
@@ -23,7 +23,7 @@ import org.apache.james.core.User;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.vault.DeletedMessage;
import org.apache.james.vault.DeletedMessageVault;
-import org.apache.james.vault.Query;
+import org.apache.james.vault.search.Query;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashBasedTable;
@@ -61,8 +61,12 @@ public class MemoryDeletedMessagesVault implements DeletedMessageVault {
public synchronized Flux<DeletedMessage> search(User user, Query query) {
Preconditions.checkNotNull(user);
Preconditions.checkNotNull(query);
- Preconditions.checkArgument(query.getCriteria().isEmpty(), "Search is not supported yet...");
+ return listAll(user)
+ .filter(query.toPredicate());
+ }
+
+ private Flux<DeletedMessage> listAll(User user) {
return Flux.fromIterable(table.row(user).values());
}
}
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java
index cf62ee3..d577f21 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java
@@ -25,17 +25,31 @@ import org.apache.james.vault.DeletedMessage;
public class Criterion<T> {
+ interface ValueMatcher<T> {
+ boolean matches(T referenceValue);
+ }
+
+ interface ExpectMatcher<T> {
+ Criterion<T> withMatcher(ValueMatcher<T> valueMatcher);
+ }
+
+ interface Builder {
+ static <U> ExpectMatcher<U> forField(DeletedMessageField<U> field) {
+ return matcher -> new Criterion<>(field, matcher);
+ }
+ }
+
private static final boolean DEFAULT_TO_NON_MATCHED_IF_NON_EXIST = false;
private final DeletedMessageField<T> field;
private final ValueMatcher<T> valueMatcher;
- Criterion(DeletedMessageField<T> field, ValueMatcher<T> valueMatcher) {
+ private Criterion(DeletedMessageField<T> field, ValueMatcher<T> valueMatcher) {
this.field = field;
this.valueMatcher = valueMatcher;
}
- public Predicate<DeletedMessage> toPredicate() {
+ Predicate<DeletedMessage> toPredicate() {
return deletedMessage -> field.valueExtractor().extract(deletedMessage)
.map(valueMatcher::matches)
.orElse(DEFAULT_TO_NON_MATCHED_IF_NON_EXIST);
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java
index 0ebd408..ed2b0a4 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java
@@ -28,87 +28,93 @@ import static org.apache.james.vault.search.DeletedMessageField.SENDER;
import static org.apache.james.vault.search.DeletedMessageField.SUBJECT;
import java.time.ZonedDateTime;
-import java.util.List;
+import java.util.Collection;
+import java.util.Locale;
import org.apache.james.core.MailAddress;
import org.apache.james.mailbox.model.MailboxId;
-public interface CriterionFactory<T> {
+public interface CriterionFactory {
- DeletedMessageField<T> deletedMessageField();
+ class StringCriterionFactory {
- interface EqualsMatcherFactory<T> extends CriterionFactory<T> {
+ private final Criterion.ExpectMatcher<String> builder;
- default Criterion<T> equalsMatcher(T testedValue) {
- ValueMatcher.Equals<T> matcher = () -> testedValue;
- return new Criterion<>(deletedMessageField(), matcher);
+ private StringCriterionFactory(Criterion.ExpectMatcher<String> builder) {
+ this.builder = builder;
}
- }
- interface StringMatcherFactory extends CriterionFactory<String> {
+ public Criterion<String> contains(String subString) {
+ return builder.withMatcher(value -> value.contains(subString));
+ }
- default Criterion<String> contains(String subString) {
- ValueMatcher.StringContains matcher = () -> subString;
- return new Criterion<>(deletedMessageField(), matcher);
+ public Criterion<String> containsIgnoreCase(String subString) {
+ return builder.withMatcher(value -> value.toLowerCase(Locale.US).contains(subString.toLowerCase(Locale.US)));
}
- default Criterion<String> containsIgnoreCase(String subString) {
- ValueMatcher.StringContainsIgnoreCase matcher = () -> subString;
- return new Criterion<>(deletedMessageField(), matcher);
+ public Criterion<String> equals(String expectedString) {
+ return builder.withMatcher(expectedString::equals);
}
- default Criterion<String> equals(String testedString) {
- ValueMatcher.Equals<String> matcher = () -> testedString;
- return new Criterion<>(deletedMessageField(), matcher);
+ public Criterion<String> equalsIgnoreCase(String expectedString) {
+ return builder.withMatcher(expectedString::equalsIgnoreCase);
}
}
- interface ZonedDateTimeMatcherFactory extends CriterionFactory<ZonedDateTime> {
+ class ZonedDateTimeCriterionFactory {
- default Criterion<ZonedDateTime> beforeOrEquals(ZonedDateTime testedInstant) {
- ValueMatcher.ZonedDateTimeBeforeOrEquals matcher = () -> testedInstant;
- return new Criterion<>(deletedMessageField(), matcher);
+ private final Criterion.ExpectMatcher<ZonedDateTime> builder;
+
+ private ZonedDateTimeCriterionFactory(Criterion.ExpectMatcher<ZonedDateTime> builder) {
+ this.builder = builder;
}
- default Criterion<ZonedDateTime> afterOrEquals(ZonedDateTime testedInstant) {
- ValueMatcher.ZonedDateTimeAfterOrEquals matcher = () -> testedInstant;
- return new Criterion<>(deletedMessageField(), matcher);
+ public Criterion<ZonedDateTime> beforeOrEquals(ZonedDateTime expectedValue) {
+ return builder.withMatcher(actualValue -> !expectedValue.isBefore(actualValue));
+ }
+
+ public Criterion<ZonedDateTime> afterOrEquals(ZonedDateTime expectedValue) {
+ return builder.withMatcher(actualValue -> !expectedValue.isAfter(actualValue));
}
}
- interface ListMatcherFactory<T> extends CriterionFactory<List<T>> {
+ static ZonedDateTimeCriterionFactory deletionDate() {
+ return new ZonedDateTimeCriterionFactory(Criterion.Builder.forField(DELETION_DATE));
+ }
- default Criterion<List<T>> contains(T testedValue) {
- ValueMatcher.ListContains<T> matcher = () -> testedValue;
- return new Criterion<>(deletedMessageField(), matcher);
- }
+ static ZonedDateTimeCriterionFactory deliveryDate() {
+ return new ZonedDateTimeCriterionFactory(Criterion.Builder.forField(DELIVERY_DATE));
}
- static ZonedDateTimeMatcherFactory deletionDate() {
- return () -> DELETION_DATE;
+ static Criterion<Collection<MailAddress>> containsRecipient(MailAddress recipient) {
+ return Criterion.Builder.forField(RECIPIENTS)
+ .withMatcher(actualValue -> actualValue.contains(recipient));
}
- static ZonedDateTimeMatcherFactory deliveryDate() {
- return () -> DELIVERY_DATE;
+ static Criterion<MailAddress> hasSender(MailAddress sender) {
+ return Criterion.Builder.forField(SENDER)
+ .withMatcher(sender::equals);
}
- static ListMatcherFactory<MailAddress> recipients() {
- return () -> RECIPIENTS;
+ static Criterion<Boolean> hasAttachment() {
+ return hasAttachment(true);
}
- static EqualsMatcherFactory<MailAddress> sender() {
- return () -> SENDER;
+ static Criterion<Boolean> hasNoAttachment() {
+ return hasAttachment(false);
}
- static EqualsMatcherFactory<Boolean> hasAttachment() {
- return () -> HAS_ATTACHMENT;
+ static Criterion<Boolean> hasAttachment(boolean hasAttachment) {
+ return Criterion.Builder.forField(HAS_ATTACHMENT)
+ .withMatcher(actualValue -> hasAttachment == actualValue);
}
- static StringMatcherFactory subject() {
- return () -> SUBJECT;
+ static StringCriterionFactory subject() {
+ return new StringCriterionFactory(Criterion.Builder.forField(SUBJECT));
}
- static ListMatcherFactory<MailboxId> originMailboxes() {
- return () -> ORIGIN_MAILBOXES;
+ static Criterion<Collection<MailboxId>> containsOriginMailbox(MailboxId mailboxId) {
+ return Criterion.Builder.forField(ORIGIN_MAILBOXES)
+ .withMatcher(actualValue -> actualValue.contains(mailboxId));
}
}
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java
index f0450b0..4662ca7 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java
@@ -20,33 +20,33 @@
package org.apache.james.vault.search;
import java.time.ZonedDateTime;
-import java.util.List;
+import java.util.Collection;
import java.util.Optional;
import org.apache.james.core.MailAddress;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.vault.DeletedMessage;
-public interface DeletedMessageField<T> {
+interface DeletedMessageField<T> {
interface ValueExtractor<T> {
Optional<T> extract(DeletedMessage deletedMessage);
- ValueExtractor<ZonedDateTime> DELETION_DATE_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getDeletionDate());
- ValueExtractor<ZonedDateTime> DELIVERY_DATE_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getDeliveryDate());
- ValueExtractor<List<MailAddress>> RECIPIENTS_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getRecipients());
+ ValueExtractor<ZonedDateTime> DELETION_DATE_EXTRACTOR = deletedMessage -> Optional.of(deletedMessage.getDeletionDate());
+ ValueExtractor<ZonedDateTime> DELIVERY_DATE_EXTRACTOR = deletedMessage -> Optional.of(deletedMessage.getDeliveryDate());
+ ValueExtractor<Collection<MailAddress>> RECIPIENTS_EXTRACTOR = deletedMessage -> Optional.of(deletedMessage.getRecipients());
ValueExtractor<MailAddress> SENDER_EXTRACTOR = deletedMessage -> deletedMessage.getSender().asOptional();
ValueExtractor<Boolean> HAS_ATTACHMENT_EXTRACTOR = deletedMessage -> Optional.of(deletedMessage.hasAttachment());
- ValueExtractor<List<MailboxId>> ORIGIN_MAILBOXES_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getOriginMailboxes());
+ ValueExtractor<Collection<MailboxId>> ORIGIN_MAILBOXES_EXTRACTOR = deletedMessage -> Optional.of(deletedMessage.getOriginMailboxes());
ValueExtractor<String> SUBJECT_EXTRACTOR = DeletedMessage::getSubject;
}
DeletedMessageField<ZonedDateTime> DELETION_DATE = () -> ValueExtractor.DELETION_DATE_EXTRACTOR;
DeletedMessageField<ZonedDateTime> DELIVERY_DATE = () -> ValueExtractor.DELIVERY_DATE_EXTRACTOR;
- DeletedMessageField<List<MailAddress>> RECIPIENTS = () -> ValueExtractor.RECIPIENTS_EXTRACTOR;
+ DeletedMessageField<Collection<MailAddress>> RECIPIENTS = () -> ValueExtractor.RECIPIENTS_EXTRACTOR;
DeletedMessageField<MailAddress> SENDER = () -> ValueExtractor.SENDER_EXTRACTOR;
DeletedMessageField<Boolean> HAS_ATTACHMENT = () -> ValueExtractor.HAS_ATTACHMENT_EXTRACTOR;
- DeletedMessageField<List<MailboxId>> ORIGIN_MAILBOXES = () -> ValueExtractor.ORIGIN_MAILBOXES_EXTRACTOR;
+ DeletedMessageField<Collection<MailboxId>> ORIGIN_MAILBOXES = () -> ValueExtractor.ORIGIN_MAILBOXES_EXTRACTOR;
DeletedMessageField<String> SUBJECT = () -> ValueExtractor.SUBJECT_EXTRACTOR;
ValueExtractor<T> valueExtractor();
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Query.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Query.java
index c7b1f9b..039fd52 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Query.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Query.java
@@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableList;
public class Query {
public static final Query ALL = new Query(ImmutableList.of());
+ private static final Predicate<DeletedMessage> MATCH_ALL = any -> true;
public static Query of(Criterion... criteria) {
return new Query(ImmutableList.copyOf(criteria));
@@ -42,6 +43,7 @@ public class Query {
public Predicate<DeletedMessage> toPredicate() {
return criteria.stream()
.map(Criterion::toPredicate)
- .reduce(any -> true, Predicate::and);
+ .reduce(Predicate::and)
+ .orElse(MATCH_ALL);
}
}
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/ValueMatcher.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/ValueMatcher.java
deleted file mode 100644
index 337fff7..0000000
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/ValueMatcher.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- ****************************************************************/
-
-package org.apache.james.vault.search;
-
-import java.time.ZonedDateTime;
-import java.util.List;
-import java.util.Locale;
-
-public interface ValueMatcher<T> {
-
- boolean matches(T referenceValue);
-
- interface SingleValueMatcher<T> extends ValueMatcher<T> {
- T testedValue();
- }
-
- interface ListMatcher<T> extends ValueMatcher<List<T>> {
- T testedValue();
- }
-
- interface Equals<T> extends SingleValueMatcher<T> {
- @Override
- default boolean matches(T referenceValue) {
- return referenceValue.equals(testedValue());
- }
- }
-
- interface StringContains extends SingleValueMatcher<String> {
- @Override
- default boolean matches(String referenceValue) {
- return referenceValue.contains(testedValue());
- }
- }
-
- interface StringContainsIgnoreCase extends SingleValueMatcher<String> {
- @Override
- default boolean matches(String referenceValue) {
- return referenceValue.toLowerCase(Locale.US).contains(testedValue().toLowerCase(Locale.US));
- }
- }
-
- interface ListContains<T> extends ListMatcher<T> {
- @Override
- default boolean matches(List<T> referenceValue) {
- return referenceValue.contains(testedValue());
- }
- }
-
- interface ZonedDateTimeBeforeOrEquals extends SingleValueMatcher<ZonedDateTime> {
- @Override
- default boolean matches(ZonedDateTime referenceValue) {
- return referenceValue.isBefore(testedValue()) || referenceValue.isEqual(testedValue());
- }
- }
-
- interface ZonedDateTimeAfterOrEquals extends SingleValueMatcher<ZonedDateTime> {
- @Override
- default boolean matches(ZonedDateTime referenceValue) {
- return referenceValue.isAfter(testedValue()) || referenceValue.isEqual(testedValue());
- }
- }
-}
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java
index c2fb8c2..84690dc 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageFixture.java
@@ -39,6 +39,7 @@ public interface DeletedMessageFixture {
InMemoryMessageId MESSAGE_ID_2 = InMemoryMessageId.of(45);
InMemoryId MAILBOX_ID_1 = InMemoryId.of(43);
InMemoryId MAILBOX_ID_2 = InMemoryId.of(44);
+ InMemoryId MAILBOX_ID_3 = InMemoryId.of(45);
User USER = User.fromUsername("bob@apache.org");
User USER_2 = User.fromUsername("dimitri@apache.org");
ZonedDateTime DELIVERY_DATE = ZonedDateTime.parse("2014-10-30T14:12:00Z");
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java
new file mode 100644
index 0000000..cd2c852
--- /dev/null
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java
@@ -0,0 +1,653 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.vault;
+
+import static org.apache.james.vault.DeletedMessageFixture.CONTENT;
+import static org.apache.james.vault.DeletedMessageFixture.DELETION_DATE;
+import static org.apache.james.vault.DeletedMessageFixture.DELIVERY_DATE;
+import static org.apache.james.vault.DeletedMessageFixture.MAILBOX_ID_1;
+import static org.apache.james.vault.DeletedMessageFixture.MAILBOX_ID_2;
+import static org.apache.james.vault.DeletedMessageFixture.MAILBOX_ID_3;
+import static org.apache.james.vault.DeletedMessageFixture.SUBJECT;
+import static org.apache.james.vault.DeletedMessageFixture.USER;
+import static org.apache.james.vault.DeletedMessageFixture.USER_2;
+import static org.apache.mailet.base.MailAddressFixture.RECIPIENT1;
+import static org.apache.mailet.base.MailAddressFixture.RECIPIENT2;
+import static org.apache.mailet.base.MailAddressFixture.RECIPIENT3;
+import static org.apache.mailet.base.MailAddressFixture.SENDER;
+import static org.apache.mailet.base.MailAddressFixture.SENDER2;
+import static org.apache.mailet.base.MailAddressFixture.SENDER3;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.core.MaybeSender;
+import org.apache.james.core.User;
+import org.apache.james.mailbox.inmemory.InMemoryMessageId;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.vault.search.CriterionFactory;
+import org.apache.james.vault.search.Query;
+import org.junit.jupiter.api.Test;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public interface DeletedMessageVaultSearchContract {
+ DeletedMessageVault getVault();
+
+ interface AllContracts extends SubjectContract, DeletionDateContract, DeliveryDateContract, RecipientsContract, SenderContract,
+ HasAttachmentsContract, OriginMailboxesContract, PerUserContract, MultipleSearchCriterionsContract {
+ }
+
+ interface DeliveryDateContract extends DeletedMessageVaultSearchContract {
+
+ @Test
+ default void shouldReturnMessagesWithDeliveryBeforeDateWhenBeforeOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeliveryDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeliveryDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deliveryDate().beforeOrEquals(DELIVERY_DATE.plusMinutes(30)))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesWithDeliveryEqualDateWhenBeforeOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeliveryDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeliveryDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deliveryDate().beforeOrEquals(DELIVERY_DATE))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesWithDeliveryAfterDateWhenAfterOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeliveryDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeliveryDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deliveryDate().afterOrEquals(DELIVERY_DATE.plusMinutes(30)))))
+ .containsOnly(message2);
+ }
+
+ @Test
+ default void shouldReturnMessagesWithDeliveryEqualDateWhenAfterOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeliveryDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeliveryDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deliveryDate().afterOrEquals(DELIVERY_DATE.plusMinutes(60)))))
+ .containsOnly(message2);
+ }
+ }
+
+ interface DeletionDateContract extends DeletedMessageVaultSearchContract {
+
+ @Test
+ default void shouldReturnMessagesWithDeletionBeforeDateWhenBeforeOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeletionDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeletionDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deletionDate().beforeOrEquals(DELIVERY_DATE.plusMinutes(30)))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesWithDeletionEqualDateWhenBeforeOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeletionDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeletionDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deletionDate().beforeOrEquals(DELIVERY_DATE))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesWithDeletionAfterDateWhenAfterOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeletionDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeletionDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deletionDate().afterOrEquals(DELIVERY_DATE.plusMinutes(30)))))
+ .containsOnly(message2);
+ }
+
+ @Test
+ default void shouldReturnMessagesWithDeletionEqualDateWhenAfterOrEquals() {
+ DeletedMessage message1 = storeMessageWithDeletionDate(DELIVERY_DATE);
+ DeletedMessage message2 = storeMessageWithDeletionDate(DELIVERY_DATE.plusMinutes(60));
+
+ assertThat(search(Query.of(CriterionFactory.deletionDate().afterOrEquals(DELIVERY_DATE.plusMinutes(60)))))
+ .containsOnly(message2);
+ }
+ }
+
+ interface RecipientsContract extends DeletedMessageVaultSearchContract {
+
+ @Test
+ default void shouldReturnMessagesWithRecipientWhenContains() {
+ DeletedMessage message1 = storeMessageWithRecipients(RECIPIENT1, RECIPIENT2);
+ DeletedMessage message2 = storeMessageWithRecipients(RECIPIENT1);
+ DeletedMessage message3 = storeMessageWithRecipients(RECIPIENT3);
+
+ assertThat(search(Query.of(CriterionFactory.containsRecipient(RECIPIENT1))))
+ .containsOnly(message1, message2);
+
+ }
+
+ @Test
+ default void shouldReturnNoMessageWhenDoesntContains() {
+ storeMessageWithRecipients(RECIPIENT1, RECIPIENT2);
+ storeMessageWithRecipients(RECIPIENT1);
+ storeMessageWithRecipients(RECIPIENT2);
+
+ assertThat(search(Query.of(CriterionFactory.containsRecipient(RECIPIENT3))))
+ .isEmpty();
+ }
+ }
+
+ interface SenderContract extends DeletedMessageVaultSearchContract {
+
+ @Test
+ default void shouldReturnMessagesWithSenderWhenEquals() {
+ DeletedMessage message1 = storeMessageWithSender(MaybeSender.of(SENDER));
+ DeletedMessage message2 = storeMessageWithSender(MaybeSender.of(SENDER2));
+
+ assertThat(search(Query.of(CriterionFactory.hasSender(SENDER))))
+ .containsOnly(message1);
+
+ }
+
+ @Test
+ default void shouldReturnNoMessageWhenSenderDoesntEquals() {
+ storeMessageWithSender(MaybeSender.of(SENDER));
+ storeMessageWithSender(MaybeSender.of(SENDER2));
+
+ assertThat(search(Query.of(CriterionFactory.hasSender(SENDER3))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldNotReturnMessagesWithNullSenderWhenEquals() {
+ DeletedMessage message1 = storeMessageWithSender(MaybeSender.of(SENDER));
+ storeMessageWithSender(MaybeSender.of(SENDER2));
+ storeMessageWithSender(MaybeSender.nullSender());
+ storeMessageWithSender(MaybeSender.nullSender());
+
+ assertThat(search(Query.of(CriterionFactory.hasSender(SENDER))))
+ .containsOnly(message1);
+ }
+ }
+
+ interface HasAttachmentsContract extends DeletedMessageVaultSearchContract {
+
+ @Test
+ default void shouldReturnMessagesWithAttachmentWhenHasAttachment() {
+ DeletedMessage message1 = storeMessageWithHasAttachment(true);
+ DeletedMessage message2 = storeMessageWithHasAttachment(false);
+ DeletedMessage message3 = storeMessageWithHasAttachment(true);
+
+ assertThat(search(Query.of(CriterionFactory.hasAttachment())))
+ .containsOnly(message1, message3);
+ }
+
+ @Test
+ default void shouldReturnMessagesWithOutAttachmentWhenHasNoAttachement() {
+ DeletedMessage message1 = storeMessageWithHasAttachment(false);
+ DeletedMessage message2 = storeMessageWithHasAttachment(false);
+ DeletedMessage message3 = storeMessageWithHasAttachment(true);
+
+ assertThat(search(Query.of(CriterionFactory.hasNoAttachment())))
+ .containsOnly(message1, message2);
+ }
+ }
+
+ interface OriginMailboxesContract extends DeletedMessageVaultSearchContract {
+
+ @Test
+ default void shouldReturnMessagesWithOriginMailboxesWhenContains() {
+ DeletedMessage message1 = storeMessageWithOriginMailboxes(MAILBOX_ID_1, MAILBOX_ID_2);
+ DeletedMessage message2 = storeMessageWithOriginMailboxes(MAILBOX_ID_1);
+ DeletedMessage message3 = storeMessageWithOriginMailboxes(MAILBOX_ID_3);
+
+ assertThat(search(Query.of(CriterionFactory.containsOriginMailbox(MAILBOX_ID_1))))
+ .containsOnly(message1, message2);
+
+ }
+
+ @Test
+ default void shouldReturnNoMessageWhenOriginMailboxesDoesntContains() {
+ storeMessageWithOriginMailboxes(MAILBOX_ID_1, MAILBOX_ID_2);
+ storeMessageWithOriginMailboxes(MAILBOX_ID_1);
+ storeMessageWithOriginMailboxes(MAILBOX_ID_2);
+
+ assertThat(search(Query.of(CriterionFactory.containsOriginMailbox(MAILBOX_ID_3))))
+ .isEmpty();
+ }
+ }
+
+ interface SubjectContract extends DeletedMessageVaultSearchContract {
+
+ String APACHE_JAMES_PROJECT = "apache james project";
+ String OPEN_SOURCE_SOFTWARE = "open source software";
+
+ @Test
+ default void shouldReturnMessagesContainsAtTheMiddle() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().contains("james"))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesContainsAtTheBeginning() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().contains("apache"))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesContainsAtTheEnd() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().contains("software"))))
+ .containsOnly(message2);
+ }
+
+ @Test
+ default void shouldNotReturnMissingSubjectMessagesWhenContains() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageNoSubject();
+
+ assertThat(search(Query.of(CriterionFactory.subject().contains("james"))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldNotReturnMessagesContainsIgnoreCaseWhenContains() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().contains("SoftWare"))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldReturnMessagesContainsIgnoreCaseAtTheMiddle() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().containsIgnoreCase("JAmEs"))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesContainsIgnoreCaseAtTheBeginning() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().containsIgnoreCase("SouRCE"))))
+ .containsOnly(message2);
+ }
+
+ @Test
+ default void shouldReturnMessagesContainsIgnoreCaseAtTheEnd() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(
+ CriterionFactory.subject().containsIgnoreCase("ProJECT"))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesContainsWhenContainsIgnoreCase() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(
+ CriterionFactory.subject().containsIgnoreCase("project"))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldNotReturnMissingSubjectMessagesWhenContainsIgnoreCase() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageNoSubject();
+
+ assertThat(search(Query.of(CriterionFactory.subject().containsIgnoreCase("JAMes"))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldReturnMessagesStrictlyEquals() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equals(APACHE_JAMES_PROJECT))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldNotReturnMessagesContainsWhenEquals() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equals("james"))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldNotReturnMessagesContainsIgnoreCaseWhenEquals() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equals("proJECT"))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldNotReturnMessagesEqualsIgnoreCaseWhenEquals() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equals("Apache James Project"))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldReturnMessagesWhenEqualsIgnoreCase() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equals("Apache James PROJECT"))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldReturnMessagesStrictlyEqualsWhenEqualsIgnoreCase() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equalsIgnoreCase(APACHE_JAMES_PROJECT))))
+ .containsOnly(message1);
+ }
+
+ @Test
+ default void shouldNotReturnMessagesContainsWhenEqualsIgnoreCase() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equalsIgnoreCase("james"))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldNotReturnMessagesContainsIgnoreCaseWhenEqualsIgnoreCase() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageWithSubject(OPEN_SOURCE_SOFTWARE);
+
+ assertThat(search(Query.of(CriterionFactory.subject().equalsIgnoreCase("proJECT"))))
+ .isEmpty();
+ }
+
+ @Test
+ default void shouldNotReturnMissingSubjectMessagesWhenEquals() {
+ DeletedMessage message1 = storeMessageWithSubject(APACHE_JAMES_PROJECT);
+ DeletedMessage message2 = storeMessageNoSubject();
+
+ assertThat(search(Query.of(CriterionFactory.subject().equals(APACHE_JAMES_PROJECT))))
+ .containsOnly(message1);
+ }
+ }
+
+ interface MultipleSearchCriterionsContract extends DeletedMessageVaultSearchContract {
+
+ @Test
+ default void searchShouldReturnOnlyMessageWhichMatchMultipleCriterions() {
+ DeletedMessage message1 = storeDefaultMessage();
+ DeletedMessage message2 = storeDefaultMessage();
+ DeletedMessage message3 = storeDefaultMessage();
+ DeletedMessage message4 = storeMessageWithOriginMailboxes(MAILBOX_ID_2);
+ DeletedMessage message5 = storeMessageWithSender(MaybeSender.of(SENDER2));
+ DeletedMessage message6 = storeMessageWithDeletionDate(DELETION_DATE.minusHours(1));
+
+ assertThat(search(Query.of(
+ CriterionFactory.containsOriginMailbox(MAILBOX_ID_1),
+ CriterionFactory.hasSender(SENDER),
+ CriterionFactory.deletionDate().afterOrEquals(DELETION_DATE))))
+ .containsOnly(message1, message2, message3);
+ }
+
+ @Test
+ default void searchShouldReturnAllMessageWhenSearchForAllCriterions() {
+ DeletedMessage message1 = storeDefaultMessage();
+ DeletedMessage message2 = storeDefaultMessage();
+ DeletedMessage message3 = storeDefaultMessage();
+ DeletedMessage message4 = storeMessageWithOriginMailboxes(MAILBOX_ID_2);
+ DeletedMessage message5 = storeMessageWithSender(MaybeSender.of(SENDER2));
+ DeletedMessage message6 = storeMessageWithDeletionDate(DELETION_DATE.minusHours(1));
+
+ assertThat(search(Query.ALL))
+ .containsOnly(message1, message2, message3, message4, message5, message6);
+ }
+
+ @Test
+ default void searchShouldReturnAllMessageEvenNullSubjectWhenSearchForAllCriterions() {
+ DeletedMessage message1 = storeDefaultMessage();
+ DeletedMessage message2 = storeDefaultMessage();
+ DeletedMessage message3 = storeDefaultMessage();
+ DeletedMessage message4 = storeMessageNoSubject();
+
+ assertThat(search(Query.ALL))
+ .containsOnly(message1, message2, message3, message4);
+ }
+
+ @Test
+ default void searchShouldReturnAllMessageEvenNullSenderWhenSearchForAllCriterions() {
+ DeletedMessage message1 = storeDefaultMessage();
+ DeletedMessage message2 = storeDefaultMessage();
+ DeletedMessage message3 = storeDefaultMessage();
+ DeletedMessage message4 = storeMessageWithSender(MaybeSender.nullSender());
+
+ assertThat(search(Query.ALL))
+ .containsOnly(message1, message2, message3, message4);
+ }
+
+ @Test
+ default void searchShouldReturnMessageWhenHavingSameCriterionTypes() {
+ DeletedMessage message1 = storeMessageWithRecipients(RECIPIENT1, RECIPIENT2, RECIPIENT3);
+ DeletedMessage message2 = storeMessageWithRecipients(RECIPIENT1, RECIPIENT2);
+ DeletedMessage message3 = storeMessageWithRecipients(RECIPIENT1);
+
+ assertThat(search(Query.of(
+ CriterionFactory.containsRecipient(RECIPIENT1),
+ CriterionFactory.containsRecipient(RECIPIENT2))))
+ .containsOnly(message1, message2);
+ }
+
+ @Test
+ default void searchShouldReturnEmptyWhenHavingSameCriterionTypesButOppositeMatching() {
+ DeletedMessage message1 = storeMessageWithDeletionDate(DELETION_DATE);
+ DeletedMessage message2 = storeMessageWithDeletionDate(DELETION_DATE);
+ DeletedMessage message3 = storeMessageWithDeletionDate(DELETION_DATE.plusHours(2));
+ DeletedMessage message4 = storeMessageWithDeletionDate(DELETION_DATE.minusHours(2));
+
+ assertThat(search(Query.of(
+ CriterionFactory.deletionDate().afterOrEquals(DELETION_DATE.plusHours(1)),
+ CriterionFactory.deletionDate().beforeOrEquals(DELETION_DATE.minusHours(1)))))
+ .isEmpty();
+ }
+ }
+
+ interface PerUserContract extends DeletedMessageVaultSearchContract {
+
+ default DeletedMessage storeMessageWithUser(User user) {
+ DeletedMessage deletedMessage = defaultDeletedMessageFinalStage(DELIVERY_DATE, DELETION_DATE)
+ .subject(SUBJECT)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, user);
+ }
+
+ @Test
+ default void searchForAnUserShouldNotReturnMessagesFromAnotherUser() {
+ DeletedMessage message1 = storeMessageWithUser(USER);
+ DeletedMessage message2 = storeMessageWithUser(USER);
+ DeletedMessage message3 = storeMessageWithUser(USER_2);
+
+ assertThat(search(USER, Query.ALL))
+ .containsOnly(message1, message2);
+ }
+ }
+
+ AtomicLong MESSAGE_ID_GENERATOR = new AtomicLong(0);
+
+ default List<DeletedMessage> search(Query query) {
+ return search(USER, query);
+ }
+
+ default List<DeletedMessage> search(User user, Query query) {
+ return Flux.from(getVault().search(user, query)).collectList().block();
+ }
+
+ default DeletedMessage storeMessageWithDeliveryDate(ZonedDateTime deliveryDate) {
+ DeletedMessage deletedMessage = defaultDeletedMessageFinalStage(deliveryDate, DELETION_DATE)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeMessageWithDeletionDate(ZonedDateTime delitionDate) {
+ DeletedMessage deletedMessage = defaultDeletedMessageFinalStage(DELIVERY_DATE, delitionDate)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeMessageWithRecipients(MailAddress... recipients) {
+ DeletedMessage deletedMessage = DeletedMessage.builder()
+ .messageId(InMemoryMessageId.of(MESSAGE_ID_GENERATOR.incrementAndGet()))
+ .originMailboxes(MAILBOX_ID_1)
+ .user(USER)
+ .deliveryDate(DELIVERY_DATE)
+ .deletionDate(DELETION_DATE)
+ .sender(MaybeSender.of(SENDER))
+ .recipients(recipients)
+ .content(() -> new ByteArrayInputStream(CONTENT))
+ .hasAttachment(false)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeMessageWithSender(MaybeSender sender) {
+ DeletedMessage deletedMessage = DeletedMessage.builder()
+ .messageId(InMemoryMessageId.of(MESSAGE_ID_GENERATOR.incrementAndGet()))
+ .originMailboxes(MAILBOX_ID_1)
+ .user(USER)
+ .deliveryDate(DELIVERY_DATE)
+ .deletionDate(DELETION_DATE)
+ .sender(sender)
+ .recipients(RECIPIENT1, RECIPIENT2)
+ .content(() -> new ByteArrayInputStream(CONTENT))
+ .hasAttachment(false)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeMessageWithHasAttachment(boolean hasAttachment) {
+ DeletedMessage deletedMessage = DeletedMessage.builder()
+ .messageId(InMemoryMessageId.of(MESSAGE_ID_GENERATOR.incrementAndGet()))
+ .originMailboxes(MAILBOX_ID_1)
+ .user(USER)
+ .deliveryDate(DELIVERY_DATE)
+ .deletionDate(DELETION_DATE)
+ .sender(MaybeSender.of(SENDER))
+ .recipients(RECIPIENT1, RECIPIENT2)
+ .content(() -> new ByteArrayInputStream(CONTENT))
+ .hasAttachment(hasAttachment)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeMessageWithOriginMailboxes(MailboxId... originMailboxIds) {
+ DeletedMessage deletedMessage = DeletedMessage.builder()
+ .messageId(InMemoryMessageId.of(MESSAGE_ID_GENERATOR.incrementAndGet()))
+ .originMailboxes(originMailboxIds)
+ .user(USER)
+ .deliveryDate(DELIVERY_DATE)
+ .deletionDate(DELETION_DATE)
+ .sender(MaybeSender.of(SENDER))
+ .recipients(RECIPIENT1, RECIPIENT2)
+ .content(() -> new ByteArrayInputStream(CONTENT))
+ .hasAttachment(true)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeMessageNoSubject() {
+ DeletedMessage deletedMessage = defaultDeletedMessageFinalStage(DELIVERY_DATE, DELETION_DATE)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeMessageWithSubject(String subject) {
+ DeletedMessage deletedMessage = defaultDeletedMessageFinalStage(DELIVERY_DATE, DELETION_DATE)
+ .subject(subject)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeDefaultMessage() {
+ DeletedMessage deletedMessage = defaultDeletedMessageFinalStage(DELIVERY_DATE, DELETION_DATE)
+ .subject(SUBJECT)
+ .build();
+
+ return storeDeletedMessage(deletedMessage, USER);
+ }
+
+ default DeletedMessage storeDeletedMessage(DeletedMessage deletedMessage, User user) {
+ Mono.from(getVault().append(user, deletedMessage))
+ .block();
+ return deletedMessage;
+ }
+
+ default DeletedMessage.Builder.FinalStage defaultDeletedMessageFinalStage(ZonedDateTime deliveryDate, ZonedDateTime deletionDate) {
+ return DeletedMessage.builder()
+ .messageId(InMemoryMessageId.of(MESSAGE_ID_GENERATOR.incrementAndGet()))
+ .originMailboxes(MAILBOX_ID_1)
+ .user(USER)
+ .deliveryDate(deliveryDate)
+ .deletionDate(deletionDate)
+ .sender(MaybeSender.of(SENDER))
+ .recipients(RECIPIENT1)
+ .content(() -> new ByteArrayInputStream(CONTENT))
+ .hasAttachment(false);
+ }
+}
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/memory/MemoryDeletedMessagesVaultTest.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/memory/MemoryDeletedMessagesVaultTest.java
index 2598d62..9b58f29 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/memory/MemoryDeletedMessagesVaultTest.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/memory/MemoryDeletedMessagesVaultTest.java
@@ -21,9 +21,10 @@ package org.apache.james.vault.memory;
import org.apache.james.vault.DeletedMessageVault;
import org.apache.james.vault.DeletedMessageVaultContract;
+import org.apache.james.vault.DeletedMessageVaultSearchContract;
import org.junit.jupiter.api.BeforeEach;
-public class MemoryDeletedMessagesVaultTest implements DeletedMessageVaultContract {
+public class MemoryDeletedMessagesVaultTest implements DeletedMessageVaultContract, DeletedMessageVaultSearchContract.AllContracts {
private MemoryDeletedMessagesVault memoryDeletedMessagesVault;
diff --git a/mailet/test/src/main/java/org/apache/mailet/base/MailAddressFixture.java b/mailet/test/src/main/java/org/apache/mailet/base/MailAddressFixture.java
index 4efe093..455cb51 100644
--- a/mailet/test/src/main/java/org/apache/mailet/base/MailAddressFixture.java
+++ b/mailet/test/src/main/java/org/apache/mailet/base/MailAddressFixture.java
@@ -34,6 +34,8 @@ public class MailAddressFixture {
public static final Domain JAMES2_APACHE_ORG_DOMAIN = Domain.of(JAMES2_APACHE_ORG);
public static final MailAddress SENDER = createMailAddress("sender@" + JAMES_LOCAL);
+ public static final MailAddress SENDER2 = createMailAddress("sender2@" + JAMES_LOCAL);
+ public static final MailAddress SENDER3 = createMailAddress("sender3@" + JAMES_LOCAL);
public static final MailAddress RECIPIENT1 = createMailAddress("recipient1@" + JAMES_LOCAL);
public static final MailAddress RECIPIENT2 = createMailAddress("recipient2@" + JAMES_LOCAL);
public static final MailAddress RECIPIENT3 = createMailAddress("recipient3@" + JAMES_LOCAL);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[james-project] 02/04: MAILBOX-381 Search models for Query
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit bcf05109a3f9128a151688dadc84da35a64994da
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue Feb 26 11:00:33 2019 +0700
MAILBOX-381 Search models for Query
---
.../org/apache/james/vault/search/Criterion.java | 43 ++++++++
.../james/vault/search/CriterionFactory.java | 114 +++++++++++++++++++++
.../james/vault/search/DeletedMessageField.java | 53 ++++++++++
.../apache/james/vault/search/ValueMatcher.java | 79 ++++++++++++++
4 files changed, 289 insertions(+)
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java
new file mode 100644
index 0000000..cf62ee3
--- /dev/null
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Criterion.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.vault.search;
+
+import java.util.function.Predicate;
+
+import org.apache.james.vault.DeletedMessage;
+
+public class Criterion<T> {
+
+ private static final boolean DEFAULT_TO_NON_MATCHED_IF_NON_EXIST = false;
+
+ private final DeletedMessageField<T> field;
+ private final ValueMatcher<T> valueMatcher;
+
+ Criterion(DeletedMessageField<T> field, ValueMatcher<T> valueMatcher) {
+ this.field = field;
+ this.valueMatcher = valueMatcher;
+ }
+
+ public Predicate<DeletedMessage> toPredicate() {
+ return deletedMessage -> field.valueExtractor().extract(deletedMessage)
+ .map(valueMatcher::matches)
+ .orElse(DEFAULT_TO_NON_MATCHED_IF_NON_EXIST);
+ }
+}
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java
new file mode 100644
index 0000000..0ebd408
--- /dev/null
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/CriterionFactory.java
@@ -0,0 +1,114 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.vault.search;
+
+import static org.apache.james.vault.search.DeletedMessageField.DELETION_DATE;
+import static org.apache.james.vault.search.DeletedMessageField.DELIVERY_DATE;
+import static org.apache.james.vault.search.DeletedMessageField.HAS_ATTACHMENT;
+import static org.apache.james.vault.search.DeletedMessageField.ORIGIN_MAILBOXES;
+import static org.apache.james.vault.search.DeletedMessageField.RECIPIENTS;
+import static org.apache.james.vault.search.DeletedMessageField.SENDER;
+import static org.apache.james.vault.search.DeletedMessageField.SUBJECT;
+
+import java.time.ZonedDateTime;
+import java.util.List;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.mailbox.model.MailboxId;
+
+public interface CriterionFactory<T> {
+
+ DeletedMessageField<T> deletedMessageField();
+
+ interface EqualsMatcherFactory<T> extends CriterionFactory<T> {
+
+ default Criterion<T> equalsMatcher(T testedValue) {
+ ValueMatcher.Equals<T> matcher = () -> testedValue;
+ return new Criterion<>(deletedMessageField(), matcher);
+ }
+ }
+
+ interface StringMatcherFactory extends CriterionFactory<String> {
+
+ default Criterion<String> contains(String subString) {
+ ValueMatcher.StringContains matcher = () -> subString;
+ return new Criterion<>(deletedMessageField(), matcher);
+ }
+
+ default Criterion<String> containsIgnoreCase(String subString) {
+ ValueMatcher.StringContainsIgnoreCase matcher = () -> subString;
+ return new Criterion<>(deletedMessageField(), matcher);
+ }
+
+ default Criterion<String> equals(String testedString) {
+ ValueMatcher.Equals<String> matcher = () -> testedString;
+ return new Criterion<>(deletedMessageField(), matcher);
+ }
+ }
+
+ interface ZonedDateTimeMatcherFactory extends CriterionFactory<ZonedDateTime> {
+
+ default Criterion<ZonedDateTime> beforeOrEquals(ZonedDateTime testedInstant) {
+ ValueMatcher.ZonedDateTimeBeforeOrEquals matcher = () -> testedInstant;
+ return new Criterion<>(deletedMessageField(), matcher);
+ }
+
+ default Criterion<ZonedDateTime> afterOrEquals(ZonedDateTime testedInstant) {
+ ValueMatcher.ZonedDateTimeAfterOrEquals matcher = () -> testedInstant;
+ return new Criterion<>(deletedMessageField(), matcher);
+ }
+ }
+
+ interface ListMatcherFactory<T> extends CriterionFactory<List<T>> {
+
+ default Criterion<List<T>> contains(T testedValue) {
+ ValueMatcher.ListContains<T> matcher = () -> testedValue;
+ return new Criterion<>(deletedMessageField(), matcher);
+ }
+ }
+
+ static ZonedDateTimeMatcherFactory deletionDate() {
+ return () -> DELETION_DATE;
+ }
+
+ static ZonedDateTimeMatcherFactory deliveryDate() {
+ return () -> DELIVERY_DATE;
+ }
+
+ static ListMatcherFactory<MailAddress> recipients() {
+ return () -> RECIPIENTS;
+ }
+
+ static EqualsMatcherFactory<MailAddress> sender() {
+ return () -> SENDER;
+ }
+
+ static EqualsMatcherFactory<Boolean> hasAttachment() {
+ return () -> HAS_ATTACHMENT;
+ }
+
+ static StringMatcherFactory subject() {
+ return () -> SUBJECT;
+ }
+
+ static ListMatcherFactory<MailboxId> originMailboxes() {
+ return () -> ORIGIN_MAILBOXES;
+ }
+}
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java
new file mode 100644
index 0000000..f0450b0
--- /dev/null
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/DeletedMessageField.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.vault.search;
+
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.vault.DeletedMessage;
+
+public interface DeletedMessageField<T> {
+ interface ValueExtractor<T> {
+ Optional<T> extract(DeletedMessage deletedMessage);
+
+ ValueExtractor<ZonedDateTime> DELETION_DATE_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getDeletionDate());
+ ValueExtractor<ZonedDateTime> DELIVERY_DATE_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getDeliveryDate());
+ ValueExtractor<List<MailAddress>> RECIPIENTS_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getRecipients());
+ ValueExtractor<MailAddress> SENDER_EXTRACTOR = deletedMessage -> deletedMessage.getSender().asOptional();
+ ValueExtractor<Boolean> HAS_ATTACHMENT_EXTRACTOR = deletedMessage -> Optional.of(deletedMessage.hasAttachment());
+ ValueExtractor<List<MailboxId>> ORIGIN_MAILBOXES_EXTRACTOR = deletedMessage -> Optional.ofNullable(deletedMessage.getOriginMailboxes());
+ ValueExtractor<String> SUBJECT_EXTRACTOR = DeletedMessage::getSubject;
+
+ }
+
+ DeletedMessageField<ZonedDateTime> DELETION_DATE = () -> ValueExtractor.DELETION_DATE_EXTRACTOR;
+ DeletedMessageField<ZonedDateTime> DELIVERY_DATE = () -> ValueExtractor.DELIVERY_DATE_EXTRACTOR;
+ DeletedMessageField<List<MailAddress>> RECIPIENTS = () -> ValueExtractor.RECIPIENTS_EXTRACTOR;
+ DeletedMessageField<MailAddress> SENDER = () -> ValueExtractor.SENDER_EXTRACTOR;
+ DeletedMessageField<Boolean> HAS_ATTACHMENT = () -> ValueExtractor.HAS_ATTACHMENT_EXTRACTOR;
+ DeletedMessageField<List<MailboxId>> ORIGIN_MAILBOXES = () -> ValueExtractor.ORIGIN_MAILBOXES_EXTRACTOR;
+ DeletedMessageField<String> SUBJECT = () -> ValueExtractor.SUBJECT_EXTRACTOR;
+
+ ValueExtractor<T> valueExtractor();
+}
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/ValueMatcher.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/ValueMatcher.java
new file mode 100644
index 0000000..337fff7
--- /dev/null
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/ValueMatcher.java
@@ -0,0 +1,79 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.vault.search;
+
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.Locale;
+
+public interface ValueMatcher<T> {
+
+ boolean matches(T referenceValue);
+
+ interface SingleValueMatcher<T> extends ValueMatcher<T> {
+ T testedValue();
+ }
+
+ interface ListMatcher<T> extends ValueMatcher<List<T>> {
+ T testedValue();
+ }
+
+ interface Equals<T> extends SingleValueMatcher<T> {
+ @Override
+ default boolean matches(T referenceValue) {
+ return referenceValue.equals(testedValue());
+ }
+ }
+
+ interface StringContains extends SingleValueMatcher<String> {
+ @Override
+ default boolean matches(String referenceValue) {
+ return referenceValue.contains(testedValue());
+ }
+ }
+
+ interface StringContainsIgnoreCase extends SingleValueMatcher<String> {
+ @Override
+ default boolean matches(String referenceValue) {
+ return referenceValue.toLowerCase(Locale.US).contains(testedValue().toLowerCase(Locale.US));
+ }
+ }
+
+ interface ListContains<T> extends ListMatcher<T> {
+ @Override
+ default boolean matches(List<T> referenceValue) {
+ return referenceValue.contains(testedValue());
+ }
+ }
+
+ interface ZonedDateTimeBeforeOrEquals extends SingleValueMatcher<ZonedDateTime> {
+ @Override
+ default boolean matches(ZonedDateTime referenceValue) {
+ return referenceValue.isBefore(testedValue()) || referenceValue.isEqual(testedValue());
+ }
+ }
+
+ interface ZonedDateTimeAfterOrEquals extends SingleValueMatcher<ZonedDateTime> {
+ @Override
+ default boolean matches(ZonedDateTime referenceValue) {
+ return referenceValue.isAfter(testedValue()) || referenceValue.isEqual(testedValue());
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[james-project] 04/04: MAILBOX-384 Adding a failed test of a conner
case locale string search
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 370d02c961c9031c84c0cfeece10aabc24bd276a
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Feb 28 11:02:22 2019 +0700
MAILBOX-384 Adding a failed test of a conner case locale string search
---
.../vault/DeletedMessageVaultSearchContract.java | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java
index cd2c852..22fdc3d 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultSearchContract.java
@@ -39,6 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.io.ByteArrayInputStream;
import java.time.ZonedDateTime;
import java.util.List;
+import java.util.Locale;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.james.core.MailAddress;
@@ -48,6 +49,7 @@ import org.apache.james.mailbox.inmemory.InMemoryMessageId;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.vault.search.CriterionFactory;
import org.apache.james.vault.search.Query;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
@@ -57,7 +59,7 @@ public interface DeletedMessageVaultSearchContract {
DeletedMessageVault getVault();
interface AllContracts extends SubjectContract, DeletionDateContract, DeliveryDateContract, RecipientsContract, SenderContract,
- HasAttachmentsContract, OriginMailboxesContract, PerUserContract, MultipleSearchCriterionsContract {
+ HasAttachmentsContract, OriginMailboxesContract, PerUserContract, MultipleSearchCriterionsContract, StringByLocaleContract {
}
interface DeliveryDateContract extends DeletedMessageVaultSearchContract {
@@ -521,6 +523,22 @@ public interface DeletedMessageVaultSearchContract {
}
}
+ interface StringByLocaleContract extends DeletedMessageVaultSearchContract {
+
+ @Disabled("MAILBOX-384 DeletedMessageVault search will return a wrong result in case of using string " +
+ "equalsIgnoreCase with a special locale")
+ @Test
+ default void shouldReturnsMessageWhenPassingAStringInDifferentLocaleToContainsIgnoreCase() {
+ Locale TURKISH_LOCALE = Locale.forLanguageTag("tr");
+ String subjectInTurkishLanguage = "TITLE";
+ DeletedMessage message1 = storeMessageWithSubject(subjectInTurkishLanguage);
+
+ String subjectLowercase = subjectInTurkishLanguage.toLowerCase(TURKISH_LOCALE);
+ assertThat(search(Query.of(CriterionFactory.subject().containsIgnoreCase(subjectLowercase))))
+ .contains(message1);
+ }
+ }
+
AtomicLong MESSAGE_ID_GENERATOR = new AtomicLong(0);
default List<DeletedMessage> search(Query query) {
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[james-project] 01/04: MAILBOX-381 Move Query to search package
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit dae0bc7fb664c5b99fa7bef46b85777dfaf429f3
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue Feb 26 10:59:22 2019 +0700
MAILBOX-381 Move Query to search package
---
.../java/org/apache/james/vault/DeletedMessageVault.java | 1 +
.../java/org/apache/james/vault/{ => search}/Query.java | 15 ++++++++++-----
.../apache/james/vault/DeletedMessageVaultContract.java | 2 +-
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVault.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVault.java
index 30efb1b..a6bc9bb 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVault.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVault.java
@@ -21,6 +21,7 @@ package org.apache.james.vault;
import org.apache.james.core.User;
import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.vault.search.Query;
import org.reactivestreams.Publisher;
public interface DeletedMessageVault {
diff --git a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/Query.java b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Query.java
similarity index 78%
rename from mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/Query.java
rename to mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Query.java
index 4b7611c..c7b1f9b 100644
--- a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/Query.java
+++ b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/search/Query.java
@@ -17,17 +17,20 @@
* under the License. *
****************************************************************/
-package org.apache.james.vault;
+package org.apache.james.vault.search;
import java.util.List;
+import java.util.function.Predicate;
+
+import org.apache.james.vault.DeletedMessage;
import com.google.common.collect.ImmutableList;
public class Query {
public static final Query ALL = new Query(ImmutableList.of());
- interface Criterion {
-
+ public static Query of(Criterion... criteria) {
+ return new Query(ImmutableList.copyOf(criteria));
}
private final List<Criterion> criteria;
@@ -36,7 +39,9 @@ public class Query {
this.criteria = criteria;
}
- public List<Criterion> getCriteria() {
- return criteria;
+ public Predicate<DeletedMessage> toPredicate() {
+ return criteria.stream()
+ .map(Criterion::toPredicate)
+ .reduce(any -> true, Predicate::and);
}
}
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java
index 0c57404..c2125f1 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultContract.java
@@ -25,7 +25,7 @@ import static org.apache.james.vault.DeletedMessageFixture.DELETED_MESSAGE_GENER
import static org.apache.james.vault.DeletedMessageFixture.MESSAGE_ID;
import static org.apache.james.vault.DeletedMessageFixture.USER;
import static org.apache.james.vault.DeletedMessageFixture.USER_2;
-import static org.apache.james.vault.Query.ALL;
+import static org.apache.james.vault.search.Query.ALL;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org