📄 imap4.java
字号:
package mujmail.protocols;
/*
MujMail - Simple mail client for J2ME
Copyright (C) 2006 Nguyen Son Tung <n.sontung@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import mujmail.Lang;
import mujmail.MessageHeader;
import mujmail.MujMail;
import mujmail.MyException;
import mujmail.Settings;
import mujmail.account.MailAccount;
import mujmail.connections.ConnectionCompressed;
import mujmail.tasks.BackgroundTask;
import mujmail.tasks.StoppableBackgroundTask;
import mujmail.threading.Algorithm;
import mujmail.ui.AudioAlert;
import mujmail.util.Functions;
/**
* Implements InProtocol using IMAP4.
*
* The advantages of implementation using IMAP4 compared to POP3:
* - it can use the command UID_SEARCH_UNSEEN for access to identifiers of
* unread mails
* - easier deleting of mails (without disconnecting from the server)
* - getting of required bodypart
*
* IMAP supports more parallel connections to one account so identification of
* the connection must be added before each command
*
*/
public class IMAP4 extends InProtocol {
/** The name of this source file */
private static final String SOURCE_FILE = "IMAP4";
/** Flag signals if we want to print debug prints */
private static final boolean DEBUG = false;
int commandCounter = 0;
//name of a selected IMAP4 folder followed with it's UIDVALIDITY encapsulated within two slashes //
String sld_mailBox_uidval; //so looks like: INBOX/12313/
String flags;
int indexOfFlags = -1;
Vector deleted;
Timer connectionKeeper;
boolean pushing = false;
protected boolean isMujMailServer = false; /// Flag signaling that you are connected to mujMail server
static final byte GET_URL = 5; //re-retrieving mail bodies - redownload uncompleted mails
/**
* Resolves myException while running some task.
* @param ex
*/
private void resolveMyExceptionRun(MyException ex) {
ex.printStackTrace();
if (ex.getErrorCode() == MyException.COM_HALTED) {
connection.unQuit();
}
resolveExceptions(ex.getDetails() + "/ " + account.getEmail(), SOURCE_FILE);
}
private class Keeper extends TimerTask {
public void run() { //sends a command to check and keeps the connection alive to avoid long reconnecting
if (DEBUG) System.out.println(account.getEmail() + ": keeping connection alive...");
if (isBusy()) {
return;
}
lock();
if (!isConnected()) {
_close(null);
}
unlock();
}
}
public IMAP4(MailAccount account) {
super(account);
END_OF_MAIL = ")\r\n";
deleted = new Vector();
}
public void addDeleted(MessageHeader header) {
deleted.addElement(header);
}
/**
* Sends a command to the server.
* If resultOnly is <code>true</code> it flushes all response lines
* to the last response line, that begins with the tag and returns the rest
* of the line (without the tag).
*
* @return tag, when resultOnly is <code>true</code>, rest of the last
* response line otherwise
*/
protected String execute(String command, boolean resultOnly) throws MyException {
if (DEBUG) System.out.println("DEBUG IMAP4.execute(command='" + command + "', resultOnly=" + resultOnly + ")");
String tag = "A" + commandCounter++ + " ";
if (DEBUG) System.out.println("DEBUG IMAP4.execute() tag: " + tag);
if (DEBUG) System.out.println("DEBUG IMAP4.execute() sending CRLF");
connection.sendCRLF(tag + command);
if (DEBUG) System.out.println("DEBUG IMAP4.execute() CRLF sent");
if (resultOnly) {
if (DEBUG) System.out.println("DEBUG IMAP4.execute() result only, getting line");
String reply = connection.getLine();
if (DEBUG) System.out.println("DEBUG IMAP4.execute() line getted");
while ( !reply.startsWith(tag) ) {
if (DEBUG) System.out.println("DEBUG IMAP4.execute() reply: " + reply);
reply = connection.getLine();
}
if (DEBUG) System.out.println("DEBUG IMAP4.execute() reply: " + reply.substring(tag.length()));
return reply.substring(tag.length());
}
return tag;
}
/**
* Sends the command to server and returns the result that is
* mostly closed in brackets.
*/
protected String execute(String command, String arguments) throws MyException {
String tag = "A" + commandCounter++ + " ";
connection.sendCRLF(tag + command + (arguments == null ? "" : " " + arguments));
String result = "";
String temp = connection.getLine();
while (!temp.startsWith(tag)) { //multiline response
if (temp.indexOf(" " + command + " ") != -1) { //is it the response for the executed command?
int p = temp.indexOf('(');
int q = temp.indexOf(')', p + 1);
if (p != -1 && q > p) { //a response in the form of "* command (result)"
result = temp.substring(p + 1, q);
} else //a response in the form of "* command result"
{
result += temp.substring(2 + command.length() + 1);
} //2 - "* ", 1 - the space after the command
}
temp = connection.getLine();
}
temp = temp.substring(tag.length());
if (temp.startsWith("BAD ") || temp.startsWith("NO ")) {
throw new MyException(MyException.PROTOCOL_COMMAND_NOT_EXECUTED);
}
return result;
}
public boolean isConnected() {
try {
if (DEBUG) System.out.println("DEBUG IMAP4.isConnected() calling connection.isConnected");
if (connection.isConnected()) {
if (DEBUG) System.out.println("DEBUG IMAP4.isConnected() is connected, clearing input");
connection.clearInput();
if (DEBUG) System.out.println("DEBUG IMAP4.isConnected() executing noop");
if (execute("NOOP", true).startsWith("OK")) {
if (DEBUG) System.out.println("DEBUG IMAP4.isConnected() OK");
return true;
}
}
} catch (Exception ex) {
connection.close();
ex.printStackTrace();
}
if (DEBUG) System.out.println("DEBUG IMAP4.isConnected() is not");
return false;
}
public int countNew() throws MyException {
return searchMailsMatching("UNSEEN").size();
}
/**
* Returns Vector having UID of mails matching the concrete criteria.
*/
private Vector searchMailsMatching(String criteria) throws MyException {
Vector mails = new Vector();
String tag;
execute("UID SEARCH " + criteria, false);
String line = connection.getLine();
line = line.substring(line.indexOf("SEARCH") + 7).trim() + " ";
int i = 0, j = 0, mailsCount = 0;
try {
while (line.length() - 1 > i) {
// Break only in case Synchronization
// is not running
if (!targetBox.isSyncRunning() &&
Settings.maxMailsRetrieve > 0 && mailsCount >= Settings.maxMailsRetrieve) //limit exceeded
{
break;
}
j = line.indexOf(" ", i);
tag = line.substring(i, j);
// In case of synchronization we
// want all mails
if (targetBox.isSyncRunning()) {
mails.addElement(tag);
}
else if (!targetBox.wasOnceDownloaded(account.getEmail(), sld_mailBox_uidval + tag)) {
// If the mail with given message ID was
// already downloaded, remove it from
// the list of new mails
mails.addElement(tag);
mailsCount++;
}
i = j + 1;
}
} catch (Exception ex) {
// process chybicky ... proc tu odchytavat
// protoze line.substring() vyhodi Exception
// na konci: tohle by asi melo byt silent
// exception
// TODO (Betlista): tohle je hodně debilní :-/
ex.printStackTrace();
}
return mails;
}
private String parseUID(String s) {
return s.substring(s.lastIndexOf(MessageHeader.MSG_ID_SEPARATOR) + 1);
}
// Note task can be null (polling)
protected boolean open(BackgroundTask task) throws MyException {
if (DEBUG) System.out.println("DEBUG IMAP4.open() calling isConnected");
if (isConnected()) {
if (DEBUG) System.out.println("DEBUG IMAP4.open() is connected");
return true;
}
if (DEBUG) System.out.println("DEBUG IMAP4.open() is not connected");
_close(task); //we'd better close inactive connections
try {
commandCounter = 0;//reset the counter for each connection
String reply;
if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CONNECTING) + " " + account.getEmail()); }
connection.open(account.getServer() + ":" + account.getPort(),account.isSSL(), account.getSSLType());
reply = connection.getLine(); // Welcome message from server
isMujMailServer = reply.indexOf("mujMail") > 0;
if (reply.length() == 0) {
if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CONNECTING) + account.getEmail() + Lang.get(Lang.FAILED)); }
return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -