View Javadoc

1   /*
2    * jSDP: A Java implementation of SDP protocol Copyright (C) 2007 Claudio Di
3    * Vita
4    */
5   package net.sourceforge.jsdp;
6   
7   import java.util.Vector;
8   
9   import net.sourceforge.jsdp.util.TypedTime;
10  
11  /**
12   * A <tt>RepeatTime</tt> represents a <b>r=<i>&lt;field value&gt;</i></b>
13   * field contained in a SDP message. A repeat time field specify repeat times
14   * for a session: his consists of a <i>repeat interval</i>, an <i>active
15   * duration</i> and a list of offsets relative to the
16   * {@link Time#getStartTime()} start time.
17   * 
18   * @see Time
19   * 
20   * @since 0.1.0
21   * 
22   * @version 1.0
23   * 
24   * @author <a href="mailto:cdivita@users.sourceforge.net">Claudio Di Vita</a>
25   */
26  public class RepeatTime implements Field {
27  
28      /** The class Stream Unique Identifier, SUID */
29      private static final long serialVersionUID = -7772961172651467572L;
30  
31      /** The repeat interval */
32      protected long repeatInterval;
33  
34      /** The active duraction */
35      protected long activeDuration;
36  
37      /** The list of offset relative to the <b>t</b> field start time */
38      protected Vector offsets;
39  
40      /** Indicates if the field will be output as a typed time or a number */
41      protected boolean isTyped;
42  
43      /**
44       * Creates a new <tt>RepeatTime</tt>.
45       */
46      protected RepeatTime() {
47  
48          super();
49      }
50  
51      /**
52       * Creates a new <tt>RepeatTime</tt>.
53       * 
54       * @param repeatInterval the repeat interval
55       * 
56       * @param activeDuration the active duration
57       * 
58       * @param offset the offset
59       * 
60       * @throws SDPException if the parameters are not valid
61       */
62      public RepeatTime(final long repeatInterval, final long activeDuration, final long offset) throws SDPException {
63  
64          super();
65  
66          this.isTyped = true;
67  
68          setActiveDuration(activeDuration);
69          setRepeatInterval(repeatInterval);
70  
71          this.offsets = new Vector(3);
72          addOffset(offset);
73      }
74  
75      /**
76       * Creates a new <tt>RepeatTime</tt>.
77       * 
78       * @param repeatInterval the repeat interval
79       * 
80       * @param activeDuration the active duration
81       * 
82       * @param offsets the offsets
83       * 
84       * @throws SDPException if the parameters are not valid
85       */
86      public RepeatTime(final long repeatInterval, final long activeDuration, final long[] offsets) throws SDPException {
87  
88          super();
89  
90          this.isTyped = true;
91  
92          setRepeatInterval(repeatInterval);
93          setActiveDuration(activeDuration);
94  
95          this.offsets = new Vector(offsets.length);
96          for (int i = 0; i < offsets.length; i++) {
97              addOffset(offsets[i]);
98          }
99      }
100 
101     /**
102      * Parse an input string and constructs the equivalent repeat time field.
103      * 
104      * @param field the string to parse
105      * 
106      * @return a new <tt>RepeatTime</tt> instance
107      * 
108      * @throws SDPParseException if an error occurs while parsing
109      */
110     public static RepeatTime parse(final String field) throws SDPParseException {
111 
112         if (!field.startsWith("r=")) {
113             throw new SDPParseException("The string \"" + field + "\" isn't a repeat time field");
114         }
115 
116         RepeatTime r = null;
117 
118         long repeatInterval;
119         long activeDuration;
120         long[] offsets;
121 
122         String[] values = field.substring(2).split(" ");
123 
124         try {
125             switch (values.length) {
126                 case 0:
127                 case 1:
128                 case 2:
129                     throw new SDPParseException("The string \"" + field + "\" isn't a valid repeat time field");
130                 default:
131                     /* Get the repeat interval */
132                     repeatInterval = TypedTime.getTime(values[0]);
133 
134                     /* Get the active duraction */
135                     activeDuration = TypedTime.getTime(values[1]);
136 
137                     /* Get the offsets */
138                     offsets = new long[values.length - 2];
139                     for (int i = 0; i < offsets.length; i++) {
140                         offsets[i] = TypedTime.getTime(values[i + 2]);
141                     }
142 
143                     /* Create the field */
144                     r = new RepeatTime(repeatInterval, activeDuration, offsets);
145             }
146         }
147         catch (SDPException parseException) {
148             throw new SDPParseException("The string \"" + field + "\" isn't a valid repeat time field", parseException);
149         }
150 
151         return r;
152     }
153 
154     /**
155      * Adds an offset to the field.
156      * 
157      * @param offset the offset value
158      * 
159      * @throws SDPException if the offset value is negative
160      */
161     public void addOffset(final long offset) throws SDPException {
162 
163         if (offset >= 0) {
164             offsets.add(new Long(offset));
165         }
166         else {
167             throw new SDPException("Offsets must be >= 0");
168         }
169     }
170 
171     /**
172      * Returns a clone of this field.
173      * 
174      * @return a clone of this field
175      */
176     public Object clone() {
177 
178         RepeatTime field = new RepeatTime();
179         field.isTyped = this.isTyped;
180         field.activeDuration = this.activeDuration;
181         field.repeatInterval = this.repeatInterval;
182         field.offsets = (Vector) this.offsets.clone();
183 
184         return field;
185     }
186 
187     /**
188      * Returns the active duration in seconds
189      * 
190      * @return the active duration
191      */
192     public long getActiveDuration() {
193 
194         return activeDuration;
195     }
196 
197     /**
198      * Returns the list of offsets. These are relative to the start time given
199      * in the {@link Time} field with which this <tt>RepeatTime</tt> is
200      * associated.
201      * 
202      * @return an array of repeat time offsets
203      */
204     public long[] getOffsets() {
205 
206         long[] values = new long[offsets.size()];
207         for (int i = 0; i < values.length; i++) {
208             Long offset = (Long) offsets.get(i);
209             values[i] = offset.longValue();
210         }
211 
212         return values;
213     }
214 
215     /**
216      * Returns the repeat interval.
217      * 
218      * @return the repeat interval in seconds
219      */
220     public long getRepeatInterval() {
221 
222         return repeatInterval;
223     }
224 
225     /**
226      * Returns the type character for the field.
227      * 
228      * @return the field type character: <b>r</b>
229      */
230     public char getType() {
231 
232         return Field.REPEAT_TIME_FIELD;
233     }
234 
235     /**
236      * Returns whether the field will be output as a typed time or a number.
237      * 
238      * <p>
239      * Typed time is formatted as an number followed by a unit character: the
240      * unit indicates an appropriate multiplier for the number. The following
241      * unit types are allowed:
242      * </p>
243      * <ul>
244      * <li><tt><b>d</b></tt> - days (86400 seconds)</li>
245      * <li><tt><b>h</b></tt> - hours (3600 seconds)</li>
246      * <li><tt><b>m</b></tt> - minutes (60 seconds)</li>
247      * <li><tt><b>s</b></tt> - seconds (1 second)</li>
248      * </ul>
249      * 
250      * @return <tt>true</tt> if the field will be output as a typed time,
251      *         <tt>false</tt> if as a number
252      */
253     public boolean isTypedTime() {
254 
255         return isTyped;
256     }
257 
258     /**
259      * Sets the active duration.
260      * 
261      * @param activeDuration the active duration in seconds
262      * 
263      * @throws SDPException if the active duration is negative
264      */
265     public void setActiveDuration(final long activeDuration) throws SDPException {
266 
267         if (activeDuration < 0) {
268             throw new SDPException("The active duration cannot be negative");
269         }
270 
271         this.activeDuration = activeDuration;
272 
273     }
274 
275     /**
276      * Set the list of offsets. These are relative to the start time given in
277      * the {@link Time} field with which this <tt>RepeatTime</tt> is
278      * associated.
279      * 
280      * @param offsets an array of repeat time offsets
281      * 
282      * @throws SDPException if one or more offset is negative
283      */
284     public void setOffset(final long[] offsets) throws SDPException {
285 
286         Vector temp = new Vector(offsets.length);
287         for (int i = 0; i < offsets.length; i++) {
288             if (offsets[i] >= 0) {
289                 temp.add(new Long(offsets[i]));
290             }
291             else {
292                 throw new SDPException("Offsets must be >= 0");
293             }
294         }
295         // this.offsets = null;
296         // this.offsets = (Vector)temp.clone();
297         this.offsets = temp;
298     }
299 
300     /**
301      * Sets the repeat interval.
302      * 
303      * @param repeatInterval the repeat interval in seconds
304      * 
305      * @throws SDPException if repeatInterval is negative
306      */
307     public void setRepeatInterval(final long repeatInterval) throws SDPException {
308 
309         if (repeatInterval < 0) {
310             throw new SDPException("The repeat interval cannot be negative");
311         }
312 
313         this.repeatInterval = repeatInterval;
314     }
315 
316     /**
317      * Sets whether the field will be output as a typed time or a number. Typed
318      * time is formatted as an number followed by a unit character: the unit
319      * indicates an appropriate multiplier for the number. The following unit
320      * types are allowed:
321      * <ul>
322      * <li><tt><b>d</b></tt> - days (86400 seconds)</li>
323      * <li><tt><b>h</b></tt> - hours (3600 seconds)</li>
324      * <li><tt><b>m</b></tt> - minutes (60 seconds)</li>
325      * <li><tt><b>s</b></tt> - seconds (1 second)</li>
326      * </ul>
327      */
328     public void setTypedTime(final boolean typedTime) {
329 
330         this.isTyped = typedTime;
331     }
332 
333     /**
334      * Returns a string representation of the field. The representation has the
335      * form: <b>r=<i>&lt;value&gt;</i></b>
336      * 
337      * @return the string representation of the field
338      */
339     public String toString() {
340 
341         StringBuffer result;
342 
343         result = new StringBuffer(getType() + "=");
344 
345         result.append(repeatInterval + " ");
346         if (this.isTyped) {
347             result.append(TypedTime.toString(activeDuration));
348             for (int i = 0; i < offsets.size(); i++) {
349                 Long offset = (Long) offsets.get(i);
350                 result.append(" " + TypedTime.toString(offset.longValue()));
351             }
352         }
353         else {
354             result.append(activeDuration);
355             for (int i = 0; i < offsets.size(); i++) {
356                 result.append(" " + offsets.get(i));
357             }
358         }
359 
360         return result.toString();
361     }
362 }