| AbstractMailTransportService.java |
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Created on Mar 16, 2004
*/
package org.jboss.net.axis.transport.mailto;
import javax.mail.AuthenticationFailedException;
import javax.mail.FetchProfile;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.system.ServiceMBeanSupport;
/**
* <dl>
* <dt><b>Title: </b><dd>Abstract Mail Transport Service</dd>
* <p>
* <dt><b>Description: </b><dd>Both the client and server side email transport services are based off of this class.
* </dd>
* <p>
* </dl>
* @author <a href="mailto:jasone@greenrivercomputing.com">Jason Essington</a>
* @version $Revision: 1.1 $
*
* @jmx.mbean
* description="Abstract Mail Transport Service"
* extends="org.jboss.system.ServiceMBean"
*/
public abstract class AbstractMailTransportService extends ServiceMBeanSupport implements MailConstants
{
public static final String FOLDER_NAME = "INBOX";
public static final String SESSION_NAME = "java:/Mail";
public static final String ENGINE_NAME = "jboss.net:service=Axis";
private String mailFolderName = FOLDER_NAME;
private String mailSessionName = SESSION_NAME;
private String EngineName = ENGINE_NAME;
private boolean deleteMail = true;
/**
* The jndi name under which the javax.mail.Session object is stored.
* @jmx.managed-attribute
*/
public void setSessionName(String name)
{
this.mailSessionName = name;
}
/**
* @jmx.managed-attribute
* description = "The JNDI name of the mail session that will be used by this transport"
* value = "java:/Mail"
*/
public String getSessionName()
{
return this.mailSessionName;
}
/**
* The name of the folder in which the SOAP messages will reside (likely INBOX).
* @jmx.managed-attribute
*/
public void setFolderName(String name)
{
this.mailFolderName = name;
}
/**
* @jmx.managed-attribute
* description = "Folder in which incoming SOAP messages will be found"
* value = "INBOX"
*/
public String getFolderName()
{
return this.mailFolderName;
}
/**
* The jndi name under which the org.apache.axis.server.AxisServer object is stored.
* @jmx.managed-attribute
*/
public void setEngineName(String name)
{
this.EngineName = name;
}
/**
* @jmx.managed-attribute
* description = "The jmx ObjectName of the Axis Server"
* value = "jboss.net:service=Axis"
*/
public String getEngineName()
{
return this.EngineName;
}
/**
* Flag instructing the transport to delete processed messages, or not.
* @jmx.managed-attribute
*/
public void setDeleteMail(boolean delete)
{
this.deleteMail = delete;
}
/**
* @jmx.managed-attribute
* description = "Should processed messages be deleted?"
* value = "true"
*/
public boolean getDeleteMail()
{
return this.deleteMail;
}
/**
* Check our pop mail box for new emails.
*
* maybe an exception of some sort should be thrown if something bad happens? currently all exceptions are logged
* and execution of this method terminates with nothing else happening.
*
* @jmx.managed-operation
*/
public void pollMail()
{
if (log.isDebugEnabled())
log.debug("Entering: pollMail()");
Session mail = getMailSession();
// bail if there is a problem with our store or folder
Store store = null;
if ((store = getMailStore(mail)) == null)
return;
Folder folder = null;
if ((folder = getMailFolder(store)) == null)
return;
try
{
Message[] msgs = fetchMessages(folder);
//leave if there are no messages
if (msgs.length > 0)
processMessages(msgs);
}
finally
{
// now we are done, get out of here
closeFolder(folder);
closeStore(store);
}
if (log.isDebugEnabled())
log.debug("Leaving: pollMail()");
}
protected abstract void processMessages(Message[] msgs);
/**
* Fetch the mail session stored in jndi.
* @return Session
*/
protected Session getMailSession()
{
if (log.isDebugEnabled())
log.debug("Entering: getMailSession()");
Context ctx = null;
Session mail = null;
try
{
ctx = new InitialContext();
mail = (Session) ctx.lookup(getSessionName());
}
catch (NamingException ne)
{
/** @TODO we should probably turn around and throw an exception of some sort here
* since there was some problem fetching the mail session from jndi */
log.fatal("NamingException: getMailSession()\n", ne);
}
finally
{
if (ctx != null)
try
{
ctx.close();
}
catch (NamingException ne)
{
}
}
if (log.isDebugEnabled())
log.debug("Leaving: getMailSession()");
return mail;
}
protected Store getMailStore(Session mail)
{
Store store = null;
try
{
store = mail.getStore();
if (log.isDebugEnabled())
log.debug(store.getClass().getName());
}
catch (NoSuchProviderException e)
{
// Could happen if <parameter name="mail.store.protocol" value="pop3"/> is not set
log.fatal("The mail session does not have a default provider! Check the mail.store.protocal "
+ "property in the mail-service.xml file", e);
}
try
{
if (store != null)
store.connect();
}
catch (AuthenticationFailedException e)
{
// This could happen if the username and password defined in the mail-service.xml file are wrong or missing
log.fatal("The User and/or Password defined in the mail-service.xml file could be wrong or missing", e);
closeStore(store);
store = null;
}
catch (MessagingException e)
{
// This is a bad thing. We couldn't connect to the mail store for some reason.
log.fatal("Unable to connect to the mail store.", e);
closeStore(store);
store = null;
}
catch (IllegalStateException e)
{
// This means the store is already connected! I suppose since this is what we wanted any way we could
// go along our merry way?
log.warn("The store is already connected!", e);
}
return store;
}
protected Folder getMailFolder(Store store)
{
Folder folder = null;
try
{
folder = store.getFolder(getFolderName());
if (log.isDebugEnabled())
log.debug(folder.getClass().getName());
// we can only continue if this folder actually exists!
if (!folder.exists())
{
log.fatal("The folder '" + getFolderName() + "' doe not exist. Check the FolderName attribute in the "
+ "jboss-service.xml file.");
// This was fatal, lets clean up and leave.
closeStore(store);
folder = null;
}
}
catch (MessagingException e)
{
log.fatal("Unable to retrieve the folder '" + getFolderName() + "' from the store. Check the FolderName "
+ "attribute in the jboss-service.xml file.", e);
closeStore(store);
folder = null;
}
try
{
folder.open(Folder.READ_WRITE);
}
catch (MessagingException e)
{
// not sure what would cause this, but if it happens, it can't be good so log and leave
log.fatal("Failed to open the folder'" + getFolderName() + "'.", e);
closeStore(store);
folder = null;
}
return folder;
}
/**
* Lets preload some information about our mail messages into message objects.
*
* @param mail
* @return Message[]
*/
protected Message[] fetchMessages(Folder folder)
{
if (log.isDebugEnabled())
log.debug("Entering: fetchMessages(Folder folder)");
Message[] messages = new Message[0];
Store store = null;
try
{
if (log.isDebugEnabled())
log.debug("\nMessageCount: " + folder.getMessageCount());
if (folder.getMessageCount() > 0)
{
messages = folder.getMessages();
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.CONTENT_INFO);
//address information
fp.add(FetchProfile.Item.ENVELOPE);
folder.fetch(messages, fp);
if (log.isDebugEnabled())
{
log.debug("getMailMessages(Session mail)\n\t retrieved " + messages.length + " message(s)");
}
}
else if (log.isDebugEnabled())
log.debug("getMailMessages(Session mail)\n\t no mail!");
}
catch (NoSuchProviderException e)
{
log.error("NoSuchProviderException: getMailMessages(Session mail)\n", e);
}
catch (MessagingException e)
{
log.error("MessagingException: getMailMessages(Session mail)\n", e);
}
finally
{
try
{
if (store != null)
store.close();
}
catch (MessagingException e)
{
}
}
if (log.isDebugEnabled())
log.debug("Leaving: fetchMessages(Folder folder)");
return messages;
}
/**
* This closes the mail store and suppresses any exceptions. For use when bailing out due to an error of some sort.
*
* @param store
*/
protected void closeStore(Store store)
{
try
{
if (store != null)
store.close();
}
catch (Exception ignore)
{
}
return;
}
/**
* This closes a mail folder and handles exceptions by pretending they didn't happen.
* Only do this if you are leaving and the resulting state of the folder is of no consequence to you.
*
* @param folder
*/
protected void closeFolder(Folder folder)
{
try
{
// expunge deleted messages on close
folder.close(true);
}
catch (Exception ignore)
{
}
return;
}
}
| AbstractMailTransportService.java |