Loading k9mail-library/src/main/java/com/fsck/k9/mail/Flag.java +15 −26 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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. Loading @@ -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, } k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/response/CapabilityResponse.java→k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/CapabilityResponse.java +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; } Loading @@ -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; } Loading @@ -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() { Loading k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java +6 −12 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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>(); Loading Loading @@ -114,7 +110,6 @@ public class ImapConnection { open = true; boolean authSuccess = false; commandFactory = ImapCommandFactory.create(this, getLogId()); nextCommandTag = 1; adjustDNSCacheTTL(); Loading Loading @@ -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()) { Loading @@ -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()); Loading @@ -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"); } Loading Loading @@ -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); } Loading @@ -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(); Loading k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java +35 −63 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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)); } Loading Loading @@ -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 { Loading Loading @@ -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; } Loading Loading @@ -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(); } Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; } Loading @@ -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); Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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) { /* Loading Loading @@ -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(); Loading @@ -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) { Loading @@ -1244,7 +1226,7 @@ public class ImapFolder extends Folder<ImapMessage> { } } return combine(flagNames.toArray(new String[flagNames.size()]), ' '); return ImapUtility.join(" ", flagNames); } @Override Loading @@ -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(); } Loading Loading @@ -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(); } Loading Loading @@ -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) Loading @@ -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); } } k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapUtility.java +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.fsck.k9.mail.store.imap; import java.util.ArrayList; import java.util.Collection; import java.util.List; Loading Loading @@ -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 Loading
k9mail-library/src/main/java/com/fsck/k9/mail/Flag.java +15 −26 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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. Loading @@ -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, }
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/response/CapabilityResponse.java→k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/CapabilityResponse.java +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; } Loading @@ -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; } Loading @@ -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() { Loading
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java +6 −12 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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>(); Loading Loading @@ -114,7 +110,6 @@ public class ImapConnection { open = true; boolean authSuccess = false; commandFactory = ImapCommandFactory.create(this, getLogId()); nextCommandTag = 1; adjustDNSCacheTTL(); Loading Loading @@ -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()) { Loading @@ -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()); Loading @@ -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"); } Loading Loading @@ -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); } Loading @@ -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(); Loading
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java +35 −63 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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)); } Loading Loading @@ -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 { Loading Loading @@ -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; } Loading Loading @@ -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(); } Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; } Loading @@ -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); Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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) { /* Loading Loading @@ -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(); Loading @@ -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) { Loading @@ -1244,7 +1226,7 @@ public class ImapFolder extends Folder<ImapMessage> { } } return combine(flagNames.toArray(new String[flagNames.size()]), ' '); return ImapUtility.join(" ", flagNames); } @Override Loading @@ -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(); } Loading Loading @@ -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(); } Loading Loading @@ -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) Loading @@ -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); } }
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapUtility.java +4 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.fsck.k9.mail.store.imap; import java.util.ArrayList; import java.util.Collection; import java.util.List; Loading Loading @@ -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