001    package edu.nrao.sss.util;
002    
003    import java.util.EnumSet;
004    
005    /**
006     * An indicator for where an event is in its life cycle.
007     * <p>
008     * This status is meant for use by atomic events -- those that
009     * are not collections of other events.  A related but distinct
010     * enumeration, {@link EventSetStatus}, is available for
011     * events that are collections of other events.  For example,
012     * in the SSS Model, an "execution block" would be atomic and
013     * use this enumeration, while a a "scheduling block", which
014     * holds a collection of execution blocks, would use the
015     * <tt>EventSetStatus</tt> enumeration.</p>
016     * <p>
017     * <b>Version Info:</b>
018     * <table style="margin-left:2em">
019     *   <tr><td>$Revision: 1042 $</td></tr>
020     *   <tr><td>$Date: 2008-01-14 09:37:55 -0700 (Mon, 14 Jan 2008) $</td></tr>
021     *   <tr><td>$Author: dharland $ (last person to modify)</td></tr>
022     * </table></p>
023     * 
024     * @author David M. Harland
025     * @since 2007-08-15
026     */
027    public enum EventStatus
028    {
029      /**
030       * Indicates that an event is not yet ready to be scheduled.
031       * This is often the initial state for an event and usually
032       * means that the event is being crafted.
033       */
034      NOT_READY_TO_BE_SCHEDULED
035      {
036        void init()
037        {
038          validNextStatuses = EnumSet.of(NOT_YET_SCHEDULED,
039                                         CANCELED);
040          
041          parallelStatus = EventSetStatus.NOT_READY_TO_BE_SCHEDULED;
042          
043          initialized = true;
044        }
045      },
046      
047      /**
048       * Indicates that an event has not yet been scheduled.
049       */
050      NOT_YET_SCHEDULED
051      {
052        void init()
053        {
054          validNextStatuses = EnumSet.of(SCHEDULED_BUT_NOT_STARTED,
055                                         ON_HOLD,
056                                         CANCELED,
057                                         NOT_READY_TO_BE_SCHEDULED);
058          
059          parallelStatus = EventSetStatus.NOT_YET_SCHEDULED;
060          
061          initialized = true;
062        }
063      },
064      
065      /**
066       * Indicates that an event has been scheduled but has not yet begun.
067       */
068      SCHEDULED_BUT_NOT_STARTED
069      {
070        void init()
071        {
072          validNextStatuses =
073            EnumSet.of(IN_PROGRESS,
074                       ON_HOLD,
075                       CANCELED,
076                       SCHEDULED_BUT_NOT_STARTED, //allows for RE-scheduling
077                       NOT_YET_SCHEDULED); //also allows for RE-scheduling
078          
079          parallelStatus = EventSetStatus.SCHEDULED_BUT_NOT_STARTED;
080          
081          initialized = true;
082        }
083      },
084      
085      /**
086       * Indicates that an event is currently in progress.
087       */
088      IN_PROGRESS
089      {
090        void init()
091        {
092          validNextStatuses =
093            EnumSet.of(COMPLETED,
094                       NOT_YET_SCHEDULED, //if interrupted, but not canceled 
095                       CANCELED);
096          
097          parallelStatus = EventSetStatus.IN_PROGRESS;
098          
099          initialized = true;
100        }
101      },
102      
103      /**
104       * Indicates that an event has been completed.
105       */
106      COMPLETED
107      {
108        void init()
109        {
110          validNextStatuses = EnumSet.noneOf(EventStatus.class);
111          
112          parallelStatus = EventSetStatus.COMPLETED;
113          
114          initialized = true;
115        }
116      },
117      
118      /**
119       * Indicates that an event has been put on hold.
120       * A event on hold can be resumed or restarted at a later time.
121       * An actor must act to take an event out of this
122       * status.  Note that this is subtly different than postponing
123       * an event, which places its status immediately back to
124       * <tt>NOT_YET_SCHEDULED</tt>.
125       */
126      ON_HOLD
127      {
128        void init()
129        {
130          validNextStatuses = EnumSet.of(NOT_YET_SCHEDULED,
131                                         CANCELED);
132          
133          parallelStatus = EventSetStatus.ON_HOLD;
134          
135          initialized = true;
136        }
137      },
138      
139      /**
140       * Indicates that an event has been canceled.
141       * A canceled event will not be resumed or restarted.
142       */
143      CANCELED
144      {
145        void init()
146        {
147          validNextStatuses = EnumSet.noneOf(EventStatus.class);
148          
149          parallelStatus = EventSetStatus.CANCELED;
150          
151          initialized = true;
152        }
153      };
154      
155      boolean initialized = false;
156      
157      EnumSet<EventStatus> validNextStatuses;
158      EventSetStatus       parallelStatus;
159    
160      /**
161       * Initializes this status.
162       * (I had wanted to do this via the constructor, but we cannot make
163       * forwared references to other elements of this enumeration --
164       * at least as of java 1.6.)
165       */
166      abstract void init();
167      
168      /**
169       * Returns <i>true</i> if this status is a final status for an event.
170       * <tt>CANCELED</tt> and <tt>COMPLETED</tt> are examples of final
171       * statuses.
172       * 
173       * @return <i>true</i> if this status is a final status for an event.
174       */
175      public boolean isFinal()
176      {
177        if (!initialized)
178          init();
179    
180        //Statuses that have no valid next statuses are final
181        return validNextStatuses.size() == 0;
182      }
183      
184      /**
185       * Returns a set of status that are permitted to follow this status.
186       * For example, if an event has been scheduled, the only status that
187       * may immediately follow are "in progress" and "on hold"; if an event
188       * has been completed, there are no valid next statuses.
189       * 
190       * @return a set of status that are permitted to follow this status.
191       */
192      public EnumSet<EventStatus> validNextStatuses()
193      {
194        if (!initialized)
195          init();
196        
197        return validNextStatuses.clone();
198      }
199      
200      /** Returns its counter part in EventSetStatus. */
201      EventSetStatus toEventSetStatus()
202      {
203        if (!initialized)
204          init();
205        
206        return parallelStatus;
207      }
208      
209      /**
210       * Returns a text representation of this enumeration constant.
211       * @return a text representation of this enumeration constant.
212       */
213      public String toString()
214      {
215        return EnumerationUtility.getSharedInstance().enumToString(this);
216      }
217      
218      /**
219       * Returns the status represented by {@code text}.
220       * <p>
221       * For details about the transformation, see
222       * {@link EnumerationUtility#enumFromString(Class, String)}.</p>
223       * 
224       * @param text a text representation of a status.
225       * 
226       * @return the status represented by {@code text}.
227       */
228      public static EventStatus fromString(String text)
229      {
230        return EnumerationUtility.getSharedInstance()
231                                 .enumFromString(EventStatus.class, text);
232      }
233    }