All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.wcm.notification.email.AbstractEmailBuilder Maven / Gradle / Ivy

/*
 * Copyright 1997-2010 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.cq.wcm.notification.email;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.service.event.Event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.granite.security.user.UserProperties;
import com.adobe.granite.security.user.UserPropertiesManager;
import com.adobe.granite.security.user.UserPropertiesService;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.notification.NotificationContext;

public abstract class AbstractEmailBuilder implements EmailBuilder {

    protected static final String TEMPLATE_ROOT_PATH = "/etc/notification/email/default";
    protected static final String DEFAULT_CONTENT_TYPE = "text/plain; charset=utf-8";
    protected static final String DEFAULT_CHARSET = "UTF-8";
    protected final static String NOTIFICATION_SERVICE = "notification-service";


    protected abstract ResourceResolverFactory getResolverFactory();

    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());

    // -----------< Abstract Methods >-------------

    /**
     * Returns a map of additional email headers to be added to the {@link Email}.
     *
     * @param context The notification context.
     * @param event   The notification event.
     *
     * @return A {@link Map} containing additional email headers.
     */
    protected abstract Map getHeaders(NotificationContext context, Event event);

    /**
     * Returns the subject for the email.
     *
     * @param context    The notification context.
     * @param event      The event.
     * @param properties The text template properties loaded from the repository.
     *
     * @return The subject.
     */
    protected abstract String getSubject(NotificationContext context, Event event, Properties properties);

    /**
     * Returns the message body of the notification email.
     *
     * @param context    The notification context.
     * @param event      The notification event.
     * @param properties The text template properties loaded from the repository.
     *
     * @return The email body / message.
     */
    protected abstract String getMessage(NotificationContext context, Event event, Properties properties);

    /**
     * Return the content type.
     * @return the content type.
     */
    protected String getContentType() {
    	return DEFAULT_CONTENT_TYPE;
    }

    /**
     * Return the charset.
     * @return the charset.
     */
    protected String getCharset() {
        return DEFAULT_CHARSET;
    }

    /**
     * Return the template root path.
     * @return the template root path.
     */
    protected String getTemplateRootPath() {
    	return TEMPLATE_ROOT_PATH;
    }
    
    /**
     * {@inheritDoc}
     */
    public boolean shouldBuild(final NotificationContext context, final Event event) {
        return true;
    }
    
    public abstract Repository getRepository();
    
    /**
     * {@inheritDoc}
     */
    public Email build(final NotificationContext context, final Event event, final String addressFrom) {

        Email email = null;
        String addressTo = null;
        Session userSession = null;
        ResourceResolver resolver = null;
        try {
        	final SimpleCredentials credentials = new SimpleCredentials(context.getAuthorizable().getID(), new char[0]);
            userSession = ((SlingRepository) this.getRepository()).impersonateFromService(NOTIFICATION_SERVICE, credentials, null);
            resolver = getResolverFactory()
                    .getResourceResolver(Collections.singletonMap("user.jcr.session", (Object) userSession));
            final UserPropertiesManager userPropertiesManager = resolver.adaptTo(UserPropertiesManager.class);
            final UserProperties userProps =
                    userPropertiesManager.getUserProperties(context.getAuthorizable().getID(), UserPropertiesService.PROFILE_PATH);
            addressTo = userProps.getProperty(UserProperties.EMAIL);
        } catch (LoginException e) {
        	log.error("error obtaining resource resolver: ", e);
        } catch (RepositoryException e) {
        	log.error("error obtaining user properties: ", e);
        } finally {
            if (resolver != null) {
                resolver.close();
            }
            if (userSession != null) {
                userSession.logout();
            }
        }

        if (StringUtils.isNotBlank(addressTo)) {

            final Properties properties;
            try {
                properties = loadEmailProperties(context, event);

                email = new SimpleEmail();

                // email headers
                final Map headerMap = new HashMap();

                headerMap.put("Content-Type", getContentType());
                headerMap.putAll(getHeaders(context, event));

                email.setHeaders(headerMap);
                email.setCharset(getCharset());
                email.addTo(addressTo);
                email.setFrom(StringUtils.defaultIfEmpty(addressFrom, "[email protected]"));
                email.setSubject(getSubject(context, event, properties));

                // email body
                email.setMsg(getMessage(context, event, properties));

                return email;
            } catch (RepositoryException e) {
                log.error("failed building notification email template for user with destination [" + addressTo
                          + "]: {}", e);
            } catch (IOException e) {
                log.error("failed loading email text for user with destination [" + addressTo + "]: {}", e);
            } catch (EmailException e) {
                log.error("failed building email for user with destination [" + addressTo + "]: {}", e);
            }

        } else {
            log.error("failed building notification email, user has no email address set.");
        }

        return email;
    }

    /**
     * Loads the text properties for the email from a file node in the repository.
     *
     * @param context The notification context.
     * @param event   The event.
     *
     * @return A {@link Properties} object with the email text.
     *
     * @throws RepositoryException If loading the file node fails.
     * @throws IOException         If loading the input stream into the properties object fails.
     */
    protected Properties loadEmailProperties(final NotificationContext context, final Event event)
            throws RepositoryException, IOException {
        final Properties properties = new Properties();
        Session userSession = null;
        Session serviceSession = null;
        ResourceResolver resolver = null;
        try {
            final SimpleCredentials credentials = new SimpleCredentials(context.getAuthorizable().getID(), new char[0]);
            userSession = ((SlingRepository) this.getRepository()).impersonateFromService(NOTIFICATION_SERVICE, credentials, null);

            resolver = getResolverFactory()
                    .getResourceResolver(Collections.singletonMap("user.jcr.session", (Object) userSession));
            final UserPropertiesManager userPropertiesManager = resolver.adaptTo(UserPropertiesManager.class);
            final UserProperties preferences =
                    userPropertiesManager.getUserProperties(context.getAuthorizable().getID(), "preferences");

            final String language = null != preferences 
                                    ? StringUtils.defaultIfEmpty(preferences.getProperty("language"), "en") 
                                    : "en";

            String templateRoot = getTemplateRootPath();

            final String path = templateRoot + "/" + event.getTopic().replace('/', '.') + "/" + language + ".txt";
            serviceSession = ((SlingRepository) this.getRepository()).loginService(NOTIFICATION_SERVICE, null);
            final Node node = serviceSession.getNode(path);
            final InputStream is =
                    node.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_DATA).getBinary().getStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, getCharset()));
            properties.load(bufferedReader);
        } catch (LoginException e) {
            log.error("error obtaining resource resolver: ", e);
        } finally {
            if (resolver != null) {
                resolver.close();
            }
            if (userSession != null) {
                userSession.logout();
            }
            if (serviceSession != null) {
                serviceSession.logout();
            }
        }
        return properties;
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy