⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recurrencerule.java

📁 国外的一套开源CRM
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * $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 + -