Running Linux-like Crons in Java

This doesn’t handle improper input, but it works for proper input. I use it on a Spring MVC Scheduled Task that runs every minute to dynamically pull Report Schedules from the database and check if they should run at that minute.

    /*
     *  Linux Crons *
        field          allowed values  (ex:  *  1  1,5   1-5   * /5)
        -----          --------------
        minute         0-59  
        hour           0-23
        day of month   1-31
        month          1-12 
        day of week    0-7 (0 or 7 is Sun)
     */
    private boolean cronMatch(Calendar now, ReportSchedule schedule) {
        boolean match = false;
        
        int minuteToMatch = now.get(Calendar.MINUTE);
        int hourToMatch = now.get(Calendar.HOUR_OF_DAY);
        int dayOfMonthToMatch = now.get(Calendar.DAY_OF_MONTH);
        int monthToMatch = now.get(Calendar.MONTH) + 1;
        int dayOfWeekToMatch = now.get(Calendar.DAY_OF_WEEK) - 1;

        if(match(minuteToMatch, schedule.getMinute())) {
            if(match(hourToMatch, schedule.getHour())) {
                if(match(dayOfMonthToMatch, schedule.getDayOfMonth())) {
                    if(match(monthToMatch, schedule.getMonth())) {
                        if(match(dayOfWeekToMatch, schedule.getDayOfWeek())) {
                            match = true;
                        }
                    }
                }
            }
        }
        return match;
    }
    
    private boolean match(int value, String string) {
        boolean match = false;
        if(string == null) {
            return false;
        }
        if(string.trim().isEmpty()) {
            return false;
        }
        
        // Possible formats: */5    4-5    *     1    1,15,3
        try {
            if(string.equalsIgnoreCase("*")) {
                match = true;
            } else if(string.contains("/")) {
                String[] values = string.split("/");
                if(values.length == 2) {
                    int lower = Integer.parseInt(values[1]);
                    if(value % lower == 0) {
                        match = true;
                    }
                }
            } else if(string.contains("-")) {
                String[] values = string.split("-");
                if(values.length == 2) {
                    int lower = Integer.parseInt(values[0]);
                    int upper = Integer.parseInt(values[1]);
                    if(value >= lower && value <= upper) {
                        match = true;
                    }
                }
            } else if(string.contains(",")) {
                boolean found = false;
                String[] values = string.split(",");
                for(String val : values) {
                    int amount = Integer.parseInt(val);
                    if(amount == value) {
                        found = true;
                        break;
                    }
                }
                match = found;
            } else {
                int val = Integer.parseInt(string);
                if(value == val) {
                    match = true;
                }
            }
        } catch(Exception ex) {
            match = false;
        }
        
        return match;
    }

Spring and Hibernate fun

Getting the application content anywhere in your application:


import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationContextProvider implements ApplicationContextAware{
private static ApplicationContext ctx = null;
public static ApplicationContext getApplicationContext() {
return ctx;
}
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
ApplicationContextProvider.ctx = ctx;
}
}

Getting a session factory from the application context:


SessionFactory sessionFactory = (SessionFactory) ApplicationContextProvider.getApplicationContext().getBean("mySessionFactory");

HibernateTemplate

http://static.springsource.org/spring/docs/2.5.5/api/org/springframework/orm/hibernate3/HibernateTemplate.html

Generic Dao


@Repository("GenericDAO")
@Transactional
public class GenericDaoImpl implements GenericDao {

private SessionFactory sessionFactory; // Todo: use the HibernateTemplate because it's da bomb!
private HibernateTransactionManager txManager;

private Class type;

public GenericMagentoDaoImpl() { }

public GenericMagentoDaoImpl(Class type) {
this.type = type;
sessionFactory = (SessionFactory) ApplicationContextProvider.getApplicationContext().getBean("magentoSessionFactory");
}

@Override
public PK save(T o) {
Session session = sessionFactory.openSession();
try {
return (PK) session.save(o);
} finally {
session.close();
}
}

@Override
public T get(PK id) {
Session session = sessionFactory.openSession();
try {
return (T) session.get(type, id);
} finally {
session.close();
}
}

@Override
public void update(T o) {
Session session = sessionFactory.openSession();
try {
session.update(o);
} finally {
session.close();
}
}

@Override
public void delete(T o) {
Session session = sessionFactory.openSession();
try {
session.delete(o);
} finally {
session.close();
}
}

@Override
public List executeNamedQuery(String queryName, HashMap queryArgs) {
Session session = sessionFactory.openSession();
try {
final Query namedQuery = session.getNamedQuery(queryName);
//String[] namedParameters = namedQuery.getNamedParameters();
for(String key : queryArgs.keySet()) {
namedQuery.setParameter(key, queryArgs.get(key));
}
return (List) namedQuery.list();
} finally {
session.close();
}
}

@Override
public List executeNamedQueryWithLimit(String queryName, HashMap queryArgs, int limit) {
Session session = sessionFactory.openSession();
List list = new ArrayList();
try {
session.beginTransaction();
final Query namedQuery = session.getNamedQuery(queryName);
//String[] namedParameters = namedQuery.getNamedParameters();
for(String key : queryArgs.keySet()) {
namedQuery.setParameter(key, queryArgs.get(key));
}
namedQuery.setMaxResults(limit);
list = namedQuery.list();
session.getTransaction().commit();
} finally {
session.close();
}
return list;
}
}


import java.io.Serializable;
import java.util.*;

public interface GenericDao {

/** Persist the newInstance object into database */
PK save(T newInstance);

/** Retrieve an object that was previously persisted to the database using the indicated id as primary key */
T get(PK id);

/** Save changes made to a persistent object. */
void update(T transientObject);

/** Remove an object from persistent storage in the database */
void delete(T persistentObject);

public List executeNamedQuery(String queryName, HashMap queryArgs);

public List executeNamedQueryWithLimit(String queryName, HashMap queryArgs, int limit);
}