com.springsource.greenhouse.invite.mail.AsyncMailInviteService.java Source code

Java tutorial

Introduction

Here is the source code for com.springsource.greenhouse.invite.mail.AsyncMailInviteService.java

Source

/*
 * Copyright 2010 the original author or authors.
 *
 * 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 com.springsource.greenhouse.invite.mail;

import java.util.List;

import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.crypto.keygen.KeyGenerators;
import org.springframework.security.crypto.keygen.StringKeyGenerator;
import org.springframework.stereotype.Service;
import org.springframework.templating.LocalStringTemplate;
import org.springframework.templating.ResourceStringTemplateFactory;
import org.springframework.templating.StringTemplate;
import org.springframework.templating.StringTemplateFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.UriTemplate;

import com.springsource.greenhouse.account.Account;
import com.springsource.greenhouse.invite.InviteRepository;
import com.springsource.greenhouse.invite.Invitee;

/**
 * A MailInviteService implementation that sends email invites asynchronously in a separate thread.
 * Relies on Spring's @Async support enabled by AspectJ for the asynchronous behavior.
 * Uses a StringTemplate to generate the invitation mail text from a template.
 * The text will contain a link to the invite accept page and instruct the invitee to activate it.
 * @author Keith Donald
 */
@Service
public class AsyncMailInviteService implements MailInviteService {

    private final MailSender mailSender;

    private final InviteRepository inviteRepository;

    private final UriTemplate acceptUriTemplate;

    /**
     * Creates the AsyncMailInviteService.
     * @param mailSender the object that actually does the mail delivery using the JavaMail API.
     * @param inviteRepository the interface for saving the invite for retrieval later
     * @param acceptUriTemplate a template for generating the URL the invitee should visit to accept the invite; defaults to a secure application URL e.g. https://host/invite/accept?token={token}
     */
    @Inject
    public AsyncMailInviteService(MailSender mailSender, InviteRepository inviteRepository,
            @Value("#{environment['application.secureUrl']}/invite/accept?token={token}") String acceptUriTemplate) {
        this.mailSender = mailSender;
        this.inviteRepository = inviteRepository;
        this.acceptUriTemplate = new UriTemplate(acceptUriTemplate);
    }

    public void sendInvite(Account from, List<Invitee> to, String invitationBody) {
        StringTemplate textTemplate = textTemplateFactory.getStringTemplate();
        textTemplate.put("account", from);
        StringTemplate bodyTemplate = new LocalStringTemplate(invitationBody);
        for (Invitee invitee : to) {
            bodyTemplate.put("invitee", invitee);
            textTemplate.put("body", bodyTemplate.render());
            String token = tokenGenerator.generateKey();
            textTemplate.put("acceptUrl", acceptUriTemplate.expand(token));
            send(from, invitee, textTemplate.render(), token);
        }
    }

    // internal helpers

    @Async
    @Transactional
    private void send(Account from, Invitee to, String text, String token) {
        SimpleMailMessage mailMessage = createInviteMailMessage(to, text);
        if (!inviteRepository.alreadyInvited(to.getEmail())) {
            inviteRepository.saveInvite(token, to, text, from.getId());
            mailSender.send(mailMessage);
        }
    }

    private SimpleMailMessage createInviteMailMessage(Invitee to, String text) {
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setFrom("Greenhouse <noreply@springsource.com>");
        mailMessage.setTo(to.getEmail());
        mailMessage.setSubject("Your Greenhouse Invitation");
        mailMessage.setText(text);
        return mailMessage;
    }

    private final StringTemplateFactory textTemplateFactory = new ResourceStringTemplateFactory(
            new ClassPathResource("invite-text.st", getClass()));

    private final StringKeyGenerator tokenGenerator = KeyGenerators.string();

}