Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99a360de authored by Hari's avatar Hari
Browse files

Clean up and refactor

parent 3c5b7dc9
Loading
Loading
Loading
Loading
+15 −26
Original line number Diff line number Diff line
@@ -5,13 +5,13 @@ package com.fsck.k9.mail;
 * Flags that can be applied to Messages.
 */
public enum Flag {
    DELETED("DELETED"),
    SEEN("SEEN"),
    ANSWERED("ANSWERED"),
    FLAGGED("FLAGGED"),
    DRAFT("DRAFT"),
    RECENT("RECENT"),
    FORWARDED(null),
    DELETED,
    SEEN,
    ANSWERED,
    FLAGGED,
    DRAFT,
    RECENT,
    FORWARDED,

    /*
     * The following flags are for internal library use only.
@@ -19,35 +19,35 @@ public enum Flag {
    /**
     * Delete and remove from the LocalStore immediately.
     */
    X_DESTROYED(null),
    X_DESTROYED,

    /**
     * Sending of an unsent message failed. It will be retried. Used to show status.
     */
    X_SEND_FAILED(null),
    X_SEND_FAILED,

    /**
     * Sending of an unsent message is in progress.
     */
    X_SEND_IN_PROGRESS(null),
    X_SEND_IN_PROGRESS,

    /**
     * Indicates that a message is fully downloaded from the server and can be viewed normally.
     * This does not include attachments, which are never downloaded fully.
     */
    X_DOWNLOADED_FULL(null),
    X_DOWNLOADED_FULL,

    /**
     * Indicates that a message is partially downloaded from the server and can be viewed but
     * more content is available on the server.
     * This does not include attachments, which are never downloaded fully.
     */
    X_DOWNLOADED_PARTIAL(null),
    X_DOWNLOADED_PARTIAL,

    /**
     * Indicates that the copy of a message to the Sent folder has started.
     */
    X_REMOTE_COPY_STARTED(null),
    X_REMOTE_COPY_STARTED,

    /**
     * Messages with this flag have been migrated from database version 50 or earlier.
@@ -56,21 +56,10 @@ public enum Flag {
     * incomplete or broken.
     * TODO Messages with this flag should be redownloaded, if possible.
     */
    X_MIGRATED_FROM_V50(null),
    X_MIGRATED_FROM_V50,

    /**
     * This flag is used for drafts where the message should be sent as PGP/INLINE.
     */
    X_DRAFT_OPENPGP_INLINE(null);

    private String imapString;

    Flag(String imapString) {
        this.imapString = imapString;
    }

    public String getImapString() {
        return imapString;
    }

    X_DRAFT_OPENPGP_INLINE,
}
+11 −27
Original line number Diff line number Diff line
package com.fsck.k9.mail.store.imap.response;
package com.fsck.k9.mail.store.imap;


import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import com.fsck.k9.mail.store.imap.ImapList;
import com.fsck.k9.mail.store.imap.ImapResponse;
import com.fsck.k9.mail.store.imap.Responses;
import com.fsck.k9.mail.store.imap.command.ImapCommandFactory;

import static com.fsck.k9.mail.store.imap.ImapResponseParser.equalsIgnoreCase;


public class CapabilityResponse extends BaseResponse {

class CapabilityResponse {
    private final Set<String> capabilities;

    private CapabilityResponse(ImapCommandFactory commandFactory, List<ImapResponse> imapResponses, Set<String> capabilities) {
        super(commandFactory, imapResponses);
        this.capabilities = capabilities;

    private CapabilityResponse(Set<String> capabilities) {
        this.capabilities = Collections.unmodifiableSet(capabilities);
    }

    public static CapabilityResponse parse(ImapCommandFactory commandFactory, List<ImapResponse> responses) {
    public static CapabilityResponse parse(List<ImapResponse> responses) {
        for (ImapResponse response : responses) {
            CapabilityResponse result;
            if (!response.isEmpty() && equalsIgnoreCase(response.get(0), Responses.OK) && response.isList(1)) {
                ImapList capabilityList = response.getList(1);
                result = parse(commandFactory, capabilityList);
                result = parse(capabilityList);
            } else if (response.getTag() == null) {
                result = parse(commandFactory, response);
                result = parse(response);
            } else {
                result = null;
            }
@@ -43,7 +38,7 @@ public class CapabilityResponse extends BaseResponse {
        return null;
    }

    private static CapabilityResponse parse(ImapCommandFactory commandFactory, ImapList capabilityList) {
    static CapabilityResponse parse(ImapList capabilityList) {
        if (capabilityList.isEmpty() || !equalsIgnoreCase(capabilityList.get(0), Responses.CAPABILITY)) {
            return null;
        }
@@ -60,18 +55,7 @@ public class CapabilityResponse extends BaseResponse {
            capabilities.add(uppercaseCapability);
        }

        return new CapabilityResponse(commandFactory, null, capabilities);
    }

    @Override
    void parseResponse(List<ImapResponse> imapResponses) {
        //This is never called
    }

    @Override
    void combine(BaseResponse baseResponse) {
        super.combine(baseResponse);
        //This is never called
        return new CapabilityResponse(capabilities);
    }

    public Set<String> getCapabilities() {
+6 −12
Original line number Diff line number Diff line
@@ -41,9 +41,6 @@ import com.fsck.k9.mail.filter.PeekableInputStream;
import com.fsck.k9.mail.oauth.OAuth2TokenProvider;
import com.fsck.k9.mail.oauth.XOAuth2ChallengeParser;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
import com.fsck.k9.mail.store.imap.command.CapabilityCommand;
import com.fsck.k9.mail.store.imap.command.ImapCommandFactory;
import com.fsck.k9.mail.store.imap.response.CapabilityResponse;
import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZOutputStream;
import javax.net.ssl.SSLException;
@@ -73,7 +70,6 @@ public class ImapConnection {
    private Socket socket;
    private PeekableInputStream inputStream;
    private OutputStream outputStream;
    private ImapCommandFactory commandFactory;
    private ImapResponseParser responseParser;
    private int nextCommandTag;
    private Set<String> capabilities = new HashSet<String>();
@@ -114,7 +110,6 @@ public class ImapConnection {

        open = true;
        boolean authSuccess = false;
        commandFactory = ImapCommandFactory.create(this, getLogId());
        nextCommandTag = 1;

        adjustDNSCacheTTL();
@@ -256,7 +251,7 @@ public class ImapConnection {
    }

    private List<ImapResponse> extractCapabilities(List<ImapResponse> responses) {
        CapabilityResponse capabilityResponse = CapabilityResponse.parse(commandFactory, responses);
        CapabilityResponse capabilityResponse = CapabilityResponse.parse(responses);
        if (capabilityResponse != null) {
            Set<String> receivedCapabilities = capabilityResponse.getCapabilities();
            if (K9MailLib.isDebug()) {
@@ -269,7 +264,7 @@ public class ImapConnection {

    private List<ImapResponse> extractOrRequestCapabilities(List<ImapResponse> responses)
            throws IOException, MessagingException {
        CapabilityResponse capabilityResponse = CapabilityResponse.parse(commandFactory, responses);
        CapabilityResponse capabilityResponse = CapabilityResponse.parse(responses);
        if (capabilityResponse != null) {
            Set<String> receivedCapabilities = capabilityResponse.getCapabilities();
            Timber.d("Saving %s capabilities for %s", receivedCapabilities, getLogId());
@@ -293,8 +288,7 @@ public class ImapConnection {
    }

    private void requestCapabilities() throws IOException, MessagingException {
        CapabilityCommand command = commandFactory.createCapabilityCommand();
        List<ImapResponse> responses = extractCapabilities(command.executeInternal());
        List<ImapResponse> responses = extractCapabilities(executeSimpleCommand(Commands.CAPABILITY));
        if (responses.size() != 2) {
            throw new MessagingException("Invalid CAPABILITY response received");
        }
@@ -722,7 +716,7 @@ public class ImapConnection {
        return "conn" + hashCode();
    }

    List<ImapResponse> executeSimpleCommand(String command) throws IOException, MessagingException {
    public List<ImapResponse> executeSimpleCommand(String command) throws IOException, MessagingException {
        return executeSimpleCommand(command, false);
    }

@@ -744,12 +738,12 @@ public class ImapConnection {
        }
    }

    List<ImapResponse> readStatusResponse(String tag, String commandToLog, UntaggedHandler untaggedHandler)
    public List<ImapResponse> readStatusResponse(String tag, String commandToLog, UntaggedHandler untaggedHandler)
            throws IOException, NegativeImapResponseException {
        return responseParser.readStatusResponse(tag, commandToLog, getLogId(), untaggedHandler);
    }

    String sendSaslIrCommand(String command, String initialClientResponse, boolean sensitive)
    public String sendSaslIrCommand(String command, String initialClientResponse, boolean sensitive)
            throws IOException, MessagingException {
        try {
            open();
+35 −63
Original line number Diff line number Diff line
@@ -34,14 +34,13 @@ import com.fsck.k9.mail.internet.MimeHeader;
import com.fsck.k9.mail.internet.MimeMessageHelper;
import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.imap.command.ImapCommandFactory;
import com.fsck.k9.mail.store.imap.command.UidCopyCommand;
import com.fsck.k9.mail.store.imap.command.UidFetchCommand;
import com.fsck.k9.mail.store.imap.command.UidSearchCommand;
import com.fsck.k9.mail.store.imap.command.UidStoreCommand;
import com.fsck.k9.mail.store.imap.response.BaseResponse;
import com.fsck.k9.mail.store.imap.response.CopyUidResponse;
import com.fsck.k9.mail.store.imap.response.SearchResponse;
import com.fsck.k9.mail.store.imap.selectedstate.command.SelectedStateCommandFactory;
import com.fsck.k9.mail.store.imap.selectedstate.command.UidCopyCommand;
import com.fsck.k9.mail.store.imap.selectedstate.command.UidFetchCommand;
import com.fsck.k9.mail.store.imap.selectedstate.command.UidSearchCommand;
import com.fsck.k9.mail.store.imap.selectedstate.command.UidStoreCommand;
import com.fsck.k9.mail.store.imap.selectedstate.response.UidCopyResponse;
import com.fsck.k9.mail.store.imap.selectedstate.response.UidSearchResponse;
import timber.log.Timber;

import static com.fsck.k9.mail.store.imap.ImapUtility.getLastResponse;
@@ -62,7 +61,7 @@ public class ImapFolder extends Folder<ImapMessage> {
    protected volatile long uidNext = -1L;
    protected volatile ImapConnection connection;
    protected ImapStore store = null;
    private ImapCommandFactory commandFactory;
    private SelectedStateCommandFactory commandFactory;
    protected Map<Long, String> msgSeqUidMap = new ConcurrentHashMap<Long, String>();
    private final FolderNameCodec folderNameCodec;
    private final String name;
@@ -114,7 +113,7 @@ public class ImapFolder extends Folder<ImapMessage> {
        return prefixedName;
    }

    private List<ImapResponse> executeSimpleCommand(String command) throws MessagingException, IOException {
    public List<ImapResponse> executeSimpleCommand(String command) throws MessagingException, IOException {
        return handleUntaggedResponses(connection.executeSimpleCommand(command));
    }

@@ -142,7 +141,7 @@ public class ImapFolder extends Folder<ImapMessage> {

        synchronized (this) {
            connection = store.getConnection();
            commandFactory = ImapCommandFactory.create(connection, getLogId());
            commandFactory = SelectedStateCommandFactory.create(connection, this);
        }

        try {
@@ -370,12 +369,12 @@ public class ImapFolder extends Folder<ImapMessage> {
            imapFolder.create(FolderType.HOLDS_MESSAGES);
        }

        UidCopyCommand command = commandFactory.createUidCopyCommandBuilder(this)
        UidCopyCommand command = commandFactory.createUidCopyCommandBuilder()
                .idSet(uids)
                .destinationFolderName(escapedDestinationFolderName)
                .build();

        CopyUidResponse copyUidResponse = command.execute();
        UidCopyResponse copyUidResponse = command.execute();
        if (copyUidResponse == null) {
            return null;
        }
@@ -439,13 +438,13 @@ public class ImapFolder extends Folder<ImapMessage> {
    private int getRemoteMessageCount(Set<Flag> requiredFlags, Set<Flag> forbiddenFlags) throws MessagingException {
        checkOpen();

        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null)
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                .allIds(true)
                .requiredFlags(requiredFlags)
                .forbiddenFlags(forbiddenFlags)
                .build();

        SearchResponse searchResponse = searchCommand.execute();
        UidSearchResponse searchResponse = searchCommand.execute();
        return searchResponse.getNumbers().size();

    }
@@ -467,11 +466,11 @@ public class ImapFolder extends Folder<ImapMessage> {
    protected long getHighestUid() throws MessagingException {
        try {

            UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null)
            UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                    .onlyHighestId(true)
                    .build();

            SearchResponse searchResponse = searchCommand.execute();
            UidSearchResponse searchResponse = searchCommand.execute();

            return extractHighestUid(searchResponse);
        } catch (NegativeImapResponseException e) {
@@ -479,7 +478,7 @@ public class ImapFolder extends Folder<ImapMessage> {
        }
    }

    private long extractHighestUid(SearchResponse searchResponse) {
    private long extractHighestUid(UidSearchResponse searchResponse) {
        List<Long> uids = searchResponse.getNumbers();
        if (uids.isEmpty()) {
            return -1L;
@@ -519,11 +518,12 @@ public class ImapFolder extends Folder<ImapMessage> {
        }

        checkOpen();
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, listener)
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                .useUids(false)
                .addIdRange((long) start, (long) end)
                .since(earliestDate)
                .forbiddenFlags(includeDeleted ? null : Collections.singleton(Flag.DELETED))
                .listener(listener)
                .build();

        return getMessages(searchCommand.execute(), listener);
@@ -557,14 +557,14 @@ public class ImapFolder extends Folder<ImapMessage> {
    private boolean existsNonDeletedMessageInRange(int startIndex, int endIndex, Date earliestDate)
            throws MessagingException, IOException {

        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null)
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                .useUids(false)
                .addIdRange((long) startIndex, (long) endIndex)
                .since(earliestDate)
                .forbiddenFlags(Collections.singleton(Flag.DELETED))
                .build();

        SearchResponse response = searchCommand.execute();
        UidSearchResponse response = searchCommand.execute();
        return response.getNumbers().size() > 0;
    }

@@ -572,10 +572,11 @@ public class ImapFolder extends Folder<ImapMessage> {
            final MessageRetrievalListener<ImapMessage> listener) throws MessagingException {

        checkOpen();
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, listener)
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                .useUids(false)
                .idSet(mesgSeqs)
                .forbiddenFlags(includeDeleted ? null : Collections.singleton(Flag.DELETED))
                .listener(listener)
                .build();

        return getMessages(searchCommand.execute(), listener);
@@ -590,7 +591,7 @@ public class ImapFolder extends Folder<ImapMessage> {
            uidSet.add(Long.parseLong(uid));
        }

        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null)
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                .useUids(true)
                .idSet(uidSet)
                .build();
@@ -599,7 +600,7 @@ public class ImapFolder extends Folder<ImapMessage> {

    }

    private List<ImapMessage> getMessages(SearchResponse searchResponse, MessageRetrievalListener<ImapMessage> listener)
    private List<ImapMessage> getMessages(UidSearchResponse searchResponse, MessageRetrievalListener<ImapMessage> listener)
            throws MessagingException {

        checkOpen();
@@ -656,8 +657,8 @@ public class ImapFolder extends Folder<ImapMessage> {

            try {

                UidFetchCommand command = commandFactory.createUidFetchCommandBuilder(this,
                        store.getStoreConfig().getMaximumAutoDownloadMessageSize())
                UidFetchCommand command = commandFactory.createUidFetchCommandBuilder()
                        .maximumAutoDownloadMessageSize(store.getStoreConfig().getMaximumAutoDownloadMessageSize())
                        .idSet(uidWindow)
                        .messageParams(fetchProfile, messageMap)
                        .build();
@@ -734,8 +735,8 @@ public class ImapFolder extends Folder<ImapMessage> {
        checkOpen();

        try {
            UidFetchCommand command = commandFactory.createUidFetchCommandBuilder(this,
                    store.getStoreConfig().getMaximumAutoDownloadMessageSize())
            UidFetchCommand command = commandFactory.createUidFetchCommandBuilder()
                    .maximumAutoDownloadMessageSize(store.getStoreConfig().getMaximumAutoDownloadMessageSize())
                    .idSet(Collections.singleton(Long.parseLong(message.getUid())))
                    .partParams(part, bodyFactory)
                    .build();
@@ -921,25 +922,6 @@ public class ImapFolder extends Folder<ImapMessage> {
        }
    }

    public void handleUntaggedResponses(BaseResponse response) {
        int newMessageCount = response.getMessageCount();
        if (newMessageCount != -1) {
            messageCount = newMessageCount;
        }

        int expungedCount = response.getExpungedCount();
        if (messageCount > expungedCount) {
            messageCount -= expungedCount;
        } else {
            messageCount = 0;
        }

        long newUidNext = response.getUidNext();
        if (newUidNext != -1L) {
            uidNext = newUidNext;
        }
    }

    private void parseBodyStructure(ImapList bs, Part part, String id) throws MessagingException {
        if (bs.get(0) instanceof ImapList) {
            /*
@@ -1203,7 +1185,7 @@ public class ImapFolder extends Folder<ImapMessage> {
            Timber.d("Looking for UID for message with message-id %s for %s", messageId, getLogId());
        }

        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null)
        UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                .messageId(messageId)
                .build();

@@ -1227,7 +1209,7 @@ public class ImapFolder extends Folder<ImapMessage> {
        }
    }

    private String combineFlags(Iterable<Flag> flags) {
    public String combineFlags(Iterable<Flag> flags) {
        List<String> flagNames = new ArrayList<String>();
        for (Flag flag : flags) {
            if (flag == Flag.SEEN) {
@@ -1244,7 +1226,7 @@ public class ImapFolder extends Folder<ImapMessage> {
            }
        }

        return combine(flagNames.toArray(new String[flagNames.size()]), ' ');
        return ImapUtility.join(" ", flagNames);
    }

    @Override
@@ -1252,11 +1234,10 @@ public class ImapFolder extends Folder<ImapMessage> {
        open(OPEN_MODE_RW);
        checkOpen();

        UidStoreCommand command = commandFactory.createUidStoreCommandBuilder(this)
        UidStoreCommand command = commandFactory.createUidStoreCommandBuilder()
                .allIds(true)
                .value(value)
                .flagSet(flags)
                .canCreateKeywords(canCreateKeywords || store.getPermanentFlagsIndex().contains(Flag.FORWARDED))
                .build();
        command.execute();
    }
@@ -1294,11 +1275,10 @@ public class ImapFolder extends Folder<ImapMessage> {
            uids.add(Long.parseLong(message.getUid()));
        }

        UidStoreCommand command = commandFactory.createUidStoreCommandBuilder(this)
        UidStoreCommand command = commandFactory.createUidStoreCommandBuilder()
                .idSet(uids)
                .value(value)
                .flagSet(flags)
                .canCreateKeywords(canCreateKeywords || store.getPermanentFlagsIndex().contains(Flag.FORWARDED))
                .build();
        command.execute();
    }
@@ -1371,7 +1351,7 @@ public class ImapFolder extends Folder<ImapMessage> {

            inSearch = true;

            UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null)
            UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder()
                    .queryString(queryString)
                    .performFullTextSearch(store.getStoreConfig().isRemoteSearchFullText())
                    .requiredFlags(requiredFlags)
@@ -1384,12 +1364,4 @@ public class ImapFolder extends Folder<ImapMessage> {
            inSearch = false;
        }
    }

    private static String combine(Object[] parts, char separator) {
        if (parts == null) {
            return null;
        }

        return TextUtils.join(String.valueOf(separator), parts);
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

package com.fsck.k9.mail.store.imap;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -157,6 +158,9 @@ public class ImapUtility {
    }

    public static String join(String delimiter, Collection<? extends Object> tokens) {
        if (tokens == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token: tokens) {
Loading