001/* An actor that delays the the execution of the model until a specified time. 002 003 Copyright (c) 2006-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.actor.lib; 029 030import java.text.DateFormat; 031import java.text.ParseException; 032import java.util.Calendar; 033import java.util.Date; 034 035import ptolemy.actor.Director; 036import ptolemy.actor.TypedAtomicActor; 037import ptolemy.data.expr.StringParameter; 038import ptolemy.kernel.CompositeEntity; 039import ptolemy.kernel.util.IllegalActionException; 040import ptolemy.kernel.util.NameDuplicationException; 041 042/////////////////////////////////////////////////////////////////// 043//// DelayStart 044 045/** 046 This actor, which has no ports, delays the execution of the model 047 until a specified time by sleeping the thread that calls the 048 initialize() method until the specified time. If the time is 049 in the past, then there is no delay. The time is assumed to be 050 today, and is given as in "1:00 pm" for one in the afternoon. 051 <p> 052 If this actor is used in SDF, then the director must be set 053 to allow disconnected graphs. Note that it makes no sense 054 to use this actor in PN or CSP, since it will only delay the 055 start of its own thread. 056 057 @author Edward A. Lee 058 @version $Id$ 059 @since Ptolemy II 5.2 060 061 @Pt.ProposedRating Yellow (eal) 062 @Pt.AcceptedRating Red (cxh) 063 */ 064public class DelayStart extends TypedAtomicActor { 065 /** Construct an actor with the given container and name. 066 * @param container The container. 067 * @param name The name of this actor. 068 * @exception IllegalActionException If the actor cannot be contained 069 * by the proposed container. 070 * @exception NameDuplicationException If the container already has an 071 * actor with this name. 072 */ 073 public DelayStart(CompositeEntity container, String name) 074 throws NameDuplicationException, IllegalActionException { 075 super(container, name); 076 077 startTime = new StringParameter(this, "startTime"); 078 startTime.setExpression("12:00 pm"); 079 } 080 081 /////////////////////////////////////////////////////////////////// 082 //// ports and parameters //// 083 084 /** The start time. FIXME: Spec. 085 * This is a string that defaults to FIXME 086 */ 087 public StringParameter startTime; 088 089 /////////////////////////////////////////////////////////////////// 090 //// public methods //// 091 092 /** Sleep until the specified time. 093 * @exception IllegalActionException If the parent class throws it, 094 * or if the time cannot be parsed. 095 */ 096 @Override 097 public void initialize() throws IllegalActionException { 098 DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT); 099 100 try { 101 while (true) { 102 Date date = dateFormat.parse(startTime.stringValue()); 103 104 // Unfortunately, in the above, if no date is given, 105 // then the time is assumed to be on January 1, 1970. 106 // Detect this, and reset the date to today. 107 Calendar calendar = Calendar.getInstance(); 108 calendar.setTime(date); 109 110 if (calendar.get(Calendar.YEAR) == 1970) { 111 // Assume the date wasn't set. 112 Calendar now = Calendar.getInstance(); 113 calendar.set(Calendar.YEAR, now.get(Calendar.YEAR)); 114 calendar.set(Calendar.DAY_OF_MONTH, 115 now.get(Calendar.DAY_OF_MONTH)); 116 calendar.set(Calendar.MONTH, now.get(Calendar.MONTH)); 117 date = calendar.getTime(); 118 } 119 120 if (_debugging) { 121 _debug("Delaying start until: " + date); 122 } 123 124 long time = date.getTime(); 125 Director director = getDirector(); 126 long current = System.currentTimeMillis(); 127 128 if (time <= current) { 129 break; 130 } 131 132 // Synchronizing on the director here is incorrect. 133 // See Workspace.wait(Object) 134 // synchronized (director) { 135 try { 136 _workspace.wait(director, time - current); 137 } catch (InterruptedException e) { 138 // Ignore and continue; 139 } 140 // } 141 } 142 } catch (ParseException e) { 143 throw new IllegalActionException(this, 144 "Invalid startTime: " + startTime.stringValue()); 145 } 146 147 super.initialize(); 148 } 149}