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.mediapackage.elementbuilder;
24  
25  import org.opencastproject.mediapackage.Catalog;
26  import org.opencastproject.mediapackage.CatalogImpl;
27  import org.opencastproject.mediapackage.MediaPackageElement;
28  import org.opencastproject.mediapackage.MediaPackageElement.Type;
29  import org.opencastproject.mediapackage.MediaPackageElementFlavor;
30  import org.opencastproject.mediapackage.MediaPackageReferenceImpl;
31  import org.opencastproject.mediapackage.MediaPackageSerializer;
32  import org.opencastproject.mediapackage.UnsupportedElementException;
33  import org.opencastproject.util.Checksum;
34  import org.opencastproject.util.MimeType;
35  import org.opencastproject.util.MimeTypes;
36  
37  import org.apache.commons.lang3.StringUtils;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  import org.w3c.dom.Node;
41  import org.w3c.dom.NodeList;
42  
43  import java.net.URI;
44  import java.net.URISyntaxException;
45  import java.security.NoSuchAlgorithmException;
46  
47  import javax.xml.xpath.XPath;
48  import javax.xml.xpath.XPathConstants;
49  import javax.xml.xpath.XPathExpressionException;
50  import javax.xml.xpath.XPathFactory;
51  
52  /**
53   * This implementation of the {@link MediaPackageElementBuilderPlugin} recognizes metadata catalogs and provides the
54   * functionality of reading it on behalf of the media package.
55   */
56  public class CatalogBuilderPlugin implements MediaPackageElementBuilderPlugin {
57  
58    /** The xpath facility */
59    protected XPath xpath = XPathFactory.newInstance().newXPath();
60  
61    /**
62     * the logging facility provided by log4j
63     */
64    private static final Logger logger = LoggerFactory.getLogger(CatalogBuilderPlugin.class);
65  
66    /**
67     * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#accept(
68     *      org.opencastproject.mediapackage.MediaPackageElement.Type,
69     *      org.opencastproject.mediapackage.MediaPackageElementFlavor)
70     */
71    @Override
72    public boolean accept(MediaPackageElement.Type type, MediaPackageElementFlavor flavor) {
73      return type.equals(MediaPackageElement.Type.Catalog);
74    }
75  
76    /**
77     * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#accept(org.w3c.dom.Node)
78     */
79    @Override
80    public boolean accept(Node elementNode) {
81      String name = elementNode.getNodeName();
82      if (name.contains(":")) {
83        name = name.substring(name.indexOf(":") + 1);
84      }
85      return name.equalsIgnoreCase(MediaPackageElement.Type.Catalog.toString());
86    }
87  
88    /**
89     * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#accept(URI,
90     *      org.opencastproject.mediapackage.MediaPackageElement.Type,
91     *      org.opencastproject.mediapackage.MediaPackageElementFlavor)
92     */
93    @Override
94    public boolean accept(URI uri, MediaPackageElement.Type type, MediaPackageElementFlavor flavor) {
95      return MediaPackageElement.Type.Catalog.equals(type);
96    }
97  
98    /**
99     * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#elementFromURI(URI)
100    */
101   @Override
102   public MediaPackageElement elementFromURI(URI uri) throws UnsupportedElementException {
103     logger.trace("Creating video track from " + uri);
104     Catalog track = CatalogImpl.fromURI(uri);
105     return track;
106   }
107 
108   @Override
109   public String toString() {
110     return "Indefinite Catalog Builder Plugin";
111   }
112 
113   /**
114    * {@inheritDoc}
115    *
116    * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#destroy()
117    */
118   @Override
119   public void destroy() {
120   }
121 
122   /**
123    * {@inheritDoc}
124    *
125    * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#elementFromManifest(
126    *      org.w3c.dom.Node,
127    *      org.opencastproject.mediapackage.MediaPackageSerializer)
128    */
129   @Override
130   public MediaPackageElement elementFromManifest(Node elementNode, MediaPackageSerializer serializer)
131           throws UnsupportedElementException {
132     String id = null;
133     String flavor = null;
134     URI url = null;
135     long size = -1;
136     Checksum checksum = null;
137     MimeType mimeType = null;
138     String reference = null;
139 
140     try {
141       // id
142       id = (String) xpath.evaluate("@id", elementNode, XPathConstants.STRING);
143 
144       // url
145       url = serializer.decodeURI(new URI(xpath.evaluate("url/text()", elementNode).trim()));
146 
147       // flavor
148       flavor = (String) xpath.evaluate("@type", elementNode, XPathConstants.STRING);
149 
150       // reference
151       reference = (String) xpath.evaluate("@ref", elementNode, XPathConstants.STRING);
152 
153       // size
154       String documentSize = xpath.evaluate("size/text()", elementNode).trim();
155       if (!"".equals(documentSize)) {
156         size = Long.parseLong(documentSize);
157       }
158 
159       // checksum
160       String checksumValue = (String) xpath.evaluate("checksum/text()", elementNode, XPathConstants.STRING);
161       String checksumType = (String) xpath.evaluate("checksum/@type", elementNode, XPathConstants.STRING);
162       if (StringUtils.isNotEmpty(checksumValue) && checksumType != null) {
163         checksum = Checksum.create(checksumType.trim(), checksumValue.trim());
164       }
165 
166       // mimetype
167       String mimeTypeValue = (String) xpath.evaluate("mimetype/text()", elementNode, XPathConstants.STRING);
168       if (StringUtils.isNotEmpty(mimeTypeValue)) {
169         mimeType = MimeTypes.parseMimeType(mimeTypeValue);
170       }
171 
172       // create the catalog
173       Catalog dc = CatalogImpl.fromURI(url);
174       if (StringUtils.isNotEmpty(id)) {
175         dc.setIdentifier(id);
176       }
177 
178       // Add url
179       dc.setURI(url);
180 
181       // Add flavor
182       if (flavor != null) {
183         dc.setFlavor(MediaPackageElementFlavor.parseFlavor(flavor));
184       }
185 
186       // Add reference
187       if (StringUtils.isNotEmpty(reference)) {
188         dc.referTo(MediaPackageReferenceImpl.fromString(reference));
189       }
190 
191       // Set size
192       if (size > 0) {
193         dc.setSize(size);
194       }
195 
196       // Set checksum
197       if (checksum != null) {
198         dc.setChecksum(checksum);
199       }
200 
201       // Set Mimetype
202       if (mimeType != null) {
203         dc.setMimeType(mimeType);
204       }
205 
206       // Tags
207       NodeList tagNodes = (NodeList) xpath.evaluate("tags/tag", elementNode, XPathConstants.NODESET);
208       for (int i = 0; i < tagNodes.getLength(); i++) {
209         dc.addTag(tagNodes.item(i).getTextContent());
210       }
211 
212       return dc;
213     } catch (XPathExpressionException e) {
214       throw new UnsupportedElementException("Error while reading catalog information from manifest: " + e.getMessage());
215     } catch (NoSuchAlgorithmException e) {
216       throw new UnsupportedElementException("Unsupported digest algorithm: " + e.getMessage());
217     } catch (URISyntaxException e) {
218       throw new UnsupportedElementException("Error while reading dublin core catalog " + url + ": " + e.getMessage());
219     }
220   }
221 
222   /**
223    * {@inheritDoc}
224    *
225    * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#newElement(
226    *      org.opencastproject.mediapackage.MediaPackageElement.Type,
227    *      org.opencastproject.mediapackage.MediaPackageElementFlavor)
228    */
229   @Override
230   public MediaPackageElement newElement(Type type, MediaPackageElementFlavor flavor) {
231     Catalog cat = CatalogImpl.newInstance();
232     cat.setFlavor(flavor);
233     return cat;
234   }
235 
236   /**
237    * {@inheritDoc}
238    *
239    * @see org.opencastproject.mediapackage.elementbuilder.MediaPackageElementBuilderPlugin#init()
240    */
241   @Override
242   public void init() throws Exception {
243   }
244 
245 }