001/* An abstract base class for a schedule element.
002
003 Copyright (c) 2003-2013 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.graph.sched;
029
030import java.util.ConcurrentModificationException;
031import java.util.Iterator;
032import java.util.Map;
033
034///////////////////////////////////////////////////////////////////
035//// ScheduleElement
036
037/**
038 This is an abstract base class for a schedule element. Instances of the
039 Schedule and Firing subclasses are used to construct a schedule(static or
040 dynamic).
041 A Schedule can be thought of as a structure that consists of an iteration
042 count and a list of ScheduleElements. A ScheduleElement can be a
043 Firing, or another Schedule. It is usually required that,
044 all of the lowest-level ScheduleElements are Firings. It is
045 up to the scheduler to enforce this, however. The Schedule class is a
046 ScheduleElement that is a schedule. Schedules are created by schedule analyses.
047 The Firing class is a ScheduleElement that contains a Firing element. Therefore,
048 the top-level ScheduleElement must be an instance of Schedule, and all
049 of the lowest-level elements must each be instances of Firing.
050 <p>
051 This base class implements the getIterationCount() and setIterationCount()
052 methods, which return and set the iteration count for this schedule element.
053 A default value of 1 is used for the iteration count.
054
055 @author Shahrooz Shahparnia, Mingyung Ko
056 University of Maryland at College Park, based on a file by
057 Brian K. Vogel, Steve Neuendorffer
058 @version $Id$
059 @since Ptolemy II 4.0
060 @Pt.ProposedRating red (shahrooz)
061 @Pt.AcceptedRating red (ssb)
062 @see ptolemy.graph.sched.Firing
063 @see ptolemy.graph.sched.Schedule
064 @see ptolemy.graph.sched.ScheduleElement
065 @see ptolemy.graph.sched.ScheduleAnalysis
066 */
067public abstract class ScheduleElement {
068    /** Construct a schedule element with an iteration count of 1 and
069     *  with no parent schedule element. The constructor that takes
070     *  a parameter should be used when constructing a schedule
071     *  element that is contained by another schedule element.
072     */
073    public ScheduleElement() {
074        super();
075        _scheduleVersion = 0;
076    }
077
078    /** Construct a schedule element with an iteration count of 1 and
079     *  with no parent schedule element. The constructor that takes
080     *  a parameter should be used when constructing a schedule
081     *  element that is contained by another schedule element.
082     *
083     * @param firingElementClass The class of the firing elements that will be
084     * added to this schedule.
085     */
086    public ScheduleElement(Class firingElementClass) {
087        super();
088        _scheduleVersion = 0;
089        _firingElementClass = firingElementClass;
090    }
091
092    ///////////////////////////////////////////////////////////////////
093    ////                         public methods                    ////
094
095    /** Return the class type of the firing element in this class. Only firing
096     *  elements of this type are allowed set as a firing element of this
097     *  ScheduleElement.
098     *  @return Return the class type of the firing element in this class.
099     */
100    public Class firingElementClass() {
101        return _firingElementClass;
102    }
103
104    /** Return the firing element invocation sequence of the schedule in the
105     *  form of a sequence of firing elements. For a valid schedule, all of the
106     *  lowest-level nodes should be an instance of Firing. If the
107     *  schedule is not valid, then the returned iterator will contain
108     *  null elements.
109     *  <p>
110     *  It must be implemented by the derived classes to provide the proper
111     *  functionality.
112     *
113     *  @return An iterator over a sequence of firing elements.
114     *  @exception ConcurrentModificationException If the
115     *  underlying schedule structure is modified while the iterator
116     *  is active.
117     */
118    public abstract Iterator firingElementIterator();
119
120    /** Return the firing invocation sequence in the form
121     *  of a sequence of firings. All of the lowest-level nodes
122     *  should be an instance of Firing. Otherwise, the returned
123     *  iterator will contain null elements.
124     *
125     *  @return An iterator over a sequence of firings.
126     */
127    public abstract Iterator firingIterator();
128
129    /** Return the iteration count for this schedule. This method
130     *  returns the iteration count that was set by
131     *  setIterationCount(). If setIterationCount() was never invoked,
132     *  then a value of one is returned.
133     *
134     *  @return The iteration count for this schedule.
135     *  @see #setIterationCount(int)
136     */
137    public int getIterationCount() {
138        return _iterationCount;
139    }
140
141    /** Return the parent schedule element of this schedule element.
142     *  @return Return the parent schedule element of this schedule element.
143     *  @see #setParent(ScheduleElement)
144     */
145    public ScheduleElement getParent() {
146        return _parent;
147    }
148
149    /** Set the iteration count for this schedule. The
150     *  getIterationCount() method will return the value set
151     *  by this method. If this method is not invoked, a default
152     *  value of one will be used.
153     *
154     *  @param count The iteration count for this schedule.
155     *  @see #getIterationCount()
156     */
157    public void setIterationCount(int count) {
158        _incrementVersion();
159        _iterationCount = count;
160    }
161
162    /** Set the parent schedule element of this schedule element to
163     *  the specified schedule element. If this schedule element is
164     *  added to another schedule element (the parent), then the
165     *  add() method of the parent will invoke this method.
166     *  This association is used to notify the parent schedule
167     *  element when changes are made to this schedule element.
168     *
169     *  @param parent The parent schedule element of this schedule
170     *   element.
171     *  @see #getParent()
172     */
173    public void setParent(ScheduleElement parent) {
174        _parent = parent;
175    }
176
177    /** Print the schedule in a nested parenthesis style and set
178     *  character 'space' as the delimiter. Please see
179     *  {@link #toParenthesisString(Map, String)}.
180     *
181     *  @param nameMap The map from firing elements to their short names.
182     *  @return A nested parenthesis expression of the schedule.
183     */
184    public String toParenthesisString(Map nameMap) {
185        return toParenthesisString(nameMap, " ");
186    }
187
188    /** Print the schedule in a nested parenthesis style. There are an
189     *  iteration count (an integer) and some (at least one) iterands
190     *  within each pair of parentheses. The iterands could be either
191     *  firings or another schedules. For each firing, it is the firing
192     *  element (not the firing itself) that will be displayed. To
193     *  prevent long and unfriendly print out, brief names of elements
194     *  are required. Please reference the argument <code>nameMap</code>.
195     *
196     *  @param nameMap The map from firing elements to their short names.
197     *  @param delimiter The delimiter between iterands.
198     *  @return A nested parenthesis expression of the schedule.
199     */
200    public abstract String toParenthesisString(Map nameMap, String delimiter);
201
202    ///////////////////////////////////////////////////////////////////
203    ////                         protected methods                 ////
204
205    /** Return the current version of this schedule element. The
206     *  version changes whenever a structural change is made to
207     *  this schedule element.
208     *
209     *  @return The current version of this schedule element.
210     */
211    protected long _getVersion() {
212        return _scheduleVersion;
213    }
214
215    /** Increment the version of this schedule element and if this schedule
216     *  element has a parent schedule, increment the version of the parent
217     *  schedule as well. This method will therefore cause a version update
218     *  to propagate up to all parent schedule elements. This method is
219     *  called when a structure change is made to this schedule element, and
220     *  is also called by the immediate children of this schedule element
221     *  when they are modified.
222     */
223    protected void _incrementVersion() {
224        _scheduleVersion++;
225
226        if (_parent != null) {
227            _parent._incrementVersion();
228        }
229    }
230
231    ///////////////////////////////////////////////////////////////////
232    ////                         private variables                 ////
233
234    /** The parent schedule of this schedule. Null means this schedule
235     *  has no parent.
236     */
237    protected ScheduleElement _parent = null;
238
239    ///////////////////////////////////////////////////////////////////
240    ////                         private variables                 ////
241    // The iteration count for this schedule element.
242    private int _iterationCount = 1;
243
244    // The current version of this schedule.
245    private long _scheduleVersion;
246
247    private Class _firingElementClass;
248}