📄 pop3.java
字号:
package mujmail.protocols;/*MujMail - Simple mail client for J2MECopyright (C) 2006 Nguyen Son Tung <n.sontung@gmail.com>This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */import java.util.Hashtable;import java.util.Stack;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.tasks.BackgroundTask;import mujmail.threading.Algorithm;import mujmail.util.Functions;/** * Implements InProtocol using POP3. * All operations can be invoked at once and we have shared resource * BasicConnection. So we must synchronize the method run. we use lock() instead * of making run() synchronized in order to allow forced disconnecting from * servers even some job are still running. */public class POP3 extends InProtocol { /** The name of this source file */ private static final String SOURCE_FILE = "POP3"; /** Flag signals if we want to print debug prints */ private static final boolean DEBUG = false; Hashtable deleted; Timer connectionKeeper; private void resolveMyExceptionWhileRunning(MyException ex) { 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 POP3(MailAccount account) { super(account); END_OF_MAIL = ".\r\n"; deleted = new Hashtable(); } //add a mail to a queue of mails that are going to be deleted from the server public void addDeleted(MessageHeader header) { deleted.put(header.getMessageID(), header); } public boolean isConnected() { try { if (connection.isConnected()) { connection.clearInput(); connection.sendCRLF("NOOP"); if (connection.getLine().startsWith("+OK")) { return true; } } } catch (Exception ex) { connection.close(); //TODO: Close connection } return false; } public int countNew() throws MyException { connection.sendCRLF("STAT"); String reply = connection.getLine(); if (!reply.startsWith("+OK")) { return 0; } return Integer.parseInt(reply.substring(4, reply.lastIndexOf(' ')).trim()); } private int getSize(int msgNum) throws MyException { connection.sendCRLF("LIST " + msgNum); String reply = connection.getLine(); if (!reply.startsWith("+OK")) { return 0; } return Integer.parseInt(reply.substring(reply.lastIndexOf(' ') + 1).trim()); } private String getMsgID(int index) throws MyException { connection.sendCRLF("UIDL " + index); String reply = connection.getLine(); if (reply.startsWith("+OK")) { return reply.substring(reply.lastIndexOf(' ') + 1).trim(); } else { return ""; } } /** * Gets the index of given mail on the server. * @param header the header of the mail * @return the index of the mail on the server * @throws MyException */ private String getMsgNum(MessageHeader header) throws MyException { String reply, ID, num; String index = (String) mailsOnServer.get(header.getMessageID()); if (index != null) { connection.sendCRLF("UIDL " + index); //lets try if the mail is from actual session reply = connection.getLine(); if (reply.startsWith("+OK")) { ID = reply.substring(reply.lastIndexOf(' ') + 1).trim(); if (ID.equals(header.getMessageID())) { return index; } } } //we have to test and update info about all mails :( //note: if a message is marked as deleted or as read by pop3 , it will never be listed by UIDL again and we can get it anymore? connection.sendCRLF("UIDL"); connection.getLine(); boolean found = false; while (!(reply = connection.getLine()).startsWith(".")) { ID = reply.substring(reply.indexOf(' ') + 1).trim(); num = reply.substring(0, reply.indexOf(' ')); if (mailsOnServer.containsKey(ID)) //let's remove old information { mailsOnServer.remove(ID); } mailsOnServer.put(ID, num); if (ID.equals(header.getMessageID())) { found = true; } } return found ? (String) mailsOnServer.get(header.getMessageID()) : "0"; } // Note task can be null for polling task, getUrl protected boolean open(BackgroundTask task) throws MyException { if (isConnected()) { return true; } _close(task); //we'd better close inactive connections try { if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CONNECTING) + " " + account.getEmail()); } connection.open(account.getServer() + ":" + account.getPort(),account.isSSL(), account.getSSLType()); if (!connection.getLine().startsWith("+OK")) { if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CONNECTING) + account.getEmail() + Lang.get(Lang.FAILED)); } return false; } connection.sendCRLF("USER " + account.getUserName()); if (!connection.getLine().startsWith("+OK")) { connection.unGetLine(); getReportBox().report("100: " + Lang.get(Lang.PL_NOTAUTHORIZED) + account.getUserName() + "/ " + connection.getLine(), SOURCE_FILE); return false; } connection.sendCRLF("PASS " + account.getPassword()); if (!connection.getLine().startsWith("+OK")) { getReportBox().report("100: " + Lang.get(Lang.PL_NOTAUTHORIZED) + account.getUserName(), SOURCE_FILE); return false; } if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CONNECTING) + account.getEmail() + Lang.get(Lang.SUCCESS)); } connectionKeeper = new Timer(); connectionKeeper.scheduleAtFixedRate(new Keeper(), Settings.noopPeriod, Settings.noopPeriod); return true; } catch (MyException e) { if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CONNECTING) + account.getEmail() + Lang.get(Lang.FAILED)); } throw e; } catch (Exception e) { if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CONNECTING) + account.getEmail() + Lang.get(Lang.FAILED)); } throw new MyException(MyException.COM_UNKNOWN, "100: " + e); } } // Note task can be null (background Keeper task) protected synchronized void _close(BackgroundTask task, boolean waitForReply) { if (!connection.isConnected()) { return; } if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail()); } if (connectionKeeper != null) { connectionKeeper.cancel(); } connectionKeeper = null; forcedDisc = false; try { connection.sendCRLF("QUIT"); } catch (MyException e) { if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail() + ": " + e.getDetails()); } } try { connection.close(); } catch (Exception e) { if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail() + ": " + e); } } if (task != null) { task.setTitle(Lang.get(Lang.ALRT_PL_CLOSING) + account.getEmail() + Lang.get(Lang.SUCCESS)); } } protected void findFirstNewMailWhilePolling() throws MyException { int count = countNew(); for (; count > 0; --count) { String ID = getMsgID(count); if (ID.length() > 0) { if (handleMailDiscoveredByPolling(ID)) break; } } } protected void getNewMails() { try { // TODO: data overheads when we want to receive only X new mails? // check out countNew(), while (actual < max) {...} and // while (actual > 0) {..} // the same is in IMAP4 long startTime = System.currentTimeMillis(); if (!open(inProtocolTask)) { //in case of server->inbox sync we need to notify about this error //otherwise the synchronization will think that no mails are on the server //throw new MyException(MyException.PROTOCOL_CANNOT_CONNECT); return; } if (getTargetBox().isSyncRunning()) { mailsOnServer.clear(); }//we need to recreate a new mailsOnServer lists _close(null); open(null); int newMailsCount = countNew(); int max = newMailsCount; if (!targetBox.isSyncRunning() && Settings.maxMailsRetrieve > 0 && newMailsCount >= Settings.maxMailsRetrieve) //limit exceeded
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -