📄 inprotocol.java
字号:
package mujmail.protocols;/*MujMail - Simple mail client for J2MECopyright (C) 2006 Nguyen Son Tung <n.sontung@gmail.com>Copyright (C) 2008 David Hauzar <david.hauzar.mujmail@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.Vector;import mujmail.BodyPart;import mujmail.InBox;import mujmail.Lang;import mujmail.MessageHeader;import mujmail.MujMail;import mujmail.MyException;import mujmail.Settings;import mujmail.TheBox;import mujmail.account.MailAccount;import mujmail.connections.ConnectionCompressed;import mujmail.connections.ConnectionInterface;import mujmail.tasks.BackgroundTask;import mujmail.tasks.Progress;import mujmail.tasks.StoppableBackgroundTask;import mujmail.tasks.StoppableProgress;import mujmail.ui.AudioAlert;import mujmail.util.Decode;import mujmail.util.Functions;/** * The interface for manipulating and downloading mails. * For communication with servers uses the object of class BasicConnection */public abstract class InProtocol { /** The name of this source file */ private static final String SOURCE_FILE = "InProtocol"; /** Flag signals if we want to print debug prints */ private static final boolean DEBUG = false; private static final Object notifier = new Object(); /// Object on which wait fo beeing notify protected InProtocolTask inProtocolTask; /** The body part that is actually parsed. */ private BodyPart actuallyParsedBodyPart; // TODO (Betlista): describe these constants, why have REDOWNLOAD_BODY (3) and GET_URL (5) same description? //thread run modes public static final byte GET_NEW_MAILS = 1; public static final byte RETRIEVE_BODY = 2; //retrieving mail bodies public static final byte REDOWNLOAD_BODY = 3; //reretreving mail bodies - redownload incompleted mails public static final byte REMOVE_MAILS = 4; public static final byte GET_URL = 5; //reretreving mail bodies - redownload incompleted mails public static final byte SAVE_MAIL_SENT = 6; public static final byte POLL = 8; public static final byte SET_FLAGS = 9; public static final byte REMOVE_FLAGS = 10; public static final byte CONVERT_BODY = 11; public static final byte CLOSE = 16; byte runMode = -1; byte reDownloadMode = -1; //-1 for redownloading the whole mail, values >= 0 for redownloading particular bodypart only static short instanceRunning = 0; //counts how many threads ALL subclasses of Inprotocol are running short threadCount = 0; //counts how many threads a single subclass of Inprotocol are running boolean locked; //for thread synchronizing boolean forcedDisc; //if it should disconnect from the server unconditionally MailAccount account; //each server has an account private TheBox reportBox = null; /** The box to that the action of this object is associated. That means the box to that mails are actually downloded etc. */ public InBox targetBox = null; MessageHeader actHeader; //a header which should be fetched protected ConnectionInterface connection; //mailsOnServer store message unique identifier(UID) and message number of mails on the server //its used for faster accessing to the message number //and detecting if a concrete mail is on the server - used for inbox-server sync //keys are UID(String) objects are message numbers(String) in the case of POP3, //in case the case of IMAP4 objects are just random number, because we don't need to operate with message numbers in IMAP implementation Hashtable mailsOnServer; String END_OF_MAIL; //a string that indicates the end of transmitting of a mail body String saveMailData; // data to save into server mailbox if saving on server set on String flagsToSet = "()"; public InProtocol(MailAccount account) { //super("In protocol task"); this.account = account; connection = new ConnectionCompressed(); mailsOnServer = new Hashtable(); } //return if the object is busy public boolean isBusy() { return (threadCount > 0) ? true : false; } /** * Handles input flags - set processed message header flags according to * these flags. * @param flags the part of protocol line with flags */ protected void handleFlags(MessageHeader msgHeader, String flags) { if (DEBUG) { System.out.println("DEBUG InProtocol.handleFlags " + actHeader); } if (flags.indexOf("\\Seen") != -1) { msgHeader.markAsRead(); } if (flags.indexOf("\\Answered") != -1) { msgHeader.markAsReplied(); } if (flags.indexOf("\\Deleted") != -1) { msgHeader.markAsDeleted(); } if (flags.indexOf("\\Flagged") != -1) { msgHeader.markAsFlagged(); } } //zvysi counter pocet bezicich threadu protected synchronized void inThread() { ++threadCount; } protected synchronized void decThread() { --threadCount; } //returns if some of all instances (POP, IMAP, SPOP..) of inProtocol are running, resp. if the class Inprotocol is busy. public static boolean isBusyGlobal() { return instanceRunning > 0 ? true : false; } protected synchronized void incThreadGlobal() { ++instanceRunning; } protected synchronized void decThreadGlobal() { --instanceRunning; synchronized(notifier) { notifier.notifyAll(); } } public void stop() { if (isBusy()) { connection.quit(); } } /* * TODO (Betlista): add JavaDoc comment */ public abstract int countNew() throws MyException; protected synchronized void lock() { try { while (locked) { wait(100); } } catch (InterruptedException e) { } locked = true; } protected void unlock() { locked = false; } //add a mail to a queue of mails that are going to be deleted from the server abstract public void addDeleted(MessageHeader header); public boolean containsMail(MessageHeader header) { return mailsOnServer.containsKey(header.getMessageID()); } //synchronized to ensure no other threads are changing runMode //all these methods must be run in a thread /** * Retrieve mails from server * @param box Target inbox where add mails */ public synchronized void getNewMails(InBox box) { if (DEBUG) System.out.println("DEBUG InProtocol.getNewMails(InBox) - getting new mails"); incThreadGlobal(); runMode = InProtocol.GET_NEW_MAILS; this.targetBox = box; this.reportBox = box; inProtocolTask = new InProtocolTask(this, "Getting new mails"); inProtocolTask.start(targetBox, MujMail.mujmail.getMenu()); } /** * This method should be called if polling discovers mail with given ID. * @param ID id of new mail that was discovered by polling. * @return true if this is new email: that means that it was not yet * downloaded. */ protected boolean handleMailDiscoveredByPolling(String ID) { if (!getTargetBox().wasOnceDownloaded(account.getEmail(), ID)) { if (Settings.pollDownloadsMails) { getNewMails( getTargetBox()); } if (Settings.pollPlaysSound) { new AudioAlert(); } return true; } return false; } /** * Blocks calling thread until no InProtocol action of any InProtocol * instance is running. */ public static void waitForNotBusyGlobal() { try { synchronized(notifier) { if (!isBusyGlobal()) return; notifier.wait(); } } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); } } /** * Finds first new mail while polling. The connection is already open. * @throws mujmail.MyException */ protected abstract void findFirstNewMailWhilePolling() throws MyException; /** * <p>Opens the connection.</p> * <p>Note: task can be null (polling).</p> * * @param task * @return * @throws mujmail.MyException */ protected abstract boolean open(BackgroundTask task) throws MyException; private void resolveMyExceptionWhileRunning(MyException ex) { if (ex.getErrorCode() == MyException.COM_HALTED) { connection.unQuit(); } resolveExceptions(ex.getDetails() + "/ " + account.getEmail(), SOURCE_FILE); } protected abstract void getNewMails(); protected abstract void downloadBody(); protected abstract void removeMails(); protected abstract void setFlags(); protected abstract void removeFlags(); protected abstract void getURL() throws MyException; public void doWork() { //polling is an extra thread, is not counted by inThread() or inThreadGlobal() if (doPolling()) return; //if its a forced disconnect, then we will not wait for someone by calling lock() if (runMode == InProtocol.CLOSE && forcedDisc) { closeForceDist(); return; } try { //we use lock() instead of making run() synchronized in order to allow forced disconnecting from servers //even some jobs are still running lock(); inThread(); getReportBox().report(Lang.get(Lang.ALRT_INITIATING) + Lang.get(Lang.ALRT_WAIT), SOURCE_FILE); // Not in background task no setTitle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -