net.sourceforge.subsonic.backend.service.EmailReminderGenerator.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.subsonic.backend.service.EmailReminderGenerator.java

Source

/*
 * This file is part of Subsonic.
 *
 * Subsonic 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.
 *
 * Subsonic 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 Subsonic.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2013 (C) Sindre Mehus
 */

package net.sourceforge.subsonic.backend.service;

import java.text.DateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.mail.MessagingException;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import net.sourceforge.subsonic.backend.dao.PaymentDao;
import net.sourceforge.subsonic.backend.dao.SubscriptionDao;
import net.sourceforge.subsonic.backend.domain.Payment;
import net.sourceforge.subsonic.backend.domain.Subscription;

/**
 * Runs a daily task sending reminder emails for subscriptions that are about to expire.
 *
 * @author Sindre Mehus
 * @version $Id$
 */
public class EmailReminderGenerator {

    private static final Logger LOG = Logger.getLogger(EmailReminderGenerator.class);
    private static final long DELAY_HOURS = 24;

    private PaymentDao paymentDao;
    private SubscriptionDao subscriptionDao;
    private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    private static final DateFormat DATE_FORMAT = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);

    public void init() {
        Runnable task = new Runnable() {
            public void run() {
                try {
                    LOG.info("Starting email reminder generator.");
                    EmailSession emailSession = new EmailSession();
                    Calendar cal = Calendar.getInstance();

                    cal.add(Calendar.DATE, 7);
                    Date in7Days = cal.getTime();
                    cal.add(Calendar.DATE, 1);
                    Date in8Days = cal.getTime();
                    cal.add(Calendar.DATE, 6);
                    Date in14Days = cal.getTime();
                    cal.add(Calendar.DATE, 1);
                    Date in15Days = cal.getTime();

                    LOG.info("In 7 days: " + in7Days);
                    LOG.info("In 8 days: " + in8Days);
                    LOG.info("In 14 days: " + in14Days);
                    LOG.info("In 15 days: " + in15Days);

                    processPayments(emailSession, in7Days, in8Days);
                    processPayments(emailSession, in14Days, in15Days);
                    processSubscriptions(emailSession, in7Days, in8Days);
                    processSubscriptions(emailSession, in14Days, in15Days);

                    LOG.info("Completed email reminder generator.");
                } catch (Throwable x) {
                    LOG.error("Failed to process reminder emails.", x);
                }
            }
        };

        executor.scheduleWithFixedDelay(task, DELAY_HOURS, DELAY_HOURS, TimeUnit.HOURS);
        LOG.info("Scheduled email reminder generator to run every " + DELAY_HOURS + " hours.");
    }

    private void processPayments(EmailSession emailSession, Date from, Date to) throws Exception {
        List<Payment> payments = paymentDao.getPaymentsByExpirationDate(from, to);
        LOG.info(payments.size() + " payment(s) expiring between " + from + " and " + to);
        if (payments.isEmpty()) {
            return;
        }

        for (Payment payment : payments) {
            try {
                processPayment(payment, emailSession);
            } catch (Throwable x) {
                LOG.error("Failed to process " + payment, x);
            }
        }
    }

    private void processSubscriptions(EmailSession emailSession, Date from, Date to) throws Exception {
        List<Subscription> subscriptions = subscriptionDao.getSubscriptionsByExpirationDate(from, to);
        LOG.info(subscriptions.size() + " subscription(s) expiring between " + from + " and " + to);
        if (subscriptions.isEmpty()) {
            return;
        }

        for (Subscription subscription : subscriptions) {
            try {
                processSubscription(subscription, emailSession);
            } catch (Throwable x) {
                LOG.error("Failed to process " + subscription, x);
            }
        }
    }

    private void processPayment(Payment payment, EmailSession emailSession) {
        try {
            LOG.info("Processing " + payment);
            String email = payment.getPayerEmail();
            if (email == null) {
                throw new Exception("Missing email address.");
            }
            sendReminder(payment.getValidTo(), payment.getPayerFirstName(), email, emailSession);

        } catch (Throwable x) {
            LOG.error("Failed to process " + payment, x);
        }
    }

    private void processSubscription(Subscription subscription, EmailSession emailSession) {
        try {
            LOG.info("Processing " + subscription);
            String email = subscription.getEmail();
            if (email == null) {
                throw new Exception("Missing email address.");
            }
            sendReminder(subscription.getValidTo(), subscription.getFirstName(), email, emailSession);

        } catch (Throwable x) {
            LOG.error("Failed to process " + subscription, x);
        }
    }

    public void sendReminder(Date licenseExpires, String firstName, String to, EmailSession emailSession)
            throws MessagingException {
        emailSession.sendMessage("license@subsonic.org", Arrays.asList(to), null,
                Arrays.asList("license@subsonic.org", "sindre@activeobjects.no"),
                Arrays.asList("license@subsonic.org"), "Your Subsonic Premium subscription is about to expire",
                createEmailContent(licenseExpires, firstName));
        LOG.info("Sent email reminder to " + to);
    }

    private String createEmailContent(Date licenseExpires, String firstName) {

        if (StringUtils.isBlank(firstName)) {
            firstName = "Subsonic Premium user";
        }
        return "Dear " + firstName + ",\n" + "\n"
                + "This is a friendly reminder that your Subsonic Premium subscription expires on "
                + DATE_FORMAT.format(licenseExpires) + ".\n" + "\n"
                + "We hope that you enjoy the service and that you choose to renew your subscription.\n" + "\n"
                + "Please visit http://premium.subsonic.org for more details and purchase options!\n" + "\n"
                + "Note: If you previously selected the automatic renewal option you will be charged automatically, and no action is required on your part.\n"
                + "\n" + "Best regards,\n" + "The Subsonic team\n" + "\n"
                + "(This email is sent 14 and 7 days before the license expires)";
    }

    public void setPaymentDao(PaymentDao paymentDao) {
        this.paymentDao = paymentDao;
    }

    public void setSubscriptionDao(SubscriptionDao subscriptionDao) {
        this.subscriptionDao = subscriptionDao;
    }
}