com.alkacon.opencms.newsletter.A_CmsNewsletterMailData.java Source code

Java tutorial

Introduction

Here is the source code for com.alkacon.opencms.newsletter.A_CmsNewsletterMailData.java

Source

/*
 * File   : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.newsletter/src/com/alkacon/opencms/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.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.newsletter.I_CmsNewsletterMailData#getEmail()
     */
    public abstract Email getEmail() throws CmsException;

    /**
     * @see com.alkacon.opencms.newsletter.I_CmsNewsletterMailData#getEmailContentPreview()
     */
    public String getEmailContentPreview() throws CmsException {

        return getEmailContentPreview(false);
    }

    /**
     * @see com.alkacon.opencms.newsletter.I_CmsNewsletterMailData#getEmailContentPreview(boolean)
     */
    public abstract String getEmailContentPreview(boolean onlyPartialHtml) throws CmsException;

    /**
     * @see com.alkacon.opencms.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.newsletter.I_CmsNewsletterMailData#getResourceTypeName()
     */
    public abstract String getResourceTypeName();

    /**
     * @see com.alkacon.opencms.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.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.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.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.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);
    }
}