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 86044a30a55c9a4bdefddec6aa95d7020b2d193e Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Mon Nov 11 16:55:44 2019 +0700 MAILBOX-391 MailboxMapper::findMailboxWithPathLike should use MailboxQuery.UserBound --- .../james/mailbox/model/search/MailboxQuery.java | 26 ++++++++++++++-- .../cassandra/mail/CassandraMailboxMapper.java | 13 ++++---- .../cassandra/mail/CassandraMailboxMapperTest.java | 33 +++++++++++++++----- .../james/mailbox/jpa/mail/JPAMailboxMapper.java | 18 ++++++----- .../jpa/mail/TransactionalMailboxMapper.java | 5 +-- .../mailbox/maildir/mail/MaildirMailboxMapper.java | 31 ++++++++++++------- .../inmemory/mail/InMemoryMailboxMapper.java | 12 ++------ .../MailboxExpressionBackwardCompatibility.java | 35 +++++++++++++++++++++ .../james/mailbox/store/StoreMailboxManager.java | 36 +++++++++++----------- .../james/mailbox/store/mail/MailboxMapper.java | 3 +- .../store/quota/DefaultUserQuotaRootResolver.java | 8 ++++- .../mailbox/store/StoreMailboxManagerTest.java | 23 ++++++++++---- .../store/mail/model/MailboxMapperTest.java | 30 ++++++++++++++---- .../quota/DefaultUserQuotaRootResolverTest.java | 2 +- 14 files changed, 196 insertions(+), 79 deletions(-) diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/MailboxQuery.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/MailboxQuery.java index 616b108..388280f 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/MailboxQuery.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/MailboxQuery.java @@ -34,7 +34,7 @@ import com.google.common.base.Preconditions; /** * Expresses select criteria for mailboxes. */ -public final class MailboxQuery { +public class MailboxQuery { public static Builder builder() { return new Builder(); @@ -110,8 +110,24 @@ public final class MailboxQuery { } } - private final Optional<String> namespace; - private final Optional<String> user; + public static class UserBound extends MailboxQuery { + private UserBound(Optional<String> namespace, Optional<String> user, MailboxNameExpression mailboxNameExpression) { + super(namespace, user, mailboxNameExpression); + Preconditions.checkArgument(namespace.isPresent()); + Preconditions.checkArgument(user.isPresent()); + } + + public String getFixedNamespace() { + return namespace.get(); + } + + public String getFixedUser() { + return user.get(); + } + } + + protected final Optional<String> namespace; + protected final Optional<String> user; private final MailboxNameExpression mailboxNameExpression; /** @@ -162,6 +178,10 @@ public final class MailboxQuery { && isExpressionMatch(mailboxPath.getName()); } + public UserBound asUserBound() { + return new UserBound(namespace, user, mailboxNameExpression); + } + public String toString() { return MoreObjects.toStringHelper(this) .add("namespace", namespace) diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java index 919a9c2..06d5246 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java @@ -39,6 +39,7 @@ import org.apache.james.mailbox.model.MailboxACL; import org.apache.james.mailbox.model.MailboxACL.Right; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.MailboxQuery; import org.apache.james.mailbox.store.mail.MailboxMapper; import org.apache.james.util.ReactorUtils; import org.slf4j.Logger; @@ -134,9 +135,9 @@ public class CassandraMailboxMapper implements MailboxMapper { } @Override - public List<Mailbox> findMailboxWithPathLike(MailboxPath path) { - List<Mailbox> mailboxesV2 = toMailboxes(path, mailboxPathV2DAO.listUserMailboxes(path.getNamespace(), path.getUser())); - List<Mailbox> mailboxesV1 = toMailboxes(path, mailboxPathDAO.listUserMailboxes(path.getNamespace(), path.getUser())); + public List<Mailbox> findMailboxWithPathLike(MailboxQuery.UserBound query) { + List<Mailbox> mailboxesV2 = toMailboxes(query, mailboxPathV2DAO.listUserMailboxes(query.getFixedNamespace(), query.getFixedUser())); + List<Mailbox> mailboxesV1 = toMailboxes(query, mailboxPathDAO.listUserMailboxes(query.getFixedNamespace(), query.getFixedUser())); List<Mailbox> mailboxesV1NotInV2 = mailboxesV1.stream() .filter(mailboxV1 -> mailboxesV2.stream() @@ -150,11 +151,9 @@ public class CassandraMailboxMapper implements MailboxMapper { .build(); } - private List<Mailbox> toMailboxes(MailboxPath path, Flux<CassandraIdAndPath> listUserMailboxes) { - Pattern regex = Pattern.compile(constructEscapedRegexForMailboxNameMatching(path)); - + private List<Mailbox> toMailboxes(MailboxQuery.UserBound query, Flux<CassandraIdAndPath> listUserMailboxes) { return listUserMailboxes - .filter(idAndPath -> regex.matcher(idAndPath.getMailboxPath().getName()).matches()) + .filter(idAndPath -> query.isPathMatch(idAndPath.getMailboxPath())) .flatMap(this::retrieveMailbox) .collectList() .block(); diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java index ff0f610..e408fb7 100644 --- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java @@ -37,8 +37,9 @@ import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule; import org.apache.james.mailbox.exception.MailboxNotFoundException; import org.apache.james.mailbox.exception.TooLongMailboxNameException; import org.apache.james.mailbox.model.Mailbox; -import org.apache.james.mailbox.model.MailboxConstants; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.MailboxQuery; +import org.apache.james.mailbox.model.search.Wildcard; import org.junit.After; import org.junit.Before; import org.junit.Ignore; @@ -55,9 +56,7 @@ public class CassandraMailboxMapperTest { private static final CassandraId MAILBOX_ID_2 = CassandraId.timeBased(); - private static final Mailbox MAILBOX_BIS = new Mailbox(MAILBOX_PATH, UID_VALIDITY, MAILBOX_ID_2); - private static final String WILDCARD = "%"; private static final CassandraModule MODULES = CassandraModule.aggregateModules( CassandraMailboxModule.MODULE, @@ -236,7 +235,12 @@ public class CassandraMailboxMapperTest { mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID) .block(); - List<Mailbox> mailboxes = testee.findMailboxWithPathLike(new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, WILDCARD)); + List<Mailbox> mailboxes = testee.findMailboxWithPathLike(MailboxQuery.builder() + .privateNamespace() + .username(USER) + .expression(Wildcard.INSTANCE) + .build() + .asUserBound()); assertThat(mailboxes).containsOnly(MAILBOX); } @@ -250,7 +254,12 @@ public class CassandraMailboxMapperTest { mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID) .block(); - List<Mailbox> mailboxes = testee.findMailboxWithPathLike(new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, WILDCARD)); + List<Mailbox> mailboxes = testee.findMailboxWithPathLike(MailboxQuery.builder() + .privateNamespace() + .username(USER) + .expression(Wildcard.INSTANCE) + .build() + .asUserBound()); assertThat(mailboxes).containsOnly(MAILBOX); } @@ -262,7 +271,12 @@ public class CassandraMailboxMapperTest { mailboxPathV2DAO.save(MAILBOX_PATH, MAILBOX_ID) .block(); - List<Mailbox> mailboxes = testee.findMailboxWithPathLike(new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, WILDCARD)); + List<Mailbox> mailboxes = testee.findMailboxWithPathLike(MailboxQuery.builder() + .privateNamespace() + .username(USER) + .expression(Wildcard.INSTANCE) + .build() + .asUserBound()); assertThat(mailboxes).containsOnly(MAILBOX); } @@ -335,7 +349,12 @@ public class CassandraMailboxMapperTest { mailboxPathDAO.save(MAILBOX_PATH, MAILBOX_ID_2).block(); assertThat(testee.findMailboxWithPathLike( - new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, WILDCARD))) + MailboxQuery.builder() + .privateNamespace() + .username(USER) + .expression(Wildcard.INSTANCE) + .build() + .asUserBound())) .containsOnly(MAILBOX); } } diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java index ca633e7..8b69d39 100644 --- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java +++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java @@ -40,6 +40,8 @@ import org.apache.james.mailbox.model.MailboxACL; import org.apache.james.mailbox.model.MailboxACL.Right; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.MailboxQuery; +import org.apache.james.mailbox.store.MailboxExpressionBackwardCompatibility; import org.apache.james.mailbox.store.mail.MailboxMapper; import com.github.steveash.guavate.Guavate; @@ -189,23 +191,25 @@ public class JPAMailboxMapper extends JPATransactionalMapper implements MailboxM } @Override - public List<Mailbox> findMailboxWithPathLike(MailboxPath path) throws MailboxException { + public List<Mailbox> findMailboxWithPathLike(MailboxQuery.UserBound query) throws MailboxException { try { - return findMailboxWithPathLikeTypedQuery(path) + String pathLike = MailboxExpressionBackwardCompatibility.getPathLike(query); + return findMailboxWithPathLikeTypedQuery(query.getFixedNamespace(), query.getFixedUser(), pathLike) .getResultList() .stream() .map(JPAMailbox::toMailbox) + .filter(mailbox -> query.isPathMatch(mailbox.generateAssociatedPath())) .collect(Guavate.toImmutableList()); } catch (PersistenceException e) { - throw new MailboxException("Search of mailbox " + path + " failed", e); + throw new MailboxException("Search of mailbox " + query + " failed", e); } } - private TypedQuery<JPAMailbox> findMailboxWithPathLikeTypedQuery(MailboxPath path) { + private TypedQuery<JPAMailbox> findMailboxWithPathLikeTypedQuery(String namespace, String user, String pathLike) { return getEntityManager().createNamedQuery("findMailboxWithNameLikeWithUser", JPAMailbox.class) - .setParameter("nameParam", path.getName()) - .setParameter("namespaceParam", path.getNamespace()) - .setParameter("userParam", path.getUser().asId()); + .setParameter("nameParam", pathLike) + .setParameter("namespaceParam", namespace) + .setParameter("userParam", user); } public void deleteAllMemberships() throws MailboxException { diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java index 98537b1..45c8706 100644 --- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java +++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java @@ -30,6 +30,7 @@ import org.apache.james.mailbox.model.MailboxACL; import org.apache.james.mailbox.model.MailboxACL.Right; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.MailboxQuery; import org.apache.james.mailbox.store.mail.MailboxMapper; import org.apache.james.mailbox.store.transaction.Mapper; @@ -71,8 +72,8 @@ public class TransactionalMailboxMapper implements MailboxMapper { } @Override - public List<Mailbox> findMailboxWithPathLike(MailboxPath mailboxPath) throws MailboxException { - return wrapped.findMailboxWithPathLike(mailboxPath); + public List<Mailbox> findMailboxWithPathLike(MailboxQuery.UserBound query) throws MailboxException { + return wrapped.findMailboxWithPathLike(query); } @Override diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java index b7e6db5..843fe95 100644 --- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java +++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java @@ -42,11 +42,15 @@ import org.apache.james.mailbox.model.MailboxACL.Right; import org.apache.james.mailbox.model.MailboxConstants; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.MailboxQuery; +import org.apache.james.mailbox.model.search.PrefixedWildcard; +import org.apache.james.mailbox.store.MailboxExpressionBackwardCompatibility; import org.apache.james.mailbox.store.mail.MailboxMapper; import org.apache.james.mailbox.store.transaction.NonTransactionalMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.github.steveash.guavate.Guavate; import com.google.common.collect.ImmutableList; public class MaildirMailboxMapper extends NonTransactionalMapper implements MailboxMapper { @@ -119,34 +123,39 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail } @Override - public List<Mailbox> findMailboxWithPathLike(MailboxPath mailboxPath) - throws MailboxException { + public List<Mailbox> findMailboxWithPathLike(MailboxQuery.UserBound query) throws MailboxException { + String pathLike = MailboxExpressionBackwardCompatibility.getPathLike(query); final Pattern searchPattern = Pattern.compile("[" + MaildirStore.maildirDelimiter + "]" - + mailboxPath.getName().replace(".", "\\.").replace(MaildirStore.WILDCARD, ".*")); + + pathLike.replace(".", "\\.").replace(MaildirStore.WILDCARD, ".*")); FilenameFilter filter = MaildirMessageName.createRegexFilter(searchPattern); - File root = maildirStore.getMailboxRootForUser(mailboxPath.getUser()); + File root = maildirStore.getMailboxRootForUser(query.getFixedUser()); File[] folders = root.listFiles(filter); ArrayList<Mailbox> mailboxList = new ArrayList<>(); for (File folder : folders) { if (folder.isDirectory()) { - Mailbox mailbox = maildirStore.loadMailbox(session, root, mailboxPath.getNamespace(), mailboxPath.getUser(), folder.getName()); + Mailbox mailbox = maildirStore.loadMailbox(session, root, query.getFixedNamespace(), query.getFixedUser(), folder.getName()); mailboxList.add(mailbox); } } // INBOX is in the root of the folder - if (Pattern.matches(mailboxPath.getName().replace(MaildirStore.WILDCARD, ".*"), MailboxConstants.INBOX)) { - Mailbox mailbox = maildirStore.loadMailbox(session, root, mailboxPath.getNamespace(), mailboxPath.getUser(), ""); + if (Pattern.matches(pathLike.replace(MaildirStore.WILDCARD, ".*"), MailboxConstants.INBOX)) { + Mailbox mailbox = maildirStore.loadMailbox(session, root, query.getFixedNamespace(), query.getFixedUser(), ""); mailboxList.add(0, mailbox); } - return mailboxList; + return mailboxList.stream() + .filter(mailbox -> query.isPathMatch(mailbox.generateAssociatedPath())) + .collect(Guavate.toImmutableList()); } @Override public boolean hasChildren(Mailbox mailbox, char delimiter) throws MailboxException, MailboxNotFoundException { - String searchString = mailbox.getName() + MaildirStore.maildirDelimiter + MaildirStore.WILDCARD; List<Mailbox> mailboxes = findMailboxWithPathLike( - new MailboxPath(mailbox.getNamespace(), mailbox.getUser(), searchString)); - return (mailboxes.size() > 0); + MailboxQuery.builder() + .userAndNamespaceFrom(mailbox.generateAssociatedPath()) + .expression(new PrefixedWildcard(mailbox.getName() + delimiter)) + .build() + .asUserBound()); + return mailboxes.size() > 0; } @Override diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java index 9014dfc..d1d28a0 100644 --- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java +++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java @@ -35,6 +35,7 @@ import org.apache.james.mailbox.model.MailboxACL.NameType; import org.apache.james.mailbox.model.MailboxACL.Right; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.MailboxQuery; import org.apache.james.mailbox.store.mail.MailboxMapper; import com.github.steveash.guavate.Guavate; @@ -81,21 +82,14 @@ public class InMemoryMailboxMapper implements MailboxMapper { } @Override - public List<Mailbox> findMailboxWithPathLike(MailboxPath path) throws MailboxException { - final String regex = path.getName().replace("%", ".*"); + public List<Mailbox> findMailboxWithPathLike(MailboxQuery.UserBound query) throws MailboxException { return mailboxesByPath.values() .stream() - .filter(mailbox -> mailboxMatchesRegex(mailbox, path, regex)) + .filter(mailbox -> query.isPathMatch(mailbox.generateAssociatedPath())) .map(Mailbox::new) .collect(Guavate.toImmutableList()); } - private boolean mailboxMatchesRegex(Mailbox mailbox, MailboxPath path, String regex) { - return Objects.equal(mailbox.getNamespace(), path.getNamespace()) - && Objects.equal(mailbox.getUser(), path.getUser()) - && mailbox.getName().matches(regex); - } - @Override public MailboxId save(Mailbox mailbox) throws MailboxException { InMemoryId id = (InMemoryId) mailbox.getMailboxId(); diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxExpressionBackwardCompatibility.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxExpressionBackwardCompatibility.java new file mode 100644 index 0000000..e8e59a7 --- /dev/null +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxExpressionBackwardCompatibility.java @@ -0,0 +1,35 @@ +/**************************************************************** + * 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.mailbox.store; + +import static org.apache.james.mailbox.store.StoreMailboxManager.SQL_WILDCARD_CHAR; + +import org.apache.james.mailbox.model.search.MailboxNameExpression; +import org.apache.james.mailbox.model.search.MailboxQuery; + +public class MailboxExpressionBackwardCompatibility { + public static String getPathLike(MailboxQuery mailboxQuery) { + MailboxNameExpression nameExpression = mailboxQuery.getMailboxNameExpression(); + return nameExpression.getCombinedName() + .replace(nameExpression.getFreeWildcard(), SQL_WILDCARD_CHAR) + .replace(nameExpression.getLocalWildcard(), SQL_WILDCARD_CHAR) + + SQL_WILDCARD_CHAR; + } +} diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java index b86fc79..d85608f 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java @@ -68,8 +68,8 @@ import org.apache.james.mailbox.model.MessageMetaData; import org.apache.james.mailbox.model.MessageRange; import org.apache.james.mailbox.model.MultimailboxesSearchQuery; import org.apache.james.mailbox.model.QuotaRoot; -import org.apache.james.mailbox.model.search.MailboxNameExpression; import org.apache.james.mailbox.model.search.MailboxQuery; +import org.apache.james.mailbox.model.search.PrefixedWildcard; import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.QuotaRootResolver; import org.apache.james.mailbox.store.event.EventFactory; @@ -85,7 +85,6 @@ import org.slf4j.LoggerFactory; import com.github.fge.lambdas.Throwing; import com.github.steveash.guavate.Guavate; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -510,13 +509,17 @@ public class StoreMailboxManager implements MailboxManager { .block(); // rename submailboxes - MailboxPath children = new MailboxPath(from.getNamespace(), from.getUser(), from.getName() + getDelimiter() + "%"); - locker.executeWithLock(session, children, (LockAwareExecution<Void>) () -> { - List<Mailbox> subMailboxes = mapper.findMailboxWithPathLike(children); + MailboxQuery.UserBound query = MailboxQuery.builder() + .userAndNamespaceFrom(from) + .expression(new PrefixedWildcard(from.getName() + getDelimiter())) + .build() + .asUserBound(); + locker.executeWithLock(session, from, (LockAwareExecution<Void>) () -> { + List<Mailbox> subMailboxes = mapper.findMailboxWithPathLike(query); for (Mailbox sub : subMailboxes) { String subOriginalName = sub.getName(); String subNewName = to.getName() + subOriginalName.substring(from.getName().length()); - MailboxPath fromPath = new MailboxPath(children, subOriginalName); + MailboxPath fromPath = new MailboxPath(from, subOriginalName); sub.setName(subNewName); mapper.save(sub); eventBus.dispatch(EventFactory.mailboxRenamed() @@ -574,7 +577,7 @@ public class StoreMailboxManager implements MailboxManager { private List<MailboxMetaData> searchMailboxes(MailboxQuery mailboxExpression, MailboxSession session, Right right) throws MailboxException { MailboxMapper mailboxMapper = mailboxSessionMapperFactory.getMailboxMapper(session); Stream<Mailbox> baseMailboxes = mailboxMapper - .findMailboxWithPathLike(getPathLike(mailboxExpression, session)) + .findMailboxWithPathLike(toSingleUserQuery(mailboxExpression, session)) .stream(); Stream<Mailbox> delegatedMailboxes = getDelegatedMailboxes(mailboxMapper, mailboxExpression, right, session); List<Mailbox> mailboxes = Stream.concat(baseMailboxes, @@ -591,18 +594,15 @@ public class StoreMailboxManager implements MailboxManager { .collect(Guavate.toImmutableList()); } - @VisibleForTesting - public static MailboxPath getPathLike(MailboxQuery mailboxQuery, MailboxSession mailboxSession) { + public static MailboxQuery.UserBound toSingleUserQuery(MailboxQuery mailboxQuery, MailboxSession mailboxSession) { MailboxNameExpression nameExpression = mailboxQuery.getMailboxNameExpression(); - String combinedName = nameExpression.getCombinedName() - .replace(nameExpression.getFreeWildcard(), SQL_WILDCARD_CHAR) - .replace(nameExpression.getLocalWildcard(), SQL_WILDCARD_CHAR) - + SQL_WILDCARD_CHAR; - MailboxPath base = new MailboxPath( - mailboxQuery.getNamespace().orElse(MailboxConstants.USER_NAMESPACE), - mailboxQuery.getUser().orElse(mailboxSession.getUser().asString()), - combinedName); - return new MailboxPath(base, combinedName); + + return MailboxQuery.builder() + .namespace(mailboxQuery.getNamespace().orElse(MailboxConstants.USER_NAMESPACE)) + .username(mailboxQuery.getUser().orElse(mailboxSession.getUser().asString())) + .expression(nameExpression) + .build() + .asUserBound(); } private Stream<Mailbox> getDelegatedMailboxes(MailboxMapper mailboxMapper, MailboxQuery mailboxQuery, diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java index d91e6ad..6b73444 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java @@ -28,6 +28,7 @@ import org.apache.james.mailbox.model.MailboxACL; import org.apache.james.mailbox.model.MailboxACL.Right; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.MailboxQuery; import org.apache.james.mailbox.store.transaction.Mapper; /** @@ -68,7 +69,7 @@ public interface MailboxMapper extends Mapper { /** * Return a List of {@link Mailbox} which name is like the given name */ - List<Mailbox> findMailboxWithPathLike(MailboxPath mailboxPath) + List<Mailbox> findMailboxWithPathLike(MailboxQuery.UserBound query) throws MailboxException; /** diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java index d7f54d9..7bcd0e9 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java @@ -32,6 +32,7 @@ import org.apache.james.mailbox.model.MailboxConstants; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.model.QuotaRoot; +import org.apache.james.mailbox.model.search.MailboxQuery; import org.apache.james.mailbox.quota.QuotaRootDeserializer; import org.apache.james.mailbox.quota.UserQuotaRootResolver; import org.apache.james.mailbox.store.MailboxSessionMapperFactory; @@ -113,6 +114,11 @@ public class DefaultUserQuotaRootResolver implements UserQuotaRootResolver { String namespace = parts.get(0); String user = parts.get(1); return factory.getMailboxMapper(mailboxSession) - .findMailboxWithPathLike(new MailboxPath(namespace, user, "%")); + .findMailboxWithPathLike(MailboxQuery.builder() + .namespace(namespace) + .user(Username.of(user)) + .matchesAllMailboxNames() + .build() + .asUserBound()); } } diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java index c00c201..db99510 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java @@ -38,6 +38,7 @@ import org.apache.james.mailbox.exception.NotAdminException; import org.apache.james.mailbox.exception.UserDoesNotExistException; import org.apache.james.mailbox.model.Mailbox; import org.apache.james.mailbox.model.MailboxACL; +import org.apache.james.mailbox.model.MailboxConstants; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.model.MessageId; @@ -195,7 +196,7 @@ public class StoreMailboxManagerTest { } @Test - public void getPathLikeShouldReturnUserPathLikeWhenNoPrefixDefined() throws Exception { + public void getPathLikeShouldReturnUserPathLikeWhenNoPrefixDefined() { //Given MailboxSession session = MailboxSessionUtil.create("user"); MailboxQuery.Builder testee = MailboxQuery.builder() @@ -203,12 +204,17 @@ public class StoreMailboxManagerTest { //When MailboxQuery mailboxQuery = testee.build(); - assertThat(StoreMailboxManager.getPathLike(mailboxQuery, session)) - .isEqualTo(MailboxPath.forUser("user", "abc%")); + assertThat(StoreMailboxManager.toSingleUserQuery(mailboxQuery, session)) + .isEqualTo(MailboxQuery.builder() + .namespace(MailboxConstants.USER_NAMESPACE) + .username("user") + .expression(new PrefixedRegex(EMPTY_PREFIX, "abc", session.getPathDelimiter())) + .build() + .asUserBound()); } @Test - public void getPathLikeShouldReturnUserPathLikeWhenPrefixDefined() throws Exception { + public void getPathLikeShouldReturnUserPathLikeWhenPrefixDefined() { //Given MailboxSession session = MailboxSessionUtil.create("user"); MailboxQuery.Builder testee = MailboxQuery.builder() @@ -217,8 +223,13 @@ public class StoreMailboxManagerTest { //When MailboxQuery mailboxQuery = testee.build(); - assertThat(StoreMailboxManager.getPathLike(mailboxQuery, session)) - .isEqualTo(MailboxPath.forUser("user", "prefix.abc%")); + assertThat(StoreMailboxManager.toSingleUserQuery(mailboxQuery, session)) + .isEqualTo(MailboxQuery.builder() + .namespace(MailboxConstants.USER_NAMESPACE) + .username("user") + .expression(new PrefixedRegex("prefix.", "abc", session.getPathDelimiter())) + .build() + .asUserBound()); } } diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java index 06a1909..739d1bd 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperTest.java @@ -32,6 +32,9 @@ import org.apache.james.mailbox.model.Mailbox; import org.apache.james.mailbox.model.MailboxAssert; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.search.ExactName; +import org.apache.james.mailbox.model.search.MailboxQuery; +import org.apache.james.mailbox.model.search.PrefixedWildcard; import org.apache.james.mailbox.store.mail.MailboxMapper; import org.junit.Test; @@ -129,8 +132,13 @@ public abstract class MailboxMapperTest { @Test public void findMailboxWithPathLikeShouldBeLimitedToUserAndNamespace() throws MailboxException { saveAll(); - MailboxPath mailboxPathQuery = new MailboxPath(bobInboxMailbox.getNamespace(), bobInboxMailbox.getUser(), "IN" + WILDCARD); - List<Mailbox> mailboxes = mailboxMapper.findMailboxWithPathLike(mailboxPathQuery); + MailboxQuery.UserBound mailboxQuery = MailboxQuery.builder() + .userAndNamespaceFrom(bobInboxPath) + .expression(new PrefixedWildcard("IN")) + .build() + .asUserBound(); + + List<Mailbox> mailboxes = mailboxMapper.findMailboxWithPathLike(mailboxQuery); assertMailboxes(mailboxes).containOnly(bobInboxMailbox); } @@ -147,8 +155,13 @@ public abstract class MailboxMapperTest { @Test public void findMailboxWithPathLikeWithChildRegexShouldRetrieveChildren() throws MailboxException { saveAll(); - MailboxPath regexPath = new MailboxPath(benwaWorkPath.getNamespace(), benwaWorkPath.getUser(), benwaWorkPath.getName() + WILDCARD); - List<Mailbox> mailboxes = mailboxMapper.findMailboxWithPathLike(regexPath); + MailboxQuery.UserBound mailboxQuery = MailboxQuery.builder() + .userAndNamespaceFrom(benwaWorkPath) + .expression(new PrefixedWildcard(benwaWorkPath.getName())) + .build() + .asUserBound(); + + List<Mailbox> mailboxes = mailboxMapper.findMailboxWithPathLike(mailboxQuery); assertMailboxes(mailboxes).containOnly(benwaWorkMailbox, benwaWorkDoneMailbox, benwaWorkTodoMailbox); } @@ -170,8 +183,13 @@ public abstract class MailboxMapperTest { @Test public void findMailboxWithPathLikeShouldEscapeMailboxName() throws MailboxException { saveAll(); - MailboxPath regexPath = new MailboxPath(benwaInboxPath.getNamespace(), benwaInboxPath.getUser(), "INB?X"); - assertThat(mailboxMapper.findMailboxWithPathLike(regexPath)).isEmpty(); + MailboxQuery.UserBound mailboxQuery = MailboxQuery.builder() + .userAndNamespaceFrom(benwaInboxPath) + .expression(new ExactName("INB?X")) + .build() + .asUserBound(); + + assertThat(mailboxMapper.findMailboxWithPathLike(mailboxQuery)).isEmpty(); } @Test diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java index e8cb58d..97bb334 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolverTest.java @@ -87,7 +87,7 @@ public class DefaultUserQuotaRootResolverTest { public void retrieveAssociatedMailboxesShouldWork() throws Exception { MailboxMapper mockedMapper = mock(MailboxMapper.class); when(mockedFactory.getMailboxMapper(MAILBOX_SESSION)).thenReturn(mockedMapper); - when(mockedMapper.findMailboxWithPathLike(PATH_LIKE)).thenReturn(Lists.newArrayList(MAILBOX, MAILBOX_2)); + when(mockedMapper.findMailboxWithPathLike(any())).thenReturn(Lists.newArrayList(MAILBOX, MAILBOX_2)); assertThat(testee.retrieveAssociatedMailboxes(QUOTA_ROOT, MAILBOX_SESSION)).containsOnly(MAILBOX, MAILBOX_2); } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org