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

de.aipark.api.parkingarea.Schedule Maven / Gradle / Ivy

package de.aipark.api.parkingarea;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;

import java.sql.Time;
import java.sql.Timestamp;
import java.util.*;

/**
 * Created by torgen on 13.07.17.
 */
@SuppressWarnings("unused")
public class Schedule implements Comparable {
    private static final int DEFAULT_PRIORITY = 0;

    public enum Days {
        MO,
        TU,
        WE,
        TH,
        FR,
        SA,
        SU,
        PH, // holidays
        SH  // vacation
    }

    public enum Month {
        JAN,
        FEB,
        MAR,
        APR,
        MAY,
        JUN,
        JUL,
        AUG,
        SEP,
        OCT,
        NOV,
        DEC
    }

    @ApiModelProperty(position = 1, value = "days of schedule (PH = holidays, SH = vacation), empty value means always (all days including holidays and vacation)")
    private List days;

    @ApiModelProperty(position = 2, value = "start year of schedule", dataType = "java.lang.Integer", example = "2017")
    private Integer validFromYear;

    @ApiModelProperty(position = 3, value = "end year of schedule", dataType = "java.lang.Integer", example = "2018")
    private Integer validToYear;

    @ApiModelProperty(position = 4, value = "start month of schedule (1 = JAN, 2 = FEB, ...)", dataType = "java.lang.Integer", example = "3")
    private Integer validFromMonth;

    @ApiModelProperty(position = 5, value = "end month of schedule (1 = JAN, 2 = FEB, ...)", dataType = "java.lang.Integer", example = "3")
    private Integer validToMonth;

    @ApiModelProperty(position = 6, value = "start day in month of schedule (1 = first day of month)", dataType = "java.lang.Integer", example = "1")
    private Integer validFromDay;

    @ApiModelProperty(position = 7, value = "end day in month of schedule (1 = first day of month)", dataType = "java.lang.Integer", example = "1")
    private Integer validToDay;

    @ApiModelProperty(position = 8, value = "start time of schedule (24h-format: 'HH:mm:ss')", dataType = "java.util.String", example = "08:00:00")
    @JsonFormat(pattern = "HH:mm:ss")
    private Time validFromTime;

    @ApiModelProperty(position = 9, value = "end time of schedule (24h-format: 'HH:mm:ss')", dataType = "java.util.String", example = "18:00:00")
    @JsonFormat(pattern = "HH:mm:ss")
    private Time validToTime;

    @ApiModelProperty(position = 10, value = "textual description for special schedules", dataType = "java.lang.String", example = "sunrise-sunset")
    private String description;

    @ApiModelProperty(position = 11, value = "priority of schedule (bigger = more important)", dataType = "java.lang.Integer", example = "1")
    private Integer priority;

    public Schedule() {
        this.priority = DEFAULT_PRIORITY;
        this.days = new ArrayList();
    }

    //needed for schedule merging
    public Schedule(Schedule other) {
        this.priority = other.priority;
        this.days = other.days;
        this.validFromYear = other.validFromYear;
        this.validToYear = other.validToYear;
        this.validFromMonth = other.validFromMonth;
        this.validToMonth = other.validToMonth;
        this.validFromDay = other.validFromDay;
        this.validToDay = other.validToDay;
        this.validFromTime = other.validFromTime;
        this.validToTime = other.validToTime;
        this.description = other.description;
    }

    public Integer getPriority() {
        return priority;
    }

    public void setPriority(Integer priority) {
        this.priority = priority;
    }

    public List getDays() {
        return days;
    }

    public void setDays(List days) {
        this.days = days;
        Collections.sort(days);
    }

    public Integer getValidFromYear() {
        return validFromYear;
    }

    public void setValidFromYear(Integer validFromYear) {
        this.validFromYear = validFromYear;
    }

    public Integer getValidToYear() {
        return validToYear;
    }

    public void setValidToYear(Integer validToYear) {
        this.validToYear = validToYear;
    }

    public Integer getValidFromMonth() {
        return validFromMonth;
    }

    public void setValidFromMonth(Integer validFromMonth) {
        this.validFromMonth = validFromMonth;
    }

    public Integer getValidToMonth() {
        return validToMonth;
    }

    public void setValidToMonth(Integer validToMonth) {
        this.validToMonth = validToMonth;
    }

    public Integer getValidFromDay() {
        return validFromDay;
    }

    public void setValidFromDay(Integer validFromDay) {
        this.validFromDay = validFromDay;
    }

    public Integer getValidToDay() {
        return validToDay;
    }

    public void setValidToDay(Integer validToDay) {
        this.validToDay = validToDay;
    }

    public Time getValidFromTime() {
        return validFromTime;
    }

    public void setValidFromTime(Time validFromTime) {
        this.validFromTime = validFromTime;
    }

    public Time getValidToTime() {
        return validToTime;
    }

    public void setValidToTime(Time validToTime) {
        this.validToTime = validToTime;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public int compareTo(Schedule o) {
        int result = 0;
        if(this.validFromYear != null && o.validFromYear != null){
            result = this.validFromYear.compareTo(o.validFromYear);
            if(result != 0){
                return result;
            }
        }

        if(this.validToYear != null && o.validToYear != null){
            result = this.validToYear.compareTo(o.validToYear);
            if(result != 0){
                return result;
            }
        }

        if(this.validFromMonth != null && o.validFromMonth != null){
            result = this.validFromMonth.compareTo(o.validFromMonth);
            if(result != 0){
                return result;
            }
        }

        if(this.validToMonth != null && o.validToMonth != null){
            result = this.validToMonth.compareTo(o.validToMonth);
            if(result != 0){
                return result;
            }
        }

        if(this.validFromDay != null && o.validFromDay != null){
            result = this.validFromDay.compareTo(o.validFromDay);
            if(result != 0){
                return result;
            }
        }

        if(this.validToDay != null && o.validToDay != null){
            result = this.validToDay.compareTo(o.validToDay);
            if(result != 0){
                return result;
            }
        }

        if(this.days != null && o.days != null){
            //necessary for correct displaying order of multiple schedules with different days
            SortedSet sortedSetL1 = new TreeSet(this.days);
            SortedSet sortedSetL2 = new TreeSet(o.days);
            Days l1Day = Days.MO;
            if (!sortedSetL1.isEmpty()) {
                l1Day = sortedSetL1.first();
            }
            Days l2Day = Days.MO;
            if (!sortedSetL2.isEmpty()) {
                l2Day = sortedSetL2.first();
            }
            result = l1Day.compareTo(l2Day);
            if(result != 0){
                return result;
            }
        }

        if(this.validFromTime != null && o.validFromTime != null){
            result = this.validFromTime.compareTo(o.validFromTime);
            if(result != 0){
                return result;
            }
        }

        if(this.validToTime != null && o.validToTime != null){
            result = this.validToTime.compareTo(o.validToTime);
            if(result != 0){
                return result;
            }
        }

        if(this.priority != null && o.priority != null){
            result = this.priority.compareTo(o.priority);
            if(result != 0){
                return result;
            }
        }

        return result;
    }

    @SuppressWarnings("SimplifiableIfStatement")
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Schedule schedule = (Schedule) o;

        if (priority != null ? !priority.equals(schedule.priority) : schedule.priority != null) return false;
        if (days != null ? !days.equals(schedule.days) : schedule.days != null) return false;
        if (validFromYear != null ? !validFromYear.equals(schedule.validFromYear) : schedule.validFromYear != null)
            return false;
        if (validToYear != null ? !validToYear.equals(schedule.validToYear) : schedule.validToYear != null)
            return false;
        if (validFromMonth != null ? !validFromMonth.equals(schedule.validFromMonth) : schedule.validFromMonth != null)
            return false;
        if (validToMonth != null ? !validToMonth.equals(schedule.validToMonth) : schedule.validToMonth != null)
            return false;
        if (validFromDay != null ? !validFromDay.equals(schedule.validFromDay) : schedule.validFromDay != null)
            return false;
        if (validToDay != null ? !validToDay.equals(schedule.validToDay) : schedule.validToDay != null) return false;
        if (validFromTime != null ? !validFromTime.equals(schedule.validFromTime) : schedule.validFromTime != null)
            return false;
        if (validToTime != null ? !validToTime.equals(schedule.validToTime) : schedule.validToTime != null)
            return false;
        return description != null ? description.equals(schedule.description) : schedule.description == null;
    }

    @Override
    public int hashCode() {
        int result = priority != null ? priority.hashCode() : 0;
        result = 31 * result + (days != null ? days.hashCode() : 0);
        result = 31 * result + (validFromYear != null ? validFromYear.hashCode() : 0);
        result = 31 * result + (validToYear != null ? validToYear.hashCode() : 0);
        result = 31 * result + (validFromMonth != null ? validFromMonth.hashCode() : 0);
        result = 31 * result + (validToMonth != null ? validToMonth.hashCode() : 0);
        result = 31 * result + (validFromDay != null ? validFromDay.hashCode() : 0);
        result = 31 * result + (validToDay != null ? validToDay.hashCode() : 0);
        result = 31 * result + (validFromTime != null ? validFromTime.hashCode() : 0);
        result = 31 * result + (validToTime != null ? validToTime.hashCode() : 0);
        result = 31 * result + (description != null ? description.hashCode() : 0);
        return result;
    }

    //this method equals de.aipark.backend.modules.parser.parkingarea.scheduleparser.jsCompatible.Schedule.scheduleToString()
    //method implementation, copy the following code to marked place in the backend project class
    @Override
    public String toString() {
        //don't copy the following two lines
        ResourceBundle bundle = ResourceBundle.getBundle("Api");
        Collections.sort(days); //sort days within one schedule
        //don't copy these two lines above

        if(description != null && !description.isEmpty()){
            if(days.isEmpty()
                    && validFromDay == null
                    && validToDay == null
                    && validFromMonth == null
                    && validToMonth == null
                    && validFromTime == null
                    && validToTime == null
                    && validFromYear == null
                    && validToYear == null){
                return description;
            }
        }

        //---- COPY CODE FROM HERE TO de.aipark.backend.modules.parser.parkingarea.scheduleparser.jsCompatible.Schedule.scheduleToString() ------
        StringBuilder result = new StringBuilder();
        Days dayBefore = null;
        for (Days day : days) {
            if (day.ordinal() > Days.SU.ordinal()) {
                break;
            }
            if (dayBefore == null) {
                result.append(bundle.getString(day.toString()));
            } else {
                if (dayBefore.ordinal() + 1 == day.ordinal()) {
                    if (!result.toString().endsWith("-")) {
                        result.append("-");
                    }
                } else {
                    if (result.toString().endsWith("-")) {
                        result.append(bundle.getString(dayBefore.toString()));
                    }
                    result.append(",").append(bundle.getString(day.toString()));
                }
            }
            dayBefore = day;
        }
        if (result.toString().endsWith("-") && dayBefore != null) {
            result.append(bundle.getString(dayBefore.toString()));
        }

        if (days.contains(Days.PH)) {
            if (!result.toString().equals("")) {
                result.append(" ");
            }
            result.append(bundle.getString(Days.PH.toString()));
        }
        if (days.contains(Days.SH)) {
            if (!result.toString().equals("")) {
                result.append(" ");
            }
            result.append(bundle.getString(Days.SH.toString()));
        }

        if (!result.toString().endsWith(" ")) {
            result.append(" ");
        }

        if (validFromTime != null) {
            result.append(validFromTime.toString(), 0, validFromTime.toString().lastIndexOf(":"));
        }
        if (validToTime != null) {
            result.append("-").append(validToTime.toString(), 0, validToTime.toString().lastIndexOf(":"));
        }

        boolean fromValue = false;
        if (!result.toString().endsWith(" ")) {
            result.append(" ");
        }
        if (validFromDay != null) {
            result.append(validFromDay).append(".");
            fromValue = true;
        }
        if (validFromMonth != null) {
            result.append(bundle.getString(Month.values()[validFromMonth - 1].toString()));
            fromValue = true;
        }
        if (validFromYear != null) {
            if (!result.toString().endsWith(" ")) {
                result.append(" ");
            }
            result.append(validFromYear);
            fromValue = true;
        }
        if (fromValue) {
            result.append("-");
        }
        if (validToDay != null) {
            result.append(validToDay).append(".");
        }
        if (validToMonth != null) {
            result.append(bundle.getString(Month.values()[validToMonth - 1].toString()));
        }
        if (validToYear != null) {
            if (!result.toString().endsWith("-")) {
                result.append(" ");
            }
            result.append(validToYear);
        }

        result = new StringBuilder(result.toString().trim());

        if (description != null && !description.isEmpty()) {
            result.append(" ").append(description);
        }

        result = new StringBuilder(result.toString().trim());

        return result.toString();

        //---- COPY CODE UNTIL HERE TO de.aipark.backend.modules.parser.parkingarea.scheduleparser.jsCompatible.Schedule.scheduleToString() ------
    }

    public boolean match(Timestamp timestamp, boolean isVacation, boolean isHoliday) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(timestamp);

        if (!days.isEmpty()
                && !(days.contains(Days.values()[(cal.get(Calendar.DAY_OF_WEEK) - 2 + 7) % 7])
                || (days.contains(Days.PH) && isHoliday)
                || (days.contains(Days.SH) && isVacation)
        )) {
            return false;
        }
        if ((validFromMonth != null && validToMonth != null) || (validFromDay != null && validToDay != null)) {
            Integer fromMonthDayValue = 0;
            Integer toMonthDayValue = 0;
            Integer timestampMonthDayValue = 0;

            if (validFromMonth != null && validToMonth != null) {
                fromMonthDayValue += validFromMonth * 100;
                toMonthDayValue += validToMonth * 100;
                timestampMonthDayValue += (cal.get(Calendar.MONTH) + 1) * 100;
            }

            if (validFromDay != null && validToDay != null) {
                fromMonthDayValue += validFromDay;
                toMonthDayValue += validToDay;
                timestampMonthDayValue += cal.get(Calendar.DAY_OF_MONTH);
            }

            if (checkTimestampOutOfMonthBoundaries(fromMonthDayValue, toMonthDayValue, timestampMonthDayValue))
                return false;
        }

        if (validFromTime != null && validToTime != null) {
            Calendar fromTime = Calendar.getInstance();
            fromTime.setTime(validFromTime);
            Calendar toTime = Calendar.getInstance();
            toTime.setTime(validToTime);

            Integer timestampValue = cal.get(Calendar.HOUR_OF_DAY) * 100 + cal.get(Calendar.MINUTE);
            Integer fromTimeValue = fromTime.get(Calendar.HOUR_OF_DAY) * 100 + fromTime.get(Calendar.MINUTE);
            Integer toTimeValue = toTime.get(Calendar.HOUR_OF_DAY) * 100 + toTime.get(Calendar.MINUTE);

            if (checkTimestampOutOfMonthBoundaries(fromTimeValue, toTimeValue, timestampValue)) return false;
        }

        return (validFromYear == null || validFromYear <= cal.get(Calendar.YEAR)) && (validToYear == null || validToYear >= cal.get(Calendar.YEAR));
    }

    private boolean checkTimestampOutOfMonthBoundaries(Integer fromMonthDayValue, Integer toMonthDayValue, Integer timestampMonthDayValue) {
        if (fromMonthDayValue < toMonthDayValue) {
            return (fromMonthDayValue > timestampMonthDayValue || toMonthDayValue < timestampMonthDayValue);
        } else {
            return (fromMonthDayValue > timestampMonthDayValue && toMonthDayValue < timestampMonthDayValue);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy