ca.myewb.frame.Cron.java Source code

Java tutorial

Introduction

Here is the source code for ca.myewb.frame.Cron.java

Source

/*
    
This file is part of OpenMyEWB.
    
OpenMyEWB 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.
    
OpenMyEWB 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 OpenMyEWB.  If not, see <http://www.gnu.org/licenses/>.
    
OpenMyEWB is Copyright 2005-2009 Nicolas Kruchten (nicolas@kruchten.com), Francis Kung, Engineers Without Borders Canada, Michael Trauttmansdorff, Jon Fishbein, David Kadish
    
*/

package ca.myewb.frame;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Restrictions;

import ca.myewb.model.ApplicationSessionModel;
import ca.myewb.model.DailyStatsModel;
import ca.myewb.model.EmailModel;
import ca.myewb.model.PlacementModel;
import ca.myewb.model.UserModel;

public class Cron {
    static SimpleDateFormat formatter = new SimpleDateFormat("EEE, MMM d");

    public static void main(String[] args) throws IOException {
        Logger log = Logger.getLogger(Cron.class.getName());
        log.addAppender(new ConsoleAppender(new SimpleLayout()));

        if (args.length < 2) {
            log.error("need dbsuffix and run time mode as arguments!");
            System.exit(0);
        }

        String dbSuffix = args[0];
        String time = args[1];
        boolean safemode = ((args.length > 2) && (args[2].equals("-safe")));

        if (safemode) {
            log.info("cron job started in SAFEMODE, no changes will be persisted.");
        }

        Properties appProperties = new Properties();
        java.net.URL url = Thread.currentThread().getContextClassLoader().getResource("app.properties");
        InputStream stream = url.openStream();
        appProperties.load(stream);

        Helpers.setPrefixes(appProperties.getProperty("appprefix"), appProperties.getProperty("defaulturl"),
                appProperties.getProperty("domain"));
        Helpers.setEnShortName(appProperties.getProperty("enshortname"));
        Helpers.setFrShortName(appProperties.getProperty("frshortname"));
        Helpers.setLongName(appProperties.getProperty("longname"));
        Helpers.setSystemEmail(appProperties.getProperty("systememail"));
        Helpers.setDevMode(appProperties.getProperty("devmode").equals("yes"));

        // Prepare Hibernate
        Session session = null;
        Transaction tx = null;

        try {
            // Set up the database connection
            HibernateUtil.createFactory(dbSuffix);
            session = HibernateUtil.currentSession();
            tx = session.beginTransaction();

            Properties props = new Properties();
            props.setProperty("directive.foreach.counter.initial.value", "0");
            props.setProperty("file.resource.loader.path", "tmpl");
            props.setProperty(Velocity.RUNTIME_LOG, "logs/velocity.log.txt");

            Velocity.init(props);
        } catch (Exception e) {
            log.error("Error initializing Hibernate or Velocity!  Bailing!", e);
            System.exit(1);
        }

        try {
            if (time.equals("daily")) {
                daily(log, session);
            } else if (time.equals("halfhourly")) {
                halfHourly(log, session);
            }

            if (safemode) {
                log.info("SAFEMODE: rolling back transaction.");
                tx.rollback();
                log.info("transaction rolled back.");
            } else {
                tx.commit();
                log.info("transaction committed.");
            }
        } catch (Exception e) {
            tx.rollback();
            HibernateUtil.closeSession();
            log.error("Exception while running cron script: tx rolled back!", e);
            System.exit(1);
        }

        HibernateUtil.closeSession();
    }

    private static void halfHourly(Logger log, Session session) throws Exception {
        createSessionEndEmails(log, session);
    }

    private static void daily(Logger log, Session session) throws Exception {
        doTwoWeekWarnings(log, session);

        doOneWeekWarnings(log, session);

        doOneDayWarnings(log, session);

        doMembershipExpiry(log, session);

        doDailystatsBuffer(log, session);

        doNMTandLTOVmemberships(log, session);
    }

    private static void doNMTandLTOVmemberships(Logger log, Session session) throws HibernateException, Exception {
        log.info("Getting list of active placements...");
        Vector<PlacementModel> OVs = new Vector<PlacementModel>(PlacementModel.getActivePlacements());

        log.info("Getting list of NMT's...");
        List<UserModel> nmts = (new SafeHibList<UserModel>(session.createQuery(
                "SELECT u FROM UserModel u, RoleModel r " + "WHERE r.user=u AND r.group=? AND r.end IS NULL")
                .setEntity(0, Helpers.getGroup("NMT")))).list();
        log.info("Getting list of Admins...");
        List<UserModel> admins = (new SafeHibList<UserModel>(session
                .createQuery("SELECT u FROM UserModel u, RoleModel r "
                        + "WHERE r.user=u AND r.group=? AND r.end IS NULL")
                .setEntity(0, Helpers.getGroup("Admin")))).list();

        Vector<UserModel> autoUpgrades = new Vector<UserModel>(nmts);
        autoUpgrades.addAll(admins);

        // Limit to long terms
        for (PlacementModel p : OVs) {
            if (p.isLongterm()) {
                autoUpgrades.add(p.getOv());
            }
        }

        log.info("Upgrading Users...");
        for (UserModel u : autoUpgrades) {
            if (u.getExpiry() == null || u.canRenew()) {
                log.info(u.getFirstname() + " " + u.getLastname() + "'s membership is being "
                        + (u.getExpiry() == null ? "upgraded" : "renewed") + " automatically.");
                u.renew(null, false);
            }

        }

    }

    private static void doDailystatsBuffer(Logger log, Session session) {
        log.info("----- adding rows to dailystatsbuffer");

        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 35);

        for (int i = 0; i < 35; i++) {
            List list = session.createQuery("from DailyStatsModel as ds where ds.day=?").setDate(0, cal.getTime())
                    .list();

            if (list.isEmpty()) {
                log.info("added row for " + cal.getTime().toString());

                DailyStatsModel.newDailyStats(cal.getTime());
                cal.add(Calendar.DAY_OF_YEAR, -1);
            }
        }
    }

    private static void doTwoWeekWarnings(Logger log, Session session) throws Exception {
        // 2-week warning
        log.info("----- 14-day warning");

        Calendar calendar = Calendar.getInstance();
        Criteria crit = session.createCriteria(UserModel.class);
        crit.add(Restrictions.isNotNull("email"));
        crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        calendar.add(Calendar.DAY_OF_YEAR, 14);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        crit.add(Restrictions.eq("expiry", calendar.getTime()));

        Iterator it = crit.list().iterator();

        while (it.hasNext()) {
            UserModel u = (UserModel) it.next();
            log.info(u.getFirstname() + " " + u.getLastname() + ": " + u.getEmail());

            VelocityContext mailCtx = new VelocityContext();
            mailCtx.put("helpers", new Helpers());
            mailCtx.put("name", u.getFirstname());
            mailCtx.put("numdays", "14 days");
            mailCtx.put("expiry", formatter.format(calendar.getTime()));

            Template template = Velocity.getTemplate("emails/expirywarning.vm");
            StringWriter writer = new StringWriter();
            template.merge(mailCtx, writer);

            EmailModel.sendEmail(u.getEmail(), writer.toString());
        }
    }

    private static void doOneWeekWarnings(Logger log, Session session) throws Exception {
        // 1-week warning
        log.info("----- 7-day warning");

        Calendar calendar = Calendar.getInstance();
        Criteria crit = session.createCriteria(UserModel.class);
        crit.add(Restrictions.isNotNull("email"));
        crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        calendar.add(Calendar.DAY_OF_YEAR, 7);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        crit.add(Restrictions.eq("expiry", calendar.getTime()));

        Iterator it = crit.list().iterator();

        while (it.hasNext()) {
            UserModel u = (UserModel) it.next();
            log.info(u.getFirstname() + " " + u.getLastname() + ": " + u.getEmail());

            VelocityContext mailCtx = new VelocityContext();
            mailCtx.put("helpers", new Helpers());
            mailCtx.put("name", u.getFirstname());
            mailCtx.put("numdays", "7 days");
            mailCtx.put("expiry", formatter.format(calendar.getTime()));

            Template template = Velocity.getTemplate("emails/expirywarning.vm");
            StringWriter writer = new StringWriter();
            template.merge(mailCtx, writer);

            EmailModel.sendEmail(u.getEmail(), writer.toString());
        }
    }

    private static void doOneDayWarnings(Logger log, Session session) throws Exception {
        // 1-day warning
        log.info("----- 1-day warning");

        Calendar calendar = Calendar.getInstance();
        Criteria crit = session.createCriteria(UserModel.class);
        crit.add(Restrictions.isNotNull("email"));
        crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        crit.add(Restrictions.eq("expiry", calendar.getTime()));

        Iterator it = crit.list().iterator();

        while (it.hasNext()) {
            UserModel u = (UserModel) it.next();
            log.info(u.getFirstname() + " " + u.getLastname() + ": " + u.getEmail());

            VelocityContext mailCtx = new VelocityContext();
            mailCtx.put("helpers", new Helpers());
            mailCtx.put("name", u.getFirstname());
            mailCtx.put("numdays", "1 day");
            mailCtx.put("expiry", formatter.format(calendar.getTime()));

            Template template = Velocity.getTemplate("emails/expirywarning.vm");
            StringWriter writer = new StringWriter();
            template.merge(mailCtx, writer);

            EmailModel.sendEmail(u.getEmail(), writer.toString());
        }
    }

    private static void doMembershipExpiry(Logger log, Session session) throws Exception {
        // expiry
        log.info("----- Expiry");

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        Criteria crit = session.createCriteria(UserModel.class);
        crit.add(Restrictions.isNotNull("email"));
        crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        crit.add(Restrictions.le("expiry", calendar.getTime()));

        Iterator it = crit.list().iterator();

        while (it.hasNext()) {
            UserModel u = (UserModel) it.next();
            log.info(u.getFirstname() + " " + u.getLastname() + ": " + u.getEmail());

            u.expire();

            VelocityContext mailCtx = new VelocityContext();
            mailCtx.put("helpers", new Helpers());
            mailCtx.put("name", u.getFirstname());

            Template template = Velocity.getTemplate("emails/expiry.vm");
            StringWriter writer = new StringWriter();
            template.merge(mailCtx, writer);

            EmailModel.sendEmail(u.getEmail(), writer.toString());
        }
    }

    private static void createSessionEndEmails(Logger log, Session session) throws Exception {
        List<ApplicationSessionModel> sessions = new SafeHibList<ApplicationSessionModel>(
                session.createCriteria(ApplicationSessionModel.class).add(Restrictions.le("closeDate", new Date()))
                        .add(Restrictions.eq("emailSent", false))
                        .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)).list();
        for (Iterator iter = sessions.iterator(); iter.hasNext();) {
            ApplicationSessionModel s = (ApplicationSessionModel) iter.next();

            EmailModel.sendEmail(
                    Helpers.getSystemEmail(), s.getApplicantEmails(true), "[" + Helpers.getEnShortName()
                            + "-applications] Application Session " + s.getName() + " has closed",
                    s.getCloseEmailText(), Helpers.getEnShortName() + "-applications");

            s.croned();

            log.info("Created close session email for " + s.getName());
        }
    }
}