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.opencastproject.util.XmlSafeParser;
26  
27  import org.w3c.dom.Document;
28  import org.w3c.dom.Element;
29  
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.util.ArrayList;
33  import java.util.HashMap;
34  import java.util.Iterator;
35  import java.util.List;
36  
37  import javax.xml.parsers.ParserConfigurationException;
38  import javax.xml.transform.TransformerException;
39  
40  /**
41   * Implements the mpeg-7 metadata container.
42   */
43  public class Mpeg7CatalogImpl implements Mpeg7Catalog {
44  
45    /** Serial version UID */
46    private static final long serialVersionUID = 5521535164920498997L;
47  
48    /** The multimedia content list */
49    private HashMap<MultimediaContent.Type, MultimediaContentImpl<? extends MultimediaContentType>> multimediaContent = null;
50  
51    /** The default element namespace */
52    public static final String NS = "mpeg7";
53  
54    /**
55     * Creates a new mpeg-7 metadata container.
56     */
57    public Mpeg7CatalogImpl() {
58      multimediaContent = new HashMap<MultimediaContent.Type, MultimediaContentImpl<? extends MultimediaContentType>>();
59    }
60  
61    /**
62     * Creates a new mpeg-7 metadata container from the serialized stream.
63     */
64    public Mpeg7CatalogImpl(InputStream in) {
65      this();
66      loadCatalogData(in);
67    }
68  
69    /**
70     * Populates the catalog.
71     *
72     * @param in
73     *          The input stream containing the content
74     * @throws IllegalStateException
75     *           if reading the catalog fails
76     */
77    private void loadCatalogData(InputStream in) throws IllegalStateException {
78      Mpeg7Parser parser = new Mpeg7Parser(this);
79      try {
80        parser.parse(in);
81      } catch (Exception e) {
82        throw new IllegalStateException("Unable to load mpeg-7 catalog data:" + e.getMessage(), e);
83      }
84    }
85  
86    /**
87     * Creates a new mpeg-7 metadata container file.
88     *
89     * @return the new mpeg-7 metadata container
90     */
91    public static Mpeg7CatalogImpl newInstance() {
92      Mpeg7CatalogImpl mpeg7 = new Mpeg7CatalogImpl();
93      return mpeg7;
94    }
95  
96    /**
97     * @see org.opencastproject.metadata.mpeg7.Mpeg7#multimediaContent()
98     */
99    public Iterator<MultimediaContent<? extends MultimediaContentType>> multimediaContent() {
100     List<MultimediaContent<? extends MultimediaContentType>> result = new ArrayList<MultimediaContent<? extends MultimediaContentType>>();
101     for (MultimediaContent<? extends MultimediaContentType> o : multimediaContent.values()) {
102       result.add(o);
103     }
104     return result.iterator();
105   }
106 
107   /**
108    * @see org.opencastproject.metadata.mpeg7.Mpeg7#getMultimediaContent(org.opencastproject.mediapackage.mpeg7.MultimediaContent.Type)
109    */
110   public MultimediaContent<? extends MultimediaContentType> getMultimediaContent(MultimediaContent.Type type) {
111     return multimediaContent.get(type);
112   }
113 
114   /**
115    * Saves the mpeg-7 metadata container to disk.
116    *
117    * @throws ParserConfigurationException
118    *           if the xml parser environment is not correctly configured
119    * @throws TransformerException
120    *           if serialization of the metadata document fails
121    * @throws IOException
122    *           if an error with catalog file handling occurs
123    */
124   public Document toXml() throws ParserConfigurationException, TransformerException, IOException {
125     Document doc = createDocument();
126 
127     // Root element
128     Element root = doc.getDocumentElement();
129 
130     // Description
131     Element descriptionNode = doc.createElement("Description");
132     descriptionNode.setAttribute("xsi:type", "ContentEntityType");
133     root.appendChild(descriptionNode);
134 
135     // MultimediaContent
136     for (MultimediaContent<? extends MultimediaContentType> mc : multimediaContent.values()) {
137       descriptionNode.appendChild(mc.toXml(doc));
138     }
139 
140     return doc;
141   }
142 
143   /**
144    * Create a DOM representation of the Mpeg-7.
145    */
146   private Document createDocument() throws ParserConfigurationException {
147     Document doc = XmlSafeParser.newDocumentBuilderFactory().newDocumentBuilder().newDocument();
148     Element rootElement = doc.createElementNS("urn:mpeg:mpeg7:schema:2001", "Mpeg7");
149     rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:mpeg7", "urn:mpeg7:schema:2001");
150     rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xsi",
151             "http://www.w3.org/2001/XMLSchema-instance");
152     doc.appendChild(rootElement);
153     return doc;
154   }
155 
156   /**
157    * @see org.opencastproject.metadata.mpeg7.Mpeg7#addAudioContent(java.lang.String,
158    *      org.opencastproject.metadata.mpeg7.MediaTime, org.opencastproject.metadata.mpeg7.MediaLocator)
159    */
160   @SuppressWarnings("unchecked")
161   public Audio addAudioContent(String id, MediaTime time, MediaLocator locator) {
162     MultimediaContentImpl<Audio> content = (MultimediaContentImpl<Audio>) getMultimediaContent(MultimediaContent.Type.AudioType);
163     if (content == null) {
164       content = new MultimediaContentImpl<Audio>(MultimediaContent.Type.AudioType);
165       multimediaContent.put(MultimediaContent.Type.AudioType, content);
166     }
167     MultimediaContentTypeImpl<AudioSegment> audio = new MultimediaContentTypeImpl<AudioSegment>(MultimediaContentType.Type.Audio, id);
168     audio.setMediaTime(time);
169     audio.setMediaLocator(locator);
170     content.add(audio);
171     return audio;
172   }
173 
174   /**
175    * @see org.opencastproject.metadata.mpeg7.Mpeg7#removeAudioContent(java.lang.String)
176    */
177   public Audio removeAudioContent(String id) {
178     MultimediaContentType element = removeContentElement(id, MultimediaContent.Type.AudioType);
179     if (element != null)
180       return (Audio) element;
181     return null;
182   }
183 
184   /**
185    * @see org.opencastproject.metadata.mpeg7.Mpeg7#hasAudioContent()
186    */
187   public boolean hasAudioContent() {
188     MultimediaContent<?> content = getMultimediaContent(MultimediaContent.Type.AudioType);
189     return content != null && content.size() > 0;
190   }
191 
192   /**
193    * @see org.opencastproject.metadata.mpeg7.Mpeg7#audioContent()
194    */
195   @SuppressWarnings("unchecked")
196   public Iterator<Audio> audioContent() {
197     MultimediaContent<Audio> content = (MultimediaContent<Audio>) getMultimediaContent(MultimediaContent.Type.AudioType);
198     if (content != null)
199       return content.elements();
200     return null;
201   }
202 
203   /**
204    * @see org.opencastproject.metadata.mpeg7.Mpeg7#addVideoContent(java.lang.String,
205    *      org.opencastproject.mediapackage.mpeg7.MediaTime, org.opencastproject.mediapackage.mpeg7.MediaLocator)
206    */
207   @SuppressWarnings("unchecked")
208   public Video addVideoContent(String id, MediaTime time, MediaLocator locator) {
209     MultimediaContentImpl<Video> content = (MultimediaContentImpl<Video>) getMultimediaContent(MultimediaContent.Type.VideoType);
210     if (content == null) {
211       content = new MultimediaContentImpl<Video>(MultimediaContent.Type.VideoType);
212       multimediaContent.put(MultimediaContent.Type.VideoType, content);
213     }
214     MultimediaContentTypeImpl<VideoSegment> video = new MultimediaContentTypeImpl<VideoSegment>(MultimediaContentType.Type.Video, id);
215     content.add(video);
216     video.setMediaTime(time);
217     video.setMediaLocator(locator);
218     return video;
219   }
220 
221   /**
222    * @see org.opencastproject.metadata.mpeg7.Mpeg7#removeVideoContent(java.lang.String)
223    */
224   public Video removeVideoContent(String id) {
225     MultimediaContentType element = removeContentElement(id, MultimediaContent.Type.VideoType);
226     if (element != null)
227       return (Video) element;
228     return null;
229   }
230 
231   /**
232    * @see org.opencastproject.metadata.mpeg7.Mpeg7#hasVideoContent()
233    */
234   public boolean hasVideoContent() {
235     MultimediaContent<?> content = getMultimediaContent(MultimediaContent.Type.VideoType);
236     return content != null && content.size() > 0;
237   }
238 
239   /**
240    * @see org.opencastproject.metadata.mpeg7.Mpeg7#videoContent()
241    */
242   @SuppressWarnings("unchecked")
243   public Iterator<Video> videoContent() {
244     MultimediaContent<Video> content = (MultimediaContent<Video>) getMultimediaContent(MultimediaContent.Type.VideoType);
245     if (content != null)
246       return content.elements();
247     return null;
248   }
249 
250   /**
251    * @see org.opencastproject.metadata.mpeg7.Mpeg7#addAudioVisualContent(java.lang.String,
252    *      org.opencastproject.mediapackage.mpeg7.MediaTime, org.opencastproject.mediapackage.mpeg7.MediaLocator)
253    */
254   @SuppressWarnings("unchecked")
255   public AudioVisual addAudioVisualContent(String id, MediaTime time, MediaLocator locator) {
256     MultimediaContentImpl<AudioVisual> content = (MultimediaContentImpl<AudioVisual>) getMultimediaContent(MultimediaContent.Type.AudioVisualType);
257     if (content == null) {
258       content = new MultimediaContentImpl<AudioVisual>(MultimediaContent.Type.AudioVisualType);
259       multimediaContent.put(MultimediaContent.Type.AudioVisualType, content);
260     }
261     MultimediaContentTypeImpl<AudioVisualSegment> audioVisual = new MultimediaContentTypeImpl<AudioVisualSegment>(MultimediaContentType.Type.AudioVisual, id);
262     audioVisual.setMediaTime(time);
263     audioVisual.setMediaLocator(locator);
264     content.add(audioVisual);
265     return audioVisual;
266   }
267 
268   /**
269    * @see org.opencastproject.metadata.mpeg7.Mpeg7#removeAudioVisualContent(java.lang.String)
270    */
271   public AudioVisual removeAudioVisualContent(String id) {
272     MultimediaContentType element = removeContentElement(id, MultimediaContent.Type.AudioVisualType);
273     if (element != null)
274       return (AudioVisual) element;
275     return null;
276   }
277 
278   /**
279    * @see org.opencastproject.metadata.mpeg7.Mpeg7#hasAudioVisualContent()
280    */
281   public boolean hasAudioVisualContent() {
282     MultimediaContent<?> content = getMultimediaContent(MultimediaContent.Type.AudioVisualType);
283     return content != null && content.size() > 0;
284   }
285 
286   /**
287    * @see org.opencastproject.metadata.mpeg7.Mpeg7#audiovisualContent()
288    */
289   @SuppressWarnings("unchecked")
290   public Iterator<AudioVisual> audiovisualContent() {
291     MultimediaContent<AudioVisual> content = (MultimediaContent<AudioVisual>) getMultimediaContent(MultimediaContent.Type.AudioVisualType);
292     if (content != null)
293       return content.elements();
294     return null;
295   }
296 
297   /**
298    * @see org.opencastproject.metadata.mpeg7.Mpeg7#getAudioById(java.lang.String)
299    */
300   @SuppressWarnings("unchecked")
301   public Audio getAudioById(String id) {
302     MultimediaContent<Audio> content = (MultimediaContent<Audio>) getMultimediaContent(MultimediaContent.Type.AudioType);
303     if (content == null)
304       return null;
305     return content.getElementById(id);
306   }
307 
308   /**
309    * @see org.opencastproject.metadata.mpeg7.Mpeg7#getAudioVisualById(java.lang.String)
310    */
311   @SuppressWarnings("unchecked")
312   public AudioVisual getAudioVisualById(String id) {
313     MultimediaContent<AudioVisual> content = (MultimediaContent<AudioVisual>) getMultimediaContent(MultimediaContent.Type.AudioVisualType);
314     if (content == null)
315       return null;
316     return content.getElementById(id);
317   }
318 
319   /**
320    * @see org.opencastproject.metadata.mpeg7.Mpeg7#getVideoById(java.lang.String)
321    */
322   @SuppressWarnings("unchecked")
323   public Video getVideoById(String id) {
324     MultimediaContent<Video> content = (MultimediaContent<Video>) getMultimediaContent(MultimediaContent.Type.VideoType);
325     if (content == null)
326       return null;
327     return content.getElementById(id);
328   }
329 
330   /**
331    * Removes the content element of the specified type with the given identifier.
332    *
333    * @param id
334    *          the content element identifier
335    * @param type
336    *          the content type
337    * @return the element or <code>null</code>
338    */
339   private MultimediaContentType removeContentElement(String id, MultimediaContent.Type type) {
340     MultimediaContentImpl<? extends MultimediaContentType> content = multimediaContent.get(type);
341     if (content != null)
342       return content.remove(id);
343     return null;
344   }
345 
346   @SuppressWarnings("unchecked")
347   @Override
348   public Mpeg7Catalog clone() {
349     Mpeg7CatalogImpl clone = new Mpeg7CatalogImpl();
350     clone.multimediaContent = (HashMap<MultimediaContent.Type, MultimediaContentImpl<? extends MultimediaContentType>>) this.multimediaContent
351             .clone();
352     return clone;
353   }
354 }