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     }
129     if (text.contains(DayDelimiter)) {
130       days = Integer.parseInt(text.substring(1, text.indexOf(DayDelimiter)));
131     }
132     index = text.indexOf(TimeDelimiter);
133     if (text.contains(HourDelimiter)) {
134       hours = Short.parseShort(text.substring(index + 1, text.indexOf(HourDelimiter)));
135       index = text.indexOf(HourDelimiter);
136     }
137     if (text.contains(MinuteDelimiter)) {
138       minutes = Short.parseShort(text.substring(index + 1, text.indexOf(MinuteDelimiter)));
139       index = text.indexOf(MinuteDelimiter);
140     }
141     if (text.contains(SecondsDelimiter)) {
142       seconds = Short.parseShort(text.substring(index + 1, text.indexOf(SecondsDelimiter)));
143       index = text.indexOf(SecondsDelimiter);
144     }
145     if (text.contains(FractionDelimiter)) {
146       fractions = Integer.parseInt(text.substring(index + 1, text.indexOf(FractionDelimiter)));
147       index = text.indexOf(FractionDelimiter);
148     }
149     if (text.contains(FPSDelimiter)) {
150       fractionsPerSecond = Integer.parseInt(text.substring(index + 1, text.indexOf(FPSDelimiter)));
151     }
152   }
153 
154   /**
155    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getDays()
156    */
157   public int getDays() {
158     return days;
159   }
160 
161   /**
162    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getFractions()
163    */
164   public int getFractions() {
165     return fractions;
166   }
167 
168   /**
169    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getFractionsPerSecond()
170    */
171   public int getFractionsPerSecond() {
172     return fractionsPerSecond;
173   }
174 
175   /**
176    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getHours()
177    */
178   public int getHours() {
179     return hours;
180   }
181 
182   /**
183    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getMinutes()
184    */
185   public int getMinutes() {
186     return minutes;
187   }
188 
189   /**
190    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getSeconds()
191    */
192   public int getSeconds() {
193     return seconds;
194   }
195 
196   /**
197    * Sets the number of days.
198    *
199    * @param days
200    */
201   public void setDayDuration(int days) {
202     this.days = days;
203   }
204 
205   /**
206    * Sets the number of fractions.
207    *
208    * @param fractions
209    *          the fractions
210    */
211   public void setFractionDuration(int fractions) {
212     this.fractions = fractions;
213   }
214 
215   /**
216    * Sets the number of fractions per second.
217    *
218    * @param fractionsPerSecond
219    *          the fractions per second
220    */
221   public void setFractionsPerSecond(int fractionsPerSecond) {
222     this.fractionsPerSecond = fractionsPerSecond;
223   }
224 
225   /**
226    * Sets the number of hours.
227    *
228    * @param hours
229    *          the hours
230    */
231   public void setHourDuration(short hours) {
232     this.hours = hours;
233   }
234 
235   /**
236    * Sets the number of minutes.
237    *
238    * @param minutes
239    *          the number of minutes
240    */
241   public void setMinuteDuration(short minutes) {
242     this.minutes = minutes;
243   }
244 
245   /**
246    * Sets the number of seconds.
247    *
248    * @param seconds
249    *          the number of seconds
250    */
251   public void setSecondDuration(short seconds) {
252     this.seconds = seconds;
253   }
254 
255   /**
256    * @see java.lang.Object#toString()
257    */
258   @Override
259   public String toString() {
260     StringBuffer returnString = new StringBuffer("PT");
261     Formatter f = new Formatter(returnString);
262     if (hours != 0) {
263       f.format("%02d" + HourDelimiter, hours);
264     }
265     if (minutes != 0) {
266       f.format("%02d" + MinuteDelimiter, minutes);
267     }
268     if (seconds != 0) {
269       f.format("%02d" + SecondsDelimiter, seconds);
270     }
271     if (fractionsPerSecond != 0) {
272       f.format("%d" + FractionDelimiter + "%d" + FPSDelimiter, fractions, fractionsPerSecond);
273     }
274     f.close();
275     return returnString.toString();
276   }
277 
278   /**
279    * @see org.opencastproject.metadata.mpeg7.MediaDuration#getDurationInMilliseconds()
280    */
281   public long getDurationInMilliseconds() {
282     long s = seconds * MS_PER_SECOND;
283     s += minutes * MS_PER_MINUTE;
284     s += hours * MS_PER_HOUR;
285     s += days * MS_PER_DAY;
286     if (fractionsPerSecond > 0) {
287       s += (fractions * 1000L / fractionsPerSecond);
288     }
289     return s;
290   }
291 
292   /**
293    * {@inheritDoc}
294    *
295    * @see java.lang.Object#hashCode()
296    */
297   @Override
298   public int hashCode() {
299     return super.hashCode();
300   }
301 
302   /**
303    * {@inheritDoc}
304    *
305    * @see java.lang.Object#equals(java.lang.Object)
306    */
307   @Override
308   public boolean equals(Object obj) {
309     if (obj instanceof MediaDuration) {
310       return ((MediaDuration) obj).getDurationInMilliseconds() == getDurationInMilliseconds();
311     }
312     return false;
313   }
314 
315   /**
316    * @see org.opencastproject.mediapackage.XmlElement#toXml(org.w3c.dom.Document)
317    */
318   public Node toXml(Document document) {
319     Element node = document.createElement("MediaDuration");
320     node.setTextContent(toString());
321     return node;
322   }
323 
324 }