Пример #1
0
  /**
   * Appends the given messages to the selected folder. This implementation also determines the new
   * UID of the given message on the IMAP server and sets the Message's UID to the new server UID.
   */
  @Override
  public void appendMessages(Message[] messages) throws MessagingException {
    checkOpen();
    try {
      for (Message message : messages) {
        // Create output count
        CountingOutputStream out = new CountingOutputStream();
        EOLConvertingOutputStream eolOut = new EOLConvertingOutputStream(out);
        message.writeTo(eolOut);
        eolOut.flush();
        // Create flag list (most often this will be "\SEEN")
        String flagList = "";
        Flag[] flags = message.getFlags();
        if (flags.length > 0) {
          StringBuilder sb = new StringBuilder();
          for (int i = 0, count = flags.length; i < count; i++) {
            Flag flag = flags[i];
            if (flag == Flag.SEEN) {
              sb.append(" " + ImapConstants.FLAG_SEEN);
            } else if (flag == Flag.FLAGGED) {
              sb.append(" " + ImapConstants.FLAG_FLAGGED);
            }
          }
          if (sb.length() > 0) {
            flagList = sb.substring(1);
          }
        }

        mConnection.sendCommand(
            String.format(
                ImapConstants.APPEND + " \"%s\" (%s) {%d}",
                ImapStore.encodeFolderName(mName, mStore.mPathPrefix),
                flagList,
                out.getCount()),
            false);
        ImapResponse response;
        do {
          response = mConnection.readResponse();
          if (response.isContinuationRequest()) {
            eolOut = new EOLConvertingOutputStream(mConnection.mTransport.getOutputStream());
            message.writeTo(eolOut);
            eolOut.write('\r');
            eolOut.write('\n');
            eolOut.flush();
          } else if (!response.isTagged()) {
            handleUntaggedResponse(response);
          }
        } while (!response.isTagged());

        // TODO Why not check the response?

        /*
         * Try to recover the UID of the message from an APPENDUID response.
         * e.g. 11 OK [APPENDUID 2 238268] APPEND completed
         */
        final ImapList appendList = response.getListOrEmpty(1);
        if ((appendList.size() >= 3) && appendList.is(0, ImapConstants.APPENDUID)) {
          String serverUid = appendList.getStringOrEmpty(2).getString();
          if (!TextUtils.isEmpty(serverUid)) {
            message.setUid(serverUid);
            continue;
          }
        }

        /*
         * Try to find the UID of the message we just appended using the
         * Message-ID header.  If there are more than one response, take the
         * last one, as it's most likely the newest (the one we just uploaded).
         */
        String messageId = message.getMessageId();
        if (messageId == null || messageId.length() == 0) {
          continue;
        }
        // Most servers don't care about parenthesis in the search query [and, some
        // fail to work if they are used]
        String[] uids = searchForUids(String.format("HEADER MESSAGE-ID %s", messageId));
        if (uids.length > 0) {
          message.setUid(uids[0]);
        }
        // However, there's at least one server [AOL] that fails to work unless there
        // are parenthesis, so, try this as a last resort
        uids = searchForUids(String.format("(HEADER MESSAGE-ID %s)", messageId));
        if (uids.length > 0) {
          message.setUid(uids[0]);
        }
      }
    } catch (IOException ioe) {
      throw ioExceptionHandler(mConnection, ioe);
    } finally {
      destroyResponses();
    }
  }