Java tutorial
/* 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()); } } }