www.pudn.com > mailfetcher2.rar > PopFetcher.java


package mfetcher;

//
// PopFetcher
//

//
// Copyright (C) 1999 John Mettraux
//
// 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.
//
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

import java.io.*;
import java.net.*;
import java.util.Vector;

/**
* Instantiates this class and add to it your own implemented MessageListeners or
* MessagePackListeners to react on each new command mail.
*
* @author John Mettraux
*/


public class PopFetcher
extends Thread
{

/**
* The well-known POP3 port...
*/

public final static int PORT = 110;
public static PrintWriter commLog = null;

//
// DATAS

private String mailServer;
private String account;
private String pass;
private long sleepTime;
private boolean deleteMessagesOnServer;
// some mailServers are configured to automatically delete messages
// after they've been RETRieved

private Vector messageListeners;
private Vector messagePackListeners;

private ExceptionListener exceptionListener;

//
// CONSTRUCTORS

/**
* Easiest constructor : it assumes the POP3 server doesn't delete messages
* when they are retrieved
* <br>(it is almost always the case. The only exception to
* this rule I know : unifr.ch).
*
* @param mailServer the POP3 server
* @param account the user's name
* @param pass the pass for the user's account
* @param sleepTime how many millis to sleep before next mailfetching
*/

public PopFetcher
(String mailServer,
String account,
String pass,
long sleepTime)
{
this (mailServer, account, pass, sleepTime, true);
//
// this class assumes by default that the server doesn't
// automatically deletes RETRieved messages
//
}

/**
* Full parameters constructor
* <br>You can set if the PopFetcher instance deletes or not messages
* after they've been retrieved... Beware of duplicates !
*
* @param mailServer the POP3 server
* @param account the user's name
* @param pass the pass for the user's account
* @param sleepTime how many millis to sleep before next mailfetching
* @param deleteMessagesOnServer when true (default) deletes messages after retrieval
*/

public PopFetcher
(String mailServer,
String account,
String pass,
long sleepTime,
boolean deleteMessagesOnServer)
{

super();

this.mailServer = mailServer;
this.account = account;
this.pass = pass;
this.sleepTime = sleepTime;

this.deleteMessagesOnServer = deleteMessagesOnServer;

messageListeners = new Vector();
messagePackListeners = new Vector();

exceptionListener = null;
}

//
// PUBLIC METHODS

/**
* Adds a MessageListener
*
* @param ml MessageListener
*/

public void addMessageListener (MessageListener ml)
{
messageListeners.addElement(ml);
}

/**
* Adds a MessagePackListener
*
* @param mpl MessagePackListener
*/

public void addMessagePackListener (MessagePackListener mpl)
{
messagePackListeners.addElement(mpl);
}

/**
* Removes a MessageListener
*
* @param ml MessageListener
*/

public void removeMessageListener (MessageListener ml)
{
messageListeners.removeElement(ml);
}

/**
* Removes a MessagePackListener
*
* @param mpl MessagePackListener
*/

public void removeMessagePackListener (MessagePackListener mpl)
{
messagePackListeners.removeElement(mpl);
}

/**
* sets the ExceptionListener of the PopWatcher
*
* @param el An ExceptionListener
*/

public void setExceptionListener (ExceptionListener el)
{
exceptionListener = el;
}

//
// RUN METHOD

/**
* Runs the PopFetcher
* <br>it immediately fetches the mail then sleeps
*/

public void run ()
{

//
// FETCH MAIL and DISPACTH MESSAGES

try {
dispatchMessages(getMessages());
} catch (Exception e) {
if (exceptionListener != null)
exceptionListener.processException(null, e);
// else do nada...
}

}

//
// protected METHODS

/**
* Dispatch the messages to the MessageListener instances and the MessagePackListeners respectively.
*
* @param messages Messages as array of String arrays
*/

protected void dispatchMessages (String[][] messages)
{
if (messages == null)
return;

//
// build the MessageEvent array
MessageEvent[] messageEvents = new MessageEvent[messages.length];

for (int i=0; i<messages.length; i++) {
messageEvents[i] = new MessageEvent(messages[i]);
}

//
// dispatch to MessageListeners
for (int i=0; i<messageListeners.size(); i++) {
MessageListener ml =
(MessageListener)messageListeners.elementAt(i);
for (int j=0; j<messageEvents.length; j++)
ml.messageReceived(messageEvents[j]);
}

//
// dispatch to MessagePackListeners
for (int i=0; i<messagePackListeners.size(); i++) {
((MessagePackListener)messagePackListeners.elementAt(i))
.messagePackReceived(messageEvents);
}
}

/**
* Connects to the server and retrieves the messages.
*
* @return the messages as an array of String arrays (Ready for dispatchMessages() ).
* @exception java.io.IOException Generally when Socket to server cannot be instantiated.
* @exception mfetcher.PopException Generally POP3 protocols errors (-ERR)
*/

public String[][] getMessages ()
throws IOException, PopException
{
Socket socket =
new Socket(mailServer, PORT);
BufferedReader fromServer =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter toServer =
new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

try
{

String line = null;

//
// getting "+OK ducon POP3 Server version x.0b5..."
line = readLine(fromServer);

//
// sending USER
send(toServer, "USER "+account);

//
// getting response
line = readLine(fromServer);
if (line == null || line.startsWith("-ERR"))
throw new PopException("USER command failed.");

//
// sending PASS
send(toServer, "PASS "+pass);

//
// getting response
line = readLine(fromServer);
if (line == null || line.startsWith("-ERR"))
{
//throw new PopException("PASS or USER invalid.");
throw new PopException("PASS or USER invalid : '"+line+"'");
}

//
// sending STAT
send(toServer, "STAT");

//
// getting response
line = readLine(fromServer);
if (line == null || line.startsWith("-ERR"))
throw new PopException("STAT command failed.");
line = line.substring(4);
int space = line.indexOf(" ");
if (space == -1)
throw new PopException("STAT response in incorrect format.");
line = line.substring(0, space);
int messageNumber = 0;
try {
messageNumber = Integer.parseInt(line);
} catch (NumberFormatException nfe) {
throw new PopException("STAT response : incorrect number format.");
}
if (messageNumber == 0)
//
// no messages on server
return null;
String[][] messages = new String[messageNumber][];

//
// GETTING EACH MESSAGE
//

for (int i=0; i<messageNumber; i++) {

//
// sending RETR command
send(toServer, "RETR "+(i+1));

//
// getting message
line = readLine(fromServer);
if (line == null || line.startsWith("-ERR"))
//throw new PopException("RETR failed for message #"+i);
break;

//
// reading message body
Vector message = new Vector();
while (true) {
line = readLine(fromServer);
if (line == null || line.equals("."))
break;
message.addElement(line);
}

//
// message : Vector -> array
String[] msg = new String[message.size()];
for (int j=0; j<msg.length; j++) {
msg[j] = (String)message.elementAt(j);
}

messages[i] = msg;
}

//
// DELETING EVERY MESSAGE
//

if (deleteMessagesOnServer)
for (int i=0; i<messageNumber; i++) {

//
// sending DELE command
send(toServer, "DELE "+(i+1));

//
// getting response
line = readLine(fromServer);
if (line == null || line.startsWith("-ERR"))
//throw new PopException("Error while DELETING message #"+i);
break;

}

//
// sending QUIT command
send(toServer, "QUIT");
line = readLine(fromServer);

//
// that's all folks !
return messages;

}
finally
{

//
// close all
toServer.close();
fromServer.close();
socket.close();

}
}

private void send (PrintWriter pw, String message)
//
// a shortcut for sending commands to the POP3 server.
//
{
if (commLog != null) {
if(message.startsWith("PASS "))
commLog.println("PASS ????");
else
commLog.println(message);
commLog.flush();
}
pw.print(message+"\r\n");
pw.flush();
}

private String readLine (BufferedReader br)
{
String line;
try {
line = br.readLine();
} catch (IOException e) {
line = null;
}
if(commLog != null) {
if (line == null) {
commLog.println("<null>");
} else if (line.startsWith("-ERR")) {
commLog.println(line);
} else if (line.startsWith("+OK")) {
commLog.println(line);
} else if (line.equals(".")) {
commLog.println(line);
} else {
//commLog.println(line);
}
commLog.flush();
}
return line;
}

//
// for debugging purpose only

private void debug (String info)
{
System.out.println(info);
}

}