All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.taskurotta.server.config.expiration.impl.SkippingHolidaysTimeoutPolicy Maven / Gradle / Ivy

package ru.taskurotta.server.config.expiration.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.taskurotta.service.config.model.ExpirationPolicy;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * ExpirationPolicy having knowledge of holidays, i.e. days which are excluded at expiration time evaluation.
 *
 * List of holidays should be passed as a path to a file containing new-line separated list of
 * Date strings .
 *
 * Example (formatted as "dd.MM.yyyy" - defaults):
 * 01.01.2013
 * #comment starting with hash symbol permitted
 * 02.01.2013
 * ...
 * 08.01.2013
 */
public class SkippingHolidaysTimeoutPolicy implements ExpirationPolicy {

    public static final String PROP_TIMEOUT = "timeout";
    public static final String PROP_LOCATION = "location";
    public static final String PROP_FORMAT = "format";

    private static final Logger logger = LoggerFactory.getLogger(SkippingHolidaysTimeoutPolicy.class);

    private int timeout = 1;
    private TimeUnit timeoutUnit = TimeUnit.DAYS;
    private String format = "dd.MM.yyyy";
    private List holidays;

    public SkippingHolidaysTimeoutPolicy(Properties properties) throws IOException, ParseException {
        String timeout = properties.getProperty(PROP_TIMEOUT);
        if (timeout != null) {
            String intStr = timeout.replaceAll("\\D", "").trim();
            String timeUnitStr = timeout.replaceAll("\\d", "").trim();
            if (intStr.length() > 0) {
                this.timeout = Integer.valueOf(intStr);
            }
            if (timeUnitStr.length() > 0) {
                this.timeoutUnit = TimeUnit.valueOf(timeUnitStr.toUpperCase());
            }
        }
        String format =properties.getProperty(PROP_FORMAT);
        if (format!=null) {
            this.format = format;
        }

        initHolidaysList(properties.getProperty(PROP_LOCATION));
    }

    public SkippingHolidaysTimeoutPolicy(int timeout, TimeUnit timeoutUnit, List holidays) {
        this.timeout = timeout;
        this.timeoutUnit = timeoutUnit;
        this.holidays = holidays;
    }

    private void initHolidaysList(String fileLocation) throws IOException, ParseException {
        if (fileLocation!=null) {
            holidays = new ArrayList<>();
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            sdf.setLenient(false);
            BufferedReader br = new BufferedReader(new FileReader(fileLocation));
            String line;
            while((line=br.readLine()) != null) {
                if (!line.startsWith("#") && line.trim().length()>0) {
                    holidays.add(sdf.parse(line.trim()));
                }

            }
            br.close();
            //Collections.sort(holidays);
            logger.debug("Holidays dates getted are [{}]", listHolidays());
        }
    }

    private String listHolidays() {
        String result = null;
        if (holidays != null) {
            StringBuilder sb = new StringBuilder();
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            for(Date date: holidays ){
                if (sb.length() > 0) {
                    sb.append(", ");
                }
                sb.append(sdf.format(date));
            }
            result = sb.toString();
        }
        return result;
    }


    //TODO: upgrade algorithm?
    private boolean isHoliday(long date, List holidays) {
        boolean result = false;
        if (holidays!=null && !holidays.isEmpty()) {
            Date targetDate = new Date(date);
            for(Date holiday: holidays) {
                if (isSameDay(holiday, targetDate)) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }

    //keep only future holidays in list
    private List getActualHolidays(long forDate) {
        List result = null;
        if (holidays!=null && !holidays.isEmpty()) {
            result = new ArrayList<>();
            Date target = new Date(forDate);
            for(Date date: holidays) {
                if (date.after(target) && !isSameDay(date, target)) {
                    result.add(date);
                }
            }
        }
        return result;
    }

    public static boolean isSameDay(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
    }

    @Override
    public long getExpirationTime(UUID taskId, UUID processId, long forTime) {
        long result = forTime;
        List actualHolidays = getActualHolidays(forTime);
        do {
            result = result + timeoutUnit.toMillis(timeout);
        } while(isHoliday(result, actualHolidays));

        logger.debug("Expiration time getted for time[{}] is [{}]", new Date(forTime), new Date(result));

        return result;
    }

    @Override
    public boolean readyToRecover(UUID taskId, UUID processId) {
        return true;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy