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 e9a6f8e4d8a90c12eb73f7f5a93568a9918a00ec Author: Rene Cordier <[email protected]> AuthorDate: Fri Jul 3 15:53:20 2020 +0700 JAMES-3095 MailboxValidation refactoring --- .../apache/james/jmap/model/MailboxFactory.scala | 172 +++++++++------------ .../james/jmap/model/MailboxValidationTest.scala | 109 +++++-------- 2 files changed, 116 insertions(+), 165 deletions(-) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala index 738b0f9..91e63b9 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/MailboxFactory.scala @@ -22,7 +22,6 @@ package org.apache.james.jmap.model import javax.inject.Inject import org.apache.james.jmap.mail.MailboxName.MailboxName import org.apache.james.jmap.mail._ -import org.apache.james.jmap.model.UnsignedInt.UnsignedInt import org.apache.james.jmap.utils.quotas.QuotaLoader import org.apache.james.mailbox._ import org.apache.james.mailbox.model.MailboxACL.EntryKey @@ -33,17 +32,26 @@ import scala.jdk.CollectionConverters._ import scala.jdk.OptionConverters._ object MailboxValidation { - def validate(mailboxName: Either[IllegalArgumentException, MailboxName], - unreadEmails: Either[NumberFormatException, UnsignedInt], - unreadThreads: Either[NumberFormatException, UnsignedInt], - totalEmails: Either[NumberFormatException, UnsignedInt], - totalThreads: Either[NumberFormatException, UnsignedInt]): Either[Exception, MailboxValidation] = { + private def retrieveMailboxName(mailboxPath: MailboxPath, pathDelimiter: Char): Either[IllegalArgumentException, MailboxName] = + mailboxPath.getName + .split(pathDelimiter) + .lastOption match { + case Some(name) => MailboxName.validate(name) + case None => Left(new IllegalArgumentException("No name for the mailbox found")) + } + + def validate(mailboxPath: MailboxPath, + pathDelimiter: Char, + unreadEmails: Long, + unreadThreads: Long, + totalEmails: Long, + totalThreads: Long): Either[Exception, MailboxValidation] = { for { - validatedName <- mailboxName - validatedUnreadEmails <- unreadEmails.map(UnreadEmails) - validatedUnreadThreads <- unreadThreads.map(UnreadThreads) - validatedTotalEmails <- totalEmails.map(TotalEmails) - validatedTotalThreads <- totalThreads.map(TotalThreads) + validatedName <- retrieveMailboxName(mailboxPath, pathDelimiter) + validatedUnreadEmails <- UnsignedInt.validate(unreadEmails).map(UnreadEmails) + validatedUnreadThreads <- UnsignedInt.validate(unreadThreads).map(UnreadThreads) + validatedTotalEmails <- UnsignedInt.validate(totalEmails).map(TotalEmails) + validatedTotalThreads <- UnsignedInt.validate(totalThreads).map(TotalThreads) } yield MailboxValidation( mailboxName = validatedName, unreadEmails = validatedUnreadEmails, @@ -61,14 +69,6 @@ case class MailboxValidation(mailboxName: MailboxName, class MailboxFactory @Inject() (subscriptionManager: SubscriptionManager, mailboxManager: MailboxManager) { - private def retrieveMailboxName(mailboxPath: MailboxPath, mailboxSession: MailboxSession): Either[IllegalArgumentException, MailboxName] = - mailboxPath.getName - .split(mailboxSession.getPathDelimiter) - .lastOption match { - case Some(name) => MailboxName.validate(name) - case None => Left(new IllegalArgumentException("No name for the mailbox found")) - } - private def getRole(mailboxPath: MailboxPath, mailboxSession: MailboxSession): Option[Role] = Role.from(mailboxPath.getName) .filter(_ => mailboxPath.belongsTo(mailboxSession)).toScala @@ -117,88 +117,25 @@ class MailboxFactory @Inject() (subscriptionManager: SubscriptionManager, mailbo mailboxSession: MailboxSession, allMailboxesMetadata: Seq[MailboxMetaData], quotaLoader: QuotaLoader): SMono[Mailbox] = { - - val id: MailboxId = mailboxMetaData.getId - - val name: Either[IllegalArgumentException, MailboxName] = retrieveMailboxName(mailboxMetaData.getPath, mailboxSession) - - val role: Option[Role] = getRole(mailboxMetaData.getPath, mailboxSession) - val sortOrder: SortOrder = getSortOrder(role) - val quotas: SMono[Quotas] = quotaLoader.getQuotas(mailboxMetaData.getPath) - val rights: Rights = getRights(mailboxMetaData.getResolvedAcls) - val sanitizedCounters: MailboxCounters = mailboxMetaData.getCounters.sanitize() - val unreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen) - val unreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen) - val totalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount) - val totalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount) - - val namespace: MailboxNamespace = getNamespace(mailboxMetaData.getPath, mailboxSession) - - val parentPath: Option[MailboxPath] = getParentPath(mailboxMetaData.getPath, mailboxSession) - val parentId: Option[MailboxId] = allMailboxesMetadata.filter(otherMetadata => parentPath.contains(otherMetadata.getPath)) - .map(_.getId) - .headOption - - val myRights: MailboxRights = getMyRights(mailboxMetaData.getPath, mailboxMetaData.getResolvedAcls, mailboxSession) - - val isSubscribed: IsSubscribed = retrieveIsSubscribed(mailboxMetaData.getPath, mailboxSession) - - MailboxValidation.validate(name, unreadEmails, unreadThreads, totalEmails, totalThreads) match { + MailboxValidation.validate(mailboxMetaData.getPath, mailboxSession.getPathDelimiter, sanitizedCounters.getUnseen, sanitizedCounters.getUnseen, sanitizedCounters.getCount, sanitizedCounters.getCount) match { case Left(error) => SMono.raiseError(error) - case scala.Right(mailboxValidation) => SMono.fromPublisher(quotas) - .map(quotas => - Mailbox( - id = id, - name = mailboxValidation.mailboxName, - parentId = parentId, - role = role, - sortOrder = sortOrder, - unreadEmails = mailboxValidation.unreadEmails, - totalEmails = mailboxValidation.totalEmails, - unreadThreads = mailboxValidation.unreadThreads, - totalThreads = mailboxValidation.totalThreads, - myRights = myRights, - namespace = namespace, - rights = rights, - quotas = quotas, - isSubscribed = isSubscribed)) - } - } + case scala.Right(mailboxValidation) => + SMono.fromPublisher(quotaLoader.getQuotas(mailboxMetaData.getPath)) + .map(quotas => { + val id: MailboxId = mailboxMetaData.getId + val role: Option[Role] = getRole(mailboxMetaData.getPath, mailboxSession) + val sortOrder: SortOrder = getSortOrder(role) + val rights: Rights = getRights(mailboxMetaData.getResolvedAcls) + val namespace: MailboxNamespace = getNamespace(mailboxMetaData.getPath, mailboxSession) + val parentPath: Option[MailboxPath] = getParentPath(mailboxMetaData.getPath, mailboxSession) + val parentId: Option[MailboxId] = allMailboxesMetadata.filter(otherMetadata => parentPath.contains(otherMetadata.getPath)) + .map(_.getId) + .headOption + val myRights: MailboxRights = getMyRights(mailboxMetaData.getPath, mailboxMetaData.getResolvedAcls, mailboxSession) + val isSubscribed: IsSubscribed = retrieveIsSubscribed(mailboxMetaData.getPath, mailboxSession) - def create(id: MailboxId, mailboxSession: MailboxSession, quotaLoader: QuotaLoader): SMono[Mailbox] = { - try { - val messageManager: MessageManager = mailboxManager.getMailbox(id, mailboxSession) - val resolvedACL = messageManager.getResolvedAcl(mailboxSession) - - val name: Either[IllegalArgumentException, MailboxName] = retrieveMailboxName(messageManager.getMailboxPath, mailboxSession) - - val role: Option[Role] = getRole(messageManager.getMailboxPath, mailboxSession) - val sortOrder: SortOrder = getSortOrder(role) - val quotas: SMono[Quotas] = quotaLoader.getQuotas(messageManager.getMailboxPath) - val rights: Rights = getRights(resolvedACL) - - val sanitizedCounters: MailboxCounters = messageManager.getMailboxCounters(mailboxSession).sanitize() - val unreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen) - val unreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getUnseen) - val totalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount) - val totalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(sanitizedCounters.getCount) - - val namespace: MailboxNamespace = getNamespace(messageManager.getMailboxPath, mailboxSession) - - val parentId: Option[MailboxId] = getParentPath(messageManager.getMailboxPath, mailboxSession) - .map(parentPath => mailboxManager.getMailbox(parentPath, mailboxSession)) - .map(_.getId) - - val myRights: MailboxRights = getMyRights(messageManager.getMailboxPath, resolvedACL, mailboxSession) - - val isSubscribed: IsSubscribed = retrieveIsSubscribed(messageManager.getMailboxPath, mailboxSession) - - MailboxValidation.validate(name, unreadEmails, unreadThreads, totalEmails, totalThreads) match { - case Left(error) => SMono.raiseError(error) - case scala.Right(mailboxValidation) => SMono.fromPublisher(quotas) - .map(quotas => Mailbox( id = id, name = mailboxValidation.mailboxName, @@ -213,7 +150,46 @@ class MailboxFactory @Inject() (subscriptionManager: SubscriptionManager, mailbo namespace = namespace, rights = rights, quotas = quotas, - isSubscribed = isSubscribed)) + isSubscribed = isSubscribed)}) + } + } + + def create(id: MailboxId, mailboxSession: MailboxSession, quotaLoader: QuotaLoader): SMono[Mailbox] = { + try { + val messageManager: MessageManager = mailboxManager.getMailbox(id, mailboxSession) + val sanitizedCounters: MailboxCounters = messageManager.getMailboxCounters(mailboxSession).sanitize() + + MailboxValidation.validate(messageManager.getMailboxPath, mailboxSession.getPathDelimiter, sanitizedCounters.getUnseen, sanitizedCounters.getUnseen, sanitizedCounters.getCount, sanitizedCounters.getCount) match { + case Left(error) => SMono.raiseError(error) + case scala.Right(mailboxValidation) => + SMono.fromPublisher(quotaLoader.getQuotas(messageManager.getMailboxPath)) + .map(quotas => { + val resolvedACL = messageManager.getResolvedAcl(mailboxSession) + val role: Option[Role] = getRole(messageManager.getMailboxPath, mailboxSession) + val sortOrder: SortOrder = getSortOrder(role) + val rights: Rights = getRights(resolvedACL) + val namespace: MailboxNamespace = getNamespace(messageManager.getMailboxPath, mailboxSession) + val parentId: Option[MailboxId] = getParentPath(messageManager.getMailboxPath, mailboxSession) + .map(parentPath => mailboxManager.getMailbox(parentPath, mailboxSession)) + .map(_.getId) + val myRights: MailboxRights = getMyRights(messageManager.getMailboxPath, resolvedACL, mailboxSession) + val isSubscribed: IsSubscribed = retrieveIsSubscribed(messageManager.getMailboxPath, mailboxSession) + + Mailbox( + id = id, + name = mailboxValidation.mailboxName, + parentId = parentId, + role = role, + sortOrder = sortOrder, + unreadEmails = mailboxValidation.unreadEmails, + totalEmails = mailboxValidation.totalEmails, + unreadThreads = mailboxValidation.unreadThreads, + totalThreads = mailboxValidation.totalThreads, + myRights = myRights, + namespace = namespace, + rights = rights, + quotas = quotas, + isSubscribed = isSubscribed)}) } } catch { case error: Exception => SMono.raiseError(error) diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala index bbc5e06..dc54d01 100644 --- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala +++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/MailboxValidationTest.scala @@ -20,14 +20,19 @@ package org.apache.james.jmap.model import eu.timepit.refined.auto._ +import org.apache.james.core.Username import org.apache.james.jmap.mail.MailboxName.MailboxName import org.apache.james.jmap.mail._ import org.apache.james.jmap.model.UnsignedInt.UnsignedInt +import org.apache.james.mailbox.model.MailboxPath import org.scalatest.matchers.must.Matchers import org.scalatest.wordspec.AnyWordSpec object MailboxValidationTest { private val mailboxName: MailboxName = "name" + private val user: Username = Username.of("user") + private val mailboxPath: MailboxPath = MailboxPath.forUser(user, mailboxName) + private val pathDelimiter: Char = '.' private val unreadEmails: UnsignedInt = 1L private val unreadThreads: UnsignedInt = 2L private val totalEmails: UnsignedInt = 3L @@ -39,12 +44,6 @@ class MailboxValidationTest extends AnyWordSpec with Matchers { "MailboxValidation" should { "succeed" in { - val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName) - val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails) - val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads) - val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails) - val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads) - val expectedResult: Either[Exception, MailboxValidation] = scala.Right(MailboxValidation( mailboxName = mailboxName, unreadEmails = UnreadEmails(unreadEmails), @@ -53,86 +52,62 @@ class MailboxValidationTest extends AnyWordSpec with Matchers { totalThreads = TotalThreads(totalThreads))) MailboxValidation.validate( - validMailboxname, - validUnreadEmails, - validUnreadThreads, - validTotalEmails, - validTotalThreads) must be(expectedResult) + mailboxPath, + pathDelimiter, + unreadEmails.value, + unreadThreads.value, + totalEmails.value, + totalThreads.value) must be(expectedResult) } - "fail when mailboxName is invalid" in { - val invalidMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate("") - val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails) - val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads) - val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails) - val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads) - + "fail when mailboxPath is invalid" in { MailboxValidation.validate( - invalidMailboxname, - validUnreadEmails, - validUnreadThreads, - validTotalEmails, - validTotalThreads) mustBe a[Left[_, _]] + MailboxPath.forUser(user, ""), + pathDelimiter, + unreadEmails.value, + unreadThreads.value, + totalEmails.value, + totalThreads.value) mustBe a[Left[_, _]] } "fail when unreadEmails is invalid" in { - val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName) - val invalidUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L) - val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads) - val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails) - val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads) - MailboxValidation.validate( - validMailboxname, - invalidUnreadEmails, - validUnreadThreads, - validTotalEmails, - validTotalThreads) mustBe a[Left[_, _]] + mailboxPath, + pathDelimiter, + -1L, + unreadThreads.value, + totalEmails.value, + totalThreads.value) mustBe a[Left[_, _]] } "fail when unreadThreads is invalid" in { - val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName) - val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails) - val invalidUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L) - val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails) - val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads) - MailboxValidation.validate( - validMailboxname, - validUnreadEmails, - invalidUnreadThreads, - validTotalEmails, - validTotalThreads) mustBe a[Left[_, _]] + mailboxPath, + pathDelimiter, + unreadEmails.value, + -1L, + totalEmails.value, + totalThreads.value) mustBe a[Left[_, _]] } "fail when totalEmails is invalid" in { - val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName) - val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails) - val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads) - val invalidTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L) - val validTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalThreads) - MailboxValidation.validate( - validMailboxname, - validUnreadEmails, - validUnreadThreads, - invalidTotalEmails, - validTotalThreads) mustBe a[Left[_, _]] + mailboxPath, + pathDelimiter, + unreadEmails.value, + unreadThreads.value, + -1L, + totalThreads.value) mustBe a[Left[_, _]] } "fail when totalThreads is invalid" in { - val validMailboxname: Either[IllegalArgumentException, MailboxName] = MailboxName.validate(mailboxName) - val validUnreadEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadEmails) - val validUnreadThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(unreadThreads) - val validTotalEmails: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(totalEmails) - val invalidTotalThreads: Either[NumberFormatException, UnsignedInt] = UnsignedInt.validate(-1L) - MailboxValidation.validate( - validMailboxname, - validUnreadEmails, - validUnreadThreads, - validTotalEmails, - invalidTotalThreads) mustBe a[Left[_, _]] + mailboxPath, + pathDelimiter, + unreadEmails.value, + unreadThreads.value, + totalEmails.value, + -1L) mustBe a[Left[_, _]] } } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
