You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/11/28 02:12:34 UTC

[james-project] 17/23: JAMES-2988 Move bitewise logic with FetchGroup models

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 b0dc0b3a70fa37d4c9f8ce89f7151e5263d8f115
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Nov 25 18:11:31 2019 +0700

    JAMES-2988 Move bitewise logic with FetchGroup models
---
 .../org/apache/james/mailbox/model/FetchGroup.java | 13 +++++
 .../james/mailbox/model/PartContentDescriptor.java | 12 ++++-
 .../apache/james/mailbox/model/FetchGroupTest.java | 56 ++++++++++++++++++++++
 .../mailbox/model/PartContentDescriptorTest.java   | 55 +++++++++++++++++++++
 .../apache/james/mailbox/store/ResultUtils.java    | 40 +++++-----------
 .../mailbox/store/mail/FetchGroupConverter.java    | 16 +++----
 6 files changed, 153 insertions(+), 39 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/FetchGroup.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/FetchGroup.java
index 10f9657..56c01ee 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/FetchGroup.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/FetchGroup.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.mailbox.model;
 
+import java.util.Arrays;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Stream;
@@ -35,6 +36,7 @@ public class FetchGroup {
      * For example: could have best performance when doing store and then
      * forget. UIDs are always returned
      */
+    public static final int NO_MASK = 0;
     public static final int MINIMAL_MASK = 0x00;
     public static final int MIME_DESCRIPTOR_MASK = 0x01;
     public static final int HEADERS_MASK = 0x100;
@@ -120,6 +122,17 @@ public class FetchGroup {
                 .or(content);
     }
 
+    public boolean hasMask(int mask) {
+        return (content & mask) > NO_MASK;
+    }
+
+    public boolean hasOnlyMasks(int... masks) {
+        int allowedMask = Arrays.stream(masks)
+            .reduce((a, b) -> a | b)
+            .orElse(0);
+        return (content & (~ allowedMask)) == 0;
+    }
+
     @Override
     public String toString() {
         return "Fetch " + content;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/PartContentDescriptor.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/PartContentDescriptor.java
index 158a348..089d1fd 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/PartContentDescriptor.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/PartContentDescriptor.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.model;
 
+import static org.apache.james.mailbox.model.FetchGroup.NO_MASK;
+
 import java.util.Objects;
 
 /**
@@ -68,11 +70,17 @@ public class PartContentDescriptor {
         return path;
     }
 
-    public int hashCode() {
+    public boolean hasMask(int mask) {
+        return (content & mask) > NO_MASK;
+    }
+
+    @Override
+    public final int hashCode() {
         return Objects.hash(path);
     }
 
-    public boolean equals(Object obj) {
+    @Override
+    public final boolean equals(Object obj) {
         if (obj instanceof PartContentDescriptor) {
             PartContentDescriptor that = (PartContentDescriptor) obj;
             return Objects.equals(this.path, that.path);
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/FetchGroupTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/FetchGroupTest.java
index b3a4712..5ded8c0 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/FetchGroupTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/FetchGroupTest.java
@@ -72,4 +72,60 @@ class FetchGroupTest {
                 .addPartContent(new MimePath(path), FetchGroup.HEADERS_MASK))
             .isEqualTo(new FetchGroup(FetchGroup.MINIMAL_MASK, ImmutableSet.of(new PartContentDescriptor(FetchGroup.MINIMAL_MASK, new MimePath(path)).or(FetchGroup.HEADERS_MASK))));
     }
+
+    @Test
+    void hasMaskShouldReturnFalseWhenNotContained() {
+        assertThat(FetchGroup.MINIMAL
+                .or(FetchGroup.MIME_HEADERS_MASK)
+                .or(FetchGroup.MIME_DESCRIPTOR_MASK)
+                .hasMask(FetchGroup.HEADERS_MASK))
+            .isFalse();
+    }
+
+    @Test
+    void hasMaskShouldReturnTrueWhenContained() {
+        assertThat(FetchGroup.MINIMAL
+                .or(FetchGroup.MIME_HEADERS_MASK)
+                .or(FetchGroup.MIME_DESCRIPTOR_MASK)
+                .hasMask(FetchGroup.MIME_HEADERS_MASK))
+            .isTrue();
+    }
+
+    @Test
+    void hasOnlyMasksShouldReturnTrueWhenSuppliedEmpty() {
+        assertThat(FetchGroup.MINIMAL
+                .hasOnlyMasks())
+            .isTrue();
+    }
+
+    @Test
+    void hasOnlyMasksShouldReturnTrueWhenExactlyContainASingleValue() {
+        assertThat(FetchGroup.HEADERS
+                .hasOnlyMasks(FetchGroup.HEADERS_MASK))
+            .isTrue();
+    }
+
+    @Test
+    void hasOnlyMasksShouldReturnTrueWhenExactlyContainMultipleValues() {
+        assertThat(FetchGroup.HEADERS
+                .or(FetchGroup.BODY_CONTENT_MASK)
+                .hasOnlyMasks(FetchGroup.HEADERS_MASK, FetchGroup.BODY_CONTENT_MASK))
+            .isTrue();
+    }
+
+    @Test
+    void hasOnlyMasksShouldReturnFalseWhenNotContained() {
+        assertThat(FetchGroup.HEADERS
+                .or(FetchGroup.BODY_CONTENT_MASK)
+                .hasOnlyMasks(FetchGroup.FULL_CONTENT_MASK))
+            .isFalse();
+    }
+
+    @Test
+    void minimalShouldAlwaysBeValid() {
+        assertThat(FetchGroup.MINIMAL
+                .hasOnlyMasks(FetchGroup.FULL_CONTENT_MASK, FetchGroup.HEADERS_MASK, FetchGroup.BODY_CONTENT_MASK,
+                    FetchGroup.MIME_DESCRIPTOR_MASK))
+            .isTrue();
+    }
 }
\ No newline at end of file
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/PartContentDescriptorTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/PartContentDescriptorTest.java
new file mode 100644
index 0000000..5b0eb8c
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/PartContentDescriptorTest.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class PartContentDescriptorTest {
+    private static final int[] POSITION = {12};
+
+    @Test
+    void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(PartContentDescriptor.class)
+            .withIgnoredFields("content")
+            .verify();
+    }
+
+    @Test
+    void hasMaskShouldReturnFalseWhenNotContained() {
+        assertThat(new PartContentDescriptor(new MimePath(POSITION))
+                .or(FetchGroup.MIME_HEADERS_MASK)
+                .or(FetchGroup.MIME_DESCRIPTOR_MASK)
+                .hasMask(FetchGroup.HEADERS_MASK))
+            .isFalse();
+    }
+
+    @Test
+    void hasMaskShouldReturnTrueWhenContained() {
+        assertThat(new PartContentDescriptor(new MimePath(POSITION))
+                .or(FetchGroup.MIME_HEADERS_MASK)
+                .or(FetchGroup.MIME_DESCRIPTOR_MASK)
+                .hasMask(FetchGroup.MIME_HEADERS_MASK))
+            .isTrue();
+    }
+}
\ No newline at end of file
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/ResultUtils.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/ResultUtils.java
index 1f59126..09e2c77 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/ResultUtils.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/ResultUtils.java
@@ -91,40 +91,27 @@ public class ResultUtils {
     
     /**
      * Return the {@link MessageResult} for the given {@link MailboxMessage} and {@link FetchGroup}
-     *
-     * @return result
      */
     public static MessageResult loadMessageResult(MailboxMessage message, FetchGroup fetchGroup) throws MailboxException {
         try {
-
             MessageResultImpl messageResult = new MessageResultImpl(message);
             if (fetchGroup != null) {
-                int content = fetchGroup.content();
-
-                if ((content & FetchGroup.HEADERS_MASK) > 0) {
-                    content -= FetchGroup.HEADERS_MASK;
-                }
-                if ((content & FetchGroup.BODY_CONTENT_MASK) > 0) {
-                    content -= FetchGroup.BODY_CONTENT_MASK;
-                }
-                if ((content & FetchGroup.FULL_CONTENT_MASK) > 0) {
-                    content -= FetchGroup.FULL_CONTENT_MASK;
-                }
-                if ((content & FetchGroup.MIME_DESCRIPTOR_MASK) > 0) {
-                    content -= FetchGroup.MIME_DESCRIPTOR_MASK;
+                if (!haveValidContent(fetchGroup)) {
+                    throw new UnsupportedOperationException("Unsupported result: " + fetchGroup.content());
                 }
-                if (content != 0) {
-                    throw new UnsupportedOperationException("Unsupported result: " + content);
-                }
-
                 addPartContent(fetchGroup, message, messageResult);
             }
             return messageResult;
-
         } catch (IOException | MimeException e) {
             throw new MailboxException("Unable to parse message", e);
         }
+    }
 
+    private static boolean haveValidContent(FetchGroup fetchGroup) {
+        return fetchGroup.hasOnlyMasks(FetchGroup.HEADERS_MASK,
+            FetchGroup.BODY_CONTENT_MASK,
+            FetchGroup.FULL_CONTENT_MASK,
+            FetchGroup.MIME_DESCRIPTOR_MASK);
     }
 
     private static void addPartContent(FetchGroup fetchGroup, MailboxMessage message, MessageResultImpl messageResult)
@@ -140,20 +127,19 @@ public class ResultUtils {
     private static void addPartContent(PartContentDescriptor descriptor, MailboxMessage message, MessageResultImpl messageResult)
             throws MailboxException, IOException, MimeException {
         MimePath mimePath = descriptor.path();
-        int content = descriptor.content();
-        if ((content & FetchGroup.FULL_CONTENT_MASK) > 0) {
+        if (descriptor.hasMask(FetchGroup.FULL_CONTENT_MASK)) {
             addFullContent(message, messageResult, mimePath);
         }
-        if ((content & FetchGroup.BODY_CONTENT_MASK) > 0) {
+        if (descriptor.hasMask(FetchGroup.BODY_CONTENT_MASK)) {
             addBodyContent(message, messageResult, mimePath);
         }
-        if ((content & FetchGroup.MIME_CONTENT_MASK) > 0) {
+        if (descriptor.hasMask(FetchGroup.MIME_CONTENT_MASK)) {
             addMimeBodyContent(message, messageResult, mimePath);
         }
-        if ((content & FetchGroup.HEADERS_MASK) > 0) {
+        if (descriptor.hasMask(FetchGroup.HEADERS_MASK)) {
             addHeaders(message, messageResult, mimePath);
         }
-        if ((content & FetchGroup.MIME_HEADERS_MASK) > 0) {
+        if (descriptor.hasMask(FetchGroup.MIME_HEADERS_MASK)) {
             addMimeHeaders(message, messageResult, mimePath);
         }
     }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/FetchGroupConverter.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/FetchGroupConverter.java
index 62b30e6..61bd4e1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/FetchGroupConverter.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/FetchGroupConverter.java
@@ -27,27 +27,27 @@ public class FetchGroupConverter {
      * {@link MessageMapper.FetchType} for it
      */
     public static MessageMapper.FetchType getFetchType(FetchGroup group) {
-        if (hasMask(group, FetchGroup.FULL_CONTENT_MASK)) {
+        if (group.hasMask(FetchGroup.FULL_CONTENT_MASK)) {
             return MessageMapper.FetchType.Full;
         }
-        if (hasMask(group, FetchGroup.MIME_DESCRIPTOR_MASK)) {
+        if (group.hasMask(FetchGroup.MIME_DESCRIPTOR_MASK)) {
             // If we need the mimedescriptor we MAY need the full content later
             // too.
             // This gives us no other choice then request it
             return MessageMapper.FetchType.Full;
         }
-        if (hasMask(group, FetchGroup.MIME_CONTENT_MASK)) {
+        if (group.hasMask(FetchGroup.MIME_CONTENT_MASK)) {
             return MessageMapper.FetchType.Full;
         }
-        if (hasMask(group, FetchGroup.MIME_HEADERS_MASK)) {
+        if (group.hasMask(FetchGroup.MIME_HEADERS_MASK)) {
             return MessageMapper.FetchType.Full;
         }
         if (!group.getPartContentDescriptors().isEmpty()) {
             return MessageMapper.FetchType.Full;
         }
 
-        boolean headers = hasMask(group, FetchGroup.HEADERS_MASK);
-        boolean body = hasMask(group, FetchGroup.BODY_CONTENT_MASK);
+        boolean headers = group.hasMask(FetchGroup.HEADERS_MASK);
+        boolean body = group.hasMask(FetchGroup.BODY_CONTENT_MASK);
 
         if (body && headers) {
             return MessageMapper.FetchType.Full;
@@ -59,8 +59,4 @@ public class FetchGroupConverter {
             return MessageMapper.FetchType.Metadata;
         }
     }
-
-    private static boolean hasMask(FetchGroup group, int mask) {
-        return (group.content() & mask) > 0;
-    }
 }


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