/* * File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.v8.newsletter/src/com/alkacon/opencms/v8/newsletter/A_CmsNewsletterMailData.java,v $ * Date : $Date: 2010/10/14 13:17:50 $ * 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.v8.newsletter; import org.opencms.file.CmsFile; import org.opencms.file.CmsGroup; import org.opencms.file.CmsObject; import org.opencms.file.CmsProperty; import org.opencms.file.CmsUser; import org.opencms.jsp.CmsJspActionElement; import org.opencms.lock.CmsLock; import org.opencms.main.CmsException; import org.opencms.main.CmsLog; import org.opencms.main.OpenCms; import org.opencms.module.CmsModule; import org.opencms.security.CmsOrganizationalUnit; import org.opencms.security.CmsRole; import org.opencms.util.CmsMacroResolver; import org.opencms.xml.content.CmsXmlContent; import org.opencms.xml.content.CmsXmlContentFactory; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; import javax.mail.MessagingException; import javax.mail.internet.InternetAddress; import org.apache.commons.logging.Log; import org.apache.commons.mail.Email; /** * Basic implementation to generate newsletter emails and the list of recipients from a newsletter structured content VFS file.<p> * * @author Andreas Zahner * * @version $Revision: 1.10 $ * * @since 7.0.3 */ public abstract class A_CmsNewsletterMailData implements I_CmsNewsletterMailData { /** The macro name for the "siteurl" macro. */ protected static final String MACRO_SITEURL = "siteurl"; /** The macro name for the "title" macro. */ protected static final String MACRO_TITLE = "title"; /** The node name for the BCC node. */ protected static final String NODE_BCC = "BCC"; /** The node name for the From node. */ protected static final String NODE_FROM = "From"; /** The node name for the From name node. */ protected static final String NODE_FROM_NAME = "FromName"; /** The node name for the Subject node. */ protected static final String NODE_SUBJECT = "Subject"; /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(A_CmsNewsletterMailData.class); /** The OpenCms user context. */ private CmsObject m_cms; /** The newsletter content. */ private CmsXmlContent m_content; /** The email encoding. */ private String m_encoding; /** The email from address. */ private String m_from; /** The email from name. */ private String m_fromName; /** The group to send the newsletter to. */ private CmsGroup m_group; /** The JSP action element. */ private CmsJspActionElement m_jsp; /** The Locale to use to read the newsletter content. */ private Locale m_locale; /** The organizational unit to send the newsletter to. */ private CmsOrganizationalUnit m_ou; /** The list of recipients to send the newsletter to. */ private List<InternetAddress> m_recipients; /** The email subject. */ private String m_subject; /** * Returns the newsletter XML content.<p> * * @return the newsletter XML content */ public CmsXmlContent getContent() { return m_content; } /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#getEmail() */ public abstract Email getEmail() throws CmsException; /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#getEmailContentPreview() */ public String getEmailContentPreview() throws CmsException { return getEmailContentPreview(false); } /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#getEmailContentPreview(boolean) */ public abstract String getEmailContentPreview(boolean onlyPartialHtml) throws CmsException; /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#getRecipients() */ public List<InternetAddress> getRecipients() throws CmsException { if (m_recipients != null) { // we have explicitly set recipients, use these return m_recipients; } // we have a group or an OU to check for recipients List<InternetAddress> recipients = new ArrayList<InternetAddress>(); Iterator<CmsUser> i = new ArrayList<CmsUser>().iterator(); String groupName = ""; if (getGroup() != null) { // iterate over mailing list members (i.e. an OpenCms group) groupName = getGroup().getName(); i = getCms().getUsersOfGroup(groupName).iterator(); } else if (getOu() != null) { i = getOuUsers().iterator(); } while (i.hasNext()) { CmsUser user = i.next(); if (CmsNewsletterManager.isActiveUser(user, groupName)) { // add active users to the recipients try { recipients.add(new InternetAddress(user.getEmail())); } catch (MessagingException e) { // log invalid email address if (LOG.isErrorEnabled()) { LOG.error(Messages.get().getBundle().key( Messages.LOG_ERROR_NEWSLETTER_EMAIL_3, user.getEmail(), user.getName(), getContent().getFile().getRootPath())); } } } } if (getContent().hasValue(NODE_BCC, getLocale())) { // add the configured email address to the list of BCC recipients try { recipients.add(new InternetAddress(getContent().getStringValue(getCms(), NODE_BCC, getLocale()))); } catch (MessagingException e) { // log invalid email address if (LOG.isErrorEnabled()) { LOG.error(Messages.get().getBundle().key( Messages.LOG_ERROR_NEWSLETTER_EMAIL_BCC_2, getContent().getStringValue(getCms(), NODE_BCC, getLocale()), getContent().getFile().getRootPath())); } } } return recipients; } /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#getResourceTypeName() */ public abstract String getResourceTypeName(); /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#initialize(org.opencms.jsp.CmsJspActionElement, org.opencms.file.CmsGroup, java.lang.String) */ public void initialize(CmsJspActionElement jsp, CmsGroup group, String fileName) throws CmsException { initialize(jsp, group, null, null, fileName); } /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#initialize(org.opencms.jsp.CmsJspActionElement, org.opencms.security.CmsOrganizationalUnit, java.lang.String) */ public void initialize(CmsJspActionElement jsp, CmsOrganizationalUnit ou, String fileName) throws CmsException { initialize(jsp, null, ou, null, fileName); } /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#initialize(CmsJspActionElement, List, String) */ public void initialize(CmsJspActionElement jsp, List<InternetAddress> recipients, String fileName) throws CmsException { initialize(jsp, null, null, recipients, fileName); } /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#isSendable() */ public boolean isSendable() throws CmsException { if (m_recipients == null) { // we have a group or OU to send the newsletter to, store send information CmsFile file = getContent().getFile(); String resourceName = getCms().getSitePath(file); CmsLock lock = getCms().getLock(file); boolean unLocked = false; if (lock.isNullLock()) { unLocked = true; getCms().lockResource(resourceName); lock = getCms().getLock(file); } if (lock.isOwnedBy(getCms().getRequestContext().currentUser())) { // resource is locked by current user, write send information String value = String.valueOf(System.currentTimeMillis()) + CmsProperty.VALUE_LIST_DELIMITER; if (getGroup() != null) { value += getGroup().getId(); CmsModule module = OpenCms.getModuleManager().getModule(CmsNewsletterManager.MODULE_NAME); ((CmsNewsletterManager)module.getActionInstance()).saveSentNewsletterInfo( getGroup().getId(), file.getStructureId()); } else if (getOu() != null) { value += "ou:" + getOu().getName(); } CmsProperty property = new CmsProperty(CmsNewsletterManager.PROPERTY_NEWSLETTER_DATA, value, null, true); getCms().writePropertyObject(resourceName, property); try { getCms().unlockResource(resourceName); unLocked = false; OpenCms.getPublishManager().publishResource(getCms(), resourceName); } catch (Exception e) { // unlocking and publishing failed maybe a parent folder is locked } } else { // resource is not locked by current user return false; } if (unLocked) { getCms().unlockResource(resourceName); } } return true; } /** * @see com.alkacon.opencms.v8.newsletter.I_CmsNewsletterMailData#setRecipients(java.util.List) */ public void setRecipients(List<InternetAddress> recipients) { m_recipients = recipients; } /** * Returns the OpenCms user context.<p> * * @return the OpenCms user context */ protected CmsObject getCms() { return m_cms; } /** * Returns the email encoding.<p> * * @return the email encoding */ protected String getEncoding() { if (m_encoding == null) { m_encoding = getCms().getRequestContext().getEncoding(); } return m_encoding; } /** * Returns the email from address.<p> * * @return the email from address */ protected String getFrom() { if (m_from == null) { m_from = getContent().getStringValue(getCms(), NODE_FROM, getLocale()); } return m_from; } /** * Returns the email from address.<p> * * @return the email from address */ protected String getFromName() { if (m_fromName == null) { m_fromName = getContent().getStringValue(getCms(), NODE_FROM_NAME, getLocale()); } return m_fromName; } /** * Returns the group to send the newsletter to.<p> * * @return the group to send the newsletter to */ protected CmsGroup getGroup() { return m_group; } /** * Returns the email HTML text.<p> * * @return the email HTML text * @throws CmsException if extracting HTML text fails */ protected abstract String getHtml() throws CmsException; /** * Returns the JSP action element.<p> * * @return the JSP action element */ protected CmsJspActionElement getJsp() { return m_jsp; } /** * Returns the Locale to use to read the newsletter content.<p> * * @return the Locale to use to read the newsletter content */ protected Locale getLocale() { return m_locale; } /** * Returns the organizational unit to send the newsletter to.<p> * * @return the organizational unit to send the newsletter to */ protected CmsOrganizationalUnit getOu() { return m_ou; } /** * Returns the users for the current OU and all sub OUs which are no web user or newsletter units.<p> * * @return the users for the current OU and all sub OUs */ protected List<CmsUser> getOuUsers() { List<CmsUser> result = new ArrayList<CmsUser>(128); try { List<CmsOrganizationalUnit> units = OpenCms.getRoleManager().getOrgUnitsForRole( getCms(), CmsRole.ACCOUNT_MANAGER.forOrgUnit(getOu().getName()), true); for (Iterator<CmsOrganizationalUnit> i = units.iterator(); i.hasNext();) { CmsOrganizationalUnit ou = i.next(); if (!ou.hasFlagWebuser() && !ou.getSimpleName().startsWith(CmsNewsletterManager.NEWSLETTER_OU_NAMEPREFIX)) { result.addAll(OpenCms.getOrgUnitManager().getUsers(getCms(), ou.getName(), false)); } } } catch (CmsException e) { // log error if (LOG.isErrorEnabled()) { LOG.error(Messages.get().getBundle().key( Messages.LOG_ERROR_NEWSLETTER_UNITS_2, getCms().getRequestContext().currentUser(), getOu().getName())); } } return result; } /** * Returns the email subject.<p> * * @return the email subject */ protected String getSubject() { if (m_subject == null) { m_subject = getContent().getStringValue(getCms(), NODE_SUBJECT, getLocale()); } return m_subject; } /** * Returns the email plain text.<p> * * @return the email plain text * @throws CmsException if extracting text fails */ protected abstract String getText() throws CmsException; /** * Returns the input with resolved macros.<p> * * @param input the input to resolve * @return the input with resolved macros */ protected String resolveMacros(String input) { CmsMacroResolver resolver = CmsMacroResolver.newInstance().setCmsObject(getCms()).setKeepEmptyMacros(false); resolver.addMacro(MACRO_SITEURL, OpenCms.getSiteManager().getCurrentSite(getCms()).getUrl()); resolver.addMacro(MACRO_TITLE, getSubject()); return resolver.resolveMacros(input); } /** * Initializes the necessary members to generate the email and the list of recipients.<p> * * To make the newsletter work as expected, exactly one parameter of group, organizational unit or * list of recipients should not be <code>null</code>.<p> * * @param jsp the current action element * @param group the mailing list group to send the newsletter to * @param ou the organizational unit to send the newsletter to * @param recipients the recipients of the newsletter mail, items have to be of type {@link javax.mail.internet.InternetAddress} * @param fileName the fileName of a VFS file that can be used to generate the newsletter * @throws CmsException if reading the VFS file fails */ private void initialize( CmsJspActionElement jsp, CmsGroup group, CmsOrganizationalUnit ou, List<InternetAddress> recipients, String fileName) throws CmsException { m_cms = jsp.getCmsObject(); CmsFile file = getCms().readFile(fileName); m_content = CmsXmlContentFactory.unmarshal(getCms(), file); m_group = group; m_ou = ou; m_recipients = recipients; m_jsp = jsp; m_locale = initializeLocale(file); } /** * Initializes the locale. Either the request locale parameter has to match one of the xmlcontent locales. * Or the default locale for that resource is taken.<p> * * @param file the file to get the locale for * * @return the locale */ private Locale initializeLocale(CmsFile file) { // unmarshal the xmlcontent CmsXmlContent xmlContent = null; try { xmlContent = CmsXmlContentFactory.unmarshal(getCms(), file); } catch (CmsException e) { // could not unmarshal that resource } // get the locales for that xmlcontent if (xmlContent != null) { List<Locale> locales = xmlContent.getLocales(); if (locales.contains(getCms().getRequestContext().getLocale())) { return getCms().getRequestContext().getLocale(); } } // get the default locale return OpenCms.getLocaleManager().getDefaultLocale(getCms(), file); } }