/*
* Copyright (c) 2011 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.service.email;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
import javax.mail.Message;
import javax.mail.internet.MimeMessage;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.implement.EscapeHtmlReference;
import org.apache.velocity.context.Context;
import org.eurekastreams.commons.logging.LogFactory;
import org.eurekastreams.commons.server.UserActionRequest;
import org.eurekastreams.server.domain.SystemSettings;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.cache.Transformer;
import org.eurekastreams.server.search.modelview.PersonModelView;
import org.eurekastreams.server.service.actions.strategies.EmailerFactory;
import org.eurekastreams.server.support.email.EmailTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Responds to a message with result status.
*/
public class MessageReplier
{
/** Log. */
private final Logger log = LoggerFactory.getLogger(LogFactory.getClassName());
/** For creating response emails. */
private final EmailerFactory emailerFactory;
/** Apache Velocity templating engine. */
private final VelocityEngine velocityEngine;
/** Global context for Apache Velocity templating engine. (Holds system-wide properties.) */
private final Context velocityGlobalContext;
/** Templates for error response messages. */
private final Map<String, EmailTemplate> errorMessageTemplates;
/** Prepares exceptions for returning to the client. */
private final Transformer<Exception, Exception> exceptionSanitizer;
/**
* For getting system settings. IMPORTANT: Supplied mapper must handle transactions, since this class is invoked
* outside of one.
*/
private final DomainMapper< ? extends Serializable, SystemSettings> systemSettingsDao;
/**
* Constructor.
*
* @param inEmailerFactory
* For creating response emails.
* @param inVelocityEngine
* Apache Velocity templating engine.
* @param inVelocityGlobalContext
* Global context for Apache Velocity templating engine. (Holds system-wide properties.)
* @param inExceptionSanitizer
* Prepares exceptions for returning to the client.
* @param inSystemSettingsDao
* For getting system settings.
* @param inErrorMessageTemplates
* Templates for error response messages.
*/
public MessageReplier(final EmailerFactory inEmailerFactory, final VelocityEngine inVelocityEngine,
final Context inVelocityGlobalContext, final Transformer<Exception, Exception> inExceptionSanitizer,
final DomainMapper< ? extends Serializable, SystemSettings> inSystemSettingsDao,
final Map<String, EmailTemplate> inErrorMessageTemplates)
{
emailerFactory = inEmailerFactory;
velocityEngine = inVelocityEngine;
velocityGlobalContext = inVelocityGlobalContext;
exceptionSanitizer = inExceptionSanitizer;
systemSettingsDao = inSystemSettingsDao;
errorMessageTemplates = inErrorMessageTemplates;
}
/**
* Responds to the given message.
*
* @param message
* Original message.
* @param user
* User that sent the message.
* @param actionSelection
* Action executed.
* @param inException
* The processing error which necessitated this reply.
* @param inResponseMessages
* List to add response messages to.
*/
public void reply(final Message message, final PersonModelView user, final UserActionRequest actionSelection,
final Exception inException, final List<Message> inResponseMessages)
{
final String actionName = actionSelection.getActionKey();
try
{
Exception cleanException = exceptionSanitizer.transform(inException);
// create reponse message
MimeMessage response = emailerFactory.createMessage();
emailerFactory.setTo(response, user.getEmail());
EmailTemplate template = errorMessageTemplates.get(actionName);
if (template == null)
{
log.warn("Missing template for error response message for action {}. Sending generic response.",
actionName);
emailerFactory.setSubject(response, "Error processing received email");
emailerFactory.setTextBody(response,
"There was an error processing your email. " + cleanException.getMessage()
+ " Original message is attached.");
}
else
{
// prepare for template rendering
Context velocityContext = new VelocityContext(velocityGlobalContext);
velocityContext.put("action", actionName);
velocityContext.put("params", actionSelection.getParams());
velocityContext.put("user", user);
velocityContext.put("exception", cleanException);
velocityContext.put("originalException", inException);
velocityContext.put("settings", systemSettingsDao.execute(null));
// build the subject
StringWriter writer = new StringWriter();
velocityEngine.evaluate(velocityContext, writer, "EmailSubject-" + actionName,
template.getSubjectTemplate());
emailerFactory.setSubject(response, writer.toString());
// build the text body
Template vt = velocityEngine.getTemplate(template.getTextBodyTemplateResourcePath());
writer.getBuffer().setLength(0);
vt.merge(velocityContext, writer);
emailerFactory.setTextBody(response, writer.toString());
// build the HTML body
vt = velocityEngine.getTemplate(template.getHtmlBodyTemplateResourcePath());
// HTML-escape all content inserted
EventCartridge ec = new EventCartridge();
ec.addEventHandler(new EscapeHtmlReference());
ec.attachToContext(velocityContext);
writer.getBuffer().setLength(0);
vt.merge(velocityContext, writer);
emailerFactory.setHtmlBody(response, writer.toString());
}
// attach original message
emailerFactory.addAttachmentMessage(response, message);
inResponseMessages.add(response);
}
catch (Exception ex)
{
log.error("Error building error response message for failed action '{}'.", actionName, ex);
}
}
}