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