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 2af458075c3537e5e9e70f4567e03b47f5cd7606 Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Thu Nov 28 11:58:20 2019 +0700 JAMES-2988 Back fetchGroup with an enumSet --- mailbox/api/pom.xml | 5 + .../org/apache/james/mailbox/model/FetchGroup.java | 92 +++++++++++------- .../apache/james/mailbox/model/MessageResult.java | 10 +- .../james/mailbox/model/PartContentDescriptor.java | 42 ++++---- .../apache/james/mailbox/model/FetchGroupTest.java | 106 ++++++++------------- .../mailbox/model/PartContentDescriptorTest.java | 22 ----- .../apache/james/mailbox/store/ResultUtils.java | 36 ++++--- .../mailbox/store/mail/FetchGroupConverter.java | 20 ++-- .../james/mailbox/store/ResultUtilsTest.java | 61 ++++++++++++ .../store/mail/FetchGroupConverterTest.java | 10 +- .../imap/processor/fetch/FetchDataConverter.java | 21 ++-- .../processor/fetch/FetchDataConverterTest.java | 19 ++-- 12 files changed, 249 insertions(+), 195 deletions(-) diff --git a/mailbox/api/pom.xml b/mailbox/api/pom.xml index 8a882d7..616dc68 100644 --- a/mailbox/api/pom.xml +++ b/mailbox/api/pom.xml @@ -106,6 +106,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-params</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> 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 7923774..05844e4 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 @@ -20,18 +20,42 @@ package org.apache.james.mailbox.model; import java.util.Arrays; +import java.util.EnumSet; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; import com.github.steveash.guavate.Guavate; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; /** * Indicates the results fetched. */ public class FetchGroup { + public enum Profile { + MIME_DESCRIPTOR(MIME_DESCRIPTOR_MASK), + HEADERS(HEADERS_MASK), + FULL_CONTENT(FULL_CONTENT_MASK), + BODY_CONTENT(BODY_CONTENT_MASK), + MIME_HEADERS(MIME_HEADERS_MASK), + MIME_CONTENT(MIME_CONTENT_MASK); + + public static EnumSet<Profile> of(int content) { + return Arrays.stream(values()) + .filter(value -> (content & value.mask) > 0) + .collect(Collectors.toCollection(() -> EnumSet.noneOf(Profile.class))); + } + + private final int mask; + + Profile(int mask) { + this.mask = mask; + } + } + /** * For example: could have best performance when doing store and then * forget. UIDs are always returned @@ -45,43 +69,49 @@ public class FetchGroup { public static final int MIME_HEADERS_MASK = 0x800; public static final int MIME_CONTENT_MASK = 0x1000; - public static final FetchGroup MINIMAL = new FetchGroup(MINIMAL_MASK); - public static final FetchGroup HEADERS = new FetchGroup(HEADERS_MASK); - public static final FetchGroup FULL_CONTENT = new FetchGroup(FULL_CONTENT_MASK); - public static final FetchGroup BODY_CONTENT = new FetchGroup(BODY_CONTENT_MASK); + public static final FetchGroup MINIMAL = new FetchGroup(EnumSet.noneOf(Profile.class)); + public static final FetchGroup HEADERS = new FetchGroup(EnumSet.of(Profile.HEADERS)); + public static final FetchGroup FULL_CONTENT = new FetchGroup(EnumSet.of(Profile.FULL_CONTENT)); + public static final FetchGroup BODY_CONTENT = new FetchGroup(EnumSet.of(Profile.BODY_CONTENT)); - private final int content; + private final EnumSet<Profile> content; private final ImmutableSet<PartContentDescriptor> partContentDescriptors; @VisibleForTesting - FetchGroup(int content) { + FetchGroup(EnumSet<Profile> content) { this(content, ImmutableSet.of()); } @VisibleForTesting - FetchGroup(int content, ImmutableSet<PartContentDescriptor> partContentDescriptors) { + FetchGroup(EnumSet<Profile> content, ImmutableSet<PartContentDescriptor> partContentDescriptors) { this.content = content; this.partContentDescriptors = partContentDescriptors; } /** - * Contents to be fetched. Composed bitwise. + * Profiles to be fetched. * - * @return masks to be used for bitewise operations. - * @see #MINIMAL_MASK - * @see #MIME_DESCRIPTOR_MASK - * @see #HEADERS_MASK - * @see #FULL_CONTENT_MASK - * @see #BODY_CONTENT_MASK - * @see #MIME_HEADERS_MASK - * @see #MIME_CONTENT_MASK + * @return Return an enumset of profiles to be fetched + * @see Profile */ - public int content() { + public EnumSet<Profile> profiles() { return content; } public FetchGroup with(int content) { - return new FetchGroup(this.content | content, partContentDescriptors); + return with(Profile.of(content)); + } + + public FetchGroup with(Profile... profiles) { + Preconditions.checkArgument(profiles.length > 0); + return with(EnumSet.copyOf(ImmutableSet.copyOf(profiles))); + } + + public FetchGroup with(EnumSet<Profile> profiles) { + EnumSet<Profile> result = EnumSet.noneOf(Profile.class); + result.addAll(this.content); + result.addAll(profiles); + return new FetchGroup(result, partContentDescriptors); } /** @@ -96,15 +126,15 @@ public class FetchGroup { } /** - * Adds content for the particular part. + * Adds profiles for the particular part. * * @param path * <code>MimePath</code>, not null - * @param content - * bitwise content constant + * @param profiles + * bitwise profiles constant */ - public FetchGroup addPartContent(MimePath path, int content) { - PartContentDescriptor newContent = retrieveUpdatedPartContentDescriptor(path, content); + public FetchGroup addPartContent(MimePath path, EnumSet<Profile> profiles) { + PartContentDescriptor newContent = retrieveUpdatedPartContentDescriptor(path, profiles); return new FetchGroup(this.content, Stream.concat( @@ -114,23 +144,11 @@ public class FetchGroup { .collect(Guavate.toImmutableSet())); } - private PartContentDescriptor retrieveUpdatedPartContentDescriptor(MimePath path, int content) { + private PartContentDescriptor retrieveUpdatedPartContentDescriptor(MimePath path, EnumSet<Profile> profiles) { return partContentDescriptors.stream() .filter(descriptor -> path.equals(descriptor.path())) .findFirst() - .orElse(new PartContentDescriptor(path)) - .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; + .orElse(new PartContentDescriptor(profiles, path)); } @Override diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java index 82894d6..b21f5ce 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java @@ -84,7 +84,7 @@ public interface MessageResult extends Comparable<MessageResult> { * @param path * describing the part's position within a multipart message * @return <code>Header</code> <code>Iterator</code>, or null when - * {@link FetchGroup#content()} does not include the index and + * {@link FetchGroup#profiles()} does not include the index and * when the mime part cannot be found */ Iterator<Header> iterateHeaders(MimePath path) throws MailboxException; @@ -95,7 +95,7 @@ public interface MessageResult extends Comparable<MessageResult> { * @param path * describing the part's position within a multipart message * @return <code>Header</code> <code>Iterator</code>, or null when - * {@link FetchGroup#content()} does not include the index and + * {@link FetchGroup#profiles()} does not include the index and * when the mime part cannot be found */ Iterator<Header> iterateMimeHeaders(MimePath path) throws MailboxException; @@ -116,7 +116,7 @@ public interface MessageResult extends Comparable<MessageResult> { * @param path * describes the part * @return <code>Content</code>, or null when - * {@link FetchGroup#content()} did not been include the given + * {@link FetchGroup#profiles()} did not been include the given * index and when the mime part cannot be found */ Content getFullContent(MimePath path) throws MailboxException; @@ -137,7 +137,7 @@ public interface MessageResult extends Comparable<MessageResult> { * @param path * describes the part * @return <code>Content</code>, or null when - * {@link FetchGroup#content()} did not been include the given + * {@link FetchGroup#profiles()} did not been include the given * index and when the mime part cannot be found */ Content getBody(MimePath path) throws MailboxException; @@ -148,7 +148,7 @@ public interface MessageResult extends Comparable<MessageResult> { * @param path * describes the part * @return <code>Content</code>, or null when - * {@link FetchGroup#content()} did not been include the given + * {@link FetchGroup#profiles()} did not been include the given * index and when the mime part cannot be found */ Content getMimeBody(MimePath path) throws MailboxException; 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 089d1fd..a0ce5bf 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,45 +19,49 @@ package org.apache.james.mailbox.model; -import static org.apache.james.mailbox.model.FetchGroup.NO_MASK; - +import java.util.EnumSet; import java.util.Objects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; + /** * Describes the contents to be fetched for a mail part. All * implementations MUST implement equals. Two implementations are equal * if and only if their paths are equal. */ public class PartContentDescriptor { - private final int content; + private final EnumSet<FetchGroup.Profile> content; private final MimePath path; public PartContentDescriptor(MimePath path) { - this(0, path); + this(EnumSet.noneOf(FetchGroup.Profile.class), path); } - public PartContentDescriptor(int content, MimePath path) { + public PartContentDescriptor(EnumSet<FetchGroup.Profile> content, MimePath path) { this.content = content; this.path = path; } - public PartContentDescriptor or(int content) { - return new PartContentDescriptor(this.content | content, path); + public PartContentDescriptor with(FetchGroup.Profile... profiles) { + Preconditions.checkArgument(profiles.length > 0); + return with(EnumSet.copyOf(ImmutableSet.copyOf(profiles))); + } + + public PartContentDescriptor with(EnumSet<FetchGroup.Profile> profiles) { + EnumSet<FetchGroup.Profile> result = EnumSet.noneOf(FetchGroup.Profile.class); + result.addAll(this.content); + result.addAll(profiles); + return new PartContentDescriptor(result, path); } /** - * Contents to be fetched. Composed bitwise. + * Profiles to be fetched. * - * @return bitwise descripion - * @see FetchGroup#MINIMAL_MASK - * @see FetchGroup#MIME_DESCRIPTOR_MASK - * @see FetchGroup#HEADERS_MASK - * @see FetchGroup#FULL_CONTENT_MASK - * @see FetchGroup#BODY_CONTENT_MASK - * @see FetchGroup#MIME_HEADERS_MASK - * @see FetchGroup#MIME_CONTENT_MASK + * @return Return an enumset of profiles to be fetched + * @see FetchGroup.Profile */ - public int content() { + public EnumSet<FetchGroup.Profile> profiles() { return content; } @@ -70,10 +74,6 @@ public class PartContentDescriptor { return path; } - public boolean hasMask(int mask) { - return (content & mask) > NO_MASK; - } - @Override public final int hashCode() { return Objects.hash(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 1ad5baa..b0b072f 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 @@ -21,13 +21,38 @@ package org.apache.james.mailbox.model; import static org.assertj.core.api.Assertions.assertThat; +import java.util.EnumSet; +import java.util.stream.Stream; + +import org.apache.james.mailbox.model.FetchGroup.Profile; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import com.google.common.collect.ImmutableSet; import nl.jqno.equalsverifier.EqualsVerifier; class FetchGroupTest { + static Stream<Arguments> ofContentShouldReturnCorrectValue() { + return Stream.of( + Arguments.arguments(0, EnumSet.noneOf(Profile.class)), + Arguments.arguments(FetchGroup.MIME_DESCRIPTOR_MASK, EnumSet.of(Profile.MIME_DESCRIPTOR)), + Arguments.arguments(FetchGroup.BODY_CONTENT_MASK, EnumSet.of(Profile.BODY_CONTENT)), + Arguments.arguments(FetchGroup.FULL_CONTENT_MASK, EnumSet.of(Profile.FULL_CONTENT)), + Arguments.arguments(FetchGroup.HEADERS_MASK, EnumSet.of(Profile.HEADERS)), + Arguments.arguments(FetchGroup.MIME_HEADERS_MASK, EnumSet.of(Profile.MIME_HEADERS)), + Arguments.arguments(FetchGroup.MIME_CONTENT_MASK, EnumSet.of(Profile.MIME_CONTENT)), + Arguments.arguments(FetchGroup.HEADERS_MASK | FetchGroup.MIME_CONTENT_MASK, EnumSet.of(Profile.HEADERS, Profile.MIME_CONTENT))); + } + + @ParameterizedTest + @MethodSource + void ofContentShouldReturnCorrectValue(int content, EnumSet<Profile> expected) { + assertThat(Profile.of(content)).isEqualTo(expected); + } + @Test void shouldMatchBeanContract() { EqualsVerifier.forClass(FetchGroup.class) @@ -36,9 +61,8 @@ class FetchGroupTest { @Test void orShouldReturnAFetchGroupWithUpdatedContent() { - int expected = FetchGroup.HEADERS_MASK | FetchGroup.FULL_CONTENT_MASK; assertThat(FetchGroup.HEADERS.with(FetchGroup.FULL_CONTENT_MASK)) - .isEqualTo(new FetchGroup(expected)); + .isEqualTo(new FetchGroup(EnumSet.of(Profile.HEADERS, Profile.FULL_CONTENT))); } @Test @@ -46,8 +70,9 @@ class FetchGroupTest { int[] path = {12}; assertThat( FetchGroup.MINIMAL - .addPartContent(new MimePath(path), FetchGroup.MINIMAL_MASK)) - .isEqualTo(new FetchGroup(FetchGroup.MINIMAL_MASK, ImmutableSet.of(new PartContentDescriptor(FetchGroup.MINIMAL_MASK, new MimePath(path))))); + .addPartContent(new MimePath(path), EnumSet.noneOf(Profile.class))) + .isEqualTo(new FetchGroup(EnumSet.noneOf(Profile.class), + ImmutableSet.of(new PartContentDescriptor(new MimePath(path))))); } @Test @@ -56,11 +81,11 @@ class FetchGroupTest { int[] path2 = {13}; assertThat( FetchGroup.MINIMAL - .addPartContent(new MimePath(path), FetchGroup.MINIMAL_MASK) - .addPartContent(new MimePath(path2), FetchGroup.MINIMAL_MASK)) - .isEqualTo(new FetchGroup(FetchGroup.MINIMAL_MASK, - ImmutableSet.of(new PartContentDescriptor(FetchGroup.MINIMAL_MASK, new MimePath(path)), - new PartContentDescriptor(FetchGroup.MINIMAL_MASK, new MimePath(path2))))); + .addPartContent(new MimePath(path), EnumSet.noneOf(Profile.class)) + .addPartContent(new MimePath(path2), EnumSet.noneOf(Profile.class))) + .isEqualTo(new FetchGroup(EnumSet.noneOf(Profile.class), + ImmutableSet.of(new PartContentDescriptor(new MimePath(path)), + new PartContentDescriptor(new MimePath(path2))))); } @Test @@ -68,64 +93,9 @@ class FetchGroupTest { int[] path = {12}; assertThat( FetchGroup.MINIMAL - .addPartContent(new MimePath(path), FetchGroup.MINIMAL_MASK) - .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 - .with(FetchGroup.MIME_HEADERS_MASK) - .with(FetchGroup.MIME_DESCRIPTOR_MASK) - .hasMask(FetchGroup.HEADERS_MASK)) - .isFalse(); - } - - @Test - void hasMaskShouldReturnTrueWhenContained() { - assertThat(FetchGroup.MINIMAL - .with(FetchGroup.MIME_HEADERS_MASK) - .with(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 - .with(FetchGroup.BODY_CONTENT_MASK) - .hasOnlyMasks(FetchGroup.HEADERS_MASK, FetchGroup.BODY_CONTENT_MASK)) - .isTrue(); - } - - @Test - void hasOnlyMasksShouldReturnFalseWhenNotContained() { - assertThat(FetchGroup.HEADERS - .with(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(); + .addPartContent(new MimePath(path), EnumSet.noneOf(Profile.class)) + .addPartContent(new MimePath(path), EnumSet.of(Profile.HEADERS))) + .isEqualTo(new FetchGroup(EnumSet.noneOf(Profile.class), + ImmutableSet.of(new PartContentDescriptor(EnumSet.of(Profile.HEADERS), new MimePath(path))))); } } \ 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 index 5b0eb8c..ff9a817 100644 --- 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 @@ -19,37 +19,15 @@ 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 09e2c77..31efbfe 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 @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.List; import org.apache.james.mailbox.exception.MailboxException; @@ -43,6 +44,9 @@ import org.apache.james.mime4j.stream.RawField; import org.apache.james.mime4j.util.ByteSequence; import org.apache.james.mime4j.util.ContentUtil; +import com.github.steveash.guavate.Guavate; +import com.google.common.annotations.VisibleForTesting; + public class ResultUtils { public static List<Header> createHeaders(MailboxMessage document) throws IOException { @@ -97,7 +101,7 @@ public class ResultUtils { MessageResultImpl messageResult = new MessageResultImpl(message); if (fetchGroup != null) { if (!haveValidContent(fetchGroup)) { - throw new UnsupportedOperationException("Unsupported result: " + fetchGroup.content()); + throw new UnsupportedOperationException("Unsupported result: " + fetchGroup.profiles()); } addPartContent(fetchGroup, message, messageResult); } @@ -107,11 +111,20 @@ public class ResultUtils { } } - private static boolean haveValidContent(FetchGroup fetchGroup) { - return fetchGroup.hasOnlyMasks(FetchGroup.HEADERS_MASK, - FetchGroup.BODY_CONTENT_MASK, - FetchGroup.FULL_CONTENT_MASK, - FetchGroup.MIME_DESCRIPTOR_MASK); + @VisibleForTesting + static boolean haveValidContent(FetchGroup fetchGroup) { + EnumSet<FetchGroup.Profile> supportedGroups = EnumSet.of( + FetchGroup.Profile.HEADERS, + FetchGroup.Profile.BODY_CONTENT, + FetchGroup.Profile.FULL_CONTENT, + FetchGroup.Profile.MIME_DESCRIPTOR); + + Collection<FetchGroup.Profile> unsupportedProfiles = fetchGroup.profiles() + .stream() + .filter(value -> !supportedGroups.contains(value)) + .collect(Guavate.toImmutableSet()); + + return unsupportedProfiles.isEmpty(); } private static void addPartContent(FetchGroup fetchGroup, MailboxMessage message, MessageResultImpl messageResult) @@ -127,19 +140,20 @@ public class ResultUtils { private static void addPartContent(PartContentDescriptor descriptor, MailboxMessage message, MessageResultImpl messageResult) throws MailboxException, IOException, MimeException { MimePath mimePath = descriptor.path(); - if (descriptor.hasMask(FetchGroup.FULL_CONTENT_MASK)) { + EnumSet<FetchGroup.Profile> profiles = descriptor.profiles(); + if (profiles.contains(FetchGroup.Profile.FULL_CONTENT)) { addFullContent(message, messageResult, mimePath); } - if (descriptor.hasMask(FetchGroup.BODY_CONTENT_MASK)) { + if (profiles.contains(FetchGroup.Profile.BODY_CONTENT)) { addBodyContent(message, messageResult, mimePath); } - if (descriptor.hasMask(FetchGroup.MIME_CONTENT_MASK)) { + if (profiles.contains(FetchGroup.Profile.MIME_CONTENT)) { addMimeBodyContent(message, messageResult, mimePath); } - if (descriptor.hasMask(FetchGroup.HEADERS_MASK)) { + if (profiles.contains(FetchGroup.Profile.HEADERS)) { addHeaders(message, messageResult, mimePath); } - if (descriptor.hasMask(FetchGroup.MIME_HEADERS_MASK)) { + if (profiles.contains(FetchGroup.Profile.MIME_HEADERS)) { 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 61bd4e1..1099c93 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 @@ -19,7 +19,10 @@ package org.apache.james.mailbox.store.mail; +import java.util.EnumSet; + import org.apache.james.mailbox.model.FetchGroup; +import org.apache.james.mailbox.model.FetchGroup.Profile; public class FetchGroupConverter { /** @@ -27,27 +30,28 @@ public class FetchGroupConverter { * {@link MessageMapper.FetchType} for it */ public static MessageMapper.FetchType getFetchType(FetchGroup group) { - if (group.hasMask(FetchGroup.FULL_CONTENT_MASK)) { + EnumSet<Profile> profiles = group.profiles(); + + if (profiles.contains(Profile.FULL_CONTENT)) { return MessageMapper.FetchType.Full; } - if (group.hasMask(FetchGroup.MIME_DESCRIPTOR_MASK)) { - // If we need the mimedescriptor we MAY need the full content later - // too. + if (profiles.contains(Profile.MIME_DESCRIPTOR)) { + // If we need the mimedescriptor we MAY need the full profile later too. // This gives us no other choice then request it return MessageMapper.FetchType.Full; } - if (group.hasMask(FetchGroup.MIME_CONTENT_MASK)) { + if (profiles.contains(Profile.MIME_CONTENT)) { return MessageMapper.FetchType.Full; } - if (group.hasMask(FetchGroup.MIME_HEADERS_MASK)) { + if (profiles.contains(Profile.MIME_HEADERS)) { return MessageMapper.FetchType.Full; } if (!group.getPartContentDescriptors().isEmpty()) { return MessageMapper.FetchType.Full; } - boolean headers = group.hasMask(FetchGroup.HEADERS_MASK); - boolean body = group.hasMask(FetchGroup.BODY_CONTENT_MASK); + boolean headers = profiles.contains(Profile.HEADERS); + boolean body = profiles.contains(Profile.BODY_CONTENT); if (body && headers) { return MessageMapper.FetchType.Full; diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/ResultUtilsTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/ResultUtilsTest.java new file mode 100644 index 0000000..d122cbd --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/ResultUtilsTest.java @@ -0,0 +1,61 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.Stream; + +import org.apache.james.mailbox.model.FetchGroup; +import org.apache.james.mailbox.model.FetchGroup.Profile; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ResultUtilsTest { + static Stream<Arguments> haveValidContent() { + return Stream.of( + Arguments.of(FetchGroup.MINIMAL), + Arguments.of(FetchGroup.MINIMAL.with(Profile.MIME_DESCRIPTOR)), + Arguments.of(FetchGroup.FULL_CONTENT), + Arguments.of(FetchGroup.HEADERS), + Arguments.of(FetchGroup.BODY_CONTENT), + Arguments.of(FetchGroup.BODY_CONTENT.with(Profile.HEADERS))); + } + + @ParameterizedTest + @MethodSource + void haveValidContent(FetchGroup fetchGroup) { + assertThat(ResultUtils.haveValidContent(fetchGroup)).isTrue(); + } + + static Stream<Arguments> haveInvalidContent() { + return Stream.of( + Arguments.of(FetchGroup.MINIMAL.with(Profile.MIME_CONTENT)), + Arguments.of(FetchGroup.MINIMAL.with(Profile.MIME_HEADERS))); + } + + @ParameterizedTest + @MethodSource + void haveInvalidContent(FetchGroup fetchGroup) { + assertThat(ResultUtils.haveValidContent(fetchGroup)).isFalse(); + } + +} \ No newline at end of file diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/FetchGroupConverterTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/FetchGroupConverterTest.java index ed93a81..0c1b376 100644 --- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/FetchGroupConverterTest.java +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/FetchGroupConverterTest.java @@ -21,9 +21,11 @@ package org.apache.james.mailbox.store.mail; import static org.assertj.core.api.Assertions.assertThat; +import java.util.EnumSet; import java.util.stream.Stream; import org.apache.james.mailbox.model.FetchGroup; +import org.apache.james.mailbox.model.FetchGroup.Profile; import org.apache.james.mailbox.model.MimePath; import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; import org.junit.jupiter.params.ParameterizedTest; @@ -43,10 +45,10 @@ class FetchGroupConverterTest { Arguments.arguments(FetchGroup.MINIMAL.with(FetchGroup.MIME_CONTENT_MASK), FetchType.Full), Arguments.arguments(FetchGroup.MINIMAL.with(FetchGroup.MIME_DESCRIPTOR_MASK), FetchType.Full), Arguments.arguments(FetchGroup.MINIMAL.with(FetchGroup.MIME_HEADERS_MASK), FetchType.Full), - Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), FetchGroup.MINIMAL_MASK), FetchType.Full), - Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), FetchGroup.HEADERS_MASK), FetchType.Full), - Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), FetchGroup.BODY_CONTENT_MASK), FetchType.Full), - Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), FetchGroup.FULL_CONTENT_MASK), FetchType.Full)); + Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), EnumSet.noneOf(Profile.class)), FetchType.Full), + Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), EnumSet.of(Profile.HEADERS)), FetchType.Full), + Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), EnumSet.of(Profile.BODY_CONTENT)), FetchType.Full), + Arguments.arguments(FetchGroup.MINIMAL.addPartContent(new MimePath(PARTS), EnumSet.of(Profile.FULL_CONTENT)), FetchType.Full)); } @ParameterizedTest diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchDataConverter.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchDataConverter.java index a75080a..baa4d92 100644 --- a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchDataConverter.java +++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchDataConverter.java @@ -20,6 +20,7 @@ package org.apache.james.imap.processor.fetch; import java.util.Collection; +import java.util.EnumSet; import org.apache.james.imap.api.message.BodyFetchElement; import org.apache.james.imap.api.message.FetchData; @@ -32,10 +33,10 @@ class FetchDataConverter { FetchGroup result = FetchGroup.MINIMAL; if (fetch.isEnvelope()) { - result = result.with(FetchGroup.HEADERS_MASK); + result = result.with(FetchGroup.Profile.HEADERS); } if (fetch.isBody() || fetch.isBodyStructure()) { - result = result.with(FetchGroup.MIME_DESCRIPTOR_MASK); + result = result.with(FetchGroup.Profile.MIME_DESCRIPTOR); } Collection<BodyFetchElement> bodyElements = fetch.getBodyElements(); @@ -47,21 +48,21 @@ class FetchDataConverter { switch (sectionType) { case BodyFetchElement.CONTENT: if (isBase) { - result = addContent(result, path, isBase, FetchGroup.FULL_CONTENT_MASK); + result = addContent(result, path, isBase, FetchGroup.Profile.FULL_CONTENT); } else { - result = addContent(result, path, isBase, FetchGroup.MIME_CONTENT_MASK); + result = addContent(result, path, isBase, FetchGroup.Profile.MIME_CONTENT); } break; case BodyFetchElement.HEADER: case BodyFetchElement.HEADER_NOT_FIELDS: case BodyFetchElement.HEADER_FIELDS: - result = addContent(result, path, isBase, FetchGroup.HEADERS_MASK); + result = addContent(result, path, isBase, FetchGroup.Profile.HEADERS); break; case BodyFetchElement.MIME: - result = addContent(result, path, isBase, FetchGroup.MIME_HEADERS_MASK); + result = addContent(result, path, isBase, FetchGroup.Profile.MIME_HEADERS); break; case BodyFetchElement.TEXT: - result = addContent(result, path, isBase, FetchGroup.BODY_CONTENT_MASK); + result = addContent(result, path, isBase, FetchGroup.Profile.BODY_CONTENT); break; default: break; @@ -72,12 +73,12 @@ class FetchDataConverter { return result; } - private static FetchGroup addContent(FetchGroup result, int[] path, boolean isBase, int content) { + private static FetchGroup addContent(FetchGroup result, int[] path, boolean isBase, FetchGroup.Profile profile) { if (isBase) { - return result.with(content); + return result.with(profile); } else { MimePath mimePath = new MimePath(path); - return result.addPartContent(mimePath, content); + return result.addPartContent(mimePath, EnumSet.of(profile)); } } } diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/fetch/FetchDataConverterTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/fetch/FetchDataConverterTest.java index 192cc26..f5b1cfa 100644 --- a/protocols/imap/src/test/java/org/apache/james/imap/processor/fetch/FetchDataConverterTest.java +++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/fetch/FetchDataConverterTest.java @@ -23,15 +23,16 @@ import static org.apache.james.imap.api.message.BodyFetchElement.CONTENT; import static org.apache.james.imap.api.message.BodyFetchElement.HEADER; import static org.apache.james.imap.api.message.BodyFetchElement.MIME; import static org.apache.james.imap.api.message.BodyFetchElement.TEXT; -import static org.apache.james.mailbox.model.FetchGroup.MIME_DESCRIPTOR_MASK; import static org.assertj.core.api.Assertions.assertThat; +import java.util.EnumSet; import java.util.stream.Stream; import org.apache.james.imap.api.ImapConstants; import org.apache.james.imap.api.message.BodyFetchElement; import org.apache.james.imap.api.message.FetchData; import org.apache.james.mailbox.model.FetchGroup; +import org.apache.james.mailbox.model.FetchGroup.Profile; import org.apache.james.mailbox.model.MimePath; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -44,8 +45,8 @@ class FetchDataConverterTest { static Stream<Arguments> getFetchGroupShouldReturnCorrectValue() { return Stream.of( Arguments.arguments(new FetchData(), FetchGroup.MINIMAL), - Arguments.arguments(new FetchData().setBody(true), FetchGroup.MINIMAL.with(MIME_DESCRIPTOR_MASK)), - Arguments.arguments(new FetchData().setBodyStructure(true), FetchGroup.MINIMAL.with(MIME_DESCRIPTOR_MASK)), + Arguments.arguments(new FetchData().setBody(true), FetchGroup.MINIMAL.with(Profile.MIME_DESCRIPTOR)), + Arguments.arguments(new FetchData().setBodyStructure(true), FetchGroup.MINIMAL.with(Profile.MIME_DESCRIPTOR)), Arguments.arguments(new FetchData().setChangedSince(0L), FetchGroup.MINIMAL), Arguments.arguments(new FetchData().setEnvelope(true), FetchGroup.HEADERS), Arguments.arguments(new FetchData().setFlags(true), FetchGroup.MINIMAL), @@ -57,17 +58,17 @@ class FetchDataConverterTest { Arguments.arguments(new FetchData().add(BodyFetchElement.createRFC822Header(), PEEK), FetchGroup.HEADERS), Arguments.arguments(new FetchData().add(BodyFetchElement.createRFC822Text(), PEEK), FetchGroup.BODY_CONTENT), Arguments.arguments(new FetchData().add(new BodyFetchElement(ImapConstants.FETCH_RFC822_HEADER, HEADER, PATH, null, null, null), PEEK), - FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), FetchGroup.HEADERS_MASK)), + FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), EnumSet.of(Profile.HEADERS))), Arguments.arguments(new FetchData().add(new BodyFetchElement(ImapConstants.FETCH_RFC822_TEXT, HEADER, PATH, null, null, null), PEEK), - FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), FetchGroup.BODY_CONTENT_MASK)), + FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), EnumSet.of(Profile.BODY_CONTENT))), Arguments.arguments(new FetchData().add(new BodyFetchElement(ImapConstants.FETCH_RFC822_TEXT, CONTENT, PATH, null, null, null), PEEK), - FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), FetchGroup.BODY_CONTENT_MASK)), + FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), EnumSet.of(Profile.BODY_CONTENT))), Arguments.arguments(new FetchData().add(new BodyFetchElement(ImapConstants.FETCH_RFC822_TEXT, CONTENT, PATH, null, null, null), PEEK), - FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), FetchGroup.MIME_CONTENT_MASK)), + FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), EnumSet.of(Profile.MIME_CONTENT))), Arguments.arguments(new FetchData().add(new BodyFetchElement(ImapConstants.FETCH_RFC822_TEXT, MIME, PATH, null, null, null), PEEK), - FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), FetchGroup.MIME_HEADERS_MASK)), + FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), EnumSet.of(Profile.MIME_HEADERS))), Arguments.arguments(new FetchData().add(new BodyFetchElement(ImapConstants.FETCH_RFC822_TEXT, TEXT, PATH, null, null, null), PEEK), - FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), FetchGroup.BODY_CONTENT_MASK))); + FetchGroup.MINIMAL.addPartContent(new MimePath(PATH), EnumSet.of(Profile.BODY_CONTENT)))); } @ParameterizedTest --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org