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

Commit 3c5b7dc9 authored by Hari's avatar Hari
Browse files

Added UidCopyCommand

parent f78920e9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -17,4 +17,5 @@ public class Commands {
    public static final String UID_SEARCH = "UID SEARCH";
    public static final String UID_STORE = "UID STORE";
    public static final String UID_FETCH = "UID FETCH";
    public static final String UID_COPY = "UID COPY";
}
+23 −27
Original line number Diff line number Diff line
@@ -35,10 +35,12 @@ 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 timber.log.Timber;

@@ -349,12 +351,11 @@ public class ImapFolder extends Folder<ImapMessage> {
        ImapFolder imapFolder = (ImapFolder) folder;
        checkOpen(); //only need READ access

        String[] uids = new String[messages.size()];
        List<Long> uids = new ArrayList<>(messages.size());
        for (int i = 0, count = messages.size(); i < count; i++) {
            uids[i] = messages.get(i).getUid();
            uids.add(Long.parseLong(messages.get(i).getUid()));
        }

        try {
        String encodedDestinationFolderName = folderNameCodec.encode(imapFolder.getPrefixedName());
        String escapedDestinationFolderName = ImapUtility.encodeString(encodedDestinationFolderName);

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

            //TODO: Split this into multiple commands if the command exceeds a certain length.
            List<ImapResponse> responses = executeSimpleCommand(String.format("UID COPY %s %s",
                    combine(uids, ','), escapedDestinationFolderName));

            // Get the tagged response for the UID COPY command
            ImapResponse response = getLastResponse(responses);
        UidCopyCommand command = commandFactory.createUidCopyCommandBuilder(this)
                .idSet(uids)
                .destinationFolderName(escapedDestinationFolderName)
                .build();

            CopyUidResponse copyUidResponse = CopyUidResponse.parse(response);
        CopyUidResponse copyUidResponse = command.execute();
        if (copyUidResponse == null) {
            return null;
        }

        return copyUidResponse.getUidMapping();
        } catch (IOException ioe) {
            throw ioExceptionHandler(connection, ioe);
        }
    }

    @Override
+4 −0
Original line number Diff line number Diff line
@@ -40,6 +40,10 @@ public class ImapCommandFactory {
        return new UidFetchCommand.Builder(this, folder, maximumAutoDownloadMessageSize);
    }

    public UidCopyCommand.Builder createUidCopyCommandBuilder(ImapFolder folder) {
        return new UidCopyCommand.Builder(this, folder);
    }

    ImapConnection getConnection() {
        return connection;
    }
+81 −0
Original line number Diff line number Diff line
package com.fsck.k9.mail.store.imap.command;


import java.io.IOException;
import java.util.List;

import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.imap.Commands;
import com.fsck.k9.mail.store.imap.ImapFolder;
import com.fsck.k9.mail.store.imap.ImapResponse;
import com.fsck.k9.mail.store.imap.response.CopyUidResponse;


public class UidCopyCommand extends SelectByIdCommand {

    private String destinationFolderName;

    private UidCopyCommand(ImapCommandFactory commandFactory) {
        super(commandFactory);
    }

    @Override
    public String createCommandString() {
        StringBuilder builder = new StringBuilder(Commands.UID_COPY).append(" ");
        super.addIds(builder);
        addDestinationFolderName(builder);
        return builder.toString().trim();
    }

    @Override
    public CopyUidResponse execute() throws MessagingException {

        try {
            List<List<ImapResponse>> responses = executeInternal(false);
            CopyUidResponse response = CopyUidResponse.parse(commandFactory, responses);
            folder.handleUntaggedResponses(response);
            return response;
        } catch (IOException ioe) {
            throw folder.ioExceptionHandler(commandFactory.getConnection(), ioe);
        }

    }

    private void addDestinationFolderName(StringBuilder builder) {
        builder.append(destinationFolderName);
    }

    @Override
    Builder newBuilder() {
        return new Builder(commandFactory, folder)
                .useUids(useUids)
                .idSet(idSet)
                .idRanges(idRanges)
                .destinationFolderName(destinationFolderName);
    }

    public static class Builder extends SelectByIdCommand.Builder<UidCopyCommand, Builder> {

        public Builder(ImapCommandFactory commandFactory, ImapFolder folder) {
            super(commandFactory, folder);
        }

        public Builder destinationFolderName(String destinationFolderName) {
            command.destinationFolderName = destinationFolderName;
            return builder;
        }

        @Override
        UidCopyCommand createCommand() {
            return new UidCopyCommand(null);
        }

        @Override
        Builder createBuilder() {
            return this;
        }

    }
}

+87 −0
Original line number Diff line number Diff line
package com.fsck.k9.mail.store.imap;
package com.fsck.k9.mail.store.imap.response;


import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fsck.k9.mail.store.imap.ImapList;
import com.fsck.k9.mail.store.imap.ImapResponse;
import com.fsck.k9.mail.store.imap.ImapUtility;
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;
import static com.fsck.k9.mail.store.imap.ImapUtility.getImapSequenceValues;


class CopyUidResponse {
    private final Map<String, String> uidMapping;
public class CopyUidResponse extends BaseResponse {

    private Map<String, String> uidMapping;

    private CopyUidResponse(ImapCommandFactory commandFactory, List<ImapResponse> imapResponse) {
        super(commandFactory, imapResponse);
    }

    public static CopyUidResponse parse(ImapCommandFactory commandFactory, List<List<ImapResponse>> imapResponses) {

        CopyUidResponse combinedResponse = null;
        for (List<ImapResponse> imapResponse : imapResponses) {
            CopyUidResponse copyUidResponse = new CopyUidResponse(commandFactory, imapResponse);
            if (combinedResponse == null) {
                combinedResponse = copyUidResponse;
            } else {
                combinedResponse.combine(copyUidResponse);
            }
        }

    private CopyUidResponse(Map<String, String> uidMapping) {
        this.uidMapping = Collections.unmodifiableMap(uidMapping);
        return combinedResponse;
    }

    public static CopyUidResponse parse(ImapResponse response) {
    @Override
    void parseResponse(List<ImapResponse> imapResponses) {

        ImapResponse response = ImapUtility.getLastResponse(imapResponses);

        if (!response.isTagged() || response.size() < 2 || !equalsIgnoreCase(response.get(0), Responses.OK) ||
                !response.isList(1)) {
            return null;
            return;
        }

        ImapList responseTextList = response.getList(1);
        if (responseTextList.size() < 4 || !equalsIgnoreCase(responseTextList.get(0), Responses.COPYUID) ||
                !responseTextList.isString(1) || !responseTextList.isString(2) || !responseTextList.isString(3)) {
            return null;
            return;
        }

        List<String> sourceUids = getImapSequenceValues(responseTextList.getString(2));
@@ -35,19 +59,28 @@ class CopyUidResponse {

        int size = sourceUids.size();
        if (size == 0 || size != destinationUids.size()) {
            return null;
            return;
        }

        Map<String, String> uidMapping = new HashMap<>(size);
        uidMapping = new HashMap<>(size);
        for (int i = 0; i < size; i++) {
            String sourceUid = sourceUids.get(i);
            String destinationUid = destinationUids.get(i);
            uidMapping.put(sourceUid, destinationUid);
        }
    }

        return new CopyUidResponse(uidMapping);
    @Override
    void combine(BaseResponse baseResponse) {
        if (baseResponse == null) {
            return;
        }
        super.combine(baseResponse);
        CopyUidResponse copyUidResponse = (CopyUidResponse) baseResponse;
        this.uidMapping.putAll(copyUidResponse.getUidMapping());
    }


    public Map<String, String> getUidMapping() {
        return uidMapping;
    }
Loading