/*
* Copyright (C) 2000 - 2008 TagServlet Ltd
*
* This file is part of Open BlueDragon (OpenBD) CFML Server Engine.
*
* OpenBD is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Free Software Foundation,version 3.
*
* OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with any of the JARS listed in the README.txt (or a modified version of
* (that library), containing parts covered by the terms of that JAR, the
* licensors of this Program grant you additional permission to convey the
* resulting work.
* README.txt @ http://www.openbluedragon.org/license/README.txt
*
* http://www.openbluedragon.org/
*/
/*
* Wrapper for the Mail object that will be passed into the CFC
* for processing an incoming email via CFSMTP
*
* The idea is not to duplicate any data, but make a call down into the
* underlying Mail object for the data
*
*/
package org.alanwilliamson.openbd.plugin.cfsmtp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import javax.mail.Address;
import javax.mail.Header;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import com.naryx.tagfusion.cfm.engine.cfArrayData;
import com.naryx.tagfusion.cfm.engine.cfDateData;
import com.naryx.tagfusion.cfm.engine.cfNumberData;
import com.naryx.tagfusion.cfm.engine.cfStringData;
import com.naryx.tagfusion.cfm.engine.cfStructData;
public class BlueDragonMailWrapper extends cfStructData {
private static final long serialVersionUID = 1L;
private Mail mail;
private MimeMessage message;
public BlueDragonMailWrapper( Mail mail ) throws Exception {
this.mail = mail;
this.message = mail.getMessage();
}
public BlueDragonMailWrapper( MimeMessage message ) throws Exception {
this.mail = null;
this.message = message;
}
public void dumpLong( java.io.PrintWriter out, String _lbl, int _top ){
dump( out, _lbl, _top );
}
public void dump( java.io.PrintWriter out, String _lbl, int _top ) {
out.write( "<table class='cfdump_table_struct'><tr><th>mail</th></tr><tr><td><ul>" );
out.write( "<li><b>getAllBodyParts()</b> returns Array of ALL Parts including the inner ones</li>");
out.write( "<li><b>getBodyParts()</b> returns Array of Parts; as per email</li>");
out.write( "<li><b>getCcList()</b> returns Array of Structs (name/email) of all the people addressed in the Cc field</li>");
out.write( "<li><b>getFromList()</b> returns Array of Structs (name/email) of all the people addressed in the From field</li>");
out.write( "<li><b>getHeaders()</b> returns Array of all the email headers</li>");
out.write( "<li><b>getHeader( string )</b> returns the value of the given header</li>");
if ( mail != null )
out.write( "<li><b>getIP()</b> returns the IP address of the delivery agent</li>");
out.write( "<li><b>getMessageId()</b> returns the email message id</li>");
out.write( "<li><b>getMailFrom()</b> returns email address that was in the MAIL FROM</li>");
out.write( "<li><b>getReplyToList()</b> returns Array of Structs (name/email) of all the people addressed in the Reply-To field</li>");
out.write( "<li><b>getSentDate()</b> returns the date the message was sent</li>");
out.write( "<li><b>getReceivedDate()</b> returns the date the message was received</li>");
if ( mail != null )
out.write( "<li><b>getRecipients()</b> returns Array of email addresses; these are the emails to which the email was delivered to via RCPT TO</li>");
out.write( "<li><b>getSubject()</b> returns the email subject</li>");
out.write( "<li><b>getSize()</b> returns the size of the email</li>");
out.write( "<li><b>getToList()</b> returns Array of Structs (name/email) of all the people addressed in the To field</li>");
out.write( "<li><b>spoolMailToDir(dir)</b> saves the mail to disk and returns the full path of the saved file</li>");
out.write( "</ul></td><tr><table>" );
}
public cfStringData spoolMailToDir( String directory ){
File fileDir = new File( directory );
if ( !fileDir.isDirectory() ){
fileDir.mkdirs();
}
FileOutputStream outWriter = null;
try{
String id = this.message.getMessageID();
id = id.replace('>', '0');
id = id.replace('<', '0');
id = id.replace('@', '-');
id = id.replace('.', '-');
/* Make sure its not too long, lets chop it */
if ( id.length() > 64 ){
id = id.substring( 0, 32 ) + id.substring( id.length() - 32 );
}
id = id + ".mail";
/* Make sure the file is unique */
int x = 0;
File outFile = new File( fileDir, id );
while ( outFile.isFile() ){
outFile = new File( directory, (x++) + "" + id );
}
/* Write out the message */
outWriter = new FileOutputStream( outFile );
this.message.writeTo( outWriter );
outWriter.flush();
outWriter.close();
return new cfStringData( outFile.toString() );
}catch(Exception e){
return cfStringData.EMPTY_STRING;
}finally{
if ( outWriter != null ){
try {
outWriter.close();
} catch (IOException ignoreCloseException) {}
}
}
}
public cfArrayData getBodyParts(){
try{
cfArrayData arr = cfArrayData.createArray( 1 );
if ( message.isMimeType("multipart/*") ){
Multipart mp = (Multipart)message.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++)
arr.addElement( new BlueDragonPartWrapper(mp.getBodyPart(i)) );
}else{
arr.addElement( new BlueDragonPartWrapper( (Part)message ) );
}
return arr;
}catch(Exception e){
return cfArrayData.createArray( 1 );
}
}
public cfArrayData getAllBodyParts(){
try{
cfArrayData arr = cfArrayData.createArray( 1 );
ArrayList<BlueDragonPartWrapper> list = new ArrayList<BlueDragonPartWrapper>();
getParts( message, list );
Iterator<BlueDragonPartWrapper> it = list.iterator();
while ( it.hasNext() )
arr.addElement( it.next() );
return arr;
}catch(Exception e){
return cfArrayData.createArray( 1 );
}
}
/*
* This method flattens out all the parts and puts them in list
* This method is also recursable
*/
private void getParts( Part part, List<BlueDragonPartWrapper> list ) throws MessagingException, IOException{
if ( part.isMimeType("multipart/*") ){
Multipart mp = (Multipart)part.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++)
getParts( mp.getBodyPart(i), list );
}else{
list.add( new BlueDragonPartWrapper( part ) );
}
}
/*
* This returns the actual email addresses this mail was delivered to;
* it need not necessarily be the emails in the official headers.
*
* For example [BCC] emails will be here
*/
public cfArrayData getRecipients(){
try{
cfArrayData arr = cfArrayData.createArray( 1 );
if ( mail != null ){
Iterator c = mail.getRecipients().iterator();
while ( c.hasNext() ){
MailAddress ma = (MailAddress)c.next();
arr.addElement( new cfStringData( ma.toString() ) );
}
}
return arr;
}catch(Exception e){
return cfArrayData.createArray( 1 );
}
}
/*
* This is the actual address the mail was delivered from
* in the "MAIL FROM" exchange. This may not be the same
* as the "From" in the email headers
*/
public cfStringData getMailFrom(){
try{
if ( mail != null )
return new cfStringData( mail.getSender().toString() );
}catch(Exception e){}
return cfStringData.EMPTY_STRING;
}
/*
* This is the IP address to which the client connected from
*/
public cfStringData getIP(){
try{
if ( mail != null )
return new cfStringData( mail.getRemoteAddr() );
}catch(Exception e){}
return cfStringData.EMPTY_STRING;
}
public cfArrayData getHeaders(){
try{
cfArrayData arr = cfArrayData.createArray( 1 );
Enumeration e = message.getAllHeaders();
while (e.hasMoreElements()){
Header hdr = (Header)e.nextElement();
arr.addElement( new cfStringData( hdr.getName() ) );
}
return arr;
}catch(Exception e){
return cfArrayData.createArray( 1 );
}
}
public cfArrayData getToList(){
try {
return getAddresses( message.getRecipients( Message.RecipientType.TO ));
} catch (MessagingException e) {
return cfArrayData.createArray( 1 );
}
}
public cfArrayData getFromList(){
try {
return getAddresses( message.getFrom() );
} catch (MessagingException e) {
return cfArrayData.createArray( 1 );
}
}
public cfArrayData getReplyToList(){
try {
return getAddresses( message.getReplyTo() );
} catch (MessagingException e) {
return cfArrayData.createArray( 1 );
}
}
public cfArrayData getCcList(){
try {
return getAddresses( message.getRecipients( Message.RecipientType.CC ));
} catch (MessagingException e) {
return cfArrayData.createArray( 1 );
}
}
private cfArrayData getAddresses( Address[] a ){
try{
cfArrayData arr = cfArrayData.createArray( 1 );
for ( int x=0; x < a.length; x++ ){
InternetAddress address = (InternetAddress)a[x];
cfStructData s = new cfStructData();
s.setData("name", new cfStringData(address.getPersonal()));
s.setData("email", new cfStringData(address.getAddress()));
arr.addElement( s );
}
return arr;
}catch(Exception e){
return cfArrayData.createArray( 1 );
}
}
public cfStringData getHeader( String hdr ){
try{
String[] values = message.getHeader(hdr);
String value = "";
for ( int x=0; x < values.length; x++ ){
value += value + values[x];
if ( x < values.length-1 )
value += ";";
}
return new cfStringData( value );
}catch(Exception e){
return cfStringData.EMPTY_STRING;
}
}
public cfDateData getSentDate(){
try{
return new cfDateData( message.getSentDate() );
}catch(Exception e){
return new cfDateData( new Date() );
}
}
public cfDateData getReceivedDate(){
try{
return new cfDateData( message.getReceivedDate() );
}catch(Exception e){
return new cfDateData( new Date() );
}
}
public cfStringData getSubject(){
try{
return new cfStringData( message.getSubject() );
}catch(Exception e){
return cfStringData.EMPTY_STRING;
}
}
public cfStringData getMessageId(){
try{
return new cfStringData( message.getMessageID() );
}catch(Exception e){
return cfStringData.EMPTY_STRING;
}
}
public cfNumberData getSize(){
try{
return new cfNumberData( message.getSize() );
}catch(Exception e){
return new cfNumberData(0);
}
}
public MimeMessage getMessage() {
return message;
}
}