📄 recurrencerule.java
字号:
/*
* $Id: RecurrenceRule.java,v 1.5 2003/12/16 07:09:11 jonesde Exp $
*
* Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package org.ofbiz.service.calendar;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
/**
* Recurrence Rule Object
*
* @author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
* @version $Revision: 1.5 $
* @since 2.0
*/
public class RecurrenceRule {
public static final String module = RecurrenceRule.class.getName();
// **********************
// * byXXX constants
// **********************
public static final int MIN_SEC = 0;
public static final int MAX_SEC = 59;
public static final int MIN_MIN = 0;
public static final int MAX_MIN = 59;
public static final int MIN_HR = 0;
public static final int MAX_HR = 23;
public static final int MIN_MTH_DAY = -31;
public static final int MAX_MTH_DAY = 31;
public static final int MIN_YEAR_DAY = -366;
public static final int MAX_YEAR_DAY = 366;
public static final int MIN_WEEK_NO = -53;
public static final int MAX_WEEK_NO = 53;
public static final int MIN_MTH = 1;
public static final int MAX_MTH = 12;
// **********************
// * Frequency constants
// **********************
/** Frequency SECONDLY */
public static final int SECONDLY = 1;
/** Frequency MINUTELY */
public static final int MINUTELY = 2;
/** Frequency HOURLY */
public static final int HOURLY = 3;
/** Frequency DAILY */
public static final int DAILY = 4;
/** Frequency WEEKLY */
public static final int WEEKLY = 5;
/** Frequency MONTHLY */
public static final int MONTHLY = 6;
/** Frequency YEARLY */
public static final int YEARLY = 7;
// **********************
// * GenericValue object
// **********************
protected GenericValue rule;
// **********************
// * Parsed byXXX lists
// **********************
protected List bySecondList;
protected List byMinuteList;
protected List byHourList;
protected List byDayList;
protected List byMonthDayList;
protected List byYearDayList;
protected List byWeekNoList;
protected List byMonthList;
protected List bySetPosList;
/**
* Creates a new RecurrenceRule object from a RecurrenceInfo entity.
*@param rule GenericValue object defining this rule.
*/
public RecurrenceRule(GenericValue rule) throws RecurrenceRuleException {
this.rule = rule;
if (!rule.getEntityName().equals("RecurrenceRule"))
throw new RecurrenceRuleException("Invalid RecurrenceRule Value object.");
init();
}
/**
* Initializes the rules for this RecurrenceInfo object.
*@throws RecurrenceRuleException
*/
public void init() throws RecurrenceRuleException {
// Check the validity of the rule
String freq = rule.getString("frequency");
if (!checkFreq(freq))
throw new RecurrenceRuleException("Recurrence FREQUENCY is a required parameter.");
if (rule.getLong("intervalNumber").longValue() < 1)
throw new RecurrenceRuleException("Recurrence INTERVAL must be a positive integer.");
// Initialize the byXXX lists
bySecondList = StringUtil.split(rule.getString("bySecondList"), ",");
byMinuteList = StringUtil.split(rule.getString("byMinuteList"), ",");
byHourList = StringUtil.split(rule.getString("byHourList"), ",");
byDayList = StringUtil.split(rule.getString("byDayList"), ",");
byMonthDayList = StringUtil.split(rule.getString("byMonthDayList"), ",");
byYearDayList = StringUtil.split(rule.getString("byYearDayList"), ",");
byWeekNoList = StringUtil.split(rule.getString("byWeekNoList"), ",");
byMonthList = StringUtil.split(rule.getString("byMonthList"), ",");
bySetPosList = StringUtil.split(rule.getString("bySetPosList"), ",");
}
/**
* Gets the current date/time.
*@return long Timestamp of the current date/time
*/
private long now() {
return System.currentTimeMillis();
}
// Checks for a valid frequency property.
private boolean checkFreq(String freq) {
if (freq == null)
return false;
if (freq.equalsIgnoreCase("SECONDLY"))
return true;
if (freq.equalsIgnoreCase("MINUTELY"))
return true;
if (freq.equalsIgnoreCase("HOURLY"))
return true;
if (freq.equalsIgnoreCase("DAILY"))
return true;
if (freq.equalsIgnoreCase("WEEKLY"))
return true;
if (freq.equalsIgnoreCase("MONTHLY"))
return true;
if (freq.equalsIgnoreCase("YEARLY"))
return true;
return false;
}
/**
* Gets the end time of the recurrence rule or 0 if none.
*@return long The timestamp of the end time for this rule or 0 for none.
*/
public long getEndTime() {
if (rule == null) {
Debug.logVerbose("Rule is null.", module);
return -1;
}
long time = 0;
java.sql.Timestamp stamp = null;
stamp = rule.getTimestamp("untilDateTime");
Debug.logVerbose("Stamp value: " + stamp, module);
if (stamp != null) {
long nanos = (long) stamp.getNanos();
time = stamp.getTime();
time += (nanos / 1000000);
}
Debug.logVerbose("Returning time: " + time, module);
return time;
}
/**
* Get the number of times this recurrence will run (-1 until end time).
*@return long The number of time this recurrence will run.
*/
public long getCount() {
if (rule.get("countNumber") != null)
return rule.getLong("countNumber").longValue();
return 0;
}
/**
* Returns the frequency name of the recurrence.
*@return String The name of this frequency.
*/
public String getFrequencyName() {
return rule.getString("frequency").toUpperCase();
}
/**
* Returns the frequency of this recurrence.
*@return int The reference value for the frequency
*/
public int getFrequency() {
String freq = rule.getString("frequency");
if (freq == null)
return 0;
if (freq.equalsIgnoreCase("SECONDLY"))
return SECONDLY;
if (freq.equalsIgnoreCase("MINUTELY"))
return MINUTELY;
if (freq.equalsIgnoreCase("HOURLY"))
return HOURLY;
if (freq.equalsIgnoreCase("DAILY"))
return DAILY;
if (freq.equalsIgnoreCase("WEEKLY"))
return WEEKLY;
if (freq.equalsIgnoreCase("MONTHLY"))
return MONTHLY;
if (freq.equalsIgnoreCase("YEARLY"))
return YEARLY;
return 0;
}
/**
* Returns the interval of the frequency.
*@return long Interval value
*/
public long getInterval() {
if (rule.get("intervalNumber") == null)
return 1;
return rule.getLong("intervalNumber").longValue();
}
/**
* Returns the interval of the frequency as an int.
*@return The interval of this frequency as an integer.
*/
public int getIntervalInt() {
// if (Debug.verboseOn()) Debug.logVerbose("[RecurrenceInfo.getInterval] : " + getInterval(), module);
return (int) getInterval();
}
/**
* Returns the next recurrence of this rule.
*@param startTime The time this recurrence first began.
*@param fromTime The time to base the next recurrence on.
*@param currentCount The total number of times the recurrence has run.
*@return long The next recurrence as a long.
*/
public long next(long startTime, long fromTime, long currentCount) {
// Set up the values
if (startTime == 0)
startTime = RecurrenceUtil.now();
if (fromTime == 0)
fromTime = startTime;
// Test the end time of the recurrence.
if (getEndTime() != 0 && getEndTime() <= RecurrenceUtil.now())
return 0;
Debug.logVerbose("Rule NOT expired by end time.", module);
// Test the recurrence limit.
if (getCount() != -1 && currentCount >= getCount())
return 0;
Debug.logVerbose("Rule NOT expired by max count.", module);
boolean isSeeking = true;
long nextRuntime = 0;
long seekTime = fromTime;
int loopProtection = 0;
int maxLoop = (10 * 10 * 10 * 10 * 10);
while (isSeeking && loopProtection < maxLoop) {
Date nextRun = getNextFreq(startTime, seekTime);
seekTime = nextRun.getTime();
if (validByRule(nextRun)) {
isSeeking = false;
nextRuntime = nextRun.getTime();
}
loopProtection++;
}
return nextRuntime;
}
/**
* Tests the date to see if it falls within the rules
*@param startDate date object to test
*@return True if the date is within the rules
*/
public boolean isValid(Date startDate, Date date) {
return isValid(startDate.getTime(), date.getTime());
}
/**
* Tests the date to see if it falls within the rules
*@param startTime date object to test
*@return True if the date is within the rules
*/
public boolean isValid(long startTime, long dateTime) {
long testTime = startTime;
if (testTime == dateTime)
return true;
while (testTime < dateTime) {
testTime = next(startTime, testTime, 1);
if (testTime == dateTime)
return true;
}
return false;
}
/**
* Removes this rule from the persistant store.
*@throws RecurrenceRuleException
*/
public void remove() throws RecurrenceRuleException {
try {
rule.remove();
} catch (GenericEntityException e) {
throw new RecurrenceRuleException(e.getMessage(), e);
}
}
// Gets the next frequency/interval recurrence from specified time
private Date getNextFreq(long startTime, long fromTime) {
// Build a Calendar object
Calendar cal = Calendar.getInstance();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -