emailBean : Send DominoDocument HTML Emails c/w Embedded Images, Attachments, Custom Header/Footer

Code 1 - EmailBean.java

/**
 * @author Tony McGuckin, IBM
 */
 
package com.ibm.xsp.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.context.FacesContext;

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import lotus.domino.MIMEEntity;
import lotus.domino.MIMEHeader;
import lotus.domino.NotesException;
import lotus.domino.Session;
import lotus.domino.Stream;

import com.ibm.commons.util.NotImplementedException;
import com.ibm.domino.xsp.module.nsf.NotesContext;
import com.ibm.xsp.model.FileRowData;
import com.ibm.xsp.model.domino.wrapped.DominoDocument;
import com.ibm.xsp.model.domino.wrapped.DominoRichTextItem;
import com.ibm.xsp.model.domino.wrapped.DominoDocument.AttachmentValueHolder;
import com.ibm.xsp.persistence.PersistedContent;

public class EmailBean {
	
	private ArrayList<String> sendTo;
	private ArrayList<String> ccList;
	private ArrayList<String> bccList;
	private String senderEmail;
	private String senderName;
	private String subject;
	
	private DominoDocument document;
	private String fieldName;
	
	private String bannerHTML;
	private String footerHTML;
	
	private boolean debugMode = false;
	
	private static final Pattern imgRegExp = Pattern.compile("<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>");
	
	//-------------------------------------------------------------------------
	
	public EmailBean(){
		this.subject = "";
		this.sendTo = new ArrayList<String>();
		this.ccList = new ArrayList<String>();
		this.bccList = new ArrayList<String>();
	}
	
	//-------------------------------------------------------------------------

	public String getSendTo(){
		if(this.isDebugMode()){
			System.out.println("getSendTo() : " + this.sendTo.toString());
		}
		return this.sendTo.toString().replace("[", "").replace("]", "");
	}
	
	public void setSendTo(final String sendTo){
		this.sendTo.add(sendTo);
	}
	
	//-------------------------------------------------------------------------

	public String getCcList(){
		if(this.isDebugMode()){
			System.out.println("getCcList() : " + this.ccList.toString());
		}
		return this.ccList.toString().replace("[", "").replace("]", "");
	}
	
	public void setCcList(final String ccList){
		this.ccList.add(ccList);
	}
	
	//-------------------------------------------------------------------------

	public String getBccList(){
		if(this.isDebugMode()){
			System.out.println("getBccList() : " + this.bccList.toString());
		}
		return this.bccList.toString().replace("[", "").replace("]", "");
	}
	
	public void setBccList(final String bccList){
		this.bccList.add(bccList);
	}
	
	//-------------------------------------------------------------------------

	public String getSenderEmail(){
		return this.senderEmail;
	}
	
	public void setSenderEmail(final String senderEmail){
		this.senderEmail = senderEmail;
	}
	
	//-------------------------------------------------------------------------

	public String getSenderName(){
		return this.senderName;
	}
	
	public void setSenderName(final String senderName){
		this.senderName = senderName;
	}
	
	//-------------------------------------------------------------------------

	public String getSubject(){
		return this.subject;
	}
	
	public void setSubject(final String subject){
		this.subject = subject;
	}
	
	//-------------------------------------------------------------------------

	public boolean isDebugMode(){
		return this.debugMode;
	}
	
	public void setDebugMode(final boolean debugMode){
		this.debugMode = debugMode;
	}
	
	//-------------------------------------------------------------------------
	
	private Session getCurrentSession(){
		NotesContext nc = NotesContext.getCurrentUnchecked();
    	return (null != nc) ? nc.getCurrentSession() : null;
	}
	
	//-------------------------------------------------------------------------
	
	private Database getCurrentDatabase(){
		NotesContext nc = NotesContext.getCurrentUnchecked();
    	return (null != nc) ? nc.getCurrentDatabase() : null;
	}
	
	//-------------------------------------------------------------------------
	
	public void send() throws NotesException, IOException, Exception{
		Session session = getCurrentSession();
		Database database = getCurrentDatabase();
		if(null != session && null != database &&
			null != this.sendTo && null != this.subject &&
				null != this.senderEmail
		){
			try {
				if(this.isDebugMode()){
					System.out.println("Started send()");
				}
				session.setConvertMime(false);
				Document emailDocument = database.createDocument();

				MIMEEntity emailRoot = emailDocument.createMIMEEntity("Body");
				if(null != emailRoot){
					MIMEHeader emailHeader = emailRoot.createHeader("Reply-To");
					emailHeader.setHeaderVal(this.getSenderEmail());
					
					emailHeader = emailRoot.createHeader("Return-Path");
					emailHeader.setHeaderVal(this.getSenderEmail());
					
					final String fromSender = (null == this.getSenderName()) ?
							this.getSenderEmail() :
								"\"" + this.getSenderName() + "\" <" + this.getSenderEmail() + ">";
					
					emailHeader = emailRoot.createHeader("From");
					emailHeader.setHeaderVal(fromSender);
						
					emailHeader = emailRoot.createHeader("Sender");
					emailHeader.setHeaderVal(fromSender);
				
					emailHeader = emailRoot.createHeader("To");
					emailHeader.setHeaderVal(this.getSendTo());
					
					if(!this.ccList.isEmpty()){
						emailHeader = emailRoot.createHeader("CC");
						emailHeader.setHeaderVal(this.getCcList());
					}
					
					if(!this.bccList.isEmpty()){
						emailHeader = emailRoot.createHeader("BCC");
						emailHeader.setHeaderVal(this.getBccList());
					}
					
					emailHeader = emailRoot.createHeader("Subject");
					emailHeader.setHeaderVal(this.getSubject());
					
					MIMEEntity emailRootChild = emailRoot.createChildEntity();
					if(null != emailRootChild){
						final String boundary = System.currentTimeMillis() + "-" + this.document.getDocumentId();
						emailHeader = emailRootChild.createHeader("Content-Type");
						emailHeader.setHeaderVal("multipart/alternative; boundary=\"" + boundary + "\"");
						
						MIMEEntity emailChild = emailRootChild.createChildEntity();
						if(null != emailChild){
							final String contentAsText = this.document.getRichTextItem(this.fieldName).getContentAsText();
							Stream stream = session.createStream();
							stream.writeText(contentAsText);
							emailChild.setContentFromText(stream, "text/plain; charset=\"UTF-8\"", MIMEEntity.ENC_NONE);
							stream.close();
							
							emailChild = emailRootChild.createChildEntity();
							stream = session.createStream();
							stream.writeText(this.getHTML());
							emailChild.setContentFromText(stream, "text/html; charset=\"UTF-8\"", MIMEEntity.ENC_NONE);
							stream.close();
							stream.recycle();
							stream = null;
						}
						
						// add embedded images....
						final List<FileRowData> embeddedImages = this.getEmbeddedImagesList();
						if(null != embeddedImages && !embeddedImages.isEmpty()){
							if(this.isDebugMode()){
								System.out.println("Adding Embedded Images...");
							}
					    	for(FileRowData embeddedImage : embeddedImages) {
								emailRootChild = emailRoot.createChildEntity();
								if(null != emailRootChild && embeddedImage instanceof AttachmentValueHolder){
									InputStream is = null;
									try {
										String persistentName = ((AttachmentValueHolder)embeddedImage).getPersistentName();
										String cid = ((AttachmentValueHolder)embeddedImage).getCID();
										emailHeader = emailRootChild.createHeader("Content-Disposition");
										emailHeader.setHeaderVal("inline; filename=\"" + persistentName + "\"");
										emailHeader = emailRootChild.createHeader("Content-ID");
										emailHeader.setHeaderVal("<" + cid + ">");
										is = this.getEmbeddedImageStream(persistentName);
										Stream stream = session.createStream();
										stream.setContents(is);
										emailRootChild.setContentFromBytes(stream, embeddedImage.getType(), MIMEEntity.ENC_IDENTITY_BINARY);
										if(this.isDebugMode()){
											System.out.println("Added Embedded Image : " + persistentName);
										}
									} catch (IOException e) {
										if(this.isDebugMode()){
											System.out.println("Adding Embedded Image failed : " + e.getMessage());
										}
										throw e;
									} finally {
										if(null != is){
											is.close();
											is = null;
										}
									}
								}
					    	}
							if(this.isDebugMode()){
								System.out.println("Completed Adding Embedded Images");
							}
						}
						
						// add attachments....
						final List<FileRowData> attachments = this.getDocument().getAttachmentList(this.getFieldName());
						if(null != attachments && !attachments.isEmpty()){
							if(this.isDebugMode()){
								System.out.println("Adding Attachments...");
							}
					    	for(FileRowData attachment : attachments) {
								emailRootChild = emailRoot.createChildEntity();
								if(null != emailRootChild && attachment instanceof AttachmentValueHolder){
									InputStream is = null;
									try {
										String persistentName = ((AttachmentValueHolder)attachment).getPersistentName();
										String cid = ((AttachmentValueHolder)attachment).getCID();
										EmbeddedObject eo = this.getDocument().getDocument().getAttachment(persistentName);
										if(null != eo){
											emailHeader = emailRootChild.createHeader("Content-Disposition");
											emailHeader.setHeaderVal("attachment; filename=\"" + persistentName + "\"");
											emailHeader = emailRootChild.createHeader("Content-ID");
											emailHeader.setHeaderVal("<" + cid + ">");
											is = eo.getInputStream();
											Stream stream = session.createStream();
											stream.setContents(is);
											emailRootChild.setContentFromBytes(stream, attachment.getType(), MIMEEntity.ENC_IDENTITY_BINARY);
											if(this.isDebugMode()){
												System.out.println("Added Attachment : " + persistentName);
											}
										}
									} catch (Exception e) {
										if(this.isDebugMode()){
											System.out.println("Adding Attachment failed : " + e.getMessage());
										}
										throw e;
									} finally {
										if(null != is){
											is.close();
											is = null;
										}
									}
								}
					    	}
							if(this.isDebugMode()){
								System.out.println("Completed Adding Attachments");
							}
						}
					}
				}
				emailDocument.send();
				session.setConvertMime(true);
				if(this.isDebugMode()){
					System.out.println("Completed send()");
				}
			} catch (NotesException e) {
				if(this.isDebugMode()){
					System.out.println("Failed send() with NotesException" + e.getMessage());
				}
				throw e;
			} catch (IOException e) {
				if(this.isDebugMode()){
					System.out.println("Failed send() with IOException" + e.getMessage());
				}
				throw e;
			} catch (Exception e) {
				if(this.isDebugMode()){
					System.out.println("Failed send() with Exception" + e.getMessage());
				}
				throw e;
			}
		}
	}
	
	//-------------------------------------------------------------------------
	
	public DominoDocument getDocument(){
		return this.document;
	}
	
	public void setDocument(final DominoDocument document){
		this.document = document;
	}
	
	//-------------------------------------------------------------------------

	public String getFieldName(){
		return this.fieldName;
	}
	
	public void setFieldName(final String fieldName){
		this.fieldName = fieldName;
	}
	
	//-------------------------------------------------------------------------
	
	public List<FileRowData> getEmbeddedImagesList() throws NotesException{
		if(null != document && null != fieldName){
			return document.getEmbeddedImagesList(fieldName);
		}
		return null;
	}
	
	//-------------------------------------------------------------------------
	
	private InputStream getEmbeddedImageStream(final String fileName) throws NotesException, IOException{
		if(null != document && null != fieldName && null != fileName){
			final DominoRichTextItem drti = document.getRichTextItem(fieldName);
			if(null != drti){
				final PersistedContent pc = drti.getPersistedContent(FacesContext.getCurrentInstance(), fieldName, fileName);
				if(null != pc){
					return pc.getInputStream();
				}
			}
		}
		return null;
	}
	
	//-------------------------------------------------------------------------

	public String getHTML(){
		StringBuffer html = new StringBuffer();
		html.append(getBannerHTML());
		html.append(getBodyHTML());
		html.append(getFooterHTML());
		return html.toString();
	}
	
	//-------------------------------------------------------------------------

	public String getBannerHTML(){
		return this.bannerHTML;
	}

	public void setBannerHTML(final String bannerHTML){
		this.bannerHTML = bannerHTML;
	}
	
	//-------------------------------------------------------------------------

	public String getBodyHTML(){
		if(null != document && null != fieldName){
			if(this.isDebugMode()){
				System.out.println("Started getBodyHTML()");
			}
			final DominoRichTextItem drti = document.getRichTextItem(fieldName);
			if(null != drti){
				try {
					String html = drti.getHTML();
					if(null != html){
						final List<FileRowData> fileRowDataList = document.getEmbeddedImagesList(fieldName);
						if(null != fileRowDataList){
					    	final Matcher matcher = imgRegExp.matcher(html);
					        while(matcher.find()){
					            String src = matcher.group();
					            final String srcToken = "src=\"";
					            final int x = src.indexOf(srcToken);
					            final int y = src.indexOf("\"", x + srcToken.length());
					            final String srcText = src.substring(x + srcToken.length(), y);
					    		for(FileRowData fileRowData : fileRowDataList) {
					    			final String srcImage = fileRowData.getHref();
					    			final String cidImage = ((AttachmentValueHolder)fileRowData).getCID();
					    			if(srcText.endsWith(srcImage)){
						    			final String newSrc = src.replace(srcText, "cid:" + cidImage);
										html = html.replace(src, newSrc);
										if(this.isDebugMode()){
											System.out.println("CID referenced image: " + srcText + " with CID:" + cidImage);
										}
					    			}
					   			}
					        }
						}
					}
					if(this.isDebugMode()){
						System.out.println("Completed getBodyHTML() : " + html);
					}
			        return html;
				} catch (Exception e) {
					if(this.isDebugMode()){
						System.out.println("Failed getBodyHTML() : " + e.getMessage());
					}
				}
			}
		}
		return null;
	}
	
	public void setBodyHTML(final String bodyHTML) throws NotImplementedException{
		if(this.isDebugMode()){
			System.out.println("Method setBodyHTML(string) is not permitted");
		}
		throw new NotImplementedException();
	}
	
	//-------------------------------------------------------------------------

	public String getFooterHTML(){
		return this.footerHTML;
	}
	
	public void setFooterHTML(final String footerHTML){
		this.footerHTML = footerHTML;
	}
	
	//-------------------------------------------------------------------------
	
} // end EmailBean



Code 2 - faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
	<managed-bean>
		<managed-bean-name>emailBean</managed-bean-name>
		<managed-bean-class>com.ibm.xsp.utils.EmailBean</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
		<managed-property>
			<property-name>debugMode</property-name>
			<value>true</value>
		</managed-property>
	</managed-bean>
</faces-config>



Code 3 - emailBeanTest.xsp

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.ibm.com/xsp/core xsdxp://localhost/xsp~core.xsd">
	<xp:this.data>
		<xp:dominoDocument var="document1" formName="frmEmail">
			<xp:this.postSaveDocument>
				<![CDATA[#{javascript:
					try{
						var sendTo = document1.getItemValueString("SendTo");
						var subject = document1.getItemValueString("Subject");
						
						var senderEmail = "samantha/renovations";
						var senderName = "Samantha at Renovations";
						
						emailBean.setSendTo(sendTo);
						emailBean.setSubject(subject);
						emailBean.setSenderEmail(senderEmail);
						emailBean.setSenderName(senderName);
						emailBean.setDocument(document1);
						emailBean.setFieldName("Body");
						emailBean.setBannerHTML("<p>Hi " + sendTo + ",</p>");
						emailBean.setFooterHTML("<p>Kind regards,<br/>" + senderName + "<br/>0044 1234 5678</p>");
						
						emailBean.send();
					}catch(e){
						print(e.getMessage());
					}
				}]]>
			</xp:this.postSaveDocument>
		</xp:dominoDocument>
	</xp:this.data>
	<xp:table style="padding:20px">
		<xp:tr>
			<xp:td>
				<xp:label value="SendTo:" id="to_Label1" for="to"></xp:label>
			</xp:td>
			<xp:td>
				<xp:inputText value="#{document1.SendTo}" id="to"></xp:inputText>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td>
				<xp:label value="Subject:" id="subject_Label1" for="subject">
				</xp:label>
			</xp:td>
			<xp:td>
				<xp:inputText value="#{document1.Subject}" id="subject">
				</xp:inputText>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td valign="top">
				<xp:label value="Body:" id="body_2_Label1" for="body">
				</xp:label>
			</xp:td>
			<xp:td>
				<xp:inputRichText value="#{document1.Body}" id="body">
				</xp:inputRichText>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td valign="top">
				<xp:label value="Attachments:" id="label12" for="fileUpload1">
				</xp:label>
			</xp:td>
			<xp:td>
				<xp:fileUpload id="fileUpload1" value="#{document1.Body}">
				</xp:fileUpload>
				<xp:br></xp:br>
				<xp:br></xp:br>
				<xp:fileDownload rows="30" id="fileDownload1"
					displayLastModified="false" allowDelete="true" value="#{document1.Body}"></xp:fileDownload>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td></xp:td>
			<xp:td>
				<xp:button id="button1" value="Save and Email">
					<xp:eventHandler event="onclick" submit="true"
						refreshMode="complete">
						<xp:this.action>
							<xp:saveDocument var="document1"></xp:saveDocument>
						</xp:this.action>
					</xp:eventHandler>
				</xp:button>
			</xp:td>
		</xp:tr>
	</xp:table>
</xp:view>





Use the emailBean to create and send HTML/MIME emails based on a DominoDocument datasource.  Use CKEditor bound to the datasource to compose the email content that can also include Embedded Images.  Use the File Upload bound to the datasource to also include Attachments in the email. You can also specify your own custom Header and Footer (Signature) HTML content for the email.

Example:

emailBean.setSendTo("frank@renovations.com");
emailBean.setSubject("Todays Finance Report");
emailBean.setSenderEmail("samantha@renovations.com");
emailBean.setSenderName("Samantha - Renovations");
emailBean.setDocument(document1);
emailBean.setFieldName("Body");
emailBean.setBannerHTML("<p>Hi,</p>");
emailBean.setFooterHTML("<p>Kind regards,<br/>Samantha<br/>0012 3456 789</p>");
emailBean.send();

XPages
Tony McGuckin
April 4, 2012 2:27 AM
Rating
1,720

All code submitted to OpenNTF XSnippets, whether submitted as a "Snippet" or in the body of a Comment, is provided under the Apache License Version 2.0. See Terms of Use for full details.



6 comment(s)Login first to comment...
Steven Darcy
(at 02:23 on 21.07.2016)
Thanks All ! This is a big help however I have issues though when I use this within a loop on a document save where I pass variables into the code to send multiple emails and I hope someone might be able to assist with why.
Basically I think it's because the string values passed are not cleared and therefore if they are not overwritten then they appear on the next email, also when passing to a list, the new value adds to the previous email's passed value.

Examples:
1st Email:
emailBean.setSendTo("John")
Result: Sends email to John

2nd Email (2nd loop)
emailBean.setSendTo("Mary")
Result: Sends email to John and Mary


1st Email
emailBean.addHTML("test here")
Result: test here (within body)

2nd Email (2nd loop)
Has no addHTML
Result: test here (within body)

Any ideas?
Andrew Magerman
(at 10:51 on 20.04.2015)
just noticed that Grégory posted exactly the same thing. Aaah!
Andrew Magerman
(at 10:50 on 20.04.2015)
Bug for special characters in the subject line; fix:

emailHeader = emailRoot.createHeader("Subject");
// emailHeader.setHeaderVal(this.getSubject());
emailHeader.addValText(this.getSubject(), "UTF-8");

Per Henrik Lausten
(at 01:52 on 07.09.2014)
I had issues with encoding of special characters too and found out that I needed to both MIME encode the strings and use addValText() but without encoding as UTF-8.
See my answer on Stack Overflow: http://stackoverflow.com/a/25707583/785061
Grégory DEVISE
(at 09:53 on 28.04.2014)
Thank you very much Tony and Ulrich. Very useful code!

I meet problems with accented characters (in the subject, sender etc ...).

The solution that seems to work is to use the method :
emailHeader.addValText(xxx,"UTF-8")
instead of
emailHeader.setHeaderVal(xxx)

(I'm in a french environment / R8.53)
Ulrich Krause
(at 01:47 on 25.05.2012)
I have slightly modified the code. You can now use the bean to send mails from the backend without passing a document

There is also a new addHTML() method, that let you add HTML line by line to the mail.



import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.context.FacesContext;

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import lotus.domino.MIMEEntity;
import lotus.domino.MIMEHeader;
import lotus.domino.NotesException;
import lotus.domino.Session;
import lotus.domino.Stream;

import com.ibm.commons.util.NotImplementedException;
import com.ibm.domino.xsp.module.nsf.NotesContext;
import com.ibm.xsp.model.FileRowData;
import com.ibm.xsp.model.domino.wrapped.DominoDocument;
import com.ibm.xsp.model.domino.wrapped.DominoRichTextItem;
import com.ibm.xsp.model.domino.wrapped.DominoDocument.AttachmentValueHolder;
import com.ibm.xsp.persistence.PersistedContent;

public class EMail {

private ArrayList<String> sendTo;
private ArrayList<String> ccList;
private ArrayList<String> bccList;
//UK: 25.04.2012 added contentList
private StringBuilder contentList;
private String senderEmail;
private String senderName;
private String subject;

private DominoDocument document;
private String fieldName;
//UK: 25.04.2012 modified, set default value to an empty string
//otherwise, if bannerHTML and footerHTML are not set, NULL is added to the mail document
private String bannerHTML = "";
private String footerHTML = "";

private boolean debugMode = false;

private static final Pattern imgRegExp = Pattern.compile("<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>");

//UK: 25.04.2012 added. The bean can be called from within another java class then
public static final String BEAN_NAME = "email"; // name of the bean
public static EMail get() {
FacesContext context = FacesContext.getCurrentInstance();
EMail bean = (EMail) context.getApplication().getVariableResolver().resolveVariable(context, BEAN_NAME);
return bean;
}

// -------------------------------------------------------------------------

public EMail() {
this.subject = "";
this.sendTo = new ArrayList<String>();
this.ccList = new ArrayList<String>();
this.bccList = new ArrayList<String>();
//UK: 25.04.2012 added
this.contentList = new StringBuilder();
}

// -------------------------------------------------------------------------

public String getSendTo() {
if (this.isDebugMode()) {
System.out.println("getSendTo() : " + this.sendTo.toString());
}
return this.sendTo.toString().replace("[", "").replace("]", "");
}

public void setSendTo(final String sendTo) {
this.sendTo.add(sendTo);
}

// -------------------------------------------------------------------------

public String getCcList() {
if (this.isDebugMode()) {
System.out.println("getCcList() : " + this.ccList.toString());
}
return this.ccList.toString().replace("[", "").replace("]", "");
}

public void setCcList(final String ccList) {
this.ccList.add(ccList);
}

// -------------------------------------------------------------------------

public String getBccList() {
if (this.isDebugMode()) {
System.out.println("getBccList() : " + this.bccList.toString());
}
return this.bccList.toString().replace("[", "").replace("]", "");
}

public void setBccList(final String bccList) {
this.bccList.add(bccList);
}

// -------------------------------------------------------------------------

public String getSenderEmail() {
return this.senderEmail;
}

public void setSenderEmail(final String senderEmail) {
this.senderEmail = senderEmail;
}

// -------------------------------------------------------------------------

public String getSenderName() {
return this.senderName;
}

public void setSenderName(final String senderName) {
this.senderName = senderName;
}

// -------------------------------------------------------------------------

public String getSubject() {
return this.subject;
}

public void setSubject(final String subject) {
this.subject = subject;
}

// -------------------------------------------------------------------------

public boolean isDebugMode() {
return this.debugMode;
}

public void setDebugMode(final boolean debugMode) {
this.debugMode = debugMode;
}

// -------------------------------------------------------------------------

private Session getCurrentSession() {
NotesContext nc = NotesContext.getCurrentUnchecked();
return (null != nc) ? nc.getCurrentSession() : null;
}

// -------------------------------------------------------------------------

private Database getCurrentDatabase() {
NotesContext nc = NotesContext.getCurrentUnchecked();
return (null != nc) ? nc.getCurrentDatabase() : null;
}

// -------------------------------------------------------------------------

public void send() throws NotesException, IOException, Exception {
Session session = getCurrentSession();
Database database = getCurrentDatabase();
if (this.isDebugMode()) {
System.out.println("Started send()");
}
if (null != session && null != database && null != this.sendTo && null != this.subject
&& null != this.senderEmail) {
try {

session.setConvertMime(false);
Document emailDocument = database.createDocument();

MIMEEntity emailRoot = emailDocument.createMIMEEntity("Body");

if (null != emailRoot) {
MIMEHeader emailHeader = emailRoot.createHeader("Reply-To");
emailHeader.setHeaderVal(this.getSenderEmail());

emailHeader = emailRoot.createHeader("Return-Path");
emailHeader.setHeaderVal(this.getSenderEmail());

final String fromSender = (null == this.getSenderName()) ? this.getSenderEmail() : "\""
+ this.getSenderName() + "\" <" + this.getSenderEmail() + ">";

emailHeader = emailRoot.createHeader("From");
emailHeader.setHeaderVal(fromSender);

emailHeader = emailRoot.createHeader("Sender");
emailHeader.setHeaderVal(fromSender);

emailHeader = emailRoot.createHeader("To");
emailHeader.setHeaderVal(this.getSendTo());

if (!this.ccList.isEmpty()) {
emailHeader = emailRoot.createHeader("CC");
emailHeader.setHeaderVal(this.getCcList());
}

if (!this.bccList.isEmpty()) {
emailHeader = emailRoot.createHeader("BCC");
emailHeader.setHeaderVal(this.getBccList());
}

emailHeader = emailRoot.createHeader("Subject");
emailHeader.setHeaderVal(this.getSubject());

MIMEEntity emailRootChild = emailRoot.createChildEntity();
if (null != emailRootChild) { //UK: 25.04.2012 modified
String boundary = System.currentTimeMillis() + "- CV2" + System.currentTimeMillis();
if (null != this.document) {
boundary = System.currentTimeMillis() + "-" + this.document.getDocumentId();
}
emailHeader = emailRootChild.createHeader("Content-Type");
emailHeader.setHeaderVal("multipart/alternative; boundary=\"" + boundary + "\"");

MIMEEntity emailChild = emailRootChild.createChildEntity();
if (null != emailChild) {
String contentAsText = "";
if (null != this.document) {
contentAsText = this.document.getRichTextItem(this.fieldName).getContentAsText();
}
Stream stream = session.createStream();
stream.writeText(contentAsText);
emailChild.setContentFromText(stream, "text/plain; charset=\"UTF-8\"", MIMEEntity.ENC_NONE);
stream.close();

emailChild = emailRootChild.createChildEntity();
stream = session.createStream();
stream.writeText(this.getHTML());
emailChild.setContentFromText(stream, "text/html; charset=\"UTF-8\"", MIMEEntity.ENC_NONE);
stream.close();
stream.recycle();
stream = null;
}

// add embedded images....
final List<FileRowData> embeddedImages = this.getEmbeddedImagesList();
if (null != embeddedImages && !embeddedImages.isEmpty()) {
if (this.isDebugMode()) {
System.out.println("Adding Embedded Images...");
}
for (FileRowData embeddedImage : embeddedImages) {
emailRootChild = emailRoot.createChildEntity();
if (null != emailRootChild && embeddedImage instanceof AttachmentValueHolder) {
InputStream is = null;
try {
String persistentName = ((AttachmentValueHolder) embeddedImage)
.getPersistentName();
String cid = ((AttachmentValueHolder) embeddedImage).getCID();
emailHeader = emailRootChild.createHeader("Content-Disposition");
emailHeader.setHeaderVal("inline; filename=\"" + persistentName + "\"");
emailHeader = emailRootChild.createHeader("Content-ID");
emailHeader.setHeaderVal("<" + cid + ">");
is = this.getEmbeddedImageStream(persistentName);
Stream stream = session.createStream();
stream.setContents(is);
emailRootChild.setContentFromBytes(stream, embeddedImage.getType(),
MIMEEntity.ENC_IDENTITY_BINARY);
if (this.isDebugMode()) {
System.out.println("Added Embedded Image : " + persistentName);
}
} catch (IOException e) {
if (this.isDebugMode()) {
System.out.println("Adding Embedded Image failed : " + e.getMessage());
}
throw e;
} finally {
if (null != is) {
is.close();
is = null;
}
}
}
}
if (this.isDebugMode()) {
System.out.println("Completed Adding Embedded Images");
}
}

if (null != this.document) { //UK: 25.04.2012 added
// add attachments....
final List<FileRowData> attachments = this.getDocument().getAttachmentList(
this.getFieldName());
if (null != attachments && !attachments.isEmpty()) {
if (this.isDebugMode()) {
System.out.println("Adding Attachments...");
}
for (FileRowData attachment : attachments) {
emailRootChild = emailRoot.createChildEntity();
if (null != emailRootChild && attachment instanceof AttachmentValueHolder) {
InputStream is = null;
try {
String persistentName = ((AttachmentValueHolder) attachment)
.getPersistentName();
String cid = ((AttachmentValueHolder) attachment).getCID();
EmbeddedObject eo = this.getDocument().getDocument().getAttachment(
persistentName);
if (null != eo) {
emailHeader = emailRootChild.createHeader("Content-Disposition");
emailHeader.setHeaderVal("attachment; filename=\"" + persistentName
+ "\"");
emailHeader = emailRootChild.createHeader("Content-ID");
emailHeader.setHeaderVal("<" + cid + ">");
is = eo.getInputStream();
Stream stream = session.createStream();
stream.setContents(is);
emailRootChild.setContentFromBytes(stream, attachment.getType(),
MIMEEntity.ENC_IDENTITY_BINARY);
if (this.isDebugMode()) {
System.out.println("Added Attachment : " + persistentName);
}
}
} catch (Exception e) {
if (this.isDebugMode()) {
System.out.println("Adding Attachment failed : " + e.getMessage());
}
throw e;
} finally {
if (null != is) {
is.close();
is = null;
}
}
}
}
if (this.isDebugMode()) {
System.out.println("Completed Adding Attachments");
}
}
}
}
}

emailDocument.send();
session.setConvertMime(true);
if (this.isDebugMode()) {
System.out.println("Completed send()");
}
} catch (NotesException e) {
if (this.isDebugMode()) {
System.out.println("Failed send() with NotesException" + e.getMessage());
}
throw e;
} catch (IOException e) {
if (this.isDebugMode()) {
System.out.println("Failed send() with IOException" + e.getMessage());
}
throw e;
} catch (Exception e) {
if (this.isDebugMode()) {
System.out.println("Failed send() with Exception" + e.getMessage());
}
throw e;
}
}
}

// -------------------------------------------------------------------------

public DominoDocument getDocument() {
return this.document;
}

public void setDocument(final DominoDocument document) {
this.document = document;
}

// -------------------------------------------------------------------------

public String getFieldName() {
return this.fieldName;
}

public void setFieldName(final String fieldName) {
this.fieldName = fieldName;
}

// -------------------------------------------------------------------------

public List<FileRowData> getEmbeddedImagesList() throws NotesException {
if (null != document && null != fieldName) {
return document.getEmbeddedImagesList(fieldName);
}
return null;
}

// -------------------------------------------------------------------------

private InputStream getEmbeddedImageStream(final String fileName) throws NotesException, IOException {
if (null != document && null != fieldName && null != fileName) {
final DominoRichTextItem drti = document.getRichTextItem(fieldName);
if (null != drti) {
final PersistedContent pc = drti.getPersistedContent(FacesContext.getCurrentInstance(), fieldName,
fileName);
if (null != pc) {
return pc.getInputStream();
}
}
}
return null;
}

// -------------------------------------------------------------------------

public String getHTML() {
StringBuffer html = new StringBuffer();
html.append(getBannerHTML());
//UK: 25.04.2012 modified
if (null != getBodyHTML()) {
html.append(getBodyHTML());
}
//UK: 25.04.2012 added
html.append(getContentHTML());
html.append(getFooterHTML());
return html.toString();
}

// -------------------------------------------------------------------------

public String getBannerHTML() {
return this.bannerHTML;
}

public void setBannerHTML(final String bannerHTML) {
this.bannerHTML = bannerHTML;
}

// -------------------------------------------------------------------------

//UK: 25.04.2012 modified
public String getContentHTML() {
if (this.isDebugMode()) {
System.out.println("Started getContentHTML()");
System.out.println(this.contentList.toString());
}
return this.contentList.toString();
}
//UK: 25.04.2012 modified
public void setContentHTML(final String contentHTML) {
this.contentList.append(contentHTML);
}

// -------------------------------------------------------------------------
//UK: 25.04.2012 added
public void addHTML(final String contentHTML) {
this.contentList.append(contentHTML);
}

// -------------------------------------------------------------------------

public String getBodyHTML() {
if (null != document && null != fieldName) {
if (this.isDebugMode()) {
System.out.println("Started getBodyHTML()");
}
final DominoRichTextItem drti = document.getRichTextItem(fieldName);
if (null != drti) {
try {
String html = drti.getHTML();
if (null != html) {
final List<FileRowData> fileRowDataList = document.getEmbeddedImagesList(fieldName);
if (null != fileRowDataList) {
final Matcher matcher = imgRegExp.matcher(html);
while (matcher.find()) {
String src = matcher.group();
final String srcToken = "src=\"";
final int x = src.indexOf(srcToken);
final int y = src.indexOf("\"", x + srcToken.length());
final String srcText = src.substring(x + srcToken.length(), y);
for (FileRowData fileRowData : fileRowDataList) {
final String srcImage = fileRowData.getHref();
final String cidImage = ((AttachmentValueHolder) fileRowData).getCID();
if (srcText.endsWith(srcImage)) {
final String newSrc = src.replace(srcText, "cid:" + cidImage);
html = html.replace(src, newSrc);
if (this.isDebugMode()) {
System.out.println("CID referenced image: " + srcText + " with CID:"
+ cidImage);
}
}
}
}
}
}
if (this.isDebugMode()) {
System.out.println("Completed getBodyHTML() : " + html);
}
return html;
} catch (Exception e) {
if (this.isDebugMode()) {
System.out.println("Failed getBodyHTML() : " + e.getMessage());
}
}
}
}
return "";
}

@Deprecated
public void setBodyHTML(final String bodyHTML) throws NotImplementedException {
if (this.isDebugMode()) {
System.out.println("Method setBodyHTML(string) is not permitted");
}
throw new NotImplementedException();
}

// -------------------------------------------------------------------------

public String getFooterHTML() {
return this.footerHTML;
}

public void setFooterHTML(final String footerHTML) {
this.footerHTML = footerHTML;
}

// -------------------------------------------------------------------------

} // end EmailBean