/*
* File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.newsletter/src/com/alkacon/opencms/newsletter/CmsNewsletterMailData.java,v $
* Date : $Date: 2010/10/14 13:17:49 $
* Version: $Revision: 1.10 $
*
* This file is part of the Alkacon OpenCms Add-On Module Package
*
* Copyright (c) 2007 Alkacon Software GmbH (http://www.alkacon.com)
*
* The Alkacon OpenCms Add-On Module Package 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, either version 3 of the License, or
* (at your option) any later version.
*
* The Alkacon OpenCms Add-On Module Package 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 the Alkacon OpenCms Add-On Module Package.
* If not, see http://www.gnu.org/licenses/.
*
* For further information about Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com.
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org.
*/
package com.alkacon.opencms.newsletter;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsGroup;
import org.opencms.file.CmsResource;
import org.opencms.jsp.CmsJspActionElement;
import org.opencms.mail.CmsHtmlMail;
import org.opencms.mail.CmsSimpleMail;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.util.CmsHtmlExtractor;
import org.opencms.util.CmsStringUtil;
import org.opencms.xml.content.CmsXmlContent;
import org.opencms.xml.content.CmsXmlContentFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
/**
* Generates newsletter emails and the list of recipients from a newsletter structured content VFS file.<p>
*
* Provides some utility methods to generate email previews and get the email contents as string.<p>
*
* @author Andreas Zahner
*
* @version $Revision: 1.10 $
*
* @since 7.0.3
*/
public class CmsNewsletterMailData extends A_CmsNewsletterMailData {
/** Resource type name of a newsletter resource. */
public static final String RESOURCETYPE_NEWSLETTER_NAME = "alkacon-newsletter";
/** The node name for the ConfFile node. */
protected static final String NODE_CONFFILE = "ConfFile";
/** The node name for the HTML node. */
protected static final String NODE_HTML = "Html";
/** The node name for the HTML Only node. */
protected static final String NODE_HTML_ONLY = "HtmlOnly";
/** The node name for the MailFoot node. */
protected static final String NODE_MAILFOOT = "MailFoot";
/** The node name for the MailHead node. */
protected static final String NODE_MAILHEAD = "MailHead";
/** The node name for the Text node. */
protected static final String NODE_TEXT = "Text";
/** The xpath for the Config node including trailing "/". */
protected static final String XPATH_CONFIG = "Config/";
/** The log object for this class. */
private static final Log LOG = CmsLog.getLog(CmsNewsletterMailData.class);
/** The email HTML text. */
private String m_html;
/** Indicates if the mail is a HTML or text mail. */
private Boolean m_htmlMail;
private Boolean m_htmlOnly;
/** The email plain text. */
private String m_text;
/**
* Empty constructor.<p>
*
* Be sure to call {@link #initialize(CmsJspActionElement, CmsGroup, String)} to get correct results.<p>
*/
public CmsNewsletterMailData() {
// noop
}
/**
* Constructor, with parameters.<p>
*
* @param fileName the fileName of the newsletter
* @param group the group to send the newsletter to
* @param jsp the JSP action element
* @throws CmsException if reading or unmarshalling the file fails
*/
public CmsNewsletterMailData(String fileName, CmsGroup group, CmsJspActionElement jsp)
throws CmsException {
initialize(jsp, group, fileName);
}
/**
* Returns the mail to send as newsletter, with set subject, text and from address.<p>
*
* @return the mail to send as newsletter
* @throws CmsException if generating the email content fails
*/
@Override
public Email getEmail() throws CmsException {
// get the email data from the content fields
String from = getFrom();
String fromName = getFromName();
String subject = getSubject();
if (isHtmlMail()) {
// create and send HTML email
CmsHtmlMail mail = new CmsHtmlMail();
try {
if (CmsStringUtil.isEmptyOrWhitespaceOnly(fromName)) {
mail.setFrom(from);
} else {
mail.setFrom(from, fromName);
}
} catch (EmailException e) {
// log invalid from email address
if (LOG.isErrorEnabled()) {
LOG.error(Messages.get().getBundle().key(
Messages.LOG_ERROR_NEWSLETTER_EMAIL_FROM_2,
from,
getContent().getFile().getRootPath()));
}
}
mail.setSubject(subject);
try {
// create the email content and use it as HTML message
mail.setHtmlMsg(getHtml());
// check if HTML only mail should be sent by evaluating the optional element
if (!isHtmlOnly()) {
mail.setTextMsg(getText());
}
} catch (EmailException e) {
// ignore, error creating email texts
}
// set the mail encoding
mail.setCharset(getEncoding());
return mail;
} else {
// create and send text only email
CmsSimpleMail mail = new CmsSimpleMail();
try {
if (CmsStringUtil.isEmptyOrWhitespaceOnly(fromName)) {
mail.setFrom(from);
} else {
mail.setFrom(from, fromName);
}
} catch (EmailException e) {
// log invalid from email address
if (LOG.isErrorEnabled()) {
LOG.error(Messages.get().getBundle().key(
Messages.LOG_ERROR_NEWSLETTER_EMAIL_FROM_2,
from,
getContent().getFile().getRootPath()));
}
}
mail.setSubject(subject);
// extract the text from the HTML field
try {
mail.setMsg(getText());
} catch (Exception e) {
// cleaning text failed or setting text failed
}
// set the mail encoding
mail.setCharset(getEncoding());
return mail;
}
}
/**
* @see com.alkacon.opencms.newsletter.I_CmsNewsletterMailData#getEmailContentPreview(boolean)
*/
@Override
public String getEmailContentPreview(boolean onlyPartialHtml) throws CmsException {
boolean isHtmlMail = Boolean.valueOf(
getContent().getStringValue(getCms(), XPATH_CONFIG + NODE_HTML, getLocale())).booleanValue();
String result = getEmailContent(isHtmlMail, onlyPartialHtml);
if ((result.indexOf("</body>") == -1) && !onlyPartialHtml) {
StringBuffer previewHtml = new StringBuffer(result.length() + 256);
previewHtml.append("<html><head></head><body style=\"background-color: #FFF;\">\n<pre style=\"font-family: Courier New, monospace; font-size: 13px; color: #000;\">");
previewHtml.append(result);
previewHtml.append("</pre>\n</body></html>");
result = previewHtml.toString();
}
return result;
}
/**
* @see com.alkacon.opencms.newsletter.I_CmsNewsletterMailData#getResourceTypeName()
*/
@Override
public String getResourceTypeName() {
return RESOURCETYPE_NEWSLETTER_NAME;
}
/**
* Returns the email content from the newsletter VFS file.<p>
*
* @param isHtmlMail flag to determine if HTML or plain text content should be generated
* @param onlyPartialHtml sets if only page parts should be returned instead of a complete HTML page
*
* @return the email content
*
* @throws CmsException if reading or unmarshalling the file fails
*/
protected String getEmailContent(boolean isHtmlMail, boolean onlyPartialHtml) throws CmsException {
String text = getContent().getStringValue(getCms(), NODE_TEXT, getLocale());
if (isHtmlMail) {
// create the content of the HTML mail
StringBuffer mailHtml = new StringBuffer(4096);
String mailHead = "";
String mailFoot = "";
if (!onlyPartialHtml) {
// get mail head and foot HTML if complete HTML page content should be generated
boolean foundExternalConfig = false;
if (getContent().hasValue(XPATH_CONFIG + NODE_CONFFILE, getLocale())) {
// optional external configuration file specified, use this as mail configuration
String path = getContent().getStringValue(getCms(), XPATH_CONFIG + NODE_CONFFILE, getLocale());
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(path)
&& getCms().existsResource(path)
&& !CmsResource.isFolder(path)) {
CmsFile mailConfig = getCms().readFile(path);
CmsXmlContent mailContent = CmsXmlContentFactory.unmarshal(getCms(), mailConfig);
// get the mail head and foot from the external configuration file content
if (mailContent.hasValue(NODE_MAILHEAD, getLocale())) {
mailHead = mailContent.getStringValue(getCms(), NODE_MAILHEAD, getLocale());
mailFoot = mailContent.getStringValue(getCms(), NODE_MAILFOOT, getLocale());
foundExternalConfig = true;
}
}
}
if (!foundExternalConfig) {
// no external configuration specified, use internal configuration values
mailHead = getContent().getStringValue(getCms(), XPATH_CONFIG + NODE_MAILHEAD, getLocale());
mailFoot = getContent().getStringValue(getCms(), XPATH_CONFIG + NODE_MAILFOOT, getLocale());
}
}
mailHtml.append(mailHead);
mailHtml.append(text);
mailHtml.append(mailFoot);
// resolve eventual macros in result
return resolveMacros(mailHtml.toString());
} else {
// create the content of the text mail
try {
return CmsHtmlExtractor.extractText(text, getCms().getRequestContext().getEncoding());
} catch (Exception e) {
// error extracting text, return unmodified text
return text;
}
}
}
/**
* @see com.alkacon.opencms.newsletter.A_CmsNewsletterMailData#getHtml()
*/
@Override
protected String getHtml() throws CmsException {
if (m_html == null) {
m_html = getEmailContent(true, false);
}
return m_html;
}
/**
* @see com.alkacon.opencms.newsletter.A_CmsNewsletterMailData#getText()
*/
@Override
protected String getText() throws CmsException {
if (m_text == null) {
m_text = getEmailContent(false, false);
}
return m_text;
}
/**
* Returns if the mail is a HTML mail.<p>
*
* @return true if the mail is a HTML mail, otherwise false
*/
protected boolean isHtmlMail() {
if (m_htmlMail == null) {
m_htmlMail = Boolean.valueOf(getContent().getStringValue(getCms(), XPATH_CONFIG + NODE_HTML, getLocale()));
}
return m_htmlMail.booleanValue();
}
/**
* Returns if the mail is a HTML only mail.<p>
*
* @return true if the mail is a HTML only mail, otherwise false
*/
protected boolean isHtmlOnly() {
if (m_htmlOnly == null) {
m_htmlOnly = Boolean.valueOf(getContent().getStringValue(
getCms(),
XPATH_CONFIG + NODE_HTML_ONLY,
getLocale()));
}
return m_htmlOnly.booleanValue();
}
}