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}