/*
* Copyright (c) 2010 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.server.action.execution.notification;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.mail.internet.MimeMessage;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.text.StrLookup;
import org.apache.commons.lang.text.StrSubstitutor;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.server.domain.NotificationDTO;
import org.eurekastreams.server.domain.SystemSettings;
import org.eurekastreams.server.domain.stream.BaseObjectType;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.requests.MapperRequest;
import org.eurekastreams.server.search.modelview.PersonModelView;
import org.eurekastreams.server.service.actions.strategies.EmailerFactory;
/**
* Creates notification emails using text templates.
*/
public class TemplateEmailBuilder implements NotificationEmailBuilder
{
/** Contains the text to display for an activity type where it doesn't match the enum name. */
private static Map<BaseObjectType, String> activityTypeDisplayNameOverrides = new HashMap<BaseObjectType, String>();
/** UI profile page names for each entity type. */
private static Map<EntityType, String> entityPageNames = new HashMap<EntityType, String>();
/**
* Initialize constant lookup data.
*/
static
{
activityTypeDisplayNameOverrides.put(BaseObjectType.BOOKMARK, "link");
activityTypeDisplayNameOverrides.put(BaseObjectType.NOTE, "message");
entityPageNames.put(EntityType.PERSON, "people");
entityPageNames.put(EntityType.GROUP, "groups");
entityPageNames.put(EntityType.ORGANIZATION, "organizations");
}
/** Template for the subject. */
private String subjectTemplate;
/** Template for the text version of the body. */
private String textBodyTemplate;
/** Template for the HTML version of the body. */
private String htmlBodyTemplate;
/** For sending email. */
private EmailerFactory emailer;
/** For getting person info. */
private DomainMapper<List<Long>, List<PersonModelView>> peopleMapper;
/** For getting system settings. */
private DomainMapper<MapperRequest<SystemSettings>, SystemSettings> systemSettingsMapper;
/** Extra properties to include during resolution. */
private Map<String, String> extraProperties;
/**
* Constructor.
*
* @param inEmailer
* For sending email.
* @param inPeopleMapper
* For getting person info.
* @param inSystemSettingsMapper
* For getting system settings.
* @param inExtraProperties
* Extra properties to include during resolution.
* @param inSubjectTemplate
* Template for the subject.
* @param inTextBodyTemplate
* Template for the text version of the body.
* @param inHtmlBodyTemplate
* Template for the HTML version of the body.
*/
public TemplateEmailBuilder(final EmailerFactory inEmailer,
final DomainMapper<List<Long>, List<PersonModelView>> inPeopleMapper,
final DomainMapper<MapperRequest<SystemSettings>, SystemSettings> inSystemSettingsMapper,
final Map<String, String> inExtraProperties, final String inSubjectTemplate,
final String inTextBodyTemplate, final String inHtmlBodyTemplate)
{
emailer = inEmailer;
peopleMapper = inPeopleMapper;
systemSettingsMapper = inSystemSettingsMapper;
extraProperties = inExtraProperties;
subjectTemplate = inSubjectTemplate;
textBodyTemplate = inTextBodyTemplate;
htmlBodyTemplate = inHtmlBodyTemplate;
}
/**
* {@inheritDoc}
*/
@Override
public void build(final NotificationDTO notif, final MimeMessage inMessage) throws Exception
{
build(notif, null, inMessage);
}
/**
* Builds the email message from the notification and initial properties.
*
* @param notif
* Notification for which to build message.
* @param invocationProperties
* Initial properties to use.
* @param inMessage
* Email message.
* @throws Exception
* On error.
*/
public void build(final NotificationDTO notif, final Map<String, String> invocationProperties,
final MimeMessage inMessage) throws Exception
{
// -- build properties --
Map<String, String> properties = new HashMap<String, String>();
// from system settings
SystemSettings systemSettings = systemSettingsMapper.execute(null);
properties.put("settings.sitelabel", systemSettings.getSiteLabel());
properties.put("settings.support.email", systemSettings.getSupportEmailAddress());
properties.put("settings.support.phone", systemSettings.getSupportPhoneNumber());
properties.put("settings.support.name", systemSettings.getSupportStreamGroupDisplayName());
properties.put("settings.support.uniqueid", systemSettings.getSupportStreamGroupShortName());
// from upstream builders
if (invocationProperties != null)
{
properties.putAll(invocationProperties);
}
// from system configuration
if (extraProperties != null)
{
properties.putAll(extraProperties);
}
// actor
if (notif.getActorId() > 0)
{
properties.put("actor.id", Long.toString(notif.getActorId()));
properties.put("actor.accountid", notif.getActorAccountId());
properties.put("actor.name", notif.getActorName());
}
// activity
if (notif.getActivityId() > 0)
{
properties.put("activity.id", Long.toString(notif.getActivityId()));
String type = activityTypeDisplayNameOverrides.get(notif.getActivityType());
if (type == null)
{
type = notif.getActivityType().name().toLowerCase();
}
properties.put("activity.type", type);
}
// destination
if (notif.getDestinationId() > 0)
{
properties.put("dest.id", Long.toString(notif.getDestinationId()));
properties.put("dest.type", notif.getDestinationType().name());
properties.put("dest.uniqueid", notif.getDestinationUniqueId());
properties.put("dest.name", notif.getDestinationName());
properties.put("dest.page", entityPageNames.get(notif.getDestinationType()));
}
// auxiliary
if (notif.getAuxiliaryType() != null)
{
properties.put("aux.type", notif.getAuxiliaryType().name());
properties.put("aux.uniqueid", notif.getAuxiliaryUniqueId());
properties.put("aux.name", notif.getAuxiliaryName());
properties.put("aux.page", entityPageNames.get(notif.getAuxiliaryType()));
}
// -- build email --
// build and set the email parts
StrSubstitutor transform = new StrSubstitutor(properties, "$(", ")");
emailer.setSubject(inMessage, transform.replace(subjectTemplate));
emailer.setTextBody(inMessage, transform.replace(textBodyTemplate));
transform.setVariableResolver(new HtmlEncodingLookup(transform.getVariableResolver()));
emailer.setHtmlBody(inMessage, transform.replace(htmlBodyTemplate));
// look up recipients and put as email recipients
List<PersonModelView> recipients = peopleMapper.execute(notif.getRecipientIds());
if (recipients.size() == 1)
{
emailer.setTo(inMessage, recipients.get(0).getEmail());
}
else
{
emailer.setBcc(inMessage, EmailerFactory.buildEmailList(recipients));
}
}
/**
* Decorator used to insure that all content is appropriately HTML encoded.
*/
static class HtmlEncodingLookup extends StrLookup
{
/** Lookup. */
private StrLookup decorated;
/**
* Constructor.
*
* @param inDecorated
* Lookup.
*/
public HtmlEncodingLookup(final StrLookup inDecorated)
{
decorated = inDecorated;
}
/**
* {@inheritDoc}
*/
@Override
public String lookup(final String inKey)
{
String value = decorated.lookup(inKey);
return value == null ? null : StringEscapeUtils.escapeHtml(value);
}
}
}