use of com.zimbra.cs.pop3.Pop3Message in project zm-mailbox by Zimbra.
the class DbMailItem method loadPop3Folder.
public static List<Pop3Message> loadPop3Folder(Set<Folder> folders, Date popSince) throws ServiceException {
assert !folders.isEmpty() : folders;
Mailbox mbox = Iterables.get(folders, 0).getMailbox();
long popDate = popSince == null ? -1 : Math.max(popSince.getTime(), -1);
List<Pop3Message> result = new ArrayList<Pop3Message>();
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String dateConstraint = popDate < 0 ? "" : " AND date > ?";
stmt = conn.prepareStatement("SELECT mi.id, mi.size, mi.blob_digest FROM " + getMailItemTableName(mbox, " mi") + " WHERE " + IN_THIS_MAILBOX_AND + DbUtil.whereIn("folder_id", folders.size()) + " AND type = " + MailItem.Type.MESSAGE.toByte() + " AND " + Db.getInstance().bitAND("flags", String.valueOf(Flag.BITMASK_DELETED | Flag.BITMASK_POPPED)) + " = 0" + dateConstraint);
if (getTotalFolderSize(folders) > RESULTS_STREAMING_MIN_ROWS) {
//TODO: Because of POPPED flag, the folder size no longer represent the count.
Db.getInstance().enableStreaming(stmt);
}
int pos = 1;
pos = setMailboxId(stmt, mbox, pos);
for (Folder folder : folders) {
stmt.setInt(pos++, folder.getId());
}
if (popDate >= 0) {
stmt.setInt(pos++, (int) (popDate / 1000L));
}
rs = stmt.executeQuery();
while (rs.next()) {
result.add(new Pop3Message(rs.getInt(1), rs.getLong(2), rs.getString(3)));
}
return result;
} catch (SQLException e) {
throw ServiceException.FAILURE("loading POP3 folder data: " + folders, e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.pop3.Pop3Message in project zm-mailbox by Zimbra.
the class Mailbox method openPop3Folder.
public List<Pop3Message> openPop3Folder(OperationContext octxt, Set<Integer> folderIds, Date popSince) throws ServiceException {
boolean success = false;
try {
beginTransaction("openPop3Folder", octxt);
ImmutableSet.Builder<Folder> folders = ImmutableSet.builder();
for (int folderId : folderIds) {
folders.add(getFolderById(folderId));
}
List<Pop3Message> p3list = DbMailItem.loadPop3Folder(folders.build(), popSince);
success = true;
return p3list;
} finally {
endTransaction(success);
}
}
use of com.zimbra.cs.pop3.Pop3Message in project k-9 by k9mail.
the class Pop3Sync method downloadLargeMessages.
private void downloadLargeMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder, final BackendFolder backendFolder, List<Pop3Message> largeMessages, final AtomicInteger progress, final AtomicInteger newMessages, final int todo, FetchProfile fp, SyncListener listener) throws MessagingException {
final String folder = remoteFolder.getServerId();
Timber.d("SYNC: Fetching large messages for folder %s", folder);
int maxDownloadSize = syncConfig.getMaximumAutoDownloadMessageSize();
remoteFolder.fetch(largeMessages, fp, null, maxDownloadSize);
for (Pop3Message message : largeMessages) {
downloadSaneBody(syncConfig, remoteFolder, backendFolder, message);
String messageServerId = message.getUid();
Timber.v("About to notify listeners that we got a new large message %s:%s:%s", accountName, folder, messageServerId);
// Update the listener with what we've found
progress.incrementAndGet();
// TODO do we need to re-fetch this here?
Set<Flag> flags = backendFolder.getMessageFlags(messageServerId);
// not marked as read.
if (!flags.contains(Flag.SEEN)) {
newMessages.incrementAndGet();
}
listener.syncProgress(folder, progress.get(), todo);
boolean isOldMessage = isOldMessage(backendFolder, message);
listener.syncNewMessage(folder, messageServerId, isOldMessage);
}
Timber.d("SYNC: Done fetching large messages for folder %s", folder);
}
use of com.zimbra.cs.pop3.Pop3Message in project k-9 by k9mail.
the class Pop3Sync method downloadMessages.
private int downloadMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder, final BackendFolder backendFolder, List<Pop3Message> inputMessages, final SyncListener listener) throws MessagingException {
final Date earliestDate = syncConfig.getEarliestPollDate();
// now
Date downloadStarted = new Date();
if (earliestDate != null) {
Timber.d("Only syncing messages after %s", earliestDate);
}
final String folder = remoteFolder.getServerId();
List<Pop3Message> syncFlagMessages = new ArrayList<>();
List<Pop3Message> unsyncedMessages = new ArrayList<>();
final AtomicInteger newMessages = new AtomicInteger(0);
List<Pop3Message> messages = new ArrayList<>(inputMessages);
for (Pop3Message message : messages) {
evaluateMessageForDownload(message, folder, backendFolder, unsyncedMessages, syncFlagMessages, listener);
}
final AtomicInteger progress = new AtomicInteger(0);
final int todo = unsyncedMessages.size() + syncFlagMessages.size();
listener.syncProgress(folder, progress.get(), todo);
Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
messages.clear();
final List<Pop3Message> largeMessages = new ArrayList<>();
final List<Pop3Message> smallMessages = new ArrayList<>();
if (!unsyncedMessages.isEmpty()) {
int visibleLimit = backendFolder.getVisibleLimit();
int listSize = unsyncedMessages.size();
if ((visibleLimit > 0) && (listSize > visibleLimit)) {
unsyncedMessages = unsyncedMessages.subList(0, visibleLimit);
}
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
Timber.d("SYNC: About to fetch %d unsynced messages for folder %s", unsyncedMessages.size(), folder);
fetchUnsyncedMessages(syncConfig, remoteFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp, listener);
Timber.d("SYNC: Synced unsynced messages for folder %s", folder);
}
Timber.d("SYNC: Have %d large messages and %d small messages out of %d unsynced messages", largeMessages.size(), smallMessages.size(), unsyncedMessages.size());
unsyncedMessages.clear();
/*
* Grab the content of the small messages first. This is going to
* be very fast and at very worst will be a single up of a few bytes and a single
* download of 625k.
*/
FetchProfile fp = new FetchProfile();
// TODO: Only fetch small and large messages if we have some
fp.add(FetchProfile.Item.BODY);
// fp.add(FetchProfile.Item.FLAGS);
// fp.add(FetchProfile.Item.ENVELOPE);
downloadSmallMessages(remoteFolder, backendFolder, smallMessages, progress, newMessages, todo, fp, listener);
smallMessages.clear();
/*
* Now do the large messages that require more round trips.
*/
fp = new FetchProfile();
fp.add(FetchProfile.Item.STRUCTURE);
downloadLargeMessages(syncConfig, remoteFolder, backendFolder, largeMessages, progress, newMessages, todo, fp, listener);
largeMessages.clear();
Timber.d("SYNC: Synced remote messages for folder %s, %d new messages", folder, newMessages.get());
// If the oldest message seen on this sync is newer than the oldest message seen on the previous sync, then
// we want to move our high-water mark forward.
Date oldestMessageTime = backendFolder.getOldestMessageDate();
if (oldestMessageTime != null) {
if (oldestMessageTime.before(downloadStarted) && oldestMessageTime.after(getLatestOldMessageSeenTime(backendFolder))) {
setLatestOldMessageSeenTime(backendFolder, oldestMessageTime);
}
}
return newMessages.get();
}
use of com.zimbra.cs.pop3.Pop3Message in project k-9 by k9mail.
the class Pop3Sync method fetchUnsyncedMessages.
private void fetchUnsyncedMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder, List<Pop3Message> unsyncedMessages, final List<Pop3Message> smallMessages, final List<Pop3Message> largeMessages, final AtomicInteger progress, final int todo, FetchProfile fp, final SyncListener listener) throws MessagingException {
final String folder = remoteFolder.getServerId();
final Date earliestDate = syncConfig.getEarliestPollDate();
remoteFolder.fetch(unsyncedMessages, fp, new MessageRetrievalListener<Pop3Message>() {
@Override
public void messageFinished(Pop3Message message, int number, int ofTotal) {
try {
if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) {
if (message.isSet(Flag.DELETED)) {
Timber.v("Newly downloaded message %s:%s:%s was marked deleted on server, " + "skipping", accountName, folder, message.getUid());
} else {
Timber.d("Newly downloaded message %s is older than %s, skipping", message.getUid(), earliestDate);
}
progress.incrementAndGet();
// TODO: This might be the source of poll count errors in the UI. Is todo always the same as ofTotal
listener.syncProgress(folder, progress.get(), todo);
return;
}
if (syncConfig.getMaximumAutoDownloadMessageSize() > 0 && message.getSize() > syncConfig.getMaximumAutoDownloadMessageSize()) {
largeMessages.add(message);
} else {
smallMessages.add(message);
}
} catch (Exception e) {
Timber.e(e, "Error while storing downloaded message.");
}
}
@Override
public void messageStarted(String uid, int number, int ofTotal) {
}
@Override
public void messagesFinished(int total) {
// FIXME this method is almost never invoked by various Stores! Don't rely on it unless fixed!!
}
}, syncConfig.getMaximumAutoDownloadMessageSize());
}
Aggregations