SimpleTrigger.cs :  » Business-Application » Quartz-Enterprise-Scheduler » Quartz » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Business Application » Quartz Enterprise Scheduler 
Quartz Enterprise Scheduler » Quartz » SimpleTrigger.cs
/* 
* Copyright 2004-2009 James House 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License. You may obtain a copy 
* of the License at 
* 
*   http://www.apache.org/licenses/LICENSE-2.0 
*   
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
* License for the specific language governing permissions and limitations 
* under the License.
* 
*/

/*
* Previously Copyright (c) 2001-2004 James House
*/

using System;

using Quartz.Util;

#if NET_20
using NullableDateTimeSystem.NullableSystem.DateTime;
#else
using Nullables;
#endif

namespace Quartz{
  /// <summary> 
  /// A concrete <see cref="Trigger" /> that is used to fire a <see cref="JobDetail" />
  /// at a given moment in time, and optionally repeated at a specified interval.
  /// </summary>
  /// <seealso cref="Trigger" />
  /// <seealso cref="CronTrigger" />
  /// <seealso cref="TriggerUtils" />
  /// 
  /// <author>James House</author>
  /// <author>Contributions by Lieven Govaerts of Ebitec Nv, Belgium.</author>
  /// <author>Marko Lahma (.NET)</author>
  [Serializable]
  public class SimpleTrigger : Trigger
  {
        /// <summary>
        /// Used to indicate the 'repeat count' of the trigger is indefinite. Or in
        /// other words, the trigger should repeat continually until the trigger's
        /// ending timestamp.
        /// </summary>
        public const int RepeatIndefinitely = -1;
        private const int YearToGiveupSchedulingAt = 2299;

        private NullableDateTime nextFireTimeUtc = null;
    private NullableDateTime previousFireTimeUtc = null;

        private int repeatCount = 0;
        private TimeSpan repeatInterval = TimeSpan.Zero;
        private int timesTriggered = 0;
        private bool complete = false;

    /// <summary>
    /// Create a <see cref="SimpleTrigger" /> with no settings.
    /// </summary>
    public SimpleTrigger()
    {
    }

        /// <summary>
        /// Create a <see cref="SimpleTrigger" /> that will occur immediately, and
        /// not repeat.
        /// </summary>
        public SimpleTrigger(string name) : this(name, null)
        {
        }

    /// <summary>
    /// Create a <see cref="SimpleTrigger" /> that will occur immediately, and
    /// not repeat.
    /// </summary>
    public SimpleTrigger(string name, string group) : this(name, group, DateTime.UtcNow, null, 0, TimeSpan.Zero)
    {
    }

        /// <summary>
        /// Create a <see cref="SimpleTrigger" /> that will occur immediately, and
        /// repeat at the the given interval the given number of times.
        /// </summary>
        public SimpleTrigger(string name, int repeatCount, TimeSpan repeatInterval)
            : this(name, null, repeatCount, repeatInterval)
        {
        }

    /// <summary>
    /// Create a <see cref="SimpleTrigger" /> that will occur immediately, and
    /// repeat at the the given interval the given number of times.
    /// </summary>
    public SimpleTrigger(string name, string group, int repeatCount, TimeSpan repeatInterval)
      : this(name, group, DateTime.UtcNow, null, repeatCount, repeatInterval)
    {
    }

        /// <summary>
        /// Create a <see cref="SimpleTrigger" /> that will occur at the given time,
        /// and not repeat.
        /// </summary>
        public SimpleTrigger(string name, DateTime startTimeUtc)
            : this(name, null, startTimeUtc)
        {
        }

    /// <summary>
    /// Create a <see cref="SimpleTrigger" /> that will occur at the given time,
    /// and not repeat.
    /// </summary>
    public SimpleTrigger(string name, string group, DateTime startTimeUtc) : this(name, group, startTimeUtc, null, 0, TimeSpan.Zero)
    {
    }

        /// <summary>
        /// Create a <see cref="SimpleTrigger" /> that will occur at the given time,
        /// and repeat at the the given interval the given number of times, or until
        /// the given end time.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="startTimeUtc">A UTC <see cref="DateTime" /> set to the time for the <see cref="Trigger" /> to fire.</param>
        /// <param name="endTimeUtc">A UTC <see cref="DateTime" /> set to the time for the <see cref="Trigger" />
        /// to quit repeat firing.</param>
        /// <param name="repeatCount">The number of times for the <see cref="Trigger" /> to repeat
        /// firing, use <see cref="RepeatIndefinitely "/> for unlimited times.</param>
        /// <param name="repeatInterval">The time span to pause between the repeat firing.</param>
        public SimpleTrigger(string name, DateTime startTimeUtc,
            NullableDateTime endTimeUtc, int repeatCount, TimeSpan repeatInterval)
            : this(name, null, startTimeUtc, endTimeUtc, repeatCount, repeatInterval)
        {
        }

        /// <summary>
        /// Create a <see cref="SimpleTrigger" /> that will occur at the given time,
        /// and repeat at the the given interval the given number of times, or until
        /// the given end time.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="group">The group.</param>
        /// <param name="startTimeUtc">A UTC <see cref="DateTime" /> set to the time for the <see cref="Trigger" /> to fire.</param>
        /// <param name="endTimeUtc">A UTC <see cref="DateTime" /> set to the time for the <see cref="Trigger" />
        /// to quit repeat firing.</param>
        /// <param name="repeatCount">The number of times for the <see cref="Trigger" /> to repeat
        /// firing, use <see cref="RepeatIndefinitely "/> for unlimited times.</param>
        /// <param name="repeatInterval">The time span to pause between the repeat firing.</param>
    public SimpleTrigger(string name, string group, DateTime startTimeUtc,
            NullableDateTime endTimeUtc, 
            int repeatCount, TimeSpan repeatInterval) : base(name, group)
    {
      StartTimeUtc = startTimeUtc;
      EndTimeUtc = endTimeUtc;
      RepeatCount = repeatCount;
      RepeatInterval = repeatInterval;
    }

        /// <summary>
        /// Create a <see cref="SimpleTrigger" /> that will occur at the given time,
        /// fire the identified <see cref="IJob" /> and repeat at the the given
        /// interval the given number of times, or until the given end time.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="group">The group.</param>
        /// <param name="jobName">Name of the job.</param>
        /// <param name="jobGroup">The job group.</param>
        /// <param name="startTimeUtc">A <see cref="DateTime" /> set to the time for the <see cref="Trigger" />
        /// to fire.</param>
        /// <param name="endTimeUtc">A <see cref="DateTime" /> set to the time for the <see cref="Trigger" />
        /// to quit repeat firing.</param>
        /// <param name="repeatCount">The number of times for the <see cref="Trigger" /> to repeat
        /// firing, use RepeatIndefinitely for unlimited times.</param>
        /// <param name="repeatInterval">The time span to pause between the repeat firing.</param>
    public SimpleTrigger(string name, string group, string jobName, string jobGroup, DateTime startTimeUtc,
                 NullableDateTime endTimeUtc,
                 int repeatCount, TimeSpan repeatInterval)
      : base(name, group, jobName, jobGroup)
    {
      StartTimeUtc = startTimeUtc;
      EndTimeUtc = endTimeUtc;
      RepeatCount = repeatCount;
      RepeatInterval = repeatInterval;
    }

        /// <summary>
        /// Get or set thhe number of times the <see cref="SimpleTrigger" /> should
        /// repeat, after which it will be automatically deleted.
        /// </summary>
        /// <seealso cref="RepeatIndefinitely" />
        public int RepeatCount
        {
            get { return repeatCount; }

            set
            {
                if (value < 0 && value != RepeatIndefinitely)
                {
                    throw new ArgumentException("Repeat count must be >= 0, use the constant RepeatIndefinitely for infinite.");
                }

                repeatCount = value;
            }
        }

        /// <summary>
        /// Get or set the the time interval at which the <see cref="SimpleTrigger" /> should repeat.
        /// </summary>
        public TimeSpan RepeatInterval
        {
            get { return repeatInterval; }

            set
            {
                if (value < TimeSpan.Zero)
                {
                    throw new ArgumentException("Repeat interval must be >= 0");
                }

                repeatInterval = value;
            }
        }

        /// <summary>
        /// Get or set the number of times the <see cref="SimpleTrigger" /> has already
        /// fired.
        /// </summary>
        public virtual int TimesTriggered
        {
            get { return timesTriggered; }
            set { timesTriggered = value; }
        }

        /// <summary> 
        /// Returns the final UTC time at which the <see cref="SimpleTrigger" /> will
        /// fire, if repeatCount is RepeatIndefinitely, null will be returned.
        /// <p>
        /// Note that the return time may be in the past.
        /// </p>
        /// </summary>
        public override NullableDateTime FinalFireTimeUtc
        {
            get
            {
                if (repeatCount == 0)
                {
                    return StartTimeUtc;
                }

                if (repeatCount == RepeatIndefinitely && !EndTimeUtc.HasValue)
                {
                    return null;
                }

                if (repeatCount == RepeatIndefinitely && !EndTimeUtc.HasValue)
                {
                    return null;
                }
                else if (repeatCount == RepeatIndefinitely)
                {
                    return GetFireTimeBefore(EndTimeUtc);
                }

                DateTime lastTrigger = StartTimeUtc.AddMilliseconds(repeatCount * repeatInterval.TotalMilliseconds);

                if (!EndTimeUtc.HasValue || lastTrigger < EndTimeUtc.Value)
                {
                    return lastTrigger;
                }
                else
                {
                    return GetFireTimeBefore(EndTimeUtc);
                }
            }
        }

        /// <summary>
        /// Tells whether this Trigger instance can handle events
        /// in millisecond precision.
        /// </summary>
        /// <value></value>
        public override bool HasMillisecondPrecision
        {
            get { return true; }
        }


    /// <summary>
    /// Validates the misfire instruction.
    /// </summary>
    /// <param name="misfireInstruction">The misfire instruction.</param>
    /// <returns></returns>
    protected override bool ValidateMisfireInstruction(int misfireInstruction)
    {
            return (misfireInstruction == Quartz.MisfireInstruction.SimpleTrigger.FireNow) 
                || (misfireInstruction == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithExistingCount) 
                || (misfireInstruction == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount)
                || (misfireInstruction == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount)
                || (misfireInstruction == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount)
                || (misfireInstruction == Quartz.MisfireInstruction.SmartPolicy);
               
    }

    /// <summary>
    /// Updates the <see cref="SimpleTrigger" />'s state based on the
        /// MisfireInstruction value that was selected when the <see cref="SimpleTrigger" />
    /// was created.
    /// </summary>
    /// <remarks>
    /// If MisfireSmartPolicyEnabled is set to true,
    /// then the following scheme will be used: <br />
    /// <ul>
    /// <li>If the Repeat Count is 0, then the instruction will
        /// be interpreted as <see cref="MisfireInstruction.SimpleTrigger.FireNow" />.</li>
    /// <li>If the Repeat Count is <see cref="RepeatIndefinitely" />, then
        /// the instruction will be interpreted as <see cref="MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount" />.
        /// <b>WARNING:</b> using MisfirePolicy.SimpleTrigger.RescheduleNowWithRemainingRepeatCount 
    /// with a trigger that has a non-null end-time may cause the trigger to 
    /// never fire again if the end-time arrived during the misfire time span. 
    /// </li>
    /// <li>If the Repeat Count is > 0, then the instruction
        /// will be interpreted as <see cref="MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount" />.
    /// </li>
    /// </ul>
    /// </remarks>
    public override void UpdateAfterMisfire(ICalendar cal)
    {
      int instr = MisfireInstruction;
      if (instr == Quartz.MisfireInstruction.SmartPolicy)
      {
        if (RepeatCount == 0)
        {
                    instr = Quartz.MisfireInstruction.SimpleTrigger.FireNow;
        }
        else if (RepeatCount == RepeatIndefinitely)
        {
                    instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount;
              
        }
        else
        {
                    instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount;
        }
      }
            else if (instr == Quartz.MisfireInstruction.SimpleTrigger.FireNow && RepeatCount != 0)
      {
                instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount;
      }

            if (instr == Quartz.MisfireInstruction.SimpleTrigger.FireNow)
      {
        SetNextFireTime(DateTime.UtcNow);
      }
      else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithExistingCount)
      {
                NullableDateTime newFireTime = GetFireTimeAfter(DateTime.UtcNow);

                while (newFireTime.HasValue && cal != null && !cal.IsTimeIncluded(newFireTime.Value))
        {
          newFireTime = GetFireTimeAfter(newFireTime);

                    if (!newFireTime.HasValue)
                    {
                        break;
                    }
                    
                    //avoid infinite loop
                    if (newFireTime.Value.Year > YearToGiveupSchedulingAt)
                    {
                        newFireTime = null;
                    }
        }
        SetNextFireTime(newFireTime);
      }
      else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount)
      {
                NullableDateTime newFireTime = GetFireTimeAfter(DateTime.UtcNow);

        while (newFireTime.HasValue && cal != null && !cal.IsTimeIncluded(newFireTime.Value))
        {
          newFireTime = GetFireTimeAfter(newFireTime);

                    if (!newFireTime.HasValue)
                    {
                        break;
                    }

                    //avoid infinite loop
                    if (newFireTime.Value.Year > YearToGiveupSchedulingAt)
                    {
                        newFireTime = null;
                    }
        }

        if (newFireTime.HasValue)
        {
          int timesMissed = ComputeNumTimesFiredBetween(nextFireTimeUtc, newFireTime);
          TimesTriggered = TimesTriggered + timesMissed;
        }

        SetNextFireTime(newFireTime);
      }
      else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount)
      {
        DateTime newFireTime = DateTime.UtcNow;
        if (repeatCount != 0 && repeatCount != RepeatIndefinitely)
        {
          RepeatCount = RepeatCount - TimesTriggered;
          TimesTriggered = 0;
        }

        if (EndTimeUtc.HasValue && EndTimeUtc.Value < newFireTime) 
        {
          SetNextFireTime(null); // We are past the end time
        } 
        else 
        {
          StartTimeUtc = newFireTime;
          SetNextFireTime(newFireTime);
        }
      }
      else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount)
      {
        DateTime newFireTime = DateTime.UtcNow;
        int timesMissed = ComputeNumTimesFiredBetween(nextFireTimeUtc, newFireTime);

        if (repeatCount != 0 && repeatCount != RepeatIndefinitely)
        {
          int remainingCount = RepeatCount - (TimesTriggered + timesMissed);
          if (remainingCount <= 0)
          {
            remainingCount = 0;
          }
          RepeatCount = remainingCount;
          TimesTriggered = 0;
        }


        if (EndTimeUtc.HasValue && EndTimeUtc.Value < newFireTime) 
        {
          SetNextFireTime(null); // We are past the end time
        } 
        else 
        {
          StartTimeUtc = newFireTime;
          SetNextFireTime(newFireTime);
        } 
      }
    }

    /// <summary>
    /// Called when the <see cref="IScheduler" /> has decided to 'fire'
    /// the trigger (Execute the associated <see cref="IJob" />), in order to
    /// give the <see cref="Trigger" /> a chance to update itself for its next
    /// triggering (if any).
    /// </summary>
    /// <seealso cref="JobExecutionException" />
    public override void Triggered(ICalendar cal)
    {
      timesTriggered++;
      previousFireTimeUtc = nextFireTimeUtc;
      nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc);

      while (nextFireTimeUtc.HasValue && cal != null && !cal.IsTimeIncluded(nextFireTimeUtc.Value))
      {
        nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc);

                if (!nextFireTimeUtc.HasValue)
                {
                     break;
                }

                //avoid infinite loop
                if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt)
                {
                    nextFireTimeUtc = null;
                }
      }
    }


        /// <summary>
        /// Updates the instance with new calendar.
        /// </summary>
        /// <param name="calendar">The calendar.</param>
        /// <param name="misfireThreshold">The misfire threshold.</param>
    public override void UpdateWithNewCalendar(ICalendar calendar, TimeSpan misfireThreshold)
    {
      nextFireTimeUtc = GetFireTimeAfter(previousFireTimeUtc);

            if (nextFireTimeUtc == null || calendar == null)
            {
                return;
            }

            DateTime now = DateTime.UtcNow;
            while (nextFireTimeUtc.HasValue && !calendar.IsTimeIncluded(nextFireTimeUtc.Value))
            {
                nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc);

                if (!nextFireTimeUtc.HasValue)
                {
                    break;
                }

                //avoid infinite loop
                if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt)
                {
                    nextFireTimeUtc = null;
                }

                if (nextFireTimeUtc != null && nextFireTimeUtc.Value < now)
                {
                    TimeSpan diff = now - nextFireTimeUtc.Value;
                    if (diff >= misfireThreshold)
                    {
                        nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc);
                    }
                }
            }
        }

    /// <summary>
    /// Called by the scheduler at the time a <see cref="Trigger" /> is first
    /// added to the scheduler, in order to have the <see cref="Trigger" />
    /// compute its first fire time, based on any associated calendar.
    /// <p>
    /// After this method has been called, <see cref="GetNextFireTimeUtc" />
    /// should return a valid answer.
    /// </p>
    /// </summary>
    /// <returns> 
    /// The first time at which the <see cref="Trigger" /> will be fired
    /// by the scheduler, which is also the same value <see cref="GetNextFireTimeUtc" />
    /// will return (until after the first firing of the <see cref="Trigger" />).
    /// </returns>
        public override NullableDateTime ComputeFirstFireTimeUtc(ICalendar cal)
      {
      nextFireTimeUtc = StartTimeUtc;

      while (nextFireTimeUtc.HasValue && cal != null && !cal.IsTimeIncluded(nextFireTimeUtc.Value))
      {
        nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc);

                if (!nextFireTimeUtc.HasValue)
                {
                    break;
                }

                //avoid infinite loop
                if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt)
                {
                    return null;
                }
      }

      return nextFireTimeUtc;
    }

    
    /// <summary>
    /// Returns the next time at which the <see cref="SimpleTrigger" /> will
    /// fire. If the trigger will not fire again, <see langword="null" /> will be
    /// returned. The value returned is not guaranteed to be valid until after
    /// the <see cref="Trigger" /> has been added to the scheduler.
    /// </summary>
        public override NullableDateTime GetNextFireTimeUtc()
    {
      return nextFireTimeUtc;
    }

    /// <summary>
    /// Returns the previous time at which the <see cref="SimpleTrigger" /> fired.
    /// If the trigger has not yet fired, <see langword="null" /> will be
    /// returned.
    /// </summary>
        public override NullableDateTime GetPreviousFireTimeUtc()
    {
      return previousFireTimeUtc;
    }

    /// <summary>
    /// Set the next UTC time at which the <see cref="SimpleTrigger" /> should fire.
    /// <strong>This method should not be invoked by client code.</strong>
    /// </summary>
        public void SetNextFireTime(NullableDateTime fireTimeUtc)
    {
      nextFireTimeUtc = DateTimeUtil.AssumeUniversalTime(fireTimeUtc);
    }

    /// <summary>
    /// Set the previous UTC time at which the <see cref="SimpleTrigger" /> fired.
    /// <strong>This method should not be invoked by client code.</strong>
    /// </summary>
        public virtual void SetPreviousFireTime(NullableDateTime fireTimeUtc)
    {
      previousFireTimeUtc = DateTimeUtil.AssumeUniversalTime(fireTimeUtc);
    }

    /// <summary> 
    /// Returns the next UTC time at which the <see cref="SimpleTrigger" /> will
    /// fire, after the given UTC time. If the trigger will not fire after the given
    /// time, <see langword="null" /> will be returned.
    /// </summary>
        public override NullableDateTime GetFireTimeAfter(NullableDateTime afterTimeUtc)
    {
            afterTimeUtc = DateTimeUtil.AssumeUniversalTime(afterTimeUtc);

      if (complete)
      {
        return null;
      }

      if ((timesTriggered > repeatCount) && (repeatCount != RepeatIndefinitely))
      {
        return null;
      }

      if (!afterTimeUtc.HasValue)
      {
        afterTimeUtc = DateTime.UtcNow;
      }

      if (repeatCount == 0 && afterTimeUtc.Value.CompareTo(StartTimeUtc) >= 0)
      {
        return null;
      }

      DateTime startMillis = StartTimeUtc;
      DateTime afterMillis = afterTimeUtc.Value;
      DateTime endMillis = !EndTimeUtc.HasValue ? DateTime.MaxValue : EndTimeUtc.Value;


      if (endMillis <= afterMillis) 
      {
        return null;
      }

      if (afterMillis < startMillis) 
      {
        return startMillis;
      }

      long numberOfTimesExecuted = (long) (((long) (afterMillis - startMillis).TotalMilliseconds / repeatInterval.TotalMilliseconds) + 1);

      if ((numberOfTimesExecuted > repeatCount) && 
        (repeatCount != RepeatIndefinitely)) 
      {
        return null;
      }

      DateTime time = startMillis.AddMilliseconds(numberOfTimesExecuted * repeatInterval.TotalMilliseconds);

      if (endMillis <= time) 
      {
        return null;
      }


      return time;
    }

    /// <summary>
    /// Returns the last UTC time at which the <see cref="SimpleTrigger" /> will
    /// fire, before the given time. If the trigger will not fire before the
    /// given time, <see langword="null" /> will be returned.
    /// </summary>
        public virtual NullableDateTime GetFireTimeBefore(NullableDateTime endUtc)
    {
            endUtc = DateTimeUtil.AssumeUniversalTime(endUtc);

      if (endUtc.Value < StartTimeUtc)
      {
        return null;
      }

      int numFires = ComputeNumTimesFiredBetween(StartTimeUtc, endUtc);
      return StartTimeUtc.AddMilliseconds(numFires*repeatInterval.TotalMilliseconds);
    }

        /// <summary>
        /// Computes the number of times fired between the two UTC date times.
        /// </summary>
        /// <param name="startTimeUtc">The UTC start date and time.</param>
        /// <param name="endTimeUtc">The UTC end date and time.</param>
        /// <returns></returns>
        public virtual int ComputeNumTimesFiredBetween(NullableDateTime startTimeUtc, NullableDateTime endTimeUtc)
    {
            startTimeUtc = DateTimeUtil.AssumeUniversalTime(startTimeUtc);
            endTimeUtc = DateTimeUtil.AssumeUniversalTime(endTimeUtc);

      long time = (long) (endTimeUtc.Value - startTimeUtc.Value).TotalMilliseconds;
      return (int) (time/repeatInterval.TotalMilliseconds);
    }

    /// <summary> 
    /// Determines whether or not the <see cref="SimpleTrigger" /> will occur
    /// again.
    /// </summary>
    public override bool GetMayFireAgain()
    {
      return GetNextFireTimeUtc().HasValue;
    }

    /// <summary>
    /// Validates whether the properties of the <see cref="JobDetail" /> are
    /// valid for submission into a <see cref="IScheduler" />.
    /// </summary>
    public override void Validate()
    {
      base.Validate();

      if (repeatCount != 0 && repeatInterval.TotalMilliseconds < 1)
      {
        throw new SchedulerException("Repeat Interval cannot be zero.", SchedulerException.ErrorClientError);
      }
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.