Example #1
0
  private void fetchAndRetainMessages() throws Exception {
    String[] uids = connection.getMessageUids();
    Set<String> existingUids = PopMessage.getMatchingUids(dataSource, uids);
    int count = uids.length - existingUids.size();

    LOG.info("Found %d new message(s) on remote server", count);
    if (count == 0) {
      return; // No new messages
    }
    IOExceptionHandler.getInstance().resetSyncCounter(mbox);
    boolean checkForSelfPopping = true;
    for (int msgno = uids.length; msgno > 0; --msgno) {
      String uid = uids[msgno - 1];

      if (!existingUids.contains(uid)) {
        if (checkForSelfPopping) {
          //  Only check new messages else could match one we previously synced.
          if (poppingSelf(uid)) {
            throw ServiceException.INVALID_REQUEST(
                "User attempted to import messages from his own mailbox", null);
          }
          checkForSelfPopping = false; // Only need to check one message
        }
        LOG.debug("Fetching message with uid %s", uid);
        IOExceptionHandler.getInstance().trackSyncItem(mbox, msgno);
        // Don't allow filtering to a mountpoint when retaining the
        // message.  We don't have a local id, so we can't keep track
        // of it in the data_source_item table.
        try {
          fetchAndAddMessage(msgno, connection.getMessageSize(msgno), uid, false);
        } catch (Exception e) {
          if (IOExceptionHandler.getInstance().isRecoverable(mbox, msgno, "pop sync fail", e)) {
            // skip it; will be retried on every subsequent sync
            continue;
          }
          throw e;
        }
      }
    }
    IOExceptionHandler.getInstance().checkpointIOExceptionRate(mbox);
  }
Example #2
0
 private void fetchAndAddMessage(int msgno, int size, String uid, boolean allowFilterToMountpoint)
     throws ServiceException, IOException {
   ContentInputStream cis = null;
   MessageContent mc = null;
   checkIsEnabled();
   try {
     cis = connection.getMessage(msgno);
     mc = MessageContent.read(cis, size);
     ParsedMessage pm = mc.getParsedMessage(null, indexAttachments);
     if (pm == null) {
       LOG.warn("Empty message body for UID %d. Must be ignored.", uid);
       return;
     }
     Message msg = null;
     // bug 47796: Set received date to sent date if available otherwise use current time
     try {
       Date sentDate = pm.getMimeMessage().getSentDate();
       if (sentDate == null) {
         LOG.warn(
             "null sent date; probably due to parse error. Date header value: [%s]",
             pm.getMimeMessage().getHeader("Date", null));
       }
       pm.setReceivedDate(sentDate != null ? sentDate.getTime() : System.currentTimeMillis());
     } catch (MessagingException e) {
       LOG.warn(
           "unable to get sent date from parsed message due to exception, must use current time",
           e);
       pm.setReceivedDate(System.currentTimeMillis());
     }
     DeliveryContext dc = mc.getDeliveryContext();
     if (isOffline()) {
       msg = addMessage(null, pm, size, dataSource.getFolderId(), Flag.BITMASK_UNREAD, dc);
     } else {
       Integer localId =
           getFirstLocalId(
               RuleManager.applyRulesToIncomingMessage(
                   null,
                   mbox,
                   pm,
                   size,
                   dataSource.getEmailAddress(),
                   dc,
                   dataSource.getFolderId(),
                   true,
                   allowFilterToMountpoint));
       if (localId != null) {
         msg = mbox.getMessageById(null, localId);
       }
     }
     if (msg != null && uid != null) {
       PopMessage msgTracker = new PopMessage(dataSource, msg.getId(), uid);
       msgTracker.add();
     }
   } catch (CommandFailedException e) {
     LOG.warn("Error fetching message number %d: %s", msgno, e.getMessage());
   } finally {
     if (cis != null) {
       try {
         cis.close();
       } catch (ParseException pe) {
         LOG.error(
             "ParseException while closing ContentInputStream. Assuming cis is effectively closed",
             pe);
       }
     }
     if (mc != null) {
       mc.cleanup();
     }
   }
 }