View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  
23  package org.opencastproject.metadata.mpeg7;
24  
25  import org.w3c.dom.Document;
26  import org.w3c.dom.Element;
27  import org.w3c.dom.Node;
28  
29  import java.util.Formatter;
30  
31  /**
32   * TODO: Comment me!
33   */
34  public class MediaDurationImpl implements MediaDuration {
35  
36    /** Time delimiter */
37    private static final String TimeDelimiter = "T";
38  
39    /** Day delimiter */
40    private static final String DayDelimiter = "D";
41  
42    /** Hour delimiter */
43    private static final String HourDelimiter = "H";
44  
45    /** Minute delimiter */
46    private static final String MinuteDelimiter = "M";
47  
48    /** Seconds delimiter */
49    private static final String SecondsDelimiter = "S";
50  
51    /** Fractions delimiter */
52    private static final String FractionDelimiter = "N";
53  
54    /** Fractions per second delimiter */
55    private static final String FPSDelimiter = "F";
56  
57    /** Number of milliseconds per day */
58    private static final long MS_PER_DAY = 86400000L;
59  
60    /** Number of milliseconds per hour */
61    private static final long MS_PER_HOUR = 3600000L;
62  
63    /** Number of milliseconds per minute */
64    private static final long MS_PER_MINUTE = 60000L;
65  
66    /** Number of milliseconds per second */
67    private static final long MS_PER_SECOND = 1000L;
68  
69    private int days = 0;
70    private int hours = 0;
71    private int minutes = 0;
72    private int seconds = 0;
73    private int fractions = 0;
74    private int fractionsPerSecond = 0;
75  
76    /**
77     * Creates a media duration representing <code>PD0T00H00M00S00N0F</code>.
78     */
79    public MediaDurationImpl() {
80      days = 0;
81      hours = 0;
82      minutes = 0;
83      seconds = 0;
84      fractions = 0;
85      fractionsPerSecond = 0;
86    }
87  
88    /**
89     * Creates a media duration representing the given long value.
90     */
91    public MediaDurationImpl(long milliseconds) {
92      fractions = (int) (milliseconds % MS_PER_SECOND);
93      seconds = (int) ((milliseconds / MS_PER_SECOND) % 60);
94      minutes = (int) ((milliseconds / MS_PER_MINUTE) % 60);
95      hours = (int) ((milliseconds / MS_PER_HOUR) % 24);
96      days = (int) (milliseconds / MS_PER_DAY);
97      hours += days * 24;
98      fractionsPerSecond = 1000;
99    }
100 
101   /**
102    * Parses a duration text representation.
103    *
104    * @param text
105    *          the duration text representation
106    * @return the media duration object
107    * @throws IllegalArgumentException
108    *           if the text is not in the right format
109    */
110   public static MediaDuration parseDuration(String text) throws IllegalArgumentException {
111     MediaDurationImpl mediaDuration = new MediaDurationImpl();
112     mediaDuration.parse(text);
113     return mediaDuration;
114   }
115 
116   /**
117    * Parses a duration text representation.
118    *
119    * @param text
120    *          the duration text representation
121    * @throws IllegalArgumentException
122    *           if the text is not in the right format
123    */
124   public void parse(String text) throws IllegalArgumentException {
125     int index = 0;
126     if ((!text.startsWith("P")) || (!text.contains(TimeDelimiter)))
127       throw new IllegalArgumentException();
128     if (text.contains(DayDelimiter)) {
129       days = Integer.parseInt(text.substring(1, text.indexOf(DayDelimiter)));
130     }
131     index = text.indexOf(TimeDelimiter);
132     if (text.contains(HourDelimiter)) {
133       hours = Short.parseShort(text.substring(index + 1, text.indexOf(HourDelimiter)));
134       index = text.indexOf(HourDelimiter);
135     }
136     if (text.contains(MinuteDelimiter)) {
137       minutes = Short.parseShort(text.substring(index + 1, text.indexOf(MinuteDelimiter)));
138       index = text.indexOf(MinuteDelimiter);
139     }
140     if (text.contains(SecondsDelimiter)) {
141       seconds = Short.parseShort(text.substring(index + 1, text.indexOf(SecondsDelimiter)));
142       index = text.indexOf(SecondsDelimiter);
143     }
144     if (text.contains(FractionDelimiter)) {
145       fractions = Integer.parseInt(text.substring(index + 1, text.indexOf(FractionDelimiter)));
146       index = text.indexOf(FractionDelimiter);
147     }
148     if (text.contains(FPSDelimiter)) {
149       fractionsPerSecond = Integer.parseInt(text.substring(index + 1, text.indexOf(FPSDelimiter)));
150     }
151   }
152 
153   /**
154    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getDays()
155    */
156   public int getDays() {
157     return days;
158   }
159 
160   /**
161    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getFractions()
162    */
163   public int getFractions() {
164     return fractions;
165   }
166 
167   /**
168    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getFractionsPerSecond()
169    */
170   public int getFractionsPerSecond() {
171     return fractionsPerSecond;
172   }
173 
174   /**
175    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getHours()
176    */
177   public int getHours() {
178     return hours;
179   }
180 
181   /**
182    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getMinutes()
183    */
184   public int getMinutes() {
185     return minutes;
186   }
187 
188   /**
189    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getSeconds()
190    */
191   public int getSeconds() {
192     return seconds;
193   }
194 
195   /**
196    * Sets the number of days.
197    *
198    * @param days
199    */
200   public void setDayDuration(int days) {
201     this.days = days;
202   }
203 
204   /**
205    * Sets the number of fractions.
206    *
207    * @param fractions
208    *          the fractions
209    */
210   public void setFractionDuration(int fractions) {
211     this.fractions = fractions;
212   }
213 
214   /**
215    * Sets the number of fractions per second.
216    *
217    * @param fractionsPerSecond
218    *          the fractions per second
219    */
220   public void setFractionsPerSecond(int fractionsPerSecond) {
221     this.fractionsPerSecond = fractionsPerSecond;
222   }
223 
224   /**
225    * Sets the number of hours.
226    *
227    * @param hours
228    *          the hours
229    */
230   public void setHourDuration(short hours) {
231     this.hours = hours;
232   }
233 
234   /**
235    * Sets the number of minutes.
236    *
237    * @param minutes
238    *          the number of minutes
239    */
240   public void setMinuteDuration(short minutes) {
241     this.minutes = minutes;
242   }
243 
244   /**
245    * Sets the number of seconds.
246    *
247    * @param seconds
248    *          the number of seconds
249    */
250   public void setSecondDuration(short seconds) {
251     this.seconds = seconds;
252   }
253 
254   /**
255    * @see java.lang.Object#toString()
256    */
257   @Override
258   public String toString() {
259     StringBuffer returnString = new StringBuffer("PT");
260     Formatter f = new Formatter(returnString);
261     if (hours != 0) {
262       f.format("%02d" + HourDelimiter, hours);
263     }
264     if (minutes != 0) {
265       f.format("%02d" + MinuteDelimiter, minutes);
266     }
267     if (seconds != 0) {
268       f.format("%02d" + SecondsDelimiter, seconds);
269     }
270     if (fractionsPerSecond != 0) {
271       f.format("%d" + FractionDelimiter + "%d" + FPSDelimiter, fractions, fractionsPerSecond);
272     }
273     f.close();
274     return returnString.toString();
275   }
276 
277   /**
278    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getDurationInMilliseconds()
279    */
280   public long getDurationInMilliseconds() {
281     long s = seconds * MS_PER_SECOND;
282     s += minutes * MS_PER_MINUTE;
283     s += hours * MS_PER_HOUR;
284     s += days * MS_PER_DAY;
285     if (fractionsPerSecond > 0)
286       s += (fractions * 1000L / fractionsPerSecond);
287     return s;
288   }
289 
290   /**
291    * {@inheritDoc}
292    *
293    * @see java.lang.Object#hashCode()
294    */
295   @Override
296   public int hashCode() {
297     return super.hashCode();
298   }
299 
300   /**
301    * {@inheritDoc}
302    *
303    * @see java.lang.Object#equals(java.lang.Object)
304    */
305   @Override
306   public boolean equals(Object obj) {
307     if (obj instanceof MediaDuration)
308       return ((MediaDuration) obj).getDurationInMilliseconds() == getDurationInMilliseconds();
309     return false;
310   }
311 
312   /**
313    * @see org.opencastproject.mediapackage.XmlElement#toXml(org.w3c.dom.Document)
314    */
315   public Node toXml(Document document) {
316     Element node = document.createElement("MediaDuration");
317     node.setTextContent(toString());
318     return node;
319   }
320 
321 }