JAMES-2352 introduce a Domain type for domain

Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/33cb12e5
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/33cb12e5
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/33cb12e5

Branch: refs/heads/master
Commit: 33cb12e57c803824c92b7b55b0ce19a28c1bc95e
Parents: 607eca9
Author: Matthieu Baechler <matth...@apache.org>
Authored: Wed Mar 14 11:44:24 2018 +0100
Committer: benwa <btell...@linagora.com>
Committed: Tue Mar 27 15:13:46 2018 +0700

----------------------------------------------------------------------
 .../main/java/org/apache/james/core/Domain.java |  70 +++
 .../main/java/org/apache/james/core/User.java   |  20 +-
 .../apache/james/domainlist/api/DomainTest.java |  57 ++
 .../apache/james/mailbox/model/QuotaRoot.java   |  11 +-
 .../james/mailbox/quota/MaxQuotaManager.java    |  13 +-
 .../quota/CassandraPerDomainMaxQuotaDao.java    |  25 +-
 .../quota/CassandraPerUserMaxQuotaManager.java  |  17 +-
 .../jpa/quota/JPAPerUserMaxQuotaDAO.java        |  21 +-
 .../jpa/quota/JPAPerUserMaxQuotaManager.java    |  17 +-
 .../jpa/quota/model/MaxDomainMessageCount.java  |   6 +-
 .../jpa/quota/model/MaxDomainStorage.java       |   6 +-
 .../src/main/resources/META-INF/persistence.xml |   2 +
 .../quota/InMemoryPerUserMaxQuotaManager.java   |  21 +-
 .../james/mailbox/store/StoreRightManager.java  |   5 +-
 .../store/quota/FixedMaxQuotaManager.java       |  13 +-
 .../mailbox/store/quota/NoMaxQuotaManager.java  |  13 +-
 .../store/quota/GenericMaxQuotaManagerTest.java |   3 +-
 .../james/ai/classic/BayesianAnalysis.java      |   3 +-
 .../java/org/apache/mailet/MailetContext.java   |   7 +-
 .../mailet/base/test/FakeMailContext.java       |   5 +-
 .../transport/mailets/PostmasterAlias.java      |   3 +-
 .../james/transport/matchers/HostIsLocal.java   |   3 +-
 .../transport/matchers/SenderHostIsLocal.java   |   5 +-
 .../transport/matchers/HostIsLocalTest.java     |   5 +-
 .../matchers/SenderHostIsLocalTest.java         |   5 +-
 ...tSenderAuthIdentifyVerificationRcptHook.java |   7 +-
 .../src/main/resources/META-INF/persistence.xml |   2 +
 .../org/apache/james/utils/DataProbeImpl.java   |  22 +-
 .../src/main/resources/META-INF/persistence.xml |   2 +
 .../apache/james/domainlist/api/DomainList.java |  12 +-
 .../james/rrt/api/RecipientRewriteTable.java    |  40 +-
 .../java/org/apache/james/rrt/lib/Mapping.java  |   3 +-
 .../cassandra/CassandraDomainList.java          |  20 +-
 .../CassandraRecipientRewriteTable.java         |  28 +-
 .../CassandraRecipientRewriteTableTest.java     |   9 +-
 .../james/domainlist/xml/XMLDomainList.java     |  14 +-
 .../rrt/file/XMLRecipientRewriteTable.java      |  11 +-
 .../james/domainlist/xml/XMLDomainListTest.java |   9 +-
 .../rrt/file/XMLRecipientRewriteTableTest.java  |  15 +-
 .../james/domainlist/hbase/HBaseDomainList.java |  25 +-
 .../rrt/hbase/HBaseRecipientRewriteTable.java   |  29 +-
 .../domainlist/hbase/HBaseDomainListTest.java   |   3 +-
 .../hbase/HBaseRecipientRewriteTableTest.java   |   9 +-
 .../rrt/jdbc/JDBCRecipientRewriteTable.java     |  33 +-
 .../rrt/jdbc/JDBCRecipientRewriteTableTest.java |   9 +-
 .../james/domainlist/jpa/JPADomainList.java     |  40 +-
 .../james/domainlist/jpa/model/JPADomain.java   |   6 +-
 .../james/rrt/jpa/JPARecipientRewriteTable.java | 541 ++++++++++---------
 .../rrt/jpa/model/JPARecipientRewrite.java      |   6 +-
 .../james/domainlist/jpa/JPADomainListTest.java |   3 +-
 .../rrt/jpa/JPARecipientRewriteTableTest.java   |   9 +-
 .../domainlist/lib/AbstractDomainList.java      |  65 ++-
 .../domainlist/lib/DomainListManagement.java    |  19 +-
 .../rrt/lib/AbstractRecipientRewriteTable.java  | 100 ++--
 .../org/apache/james/rrt/lib/MappingImpl.java   |   9 +-
 .../lib/RecipientRewriteTableManagement.java    |  23 +-
 .../rrt/lib/RecipientRewriteTableUtil.java      |   9 +-
 .../user/lib/AbstractJamesUsersRepository.java  |  33 +-
 .../james/user/lib/AbstractUsersRepository.java |   3 +-
 .../domainlist/api/mock/SimpleDomainList.java   |  15 +-
 .../AbstractDomainListPrivateMethodsTest.java   |  48 +-
 .../domainlist/lib/AbstractDomainListTest.java  |  13 +-
 .../lib/AbstractRecipientRewriteTableTest.java  |  44 +-
 .../apache/james/rrt/lib/MappingImplTest.java   |  16 +-
 .../apache/james/rrt/lib/MappingsImplTest.java  |  29 +-
 .../james/rrt/lib/RewriteTablesStepdefs.java    |  25 +-
 .../user/lib/AbstractUsersRepositoryTest.java   |   5 +-
 .../domainlist/memory/MemoryDomainList.java     |  22 +-
 .../rrt/memory/MemoryRecipientRewriteTable.java |  22 +-
 .../memory/MemoryRecipientRewriteTableTest.java |   9 +-
 .../impl/JamesMailetContext.java                |  29 +-
 .../impl/JamesMailetContextTest.java            |   7 +-
 .../mailets/AbstractRecipientRewriteTable.java  |   6 +-
 .../transport/mailets/BayesianAnalysis.java     |   3 +-
 .../mailets/RecipientRewriteTableProcessor.java |  11 +-
 .../transport/mailets/WhiteListManager.java     |  19 +-
 .../mailets/XMLRecipientRewriteTable.java       |   3 +-
 .../mailets/managesieve/ManageSieveMailet.java  |   4 +-
 .../remote/delivery/HeloNameProvider.java       |   2 +-
 .../matchers/AbstractSQLWhitelistMatcher.java   |   5 +-
 .../RecipientRewriteTableProcessorTest.java     |  27 +-
 .../remote/delivery/HeloNameProviderTest.java   |   3 +-
 .../RemoteDeliveryConfigurationTest.java        |   3 +-
 .../james/fetchmail/MessageProcessor.java       |   3 +-
 .../james/fetchmail/ParsedConfiguration.java    |   3 +-
 .../org/apache/james/jmap/model/JmapMDN.java    |   3 +-
 .../smtpserver/AuthRequiredToRelayRcptHook.java |   3 +-
 .../james/smtpserver/JamesMailCmdHandler.java   |   2 +-
 .../james/smtpserver/JamesRcptCmdHandler.java   |   2 +-
 .../SenderAuthIdentifyVerificationRcptHook.java |   3 +-
 .../smtpserver/fastfail/ValidRcptHandler.java   |   5 +-
 .../apache/james/smtpserver/SMTPServerTest.java |   3 +-
 .../james/smtpserver/ValidRcptHandlerTest.java  |   7 +-
 .../james/webadmin/routes/DomainsRoutes.java    |  56 +-
 .../james/webadmin/routes/GroupsRoutes.java     |  18 +-
 .../webadmin/routes/DomainsRoutesTest.java      |   6 +-
 .../james/webadmin/routes/GroupsRoutesTest.java |  43 +-
 .../james/webadmin/routes/UsersRoutesTest.java  |   5 +-
 .../webadmin/routes/DomainQuotaRoutes.java      |  30 +-
 .../webadmin/routes/DomainQuotaService.java     |  17 +-
 .../DomainQuotaRoutesNoVirtualHostingTest.java  |  10 +-
 .../webadmin/routes/DomainQuotaRoutesTest.java  |  51 +-
 .../webadmin/routes/UserQuotaRoutesTest.java    |   9 +-
 103 files changed, 1212 insertions(+), 961 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/core/src/main/java/org/apache/james/core/Domain.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/james/core/Domain.java 
b/core/src/main/java/org/apache/james/core/Domain.java
new file mode 100644
index 0000000..1675f15
--- /dev/null
+++ b/core/src/main/java/org/apache/james/core/Domain.java
@@ -0,0 +1,70 @@
+/****************************************************************
+ * 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.core;
+
+import java.util.Locale;
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
+public class Domain {
+
+    public static Domain of(String domain) {
+        Preconditions.checkNotNull(domain);
+        Preconditions.checkArgument(!domain.isEmpty() && 
!domain.contains("@"));
+        return new Domain(domain);
+    }
+
+    private final String domainName;
+    private final String normalizedDomainName;
+
+    protected Domain(String domainName) {
+        this.domainName = domainName;
+        this.normalizedDomainName = domainName.toLowerCase(Locale.US);
+    }
+
+    public String name() {
+        return domainName;
+    }
+
+    public String asString() {
+        return normalizedDomainName;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof Domain) {
+            Domain domain = (Domain) o;
+            return Objects.equals(normalizedDomainName, 
domain.normalizedDomainName);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(normalizedDomainName);
+    }
+
+    @Override
+    public String toString() {
+        return "Domain : " + domainName;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/core/src/main/java/org/apache/james/core/User.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/james/core/User.java 
b/core/src/main/java/org/apache/james/core/User.java
index c3e0162..0ae5ab9 100644
--- a/core/src/main/java/org/apache/james/core/User.java
+++ b/core/src/main/java/org/apache/james/core/User.java
@@ -60,39 +60,27 @@ public class User {
     }
 
     private final String localPart;
-    private final Optional<String> domainPart;
+    private final Optional<Domain> domainPart;
 
     private User(String localPart, Optional<String> domainPart) {
         Preconditions.checkNotNull(localPart);
         Preconditions.checkArgument(!localPart.isEmpty(), "username should not 
be empty");
         Preconditions.checkArgument(!localPart.contains("@"), "username can 
not contain domain delimiter");
 
-        Preconditions.checkArgument(!isEmptyString(domainPart), "domain part 
can not be empty");
-        Preconditions.checkArgument(!containsDomainDelimiter(domainPart), 
"domain can not contain domain delimiter");
-
         this.localPart = localPart;
-        this.domainPart = domainPart;
-    }
-
-    private Boolean containsDomainDelimiter(Optional<String> domainPart) {
-        return domainPart.map(s -> s.contains("@")).orElse(false);
-    }
-
-    private Boolean isEmptyString(Optional<String> domainPart) {
-        return domainPart.map(String::isEmpty)
-            .orElse(false);
+        this.domainPart = domainPart.map(Domain::of);
     }
 
     public String getLocalPart() {
         return localPart;
     }
 
-    public Optional<String> getDomainPart() {
+    public Optional<Domain> getDomainPart() {
         return domainPart;
     }
 
     public String asString() {
-        return domainPart.map(domain -> localPart + "@" + domain)
+        return domainPart.map(domain -> localPart + "@" + domain.asString())
             .orElse(localPart);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/core/src/test/java/org/apache/james/domainlist/api/DomainTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/james/domainlist/api/DomainTest.java 
b/core/src/test/java/org/apache/james/domainlist/api/DomainTest.java
new file mode 100644
index 0000000..4428f96
--- /dev/null
+++ b/core/src/test/java/org/apache/james/domainlist/api/DomainTest.java
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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.domainlist.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.james.core.Domain;
+import org.junit.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class DomainTest {
+
+    @Test
+    public void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(Domain.class).verify();
+    }
+
+    @Test
+    public void shouldBeCaseInsensitive() {
+        assertThat(Domain.of("Domain")).isEqualTo(Domain.of("domain"));
+    }
+
+    @Test
+    public void shouldThrowWhenDomainContainAtSymbol() {
+        assertThatThrownBy(() -> 
Domain.of("Dom@in")).isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void shouldThrowWhenDomainIsEmpty() {
+        assertThatThrownBy(() -> 
Domain.of("")).isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void shouldThrowOnNullArgument() {
+        assertThatThrownBy(() -> 
Domain.of(null)).isInstanceOf(NullPointerException.class);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java
----------------------------------------------------------------------
diff --git 
a/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java 
b/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java
index ff421ca..aa591f3 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java
@@ -21,6 +21,8 @@ package org.apache.james.mailbox.model;
 
 import java.util.Optional;
 
+import org.apache.james.core.Domain;
+
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 
@@ -29,14 +31,14 @@ import com.google.common.base.Objects;
  */
 public class QuotaRoot {
 
-    public static QuotaRoot quotaRoot(String value, Optional<String> domain) {
+    public static QuotaRoot quotaRoot(String value, Optional<Domain> domain) {
         return new QuotaRoot(value, domain);
     }
 
     private final String value;
-    private final Optional<String> domain;
+    private final Optional<Domain> domain;
 
-    private QuotaRoot(String value, Optional<String> domain) {
+    private QuotaRoot(String value, Optional<Domain> domain) {
         this.value = value;
         this.domain = domain;
     }
@@ -56,13 +58,14 @@ public class QuotaRoot {
         return value;
     }
 
-    public Optional<String> getDomain() {
+    public Optional<Domain> getDomain() {
         return domain;
     }
 
     public String toString() {
         return MoreObjects.toStringHelper(this)
                 .add("value", value)
+                .add("domain", domain)
                 .toString();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java 
b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java
index 7773ede..355e786 100644
--- 
a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java
+++ 
b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.quota;
 import java.util.Map;
 import java.util.Optional;
 
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
@@ -122,15 +123,15 @@ public interface MaxQuotaManager {
 
     Map<Quota.Scope, QuotaSize> listMaxStorageDetails(QuotaRoot quotaRoot);
 
-    Optional<QuotaCount> getDomainMaxMessage(String domain);
+    Optional<QuotaCount> getDomainMaxMessage(Domain domain);
 
-    void setDomainMaxMessage(String domain, QuotaCount count) throws 
MailboxException;
+    void setDomainMaxMessage(Domain domain, QuotaCount count) throws 
MailboxException;
 
-    void removeDomainMaxMessage(String domain) throws MailboxException;
+    void removeDomainMaxMessage(Domain domain) throws MailboxException;
 
-    void setDomainMaxStorage(String domain, QuotaSize size) throws 
MailboxException;
+    void setDomainMaxStorage(Domain domain, QuotaSize size) throws 
MailboxException;
 
-    Optional<QuotaSize> getDomainMaxStorage(String domain);
+    Optional<QuotaSize> getDomainMaxStorage(Domain domain);
 
-    void removeDomainMaxStorage(String domain) throws MailboxException;
+    void removeDomainMaxStorage(Domain domain) throws MailboxException;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
index 1f28f4c..d72f432 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
@@ -29,6 +29,7 @@ import java.util.Optional;
 
 import javax.inject.Inject;
 
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.cassandra.table.CassandraDomainMaxQuota;
 import org.apache.james.mailbox.quota.QuotaCount;
 import org.apache.james.mailbox.quota.QuotaSize;
@@ -97,16 +98,16 @@ public class CassandraPerDomainMaxQuotaDao {
             .value(CassandraDomainMaxQuota.STORAGE, bindMarker());
     }
 
-    public void setMaxStorage(String domain, QuotaSize maxStorageQuota) {
-        session.execute(setMaxStorageStatement.bind(domain, 
QuotaCodec.quotaValueToLong(maxStorageQuota)));
+    public void setMaxStorage(Domain domain, QuotaSize maxStorageQuota) {
+        session.execute(setMaxStorageStatement.bind(domain.asString(), 
QuotaCodec.quotaValueToLong(maxStorageQuota)));
     }
 
-    public void setMaxMessage(String domain, QuotaCount maxMessageCount) {
-        session.execute(setMaxMessageStatement.bind(domain, 
QuotaCodec.quotaValueToLong(maxMessageCount)));
+    public void setMaxMessage(Domain domain, QuotaCount maxMessageCount) {
+        session.execute(setMaxMessageStatement.bind(domain.asString(), 
QuotaCodec.quotaValueToLong(maxMessageCount)));
     }
 
-    public Optional<QuotaSize> getMaxStorage(String domain) {
-        ResultSet resultSet = 
session.execute(getMaxStorageStatement.bind(domain));
+    public Optional<QuotaSize> getMaxStorage(Domain domain) {
+        ResultSet resultSet = 
session.execute(getMaxStorageStatement.bind(domain.asString()));
         if (resultSet.isExhausted()) {
             return Optional.empty();
         }
@@ -114,8 +115,8 @@ public class CassandraPerDomainMaxQuotaDao {
         return QuotaCodec.longToQuotaSize(maxStorage);
     }
 
-    public Optional<QuotaCount> getMaxMessage(String domain) {
-        ResultSet resultSet = 
session.execute(getMaxMessageStatement.bind(domain));
+    public Optional<QuotaCount> getMaxMessage(Domain domain) {
+        ResultSet resultSet = 
session.execute(getMaxMessageStatement.bind(domain.asString()));
         if (resultSet.isExhausted()) {
             return Optional.empty();
         }
@@ -123,12 +124,12 @@ public class CassandraPerDomainMaxQuotaDao {
         return QuotaCodec.longToQuotaCount(maxMessages);
     }
 
-    public void removeMaxMessage(String domain) {
-        session.execute(removeMaxMessageStatement.bind(domain));
+    public void removeMaxMessage(Domain domain) {
+        session.execute(removeMaxMessageStatement.bind(domain.asString()));
     }
 
-    public void removeMaxStorage(String domain) {
-        session.execute(removeMaxStorageStatement.bind(domain));
+    public void removeMaxStorage(Domain domain) {
+        session.execute(removeMaxStorageStatement.bind(domain.asString()));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java
index 617904d..fb2178c 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java
@@ -28,6 +28,7 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
@@ -64,32 +65,32 @@ public class CassandraPerUserMaxQuotaManager implements 
MaxQuotaManager {
     }
 
     @Override
-    public void setDomainMaxMessage(String domain, QuotaCount count) {
+    public void setDomainMaxMessage(Domain domain, QuotaCount count) {
         perDomainQuota.setMaxMessage(domain, count);
     }
 
     @Override
-    public void setDomainMaxStorage(String domain, QuotaSize size) {
+    public void setDomainMaxStorage(Domain domain, QuotaSize size) {
         perDomainQuota.setMaxStorage(domain, size);
     }
 
     @Override
-    public void removeDomainMaxMessage(String domain) {
+    public void removeDomainMaxMessage(Domain domain) {
         perDomainQuota.removeMaxMessage(domain);
     }
 
     @Override
-    public void removeDomainMaxStorage(String domain) {
+    public void removeDomainMaxStorage(Domain domain) {
         perDomainQuota.removeMaxStorage(domain);
     }
 
     @Override
-    public Optional<QuotaCount> getDomainMaxMessage(String domain) {
+    public Optional<QuotaCount> getDomainMaxMessage(Domain domain) {
         return perDomainQuota.getMaxMessage(domain);
     }
 
     @Override
-    public Optional<QuotaSize> getDomainMaxStorage(String domain) {
+    public Optional<QuotaSize> getDomainMaxStorage(Domain domain) {
         return perDomainQuota.getMaxStorage(domain);
     }
 
@@ -163,7 +164,7 @@ public class CassandraPerUserMaxQuotaManager implements 
MaxQuotaManager {
 
     @Override
     public Map<Quota.Scope, QuotaCount> listMaxMessagesDetails(QuotaRoot 
quotaRoot) {
-        Function<String, Optional<QuotaCount>> domainQuotaSupplier = 
Throwing.function(this::getDomainMaxMessage).sneakyThrow();
+        Function<Domain, Optional<QuotaCount>> domainQuotaSupplier = 
Throwing.function(this::getDomainMaxMessage).sneakyThrow();
         return Stream.of(
                 Pair.of(Quota.Scope.User, 
perUserQuota.getMaxMessage(quotaRoot)),
                 Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaSupplier)),
@@ -174,7 +175,7 @@ public class CassandraPerUserMaxQuotaManager implements 
MaxQuotaManager {
 
     @Override
     public Map<Quota.Scope, QuotaSize> listMaxStorageDetails(QuotaRoot 
quotaRoot) {
-        Function<String, Optional<QuotaSize>> domainQuotaSupplier = 
Throwing.function(this::getDomainMaxStorage).sneakyThrow();
+        Function<Domain, Optional<QuotaSize>> domainQuotaSupplier = 
Throwing.function(this::getDomainMaxStorage).sneakyThrow();
         return Stream.of(
                 Pair.of(Quota.Scope.User, 
perUserQuota.getMaxStorage(quotaRoot)),
                 Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaSupplier)),

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
index 27dfec9..19e83d8 100644
--- 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
+++ 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaDAO.java
@@ -27,6 +27,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 
 import org.apache.james.backends.jpa.TransactionRunner;
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.jpa.quota.model.MaxDomainMessageCount;
 import org.apache.james.mailbox.jpa.quota.model.MaxDomainStorage;
 import org.apache.james.mailbox.jpa.quota.model.MaxGlobalMessageCount;
@@ -86,7 +87,7 @@ public class JPAPerUserMaxQuotaDAO {
         return storedValue;
     }
 
-    public void setDomainMaxMessage(String domain, Optional<QuotaCount> count) 
{
+    public void setDomainMaxMessage(Domain domain, Optional<QuotaCount> count) 
{
         transactionRunner.run(
             entityManager -> {
                 MaxDomainMessageCount storedValue = 
getMaxDomainMessageEntity(entityManager, domain, count);
@@ -95,7 +96,7 @@ public class JPAPerUserMaxQuotaDAO {
     }
 
 
-    public void setDomainMaxStorage(String domain, Optional<QuotaSize> size) {
+    public void setDomainMaxStorage(Domain domain, Optional<QuotaSize> size) {
         transactionRunner.run(
             entityManager -> {
                 MaxDomainStorage storedValue = 
getMaxDomainStorageEntity(entityManager, domain, size);
@@ -103,8 +104,8 @@ public class JPAPerUserMaxQuotaDAO {
             });
     }
 
-    private MaxDomainMessageCount getMaxDomainMessageEntity(EntityManager 
entityManager, String domain, Optional<QuotaCount> maxMessageQuota) {
-        MaxDomainMessageCount storedValue = 
entityManager.find(MaxDomainMessageCount.class, domain);
+    private MaxDomainMessageCount getMaxDomainMessageEntity(EntityManager 
entityManager, Domain domain, Optional<QuotaCount> maxMessageQuota) {
+        MaxDomainMessageCount storedValue = 
entityManager.find(MaxDomainMessageCount.class, domain.asString());
         Long value = quotaValueToLong(maxMessageQuota);
         if (storedValue == null) {
             return new MaxDomainMessageCount(domain, value);
@@ -113,8 +114,8 @@ public class JPAPerUserMaxQuotaDAO {
         return storedValue;
     }
 
-    private MaxDomainStorage getMaxDomainStorageEntity(EntityManager 
entityManager, String domain, Optional<QuotaSize> maxStorageQuota) {
-        MaxDomainStorage storedValue = 
entityManager.find(MaxDomainStorage.class, domain);
+    private MaxDomainStorage getMaxDomainStorageEntity(EntityManager 
entityManager, Domain domain, Optional<QuotaSize> maxStorageQuota) {
+        MaxDomainStorage storedValue = 
entityManager.find(MaxDomainStorage.class, domain.asString());
         Long value = quotaValueToLong(maxStorageQuota);
         if (storedValue == null) {
             return new MaxDomainStorage(domain, value);
@@ -196,18 +197,18 @@ public class JPAPerUserMaxQuotaDAO {
         return longToQuotaCount(storedValue.getValue());
     }
 
-    public Optional<QuotaCount> getDomainMaxMessage(String domain) {
+    public Optional<QuotaCount> getDomainMaxMessage(Domain domain) {
         EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        MaxDomainMessageCount storedValue = 
entityManager.find(MaxDomainMessageCount.class, domain);
+        MaxDomainMessageCount storedValue = 
entityManager.find(MaxDomainMessageCount.class, domain.asString());
         if (storedValue == null) {
             return Optional.empty();
         }
         return longToQuotaCount(storedValue.getValue());
     }
 
-    public Optional<QuotaSize> getDomainMaxStorage(String domain) {
+    public Optional<QuotaSize> getDomainMaxStorage(Domain domain) {
         EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        MaxDomainStorage storedValue = 
entityManager.find(MaxDomainStorage.class, domain);
+        MaxDomainStorage storedValue = 
entityManager.find(MaxDomainStorage.class, domain.asString());
         if (storedValue == null) {
             return Optional.empty();
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
index cd0735f..e7de42d 100644
--- 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
+++ 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java
@@ -28,6 +28,7 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
@@ -58,32 +59,32 @@ public class JPAPerUserMaxQuotaManager implements 
MaxQuotaManager {
     }
 
     @Override
-    public void setDomainMaxMessage(String domain, QuotaCount count) {
+    public void setDomainMaxMessage(Domain domain, QuotaCount count) {
         dao.setDomainMaxMessage(domain, Optional.of(count));
     }
 
     @Override
-    public void setDomainMaxStorage(String domain, QuotaSize size) {
+    public void setDomainMaxStorage(Domain domain, QuotaSize size) {
         dao.setDomainMaxStorage(domain, Optional.of(size));
     }
 
     @Override
-    public void removeDomainMaxMessage(String domain) {
+    public void removeDomainMaxMessage(Domain domain) {
         dao.setDomainMaxMessage(domain, Optional.empty());
     }
 
     @Override
-    public void removeDomainMaxStorage(String domain) {
+    public void removeDomainMaxStorage(Domain domain) {
         dao.setDomainMaxStorage(domain, Optional.empty());
     }
 
     @Override
-    public Optional<QuotaCount> getDomainMaxMessage(String domain) {
+    public Optional<QuotaCount> getDomainMaxMessage(Domain domain) {
         return dao.getDomainMaxMessage(domain);
     }
 
     @Override
-    public Optional<QuotaSize> getDomainMaxStorage(String domain) {
+    public Optional<QuotaSize> getDomainMaxStorage(Domain domain) {
         return dao.getDomainMaxStorage(domain);
     }
 
@@ -139,7 +140,7 @@ public class JPAPerUserMaxQuotaManager implements 
MaxQuotaManager {
 
     @Override
     public Map<Quota.Scope, QuotaCount> listMaxMessagesDetails(QuotaRoot 
quotaRoot) {
-        Function<String, Optional<QuotaCount>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxMessage).sneakyThrow();
+        Function<Domain, Optional<QuotaCount>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxMessage).sneakyThrow();
         return Stream.of(
             Pair.of(Quota.Scope.User, dao.getMaxMessage(quotaRoot)),
             Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaFunction)),
@@ -150,7 +151,7 @@ public class JPAPerUserMaxQuotaManager implements 
MaxQuotaManager {
 
     @Override
     public Map<Quota.Scope, QuotaSize> listMaxStorageDetails(QuotaRoot 
quotaRoot) {
-        Function<String, Optional<QuotaSize>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxStorage).sneakyThrow();
+        Function<Domain, Optional<QuotaSize>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxStorage).sneakyThrow();
         return Stream.of(
             Pair.of(Quota.Scope.User, dao.getMaxStorage(quotaRoot)),
             Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaFunction)),

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainMessageCount.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainMessageCount.java
 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainMessageCount.java
index eccae16..9787d67 100644
--- 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainMessageCount.java
+++ 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainMessageCount.java
@@ -24,6 +24,8 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
 
+import org.apache.james.core.Domain;
+
 @Entity(name = "MaxDomainMessageCount")
 @Table(name = "JAMES_MAX_DOMAIN_MESSAGE_COUNT")
 public class MaxDomainMessageCount {
@@ -34,8 +36,8 @@ public class MaxDomainMessageCount {
     @Column(name = "VALUE", nullable = true)
     private Long value;
 
-    public MaxDomainMessageCount(String domain, Long value) {
-        this.domain = domain;
+    public MaxDomainMessageCount(Domain domain, Long value) {
+        this.domain = domain.asString();
         this.value = value;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainStorage.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainStorage.java
 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainStorage.java
index 3785306..575f070 100644
--- 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainStorage.java
+++ 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/model/MaxDomainStorage.java
@@ -24,6 +24,8 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
 
+import org.apache.james.core.Domain;
+
 @Entity(name = "MaxDomainStorage")
 @Table(name = "JAMES_MAX_DOMAIN_STORAGE")
 public class MaxDomainStorage {
@@ -35,8 +37,8 @@ public class MaxDomainStorage {
     @Column(name = "VALUE", nullable = true)
     private Long value;
 
-    public MaxDomainStorage(String domain, Long value) {
-        this.domain = domain;
+    public MaxDomainStorage(Domain domain, Long value) {
+        this.domain = domain.asString();
         this.value = value;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/jpa/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/mailbox/jpa/src/main/resources/META-INF/persistence.xml 
b/mailbox/jpa/src/main/resources/META-INF/persistence.xml
index c8f2f28..bf27655 100644
--- a/mailbox/jpa/src/main/resources/META-INF/persistence.xml
+++ b/mailbox/jpa/src/main/resources/META-INF/persistence.xml
@@ -30,6 +30,8 @@
         
<class>org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMailboxMessage</class>
         <class>org.apache.james.mailbox.jpa.mail.model.JPAProperty</class>
         <class>org.apache.james.mailbox.jpa.user.model.JPASubscription</class>
+        
<class>org.apache.james.mailbox.jpa.quota.model.MaxDomainMessageCount</class>
+        
<class>org.apache.james.mailbox.jpa.quota.model.MaxDomainStorage</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxGlobalMessageCount</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxGlobalStorage</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxUserMessageCount</class>

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryPerUserMaxQuotaManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryPerUserMaxQuotaManager.java
 
b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryPerUserMaxQuotaManager.java
index 3338613..9c42e38 100644
--- 
a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryPerUserMaxQuotaManager.java
+++ 
b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryPerUserMaxQuotaManager.java
@@ -25,6 +25,7 @@ import java.util.function.Function;
 import java.util.stream.Stream;
 
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
@@ -40,8 +41,8 @@ public class InMemoryPerUserMaxQuotaManager implements 
MaxQuotaManager {
     private Optional<QuotaCount> maxMessage = Optional.empty();
     private Optional<QuotaSize> maxStorage = Optional.empty();
 
-    private final Map<String, QuotaCount> domainMaxMessage = new 
ConcurrentHashMap<>();
-    private final Map<String, QuotaSize> domainMaxStorage = new 
ConcurrentHashMap<>();
+    private final Map<Domain, QuotaCount> domainMaxMessage = new 
ConcurrentHashMap<>();
+    private final Map<Domain, QuotaSize> domainMaxStorage = new 
ConcurrentHashMap<>();
 
     private final Map<String, QuotaSize> userMaxStorage = new 
ConcurrentHashMap<>();
     private final Map<String, QuotaCount> userMaxMessage = new 
ConcurrentHashMap<>();
@@ -52,22 +53,22 @@ public class InMemoryPerUserMaxQuotaManager implements 
MaxQuotaManager {
     }
 
     @Override
-    public void setDomainMaxMessage(String domain, QuotaCount count) {
+    public void setDomainMaxMessage(Domain domain, QuotaCount count) {
         domainMaxMessage.put(domain, count);
     }
 
     @Override
-    public void setDomainMaxStorage(String domain, QuotaSize size) {
+    public void setDomainMaxStorage(Domain domain, QuotaSize size) {
         domainMaxStorage.put(domain, size);
     }
 
     @Override
-    public void removeDomainMaxMessage(String domain) {
+    public void removeDomainMaxMessage(Domain domain) {
         domainMaxMessage.remove(domain);
     }
 
     @Override
-    public void removeDomainMaxStorage(String domain) {
+    public void removeDomainMaxStorage(Domain domain) {
         domainMaxStorage.remove(domain);
     }
 
@@ -89,7 +90,7 @@ public class InMemoryPerUserMaxQuotaManager implements 
MaxQuotaManager {
 
     @Override
     public Map<Quota.Scope, QuotaCount> listMaxMessagesDetails(QuotaRoot 
quotaRoot) {
-        Function<String, Optional<QuotaCount>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxMessage).sneakyThrow();
+        Function<Domain, Optional<QuotaCount>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxMessage).sneakyThrow();
         return Stream.of(
                 Pair.of(Quota.Scope.User, 
Optional.ofNullable(userMaxMessage.get(quotaRoot.getValue()))),
                 Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaFunction)),
@@ -100,7 +101,7 @@ public class InMemoryPerUserMaxQuotaManager implements 
MaxQuotaManager {
 
     @Override
     public Map<Quota.Scope, QuotaSize> listMaxStorageDetails(QuotaRoot 
quotaRoot) {
-        Function<String, Optional<QuotaSize>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxStorage).sneakyThrow();
+        Function<Domain, Optional<QuotaSize>> domainQuotaFunction = 
Throwing.function(this::getDomainMaxStorage).sneakyThrow();
         return Stream.of(
                 Pair.of(Quota.Scope.User, 
Optional.ofNullable(userMaxStorage.get(quotaRoot.getValue()))),
                 Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaFunction)),
@@ -115,12 +116,12 @@ public class InMemoryPerUserMaxQuotaManager implements 
MaxQuotaManager {
     }
 
     @Override
-    public Optional<QuotaCount> getDomainMaxMessage(String domain) {
+    public Optional<QuotaCount> getDomainMaxMessage(Domain domain) {
         return Optional.ofNullable(domainMaxMessage.get(domain));
     }
 
     @Override
-    public Optional<QuotaSize> getDomainMaxStorage(String domain) {
+    public Optional<QuotaSize> getDomainMaxStorage(Domain domain) {
         return Optional.ofNullable(domainMaxStorage.get(domain));
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
index 9c789aa..d17b41f 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
@@ -25,6 +25,7 @@ import java.util.Optional;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.User;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.RightManager;
@@ -207,8 +208,8 @@ public class StoreRightManager implements RightManager {
 
     @VisibleForTesting
     boolean areDomainsDifferent(String user, String otherUser) {
-        Optional<String> domain = User.fromUsername(user).getDomainPart();
-        Optional<String> otherDomain = 
User.fromUsername(otherUser).getDomainPart();
+        Optional<Domain> domain = User.fromUsername(user).getDomainPart();
+        Optional<Domain> otherDomain = 
User.fromUsername(otherUser).getDomainPart();
         return !domain.equals(otherDomain);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/FixedMaxQuotaManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/FixedMaxQuotaManager.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/FixedMaxQuotaManager.java
index 96483f6..3fc825a 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/FixedMaxQuotaManager.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/FixedMaxQuotaManager.java
@@ -3,6 +3,7 @@ package org.apache.james.mailbox.store.quota;
 import java.util.Map;
 import java.util.Optional;
 
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.UnsupportedOperationException;
 import org.apache.james.mailbox.model.Quota;
@@ -44,12 +45,12 @@ public class FixedMaxQuotaManager implements 
MaxQuotaManager {
     }
 
     @Override
-    public void setDomainMaxMessage(String domain, QuotaCount count) throws 
MailboxException {
+    public void setDomainMaxMessage(Domain domain, QuotaCount count) throws 
MailboxException {
         throw new UnsupportedOperationException("Can not modify domain 
specific upper limit for FixedMaxQuotaManager");
     }
 
     @Override
-    public void setDomainMaxStorage(String domain, QuotaSize size) throws 
UnsupportedOperationException {
+    public void setDomainMaxStorage(Domain domain, QuotaSize size) throws 
UnsupportedOperationException {
         throw new UnsupportedOperationException("Can not modify domain 
specific upper limit for FixedMaxQuotaManager");
     }
 
@@ -98,12 +99,12 @@ public class FixedMaxQuotaManager implements 
MaxQuotaManager {
     }
 
     @Override
-    public Optional<QuotaCount> getDomainMaxMessage(String domain) {
+    public Optional<QuotaCount> getDomainMaxMessage(Domain domain) {
         return Optional.empty();
     }
 
     @Override
-    public Optional<QuotaSize> getDomainMaxStorage(String domain) {
+    public Optional<QuotaSize> getDomainMaxStorage(Domain domain) {
         return Optional.empty();
     }
 
@@ -112,12 +113,12 @@ public class FixedMaxQuotaManager implements 
MaxQuotaManager {
     }
 
     @Override
-    public void removeDomainMaxMessage(String domain) throws 
UnsupportedOperationException {
+    public void removeDomainMaxMessage(Domain domain) throws 
UnsupportedOperationException {
         throw new UnsupportedOperationException("Can not modify domain 
specific upper limit for FixedMaxQuotaManager");
     }
 
     @Override
-    public void removeDomainMaxStorage(String domain) throws 
UnsupportedOperationException {
+    public void removeDomainMaxStorage(Domain domain) throws 
UnsupportedOperationException {
         throw new UnsupportedOperationException("Can not modify domain 
specific upper limit for FixedMaxQuotaManager");
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoMaxQuotaManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoMaxQuotaManager.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoMaxQuotaManager.java
index ad931c8..d5e290a 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoMaxQuotaManager.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoMaxQuotaManager.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.store.quota;
 import java.util.Map;
 import java.util.Optional;
 
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
@@ -59,22 +60,22 @@ public class NoMaxQuotaManager implements MaxQuotaManager {
     }
 
     @Override
-    public void setDomainMaxMessage(String domain, QuotaCount count) throws 
MailboxException {
+    public void setDomainMaxMessage(Domain domain, QuotaCount count) throws 
MailboxException {
         throw new MailboxException("Operation is not supported");
     }
 
     @Override
-    public void setDomainMaxStorage(String domain, QuotaSize size) throws 
MailboxException {
+    public void setDomainMaxStorage(Domain domain, QuotaSize size) throws 
MailboxException {
         throw new MailboxException("Operation is not supported");
     }
 
     @Override
-    public void removeDomainMaxMessage(String domain) throws MailboxException {
+    public void removeDomainMaxMessage(Domain domain) throws MailboxException {
         throw new MailboxException("Operation is not supported");
     }
 
     @Override
-    public void removeDomainMaxStorage(String domain) throws MailboxException {
+    public void removeDomainMaxStorage(Domain domain) throws MailboxException {
         throw new MailboxException("Operation is not supported");
     }
 
@@ -119,12 +120,12 @@ public class NoMaxQuotaManager implements MaxQuotaManager 
{
     }
 
     @Override
-    public Optional<QuotaCount> getDomainMaxMessage(String domain) {
+    public Optional<QuotaCount> getDomainMaxMessage(Domain domain) {
         return Optional.empty();
     }
 
     @Override
-    public Optional<QuotaSize> getDomainMaxStorage(String domain) {
+    public Optional<QuotaSize> getDomainMaxStorage(Domain domain) {
         return Optional.empty();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/GenericMaxQuotaManagerTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/GenericMaxQuotaManagerTest.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/GenericMaxQuotaManagerTest.java
index 9d765a8..ff26ca5 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/GenericMaxQuotaManagerTest.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/GenericMaxQuotaManagerTest.java
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.Optional;
 
+import org.apache.james.core.Domain;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
@@ -33,7 +34,7 @@ import org.junit.Test;
 
 public abstract class GenericMaxQuotaManagerTest {
 
-    public static final String DOMAIN = "domain";
+    public static final Domain DOMAIN = Domain.of("domain");
     public static final QuotaRoot QUOTA_ROOT = 
QuotaRoot.quotaRoot("benwa@domain", Optional.of(DOMAIN));
     private MaxQuotaManager maxQuotaManager;
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
----------------------------------------------------------------------
diff --git 
a/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java 
b/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
index c4be663..de77a83 100644
--- a/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
+++ b/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java
@@ -32,6 +32,7 @@ import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 import javax.sql.DataSource;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.mailet.Experimental;
 import org.apache.mailet.Mail;
@@ -343,7 +344,7 @@ public class BayesianAnalysis extends GenericMailet {
     }
 
     private boolean isSenderLocal(Mail mail) {
-        return mail.getSender() != null && 
getMailetContext().isLocalServer(mail.getSender().getDomain());
+        return mail.getSender() != null && 
getMailetContext().isLocalServer(Domain.of(mail.getSender().getDomain()));
     }
 
     void loadData(Connection conn) throws java.sql.SQLException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
----------------------------------------------------------------------
diff --git a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java 
b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
index 11d658c..e987882 100644
--- a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
+++ b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.slf4j.Logger;
 
@@ -227,12 +228,12 @@ public interface MailetContext {
 
     /**
      * Checks if a host name is local, i.e. this server is the
-     * final delivery destination for messages sent to this host.
+     * final delivery destination for messages sent to this domain.
      *
-     * @param hostname the host name to check
+     * @param domain the domain name to check
      * @return true if server is local, false otherwise
      */
-    boolean isLocalServer(String hostname);
+    boolean isLocalServer(Domain domain);
 
     /**
      * Checks if a user account is local, i.e. the account exists locally

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
----------------------------------------------------------------------
diff --git 
a/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java 
b/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
index 829d9f7..1cee292 100644
--- a/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
+++ b/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
@@ -34,6 +34,7 @@ import javax.mail.MessagingException;
 import javax.mail.internet.AddressException;
 import javax.mail.internet.MimeMessage;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.mailet.HostAddress;
 import org.apache.mailet.LookupException;
@@ -415,8 +416,8 @@ public class FakeMailContext implements MailetContext {
     }
 
     @Override
-    public boolean isLocalServer(String serverName) {
-        return serverName.equals("localhost");  // trivial implementation
+    public boolean isLocalServer(Domain domain) {
+        return domain.equals(Domain.of("localhost"));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/standard/src/main/java/org/apache/james/transport/mailets/PostmasterAlias.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/PostmasterAlias.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/PostmasterAlias.java
index 9a539d9..481ec1a 100644
--- 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/PostmasterAlias.java
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/PostmasterAlias.java
@@ -24,6 +24,7 @@ import java.util.stream.Stream;
 
 import javax.mail.MessagingException;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.mailet.Mail;
 import org.apache.mailet.base.GenericMailet;
@@ -66,7 +67,7 @@ public class PostmasterAlias extends GenericMailet {
 
     private boolean isPostmasterAlias(MailAddress addr) {
         return addr.getLocalPart().equalsIgnoreCase("postmaster")
-            && getMailetContext().isLocalServer(addr.getDomain())
+            && getMailetContext().isLocalServer(Domain.of(addr.getDomain()))
             && !getMailetContext().isLocalEmail(addr);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/standard/src/main/java/org/apache/james/transport/matchers/HostIsLocal.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/matchers/HostIsLocal.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/matchers/HostIsLocal.java
index 46763a9..46d0c7c 100644
--- 
a/mailet/standard/src/main/java/org/apache/james/transport/matchers/HostIsLocal.java
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/matchers/HostIsLocal.java
@@ -21,6 +21,7 @@
 
 package org.apache.james.transport.matchers;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.mailet.base.GenericRecipientMatcher;
 
@@ -32,6 +33,6 @@ public class HostIsLocal extends GenericRecipientMatcher {
 
     @Override
     public boolean matchRecipient(MailAddress recipient) {
-        return getMailetContext().isLocalServer(recipient.getDomain());
+        return 
getMailetContext().isLocalServer(Domain.of(recipient.getDomain()));
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/standard/src/main/java/org/apache/james/transport/matchers/SenderHostIsLocal.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/matchers/SenderHostIsLocal.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/matchers/SenderHostIsLocal.java
index 7102211..735efae 100644
--- 
a/mailet/standard/src/main/java/org/apache/james/transport/matchers/SenderHostIsLocal.java
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/matchers/SenderHostIsLocal.java
@@ -21,8 +21,8 @@
 package org.apache.james.transport.matchers;
 
 import java.util.Collection;
-import java.util.Locale;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.mailet.Mail;
 import org.apache.mailet.base.GenericMatcher;
@@ -48,8 +48,7 @@ public class SenderHostIsLocal extends GenericMatcher {
     }
 
     private boolean isLocalServer(Mail mail) {
-        return this.getMailetContext().isLocalServer(
-                mail.getSender().getDomain().toLowerCase(Locale.US));
+        return 
this.getMailetContext().isLocalServer(Domain.of(mail.getSender().getDomain()));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/standard/src/test/java/org/apache/james/transport/matchers/HostIsLocalTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/matchers/HostIsLocalTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/matchers/HostIsLocalTest.java
index 5d6c41a..2bb64cf 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/matchers/HostIsLocalTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/matchers/HostIsLocalTest.java
@@ -32,6 +32,7 @@ import static org.mockito.Mockito.when;
 
 import javax.mail.MessagingException;
 
+import org.apache.james.core.Domain;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailetContext;
 import org.apache.mailet.Matcher;
@@ -47,8 +48,8 @@ public class HostIsLocalTest {
     @BeforeEach
     public void setUp() throws Exception {
         MailetContext mailContext = mock(MailetContext.class);
-        when(mailContext.isLocalServer(JAMES_APACHE_ORG)).thenReturn(true);
-        when(mailContext.isLocalServer(JAMES2_APACHE_ORG)).thenReturn(false);
+        
when(mailContext.isLocalServer(Domain.of(JAMES_APACHE_ORG))).thenReturn(true);
+        
when(mailContext.isLocalServer(Domain.of(JAMES2_APACHE_ORG))).thenReturn(false);
 
         matcher = new HostIsLocal();
         FakeMatcherConfig mci = FakeMatcherConfig.builder()

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/mailet/standard/src/test/java/org/apache/james/transport/matchers/SenderHostIsLocalTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/matchers/SenderHostIsLocalTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/matchers/SenderHostIsLocalTest.java
index 5d5982c..d1a6759 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/matchers/SenderHostIsLocalTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/matchers/SenderHostIsLocalTest.java
@@ -32,6 +32,7 @@ import java.util.Collection;
 
 import javax.mail.MessagingException;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailetContext;
@@ -48,8 +49,8 @@ public class SenderHostIsLocalTest {
     @BeforeEach
     public void setUp() throws MessagingException {
         MailetContext mailContext = mock(MailetContext.class);
-        when(mailContext.isLocalServer(JAMES_APACHE_ORG)).thenReturn(true);
-        when(mailContext.isLocalServer(JAMES2_APACHE_ORG)).thenReturn(false);
+        
when(mailContext.isLocalServer(Domain.of(JAMES_APACHE_ORG))).thenReturn(true);
+        
when(mailContext.isLocalServer(Domain.of(JAMES2_APACHE_ORG))).thenReturn(false);
         
         matcher = new SenderHostIsLocal();
         FakeMatcherConfig mci = FakeMatcherConfig.builder()

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractSenderAuthIdentifyVerificationRcptHook.java
----------------------------------------------------------------------
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractSenderAuthIdentifyVerificationRcptHook.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractSenderAuthIdentifyVerificationRcptHook.java
index 579c2fe..eeeb6b2 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractSenderAuthIdentifyVerificationRcptHook.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractSenderAuthIdentifyVerificationRcptHook.java
@@ -20,6 +20,7 @@ package org.apache.james.protocols.smtp.core;
 
 import java.util.Locale;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.james.protocols.api.ProtocolSession;
 import org.apache.james.protocols.smtp.SMTPRetCode;
@@ -60,8 +61,8 @@ public abstract class 
AbstractSenderAuthIdentifyVerificationRcptHook implements
             // Its important to ignore case here to fix JAMES-837. This is 
save todo because if the handler is called
             // the user was already authenticated
             if ((senderAddress == null)
-                    || (!authUser.equalsIgnoreCase(username))
-                    || (!isLocalDomain(senderAddress.getDomain()))) {
+                || (!authUser.equalsIgnoreCase(username))
+                || (!isLocalDomain(Domain.of(senderAddress.getDomain())))) {
                 return INVALID_AUTH;
             }
         }
@@ -75,7 +76,7 @@ public abstract class 
AbstractSenderAuthIdentifyVerificationRcptHook implements
      * @param domain
      * @return isLocal
      */
-    protected abstract boolean isLocalDomain(String domain);
+    protected abstract boolean isLocalDomain(Domain domain);
     
     /**
      * Return true if virtualHosting should get used. If so the full email 
address will get used to 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/app/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/server/app/src/main/resources/META-INF/persistence.xml 
b/server/app/src/main/resources/META-INF/persistence.xml
index 34eae79..4688e39 100644
--- a/server/app/src/main/resources/META-INF/persistence.xml
+++ b/server/app/src/main/resources/META-INF/persistence.xml
@@ -35,6 +35,8 @@
         <class>org.apache.james.domainlist.jpa.model.JPADomain</class>
         <class>org.apache.james.user.jpa.model.JPAUser</class>
         <class>org.apache.james.rrt.jpa.model.JPARecipientRewrite</class>
+        
<class>org.apache.james.mailbox.jpa.quota.model.MaxDomainMessageCount</class>
+        
<class>org.apache.james.mailbox.jpa.quota.model.MaxDomainStorage</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxGlobalMessageCount</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxGlobalStorage</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxUserMessageCount</class>

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
index ed4d522..b911dc9 100644
--- 
a/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/utils/DataProbeImpl.java
@@ -25,12 +25,14 @@ import java.util.Map;
 import javax.inject.Inject;
 
 import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.core.Domain;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.probe.DataProbe;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.lib.Mappings;
 import org.apache.james.user.api.UsersRepository;
 
+import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
@@ -72,28 +74,28 @@ public class DataProbeImpl implements GuiceProbe, DataProbe 
{
 
     @Override
     public void addDomain(String domain) throws Exception {
-        domainList.addDomain(domain);
+        domainList.addDomain(Domain.of(domain));
     }
 
 
     @Override
     public boolean containsDomain(String domain) throws Exception {
-        return domainList.containsDomain(domain);
+        return domainList.containsDomain(Domain.of(domain));
     }
 
     @Override
     public String getDefaultDomain() throws Exception {
-        return domainList.getDefaultDomain();
+        return domainList.getDefaultDomain().name();
     }
 
     @Override
     public void removeDomain(String domain) throws Exception {
-        domainList.removeDomain(domain);
+        domainList.removeDomain(Domain.of(domain));
     }
 
     @Override
     public List<String> listDomains() throws Exception {
-        return domainList.getDomains();
+        return 
domainList.getDomains().stream().map(Domain::name).collect(Guavate.toImmutableList());
     }
 
     @Override
@@ -108,27 +110,27 @@ public class DataProbeImpl implements GuiceProbe, 
DataProbe {
 
     @Override
     public void addAddressMapping(String user, String domain, String 
toAddress) throws Exception {
-        recipientRewriteTable.addAddressMapping(user, domain, toAddress);
+        recipientRewriteTable.addAddressMapping(user, Domain.of(domain), 
toAddress);
     }
 
     @Override
     public void removeAddressMapping(String user, String domain, String 
fromAddress) throws Exception {
-        recipientRewriteTable.removeAddressMapping(user, domain, fromAddress);
+        recipientRewriteTable.removeAddressMapping(user, Domain.of(domain), 
fromAddress);
     }
 
     @Override
     public void addRegexMapping(String user, String domain, String regex) 
throws Exception {
-        recipientRewriteTable.addRegexMapping(user, domain, regex);
+        recipientRewriteTable.addRegexMapping(user, Domain.of(domain), regex);
     }
 
 
     @Override
     public void removeRegexMapping(String user, String domain, String regex) 
throws Exception {
-        recipientRewriteTable.removeRegexMapping(user, domain, regex);
+        recipientRewriteTable.removeRegexMapping(user, Domain.of(domain), 
regex);
     }
 
     @Override
     public void addDomainAliasMapping(String aliasDomain, String 
deliveryDomain) throws Exception {
-        recipientRewriteTable.addAliasDomainMapping(aliasDomain, 
deliveryDomain);
+        recipientRewriteTable.addAliasDomainMapping(Domain.of(aliasDomain), 
Domain.of(deliveryDomain));
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/container/guice/jpa-guice/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git 
a/server/container/guice/jpa-guice/src/main/resources/META-INF/persistence.xml 
b/server/container/guice/jpa-guice/src/main/resources/META-INF/persistence.xml
index cd761a3..9f00fa9 100644
--- 
a/server/container/guice/jpa-guice/src/main/resources/META-INF/persistence.xml
+++ 
b/server/container/guice/jpa-guice/src/main/resources/META-INF/persistence.xml
@@ -35,6 +35,8 @@
         <class>org.apache.james.user.jpa.model.JPAUser</class>
         <class>org.apache.james.rrt.jpa.model.JPARecipientRewrite</class>
 
+        
<class>org.apache.james.mailbox.jpa.quota.model.MaxDomainMessageCount</class>
+        
<class>org.apache.james.mailbox.jpa.quota.model.MaxDomainStorage</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxGlobalMessageCount</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxGlobalStorage</class>
         
<class>org.apache.james.mailbox.jpa.quota.model.MaxUserMessageCount</class>

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/data/data-api/src/main/java/org/apache/james/domainlist/api/DomainList.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-api/src/main/java/org/apache/james/domainlist/api/DomainList.java
 
b/server/data/data-api/src/main/java/org/apache/james/domainlist/api/DomainList.java
index fd22361..5a97971 100644
--- 
a/server/data/data-api/src/main/java/org/apache/james/domainlist/api/DomainList.java
+++ 
b/server/data/data-api/src/main/java/org/apache/james/domainlist/api/DomainList.java
@@ -20,6 +20,8 @@ package org.apache.james.domainlist.api;
 
 import java.util.List;
 
+import org.apache.james.core.Domain;
+
 /**
  * This interface should be implemented by services which offer domains for
  * which email will accepted.
@@ -32,7 +34,7 @@ public interface DomainList {
      * 
      * @return domains
      */
-    List<String> getDomains() throws DomainListException;
+    List<Domain> getDomains() throws DomainListException;
 
     /**
      * Return true if the domain exists in the service
@@ -41,7 +43,7 @@ public interface DomainList {
      *            the domain
      * @return true if the given domain exists in the service
      */
-    boolean containsDomain(String domain) throws DomainListException;
+    boolean containsDomain(Domain domain) throws DomainListException;
 
     /**
      * Add domain to the service
@@ -51,7 +53,7 @@ public interface DomainList {
      * @throws DomainListException
      *            If the domain could not be added
      */
-    void addDomain(String domain) throws DomainListException;
+    void addDomain(Domain domain) throws DomainListException;
 
     /**
      * Remove domain from the service
@@ -61,7 +63,7 @@ public interface DomainList {
      * @throws DomainListException
      *            If the domain could not be removed
      */
-    void removeDomain(String domain) throws DomainListException;
+    void removeDomain(Domain domain) throws DomainListException;
 
     /**
      * Return the default domain which will get used to deliver mail to if only
@@ -69,6 +71,6 @@ public interface DomainList {
      * 
      * @return the defaultdomain
      */
-    String getDefaultDomain() throws DomainListException;
+    Domain getDefaultDomain() throws DomainListException;
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
 
b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
index e4174a1..40ef443 100644
--- 
a/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
+++ 
b/server/data/data-api/src/main/java/org/apache/james/rrt/api/RecipientRewriteTable.java
@@ -20,6 +20,7 @@ package org.apache.james.rrt.api;
 
 import java.util.Map;
 
+import org.apache.james.core.Domain;
 import org.apache.james.rrt.lib.Mappings;
 
 /**
@@ -27,6 +28,21 @@ import org.apache.james.rrt.lib.Mappings;
  */
 public interface RecipientRewriteTable {
 
+    interface Domains {
+        Domain WILDCARD = new Domain(RecipientRewriteTable.WILDCARD) {
+
+            @Override
+            public String name() {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public String toString() {
+                return "Domain : * (Wildcard)";
+            }
+        };
+    }
+
     /**
      * The prefix which is used for error mappings
      */
@@ -58,7 +74,7 @@ public interface RecipientRewriteTable {
      *             get thrown if an error mapping was found
      * @throws RecipientRewriteTableException
      */
-    Mappings getMappings(String user, String domain) throws 
ErrorMappingException, RecipientRewriteTableException;
+    Mappings getMappings(String user, Domain domain) throws 
ErrorMappingException, RecipientRewriteTableException;
 
     /**
      * Add regex mapping
@@ -71,7 +87,7 @@ public interface RecipientRewriteTable {
      *            the regex.
      * @throws RecipientRewriteTableException
      */
-    void addRegexMapping(String user, String domain, String regex) throws 
RecipientRewriteTableException;
+    void addRegexMapping(String user, Domain domain, String regex) throws 
RecipientRewriteTableException;
 
     /**
      * Remove regex mapping
@@ -84,7 +100,7 @@ public interface RecipientRewriteTable {
      *            the regex.
      * @throws RecipientRewriteTableException
      */
-    void removeRegexMapping(String user, String domain, String regex) throws 
RecipientRewriteTableException;
+    void removeRegexMapping(String user, Domain domain, String regex) throws 
RecipientRewriteTableException;
 
     /***
      * Add address mapping
@@ -96,7 +112,7 @@ public interface RecipientRewriteTable {
      * @param address
      * @throws RecipientRewriteTableException
      */
-    void addAddressMapping(String user, String domain, String address) throws 
RecipientRewriteTableException;
+    void addAddressMapping(String user, Domain domain, String address) throws 
RecipientRewriteTableException;
 
     /**
      * Remove address mapping
@@ -108,7 +124,7 @@ public interface RecipientRewriteTable {
      * @param address
      * @throws RecipientRewriteTableException
      */
-    void removeAddressMapping(String user, String domain, String address) 
throws RecipientRewriteTableException;
+    void removeAddressMapping(String user, Domain domain, String address) 
throws RecipientRewriteTableException;
 
     /**
      * Add error mapping
@@ -121,7 +137,7 @@ public interface RecipientRewriteTable {
      *            the regex.
      * @throws RecipientRewriteTableException
      */
-    void addErrorMapping(String user, String domain, String error) throws 
RecipientRewriteTableException;
+    void addErrorMapping(String user, Domain domain, String error) throws 
RecipientRewriteTableException;
 
     /**
      * Remove error mapping
@@ -133,7 +149,7 @@ public interface RecipientRewriteTable {
      * @param error
      * @throws RecipientRewriteTableException
      */
-    void removeErrorMapping(String user, String domain, String error) throws 
RecipientRewriteTableException;
+    void removeErrorMapping(String user, Domain domain, String error) throws 
RecipientRewriteTableException;
 
     /**
      * Return the explicit mapping stored for the given user and domain. Return
@@ -146,7 +162,7 @@ public interface RecipientRewriteTable {
      * @return the collection which holds the mappings.
      * @throws RecipientRewriteTableException
      */
-    Mappings getUserDomainMappings(String user, String domain) throws 
RecipientRewriteTableException;
+    Mappings getUserDomainMappings(String user, Domain domain) throws 
RecipientRewriteTableException;
 
     /**
      * Add mapping
@@ -159,7 +175,7 @@ public interface RecipientRewriteTable {
      *            the mapping
      * @throws RecipientRewriteTableException
      */
-    void addMapping(String user, String domain, String mapping) throws 
RecipientRewriteTableException;
+    void addMapping(String user, Domain domain, String mapping) throws 
RecipientRewriteTableException;
 
     /**
      * Remove mapping
@@ -172,7 +188,7 @@ public interface RecipientRewriteTable {
      *            the mapping
      * @throws RecipientRewriteTableException
      */
-    void removeMapping(String user, String domain, String mapping) throws 
RecipientRewriteTableException;
+    void removeMapping(String user, Domain domain, String mapping) throws 
RecipientRewriteTableException;
 
     /**
      * Return a Map which holds all mappings. The key is the user@domain and 
the
@@ -192,7 +208,7 @@ public interface RecipientRewriteTable {
      *            the realDomain
      * @throws RecipientRewriteTableException
      */
-    void addAliasDomainMapping(String aliasDomain, String realDomain) throws 
RecipientRewriteTableException;
+    void addAliasDomainMapping(Domain aliasDomain, Domain realDomain) throws 
RecipientRewriteTableException;
 
     /**
      * Remove aliasDomain mapping
@@ -203,7 +219,7 @@ public interface RecipientRewriteTable {
      *            the realDomain
      * @throws RecipientRewriteTableException
      */
-    void removeAliasDomainMapping(String aliasDomain, String realDomain) 
throws RecipientRewriteTableException;
+    void removeAliasDomainMapping(Domain aliasDomain, Domain realDomain) 
throws RecipientRewriteTableException;
 
     class ErrorMappingException extends Exception {
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java 
b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
index 2354d22..6f00c70 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java
@@ -20,6 +20,7 @@
 
 package org.apache.james.rrt.lib;
 
+import org.apache.james.core.Domain;
 
 public interface Mapping {
 
@@ -33,7 +34,7 @@ public interface Mapping {
 
     boolean hasDomain();
 
-    Mapping appendDomain(String domain);
+    Mapping appendDomain(Domain domain);
 
     String getErrorMessage();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/data/data-cassandra/src/main/java/org/apache/james/domainlist/cassandra/CassandraDomainList.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-cassandra/src/main/java/org/apache/james/domainlist/cassandra/CassandraDomainList.java
 
b/server/data/data-cassandra/src/main/java/org/apache/james/domainlist/cassandra/CassandraDomainList.java
index fa68266..f52d607 100644
--- 
a/server/data/data-cassandra/src/main/java/org/apache/james/domainlist/cassandra/CassandraDomainList.java
+++ 
b/server/data/data-cassandra/src/main/java/org/apache/james/domainlist/cassandra/CassandraDomainList.java
@@ -28,12 +28,12 @@ import static 
org.apache.james.domainlist.cassandra.tables.CassandraDomainsTable
 import static 
org.apache.james.domainlist.cassandra.tables.CassandraDomainsTable.TABLE_NAME;
 
 import java.util.List;
-import java.util.Locale;
 
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.core.Domain;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.domainlist.api.DomainListException;
 import org.apache.james.domainlist.lib.AbstractDomainList;
@@ -92,36 +92,36 @@ public class CassandraDomainList extends AbstractDomainList 
{
     }
 
     @Override
-    protected List<String> getDomainListInternal() throws DomainListException {
+    protected List<Domain> getDomainListInternal() throws DomainListException {
         return executor.execute(readAllStatement.bind())
             .thenApply(resultSet -> cassandraUtils.convertToStream(resultSet)
-                .map(row -> row.getString(DOMAIN))
+                .map(row -> Domain.of(row.getString(DOMAIN)))
                 .collect(Guavate.toImmutableList()))
             .join();
     }
 
     @Override
-    protected boolean containsDomainInternal(String domain) throws 
DomainListException {
+    protected boolean containsDomainInternal(Domain domain) throws 
DomainListException {
         return executor.executeSingleRow(readStatement.bind()
-                .setString(DOMAIN, domain.toLowerCase(Locale.US)))
+                .setString(DOMAIN, domain.asString()))
             .join()
             .isPresent();
     }
 
     @Override
-    public void addDomain(String domain) throws DomainListException {
+    public void addDomain(Domain domain) throws DomainListException {
         boolean executed = executor.executeReturnApplied(insertStatement.bind()
-            .setString(DOMAIN, domain.toLowerCase(Locale.US)))
+            .setString(DOMAIN, domain.asString()))
             .join();
         if (!executed) {
-            throw new DomainListException(domain.toLowerCase(Locale.US) + " 
already exists.");
+            throw new DomainListException(domain.name() + " already exists.");
         }
     }
 
     @Override
-    public void removeDomain(String domain) throws DomainListException {
+    public void removeDomain(Domain domain) throws DomainListException {
         boolean executed = executor.executeReturnApplied(removeStatement.bind()
-            .setString(DOMAIN, domain.toLowerCase(Locale.US)))
+            .setString(DOMAIN, domain.asString()))
             .join();
         if (!executed) {
             throw new DomainListException(domain + " was not found");

http://git-wip-us.apache.org/repos/asf/james-project/blob/33cb12e5/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
----------------------------------------------------------------------
diff --git 
a/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
 
b/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
index 7f833ae..e854616 100644
--- 
a/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
+++ 
b/server/data/data-cassandra/src/main/java/org/apache/james/rrt/cassandra/CassandraRecipientRewriteTable.java
@@ -36,6 +36,7 @@ import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.core.Domain;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
 import org.apache.james.rrt.lib.AbstractRecipientRewriteTable;
 import org.apache.james.rrt.lib.Mapping;
@@ -93,33 +94,33 @@ public class CassandraRecipientRewriteTable extends 
AbstractRecipientRewriteTabl
     }
 
     @Override
-    protected void addMappingInternal(String user, String domain, Mapping 
mapping) throws RecipientRewriteTableException {
+    protected void addMappingInternal(String user, Domain domain, Mapping 
mapping) throws RecipientRewriteTableException {
         executor.executeVoid(insertStatement.bind()
             .setString(USER, getFixedUser(user))
-            .setString(DOMAIN, getFixedDomain(domain))
+            .setString(DOMAIN, getFixedDomain(domain).asString())
             .setString(MAPPING, mapping.asString()))
             .join();
     }
 
     @Override
-    protected void removeMappingInternal(String user, String domain, Mapping 
mapping) throws RecipientRewriteTableException {
+    protected void removeMappingInternal(String user, Domain domain, Mapping 
mapping) throws RecipientRewriteTableException {
         executor.executeVoid(deleteStatement.bind()
                 .setString(USER, getFixedUser(user))
-                .setString(DOMAIN, getFixedDomain(domain))
+                .setString(DOMAIN, getFixedDomain(domain).asString())
                 .setString(MAPPING, mapping.asString()))
             .join();
     }
 
     @Override
-    protected Mappings getUserDomainMappingsInternal(String user, String 
domain) throws RecipientRewriteTableException {
+    protected Mappings getUserDomainMappingsInternal(String user, Domain 
domain) throws RecipientRewriteTableException {
         return retrieveMappings(user, domain)
             .orElse(null);
     }
 
-    private Optional<Mappings> retrieveMappings(String user, String domain) {
+    private Optional<Mappings> retrieveMappings(String user, Domain domain) {
         List<String> mappings = 
executor.execute(retrieveMappingStatement.bind()
             .setString(USER, getFixedUser(user))
-            .setString(DOMAIN, getFixedDomain(domain)))
+            .setString(DOMAIN, getFixedDomain(domain).asString()))
             .thenApply(resultSet -> cassandraUtils.convertToStream(resultSet)
                 .map(row -> row.getString(MAPPING))
                 .collect(Guavate.toImmutableList()))
@@ -132,7 +133,7 @@ public class CassandraRecipientRewriteTable extends 
AbstractRecipientRewriteTabl
     protected Map<String, Mappings> getAllMappingsInternal() throws 
RecipientRewriteTableException {
         Map<String, Mappings> map = 
executor.execute(retrieveAllMappingsStatement.bind())
             .thenApply(resultSet -> cassandraUtils.convertToStream(resultSet)
-                .map(row -> new UserMapping(row.getString(USER), 
row.getString(DOMAIN), row.getString(MAPPING)))
+                .map(row -> new UserMapping(row.getString(USER), 
Domain.of(row.getString(DOMAIN)), row.getString(MAPPING)))
                 .collect(Guavate.toImmutableMap(
                     UserMapping::asKey,
                     UserMapping::toMapping,
@@ -144,10 +145,10 @@ public class CassandraRecipientRewriteTable extends 
AbstractRecipientRewriteTabl
     private static class UserMapping {
 
         private final String user;
-        private final String domain;
+        private final Domain domain;
         private final String mapping;
 
-        public UserMapping(String user, String domain, String mapping) {
+        public UserMapping(String user, Domain domain, String mapping) {
             this.user = user;
             this.domain = domain;
             this.mapping = mapping;
@@ -157,7 +158,7 @@ public class CassandraRecipientRewriteTable extends 
AbstractRecipientRewriteTabl
             return user;
         }
 
-        public String getDomain() {
+        public Domain getDomain() {
             return domain;
         }
 
@@ -175,11 +176,10 @@ public class CassandraRecipientRewriteTable extends 
AbstractRecipientRewriteTabl
     }
 
     @Override
-    protected String mapAddressInternal(String user, String domain) throws 
RecipientRewriteTableException {
+    protected String mapAddressInternal(String user, Domain domain) throws 
RecipientRewriteTableException {
         Mappings mappings = retrieveMappings(user, domain)
             .orElseGet(() -> retrieveMappings(WILDCARD, domain)
-                .orElseGet(() -> retrieveMappings(user, WILDCARD)
-                    .orElseGet(() -> MappingsImpl.empty())));
+                .orElseGet(MappingsImpl::empty));
 
         return !mappings.isEmpty() ? mappings.serialize() : null;
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to