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

org.ow2.bonita.pvm.internal.cal.BusinessCalendar Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.ow2.bonita.pvm.internal.cal;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
 * a calendar that knows about business hours.
 */
public class BusinessCalendar implements Serializable {

  private static final long serialVersionUID = 1L;
  private static BusinessCalendar instance = null;

  protected long oid = -1;
  protected int version = 0;
  protected TimeZone timeZone = TimeZone.getDefault();
  /**
   * array that contains the weekdays in the index as specified by
   * {@link Calendar#SUNDAY} (=1), {@link Calendar#MONDAY} (=2),...
   * {@link Calendar#SATURDAY} (=7).
   */
  protected Day[] days = null;
  protected Holiday[] holidays = null;

  protected long secondInMillis = 1000;
  protected long minuteInMillis = 60000;
  protected long hourInMillis = 3600000;
  protected long dayInMillis = 24 * hourInMillis;
  protected long weekInMillis = 7 * dayInMillis;
  protected long monthInMillis = 30 * dayInMillis;
  protected long yearInMillis = 365 * dayInMillis;

  protected long businessDayInMillis = 8 * hourInMillis;
  protected long businessWeekInMillis = 40 * hourInMillis;
  protected long businessMonthInMillis = 21 * dayInMillis;
  protected long businessYearInMillis = 220 * dayInMillis;

  /** constructor for persistence and creating an empty business calendar */
  public BusinessCalendar() {
  }

  public static synchronized BusinessCalendar getInstance() {
    if (instance == null) {
      instance = new BusinessCalendar();
    }
    return instance;
  }

  public Date add(Date date, Duration duration) {
    Date end = null;
    if (duration.isBusinessTime()) {
      DayPart dayPart = findDayPart(date);
      boolean isInbusinessHours = (dayPart != null);
      if (!isInbusinessHours) {
        Object[] result = new Object[2];
        findDay(date).findNextDayPartStart(0, date, result);
        date = (Date) result[0];
        dayPart = (DayPart) result[1];
      }
      long millis = convertToMillis(duration);
      end = dayPart.add(date, millis, duration.isBusinessTime());
    } else {
      long millis = convertToMillis(duration);
      end = new Date(date.getTime() + millis);
    }
    return end;
  }

  public long convertToMillis(Duration duration) {
    long millis = duration.getMillis();
    millis += duration.getSeconds() * secondInMillis;
    millis += duration.getMinutes() * minuteInMillis;
    millis += duration.getHours() * hourInMillis;
    if (duration.isBusinessTime()) {
      millis += duration.getDays() * businessDayInMillis;
      millis += duration.getWeeks() * businessWeekInMillis;
      millis += duration.getMonths() * businessMonthInMillis;
      millis += duration.getYears() * businessYearInMillis;
    } else {
      millis += duration.getDays() * dayInMillis;
      millis += duration.getWeeks() * weekInMillis;
      millis += duration.getMonths() * monthInMillis;
      millis += duration.getYears() * yearInMillis;
    }
    return millis;
  }

  public boolean isInBusinessHours(Date date) {
    return (findDayPart(date) != null);
  }

  public boolean isHoliday(Date date) {
    if (holidays != null) {
      for (Holiday holiday : holidays) {
        if (holiday.includes(date)) {
          return true;
        }
      }
    }
    return false;
  }

  protected Date findStartOfNextDay(Date date) {
    Calendar calendar = createCalendar();
    calendar.setTime(date);
    calendar.add(Calendar.DATE, 1);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    date = calendar.getTime();
    while (isHoliday(date)) {
      calendar.setTime(date);
      calendar.add(Calendar.DATE, 1);
      date = calendar.getTime();
    }
    return date;
  }

  public Calendar createCalendar() {
    return new GregorianCalendar();
  }

  protected Day findDay(Date date) {
    Calendar calendar = createCalendar();
    calendar.setTime(date);
    int weekDayIndex = calendar.get(Calendar.DAY_OF_WEEK);
    return days[weekDayIndex];
  }

  protected DayPart findDayPart(Date date) {
    DayPart dayPart = null;
    if (!isHoliday(date)) {
      Day day = findDay(date);
      DayPart[] dayParts = day.getDayParts();
      for (int i = 0; ((i < dayParts.length) && (dayPart == null)); i++) {
        DayPart candidate = dayParts[i];
        if (candidate.includes(date)) {
          dayPart = candidate;
        }
      }
    }
    return dayPart;
  }

  protected DayPart findNextDayPart(Date date) {
    DayPart nextDayPart = null;
    while (nextDayPart == null) {
      nextDayPart = findDayPart(date);
      if (nextDayPart == null) {
        date = findStartOfNextDay(date);
        Object result[] = new Object[2];
        Day day = findDay(date);
        day.findNextDayPartStart(0, date, result);
        nextDayPart = (DayPart) result[1];
      }
    }
    return nextDayPart;
  }

  // getters and setters //////////////////////////////////////////////////////

  public long getBusinessDayInMillis() {
    return businessDayInMillis;
  }

  public void setBusinessDayInMillis(long businessDayInMillis) {
    this.businessDayInMillis = businessDayInMillis;
  }

  public long getBusinessMonthInMillis() {
    return businessMonthInMillis;
  }

  public void setBusinessMonthInMillis(long businessMonthInMillis) {
    this.businessMonthInMillis = businessMonthInMillis;
  }

  public long getBusinessWeekInMillis() {
    return businessWeekInMillis;
  }

  public void setBusinessWeekInMillis(long businessWeekInMillis) {
    this.businessWeekInMillis = businessWeekInMillis;
  }

  public long getBusinessYearInMillis() {
    return businessYearInMillis;
  }

  public void setBusinessYearInMillis(long businessYearInMillis) {
    this.businessYearInMillis = businessYearInMillis;
  }

  public long getDayInMillis() {
    return dayInMillis;
  }

  public void setDayInMillis(long dayInMillis) {
    this.dayInMillis = dayInMillis;
  }

  public Day[] getDays() {
    return days;
  }

  public void setDays(Day[] days) {
    this.days = days;
  }

  public Holiday[] getHolidays() {
    return holidays;
  }

  public void setHolidays(Holiday[] holidays) {
    this.holidays = holidays;
  }

  public long getHourInMillis() {
    return hourInMillis;
  }

  public void setHourInMillis(long hourInMillis) {
    this.hourInMillis = hourInMillis;
  }

  public long getMinuteInMillis() {
    return minuteInMillis;
  }

  public void setMinuteInMillis(long minuteInMillis) {
    this.minuteInMillis = minuteInMillis;
  }

  public long getMonthInMillis() {
    return monthInMillis;
  }

  public void setMonthInMillis(long monthInMillis) {
    this.monthInMillis = monthInMillis;
  }

  public long getSecondInMillis() {
    return secondInMillis;
  }

  public void setSecondInMillis(long secondInMillis) {
    this.secondInMillis = secondInMillis;
  }

  public TimeZone getTimeZone() {
    return timeZone;
  }

  public void setTimeZone(TimeZone timeZone) {
    this.timeZone = timeZone;
  }

  public long getWeekInMillis() {
    return weekInMillis;
  }

  public void setWeekInMillis(long weekInMillis) {
    this.weekInMillis = weekInMillis;
  }

  public long getYearInMillis() {
    return yearInMillis;
  }

  public void setYearInMillis(long yearInMillis) {
    this.yearInMillis = yearInMillis;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy