<?xml version="1.0" encoding="ISO-8859-1"?>
<ss:description type="trigger" id="com.autodesk.XML.DailyTrigger"
		xmlns:ss="urn:Autodesk:Server"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="urn:Autodesk:Server Schema.xsd">
	<ss:title>
		Daily
	</ss:title>
	<ss:options>
		<ss:label/>
		<ss:option name="hour">
			<ss:label>Hour</ss:label>
			<ss:tooltip>
				Enter the hour of the day the trigger will fire.
			</ss:tooltip>
			<ss:spinner>
				<ss:integer min="0" max="23" default="12" />
			</ss:spinner>
		</ss:option>
		<ss:option name="minute">
			<ss:label>Minute</ss:label>
			<ss:tooltip>
				Enter the minute in the hour the trigger will fire.
			</ss:tooltip>
			<ss:spinner>
				<ss:integer min="0" max="59" default="0" />
			</ss:spinner>
		</ss:option>
	</ss:options>
	<ss:code>
from com.autodesk.actions import StopEvent, WorkflowDelegate
import time
from java.util.concurrent import Semaphore
from java.util import Calendar, Date, Timer, TimerTask

# It would be nice to use the Python sched module but I can't get
# it to work properly in this version of Jython.

timer = None
semaphore = None
stopRequested = 0

class DailyTimerTask(TimerTask):
	def __init__(self, w, s):
		self.workflow = w
		self.semaphore = s

	def run(self):
		# The Timer calls this method which simply triggers the workflow
		# causing it to run, and when that completes releases the semaphore
		# so that the main thread and submit a new scheduled task.
		self.workflow.trigger()
		self.semaphore.release()

def main(workflow, hour, minute):
	global timer
	global semaphore
	global stopRequested

	if workflow == None or minute == None or hour == None:
		return

	# Create a semaphore and immediately acquire it. Later when we attempt
	# to acquire it after scheduling the task, it will force the thread
	# to block. It will block until DailyTimerTask.run() releases it
	# which it will do when it has completed.
	semaphore = Semaphore(1)
	semaphore.acquire()

	# Create the Timer object that will launch the tasks.
	timer = Timer()

	# This loop gets a new calendar instance each time it runs. This
	# ensures the trigger fires a day after the last time the triggered
	# event completed. If a task takes longer than 24 hours the trigger
	# will not be fired until the day after the task has finished running.
	# There will not be two tasks running at the same time.
	while not stopRequested:
		# If the time is later than the trigger time, wait until tomorrow.
		cal = Calendar.getInstance()
		if hour &lt; cal.get(Calendar.HOUR_OF_DAY) or (hour == cal.get(Calendar.HOUR_OF_DAY) and minute &lt;= cal.get(Calendar.MINUTE)):
			cal.add(Calendar.DAY_OF_MONTH, 1)
		cal.set(Calendar.HOUR_OF_DAY, hour)
		cal.set(Calendar.MINUTE, minute)
		cal.set(Calendar.SECOND, 0)

		# Create the object that will do the work. Once a task has run it
		# cannot be rescheduled.
		task = DailyTimerTask(workflow, semaphore)

		# Schedule the task to run.
		timer.schedule(task, cal.getTime())

		# timer.schedule() does not block. So we wait on the release of
		# a semaphore which was first acquired above. DailyTimerTask.run()
		# will release it which will allow this code to acquire it so that
		# the whole thing can start again. (i.e. next time we arrive here
		# the semaphore will be unavailable so the code will block.)
		semaphore.acquire()

# Receive events from outside this script. The only events this code
# cares about are StopEvents from the UI.
def eventReceived(event):
	# TODO: Check that the event is a StopEvent
	global timer
	global semaphore
	global stopRequested

	if isinstance(event, StopEvent):
		stopRequested = 1
		if timer != None:
			timer.cancel()
			semaphore.release()

	</ss:code>
</ss:description>
