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  package org.opencastproject.elasticsearch.index.objects.theme;
23  
24  import org.opencastproject.elasticsearch.api.SearchMetadata;
25  import org.opencastproject.elasticsearch.impl.SearchMetadataCollection;
26  import org.opencastproject.elasticsearch.index.objects.IndexObject;
27  import org.opencastproject.util.DateTimeSupport;
28  import org.opencastproject.util.DateTimeSupport.UtcTimestampAdapter;
29  import org.opencastproject.util.IoSupport;
30  import org.opencastproject.util.XmlSafeParser;
31  
32  import org.apache.commons.io.IOUtils;
33  import org.apache.commons.lang3.StringUtils;
34  import org.xml.sax.SAXException;
35  
36  import java.io.IOException;
37  import java.io.InputStream;
38  import java.io.StringWriter;
39  import java.util.Date;
40  import java.util.Map;
41  
42  import javax.xml.bind.JAXBContext;
43  import javax.xml.bind.JAXBException;
44  import javax.xml.bind.Marshaller;
45  import javax.xml.bind.Unmarshaller;
46  import javax.xml.bind.annotation.XmlAccessType;
47  import javax.xml.bind.annotation.XmlAccessorType;
48  import javax.xml.bind.annotation.XmlElement;
49  import javax.xml.bind.annotation.XmlRootElement;
50  import javax.xml.bind.annotation.XmlType;
51  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
52  
53  /**
54   * Object wrapper for a theme.
55   */
56  @XmlType(name = "theme", namespace = IndexObject.INDEX_XML_NAMESPACE, propOrder = { "identifier", "creationDate",
57          "isDefault", "description", "name", "creator", "organization", "bumperActive", "bumperFile", "trailerActive",
58          "trailerFile", "titleSlideActive", "titleSlideMetadata", "titleSlideBackground", "licenseSlideActive",
59          "licenseSlideDescription", "licenseSlideBackground", "watermarkActive", "watermarkFile", "watermarkPosition" })
60  @XmlRootElement(name = "theme", namespace = IndexObject.INDEX_XML_NAMESPACE)
61  @XmlAccessorType(XmlAccessType.NONE)
62  public class IndexTheme implements IndexObject {
63  
64    /** The document type */
65    public static final String DOCUMENT_TYPE = "theme";
66  
67    /** The name of the surrounding XML tag to wrap a result of multiple theme */
68    public static final String XML_SURROUNDING_TAG = "themes";
69  
70    /** The identifier */
71    @XmlElement(name = "identifier")
72    private Long identifier = null;
73  
74    /** The date and time the theme was created in UTC format e.g. 2011-07-16T20:39:05Z */
75    @XmlElement(name = "creationDate")
76    @XmlJavaTypeAdapter(UtcTimestampAdapter.class)
77    private Date creationDate;
78  
79    /** Whether the theme is the default theme */
80    @XmlElement(name = "default")
81    private boolean isDefault = false;
82  
83    /** The description of the theme. */
84    @XmlElement(name = "description")
85    private String description = null;
86  
87    /** The name of this theme. */
88    @XmlElement(name = "name")
89    private String name = null;
90  
91    /** The creator of the theme */
92    @XmlElement(name = "creator")
93    private String creator = null;
94  
95    /** The organization of the theme */
96    @XmlElement(name = "organization")
97    private String organization = null;
98  
99    /** Whether the bumper set in this theme should be used */
100   @XmlElement(name = "bumperActive")
101   private boolean bumperActive = false;
102 
103   /** The id of the file to use as a bumper */
104   @XmlElement(name = "bumperFile")
105   private String bumperFile = null;
106 
107   /** Whether the trailer set in this theme should be used */
108   @XmlElement(name = "trailerActive")
109   private boolean trailerActive = false;
110 
111   /** The id of the file to use as a trailer for this theme. */
112   @XmlElement(name = "trailerFile")
113   private String trailerFile = null;
114 
115   /** Whether the title slide should be used in this theme */
116   @XmlElement(name = "titleSlideActive")
117   private boolean titleSlideActive = false;
118 
119   /** The definition about which metadata to use in the title slide */
120   @XmlElement(name = "titleSlideMetadata")
121   private String titleSlideMetadata = null;
122 
123   /** The id of the file to use as the background to the title slide */
124   @XmlElement(name = "titleSlideBackground")
125   private String titleSlideBackground = null;
126 
127   /** Whether the license slide in this theme should be used */
128   @XmlElement(name = "licenseSlideActive")
129   private boolean licenseSlideActive = false;
130 
131   /** The license description for the video */
132   @XmlElement(name = "licenseSlideDescription")
133   private String licenseSlideDescription = null;
134 
135   /** The id of the file to use as a background for the license */
136   @XmlElement(name = "licenseSlideBackground")
137   private String licenseSlideBackground = null;
138 
139   /** Whether the watermark from the theme should be applied to the video */
140   @XmlElement(name = "watermarkActive")
141   private boolean watermarkActive = false;
142 
143   /** The id of the file to use as watermark on the video */
144   @XmlElement(name = "watermarkFile")
145   private String watermarkFile = null;
146 
147   /** Dictates where the watermark should be placed on the video */
148   @XmlElement(name = "watermarkPosition")
149   private String watermarkPosition = null;
150 
151   /** Context for serializing and deserializing */
152   private static JAXBContext context = null;
153 
154   /**
155    * Required default no arg constructor for JAXB.
156    */
157   public IndexTheme() {
158   }
159 
160   /**
161    * @param identifier
162    *          the theme identifier
163    * @param organization
164    *          the organization
165    */
166   public IndexTheme(long identifier, String organization) {
167     this.identifier = identifier;
168     this.organization = organization;
169   }
170 
171   public long getIdentifier() {
172     return identifier;
173   }
174 
175   public Date getCreationDate() {
176     return creationDate;
177   }
178 
179   public void setCreationDate(Date creationDate) {
180     this.creationDate = creationDate;
181   }
182 
183   public boolean isDefault() {
184     return isDefault;
185   }
186 
187   public void setDefault(boolean isDefault) {
188     this.isDefault = isDefault;
189   }
190 
191   public String getDescription() {
192     return description;
193   }
194 
195   public void setDescription(String description) {
196     this.description = description;
197   }
198 
199   public String getName() {
200     return name;
201   }
202 
203   public void setName(String name) {
204     this.name = name;
205   }
206 
207   public String getCreator() {
208     return creator;
209   }
210 
211   public void setCreator(String creator) {
212     this.creator = creator;
213   }
214 
215   public String getOrganization() {
216     return organization;
217   }
218 
219   public boolean isBumperActive() {
220     return bumperActive;
221   }
222 
223   public void setBumperActive(boolean bumperActive) {
224     this.bumperActive = bumperActive;
225   }
226 
227   public String getBumperFile() {
228     return bumperFile;
229   }
230 
231   public void setBumperFile(String bumperFile) {
232     this.bumperFile = bumperFile;
233   }
234 
235   public boolean isTrailerActive() {
236     return trailerActive;
237   }
238 
239   public void setTrailerActive(boolean trailerActive) {
240     this.trailerActive = trailerActive;
241   }
242 
243   public String getTrailerFile() {
244     return trailerFile;
245   }
246 
247   public void setTrailerFile(String trailerFile) {
248     this.trailerFile = trailerFile;
249   }
250 
251   public boolean isTitleSlideActive() {
252     return titleSlideActive;
253   }
254 
255   public void setTitleSlideActive(boolean titleSlideActive) {
256     this.titleSlideActive = titleSlideActive;
257   }
258 
259   public String getTitleSlideMetadata() {
260     return titleSlideMetadata;
261   }
262 
263   public void setTitleSlideMetadata(String titleSlideMetadata) {
264     this.titleSlideMetadata = titleSlideMetadata;
265   }
266 
267   public String getTitleSlideBackground() {
268     return titleSlideBackground;
269   }
270 
271   public void setTitleSlideBackground(String titleSlideBackground) {
272     this.titleSlideBackground = titleSlideBackground;
273   }
274 
275   public boolean isLicenseSlideActive() {
276     return licenseSlideActive;
277   }
278 
279   public void setLicenseSlideActive(boolean licenseSlideActive) {
280     this.licenseSlideActive = licenseSlideActive;
281   }
282 
283   public String getLicenseSlideDescription() {
284     return licenseSlideDescription;
285   }
286 
287   public void setLicenseSlideDescription(String licenseSlideDescription) {
288     this.licenseSlideDescription = licenseSlideDescription;
289   }
290 
291   public String getLicenseSlideBackground() {
292     return licenseSlideBackground;
293   }
294 
295   public void setLicenseSlideBackground(String licenseSlideBackground) {
296     this.licenseSlideBackground = licenseSlideBackground;
297   }
298 
299   public boolean isWatermarkActive() {
300     return watermarkActive;
301   }
302 
303   public void setWatermarkActive(boolean watermarkActive) {
304     this.watermarkActive = watermarkActive;
305   }
306 
307   public String getWatermarkFile() {
308     return watermarkFile;
309   }
310 
311   public void setWatermarkFile(String watermarkFile) {
312     this.watermarkFile = watermarkFile;
313   }
314 
315   public String getWatermarkPosition() {
316     return watermarkPosition;
317   }
318 
319   public void setWatermarkPosition(String watermarkPosition) {
320     this.watermarkPosition = watermarkPosition;
321   }
322 
323   /**
324    * Reads the theme from the input stream.
325    *
326    * @param xml
327    *          the input stream
328    * @return the deserialized theme
329    * @throws IOException
330    */
331   public static IndexTheme valueOf(InputStream xml) throws IOException {
332     try {
333       if (context == null) {
334         createJAXBContext();
335       }
336       Unmarshaller unmarshaller = context.createUnmarshaller();
337       return unmarshaller.unmarshal(XmlSafeParser.parse(xml), IndexTheme.class).getValue();
338     } catch (JAXBException e) {
339       throw new IOException(e.getLinkedException() != null ? e.getLinkedException() : e);
340     } catch (SAXException e) {
341       throw new IOException(e);
342     } finally {
343       IoSupport.closeQuietly(xml);
344     }
345   }
346 
347   /**
348    * Initialize the JAXBContext.
349    */
350   private static void createJAXBContext() throws JAXBException {
351     context = JAXBContext.newInstance(IndexTheme.class);
352   }
353 
354   /**
355    * Serializes the theme to an XML format.
356    *
357    * @return A String with this theme's content as XML.
358    */
359   public String toXML() {
360     try {
361       if (context == null) {
362         createJAXBContext();
363       }
364       StringWriter writer = new StringWriter();
365       Marshaller marshaller = IndexTheme.context.createMarshaller();
366       marshaller.marshal(this, writer);
367       return writer.toString();
368     } catch (JAXBException e) {
369       throw new IllegalStateException(e.getLinkedException() != null ? e.getLinkedException() : e);
370     }
371   }
372 
373   /**
374    * Creates a search result item based on the data returned from the search index.
375    *
376    * @param metadata
377    *          the search metadata
378    * @return the search result item
379    * @throws IOException
380    *           if unmarshalling fails
381    */
382   public static IndexTheme fromSearchMetadata(SearchMetadataCollection metadata) throws IOException {
383     Map<String, SearchMetadata<?>> metadataMap = metadata.toMap();
384     String themeXml = (String) metadataMap.get(ThemeIndexSchema.OBJECT).getValue();
385     return IndexTheme.valueOf(IOUtils.toInputStream(themeXml));
386   }
387 
388   /**
389    * Creates search metadata from a theme such that the theme can be stored in the search index.
390    *
391    * @return the set of metadata
392    */
393   public SearchMetadataCollection toSearchMetadata() {
394     SearchMetadataCollection metadata = new SearchMetadataCollection(Long.toString(getIdentifier()).concat(
395             getOrganization()), IndexTheme.DOCUMENT_TYPE);
396     // Mandatory fields
397     metadata.addField(ThemeIndexSchema.ID, getIdentifier(), false);
398     metadata.addField(ThemeIndexSchema.ORGANIZATION, getOrganization(), false);
399     metadata.addField(ThemeIndexSchema.OBJECT, toXML(), false);
400 
401     // Optional fields
402     if (StringUtils.isNotBlank(getName())) {
403       metadata.addField(ThemeIndexSchema.NAME, getName(), true);
404     }
405 
406     if (StringUtils.isNotBlank(getDescription())) {
407       metadata.addField(ThemeIndexSchema.DESCRIPTION, getDescription(), true);
408     }
409 
410     metadata.addField(ThemeIndexSchema.DEFAULT, isDefault(), false);
411 
412     if (getCreationDate() != null) {
413       metadata.addField(ThemeIndexSchema.CREATION_DATE,
414               DateTimeSupport.toUTC(getCreationDate().getTime()), false);
415     }
416 
417     if (StringUtils.isNotBlank(getCreator())) {
418       metadata.addField(ThemeIndexSchema.CREATOR, getCreator(), true);
419     }
420 
421     metadata.addField(ThemeIndexSchema.BUMPER_ACTIVE, isBumperActive(), false);
422 
423     if (StringUtils.isNotBlank(getBumperFile())) {
424       metadata.addField(ThemeIndexSchema.BUMPER_FILE, getBumperFile(), false);
425     }
426 
427     metadata.addField(ThemeIndexSchema.TRAILER_ACTIVE, isTrailerActive(), false);
428 
429     if (StringUtils.isNotBlank(getTrailerFile())) {
430       metadata.addField(ThemeIndexSchema.TRAILER_FILE, getTrailerFile(), false);
431     }
432 
433     metadata.addField(ThemeIndexSchema.TITLE_SLIDE_ACTIVE, isTrailerActive(), false);
434 
435     if (StringUtils.isNotBlank(getTitleSlideMetadata())) {
436       metadata.addField(ThemeIndexSchema.TITLE_SLIDE_METADATA, getTitleSlideMetadata(), false);
437     }
438 
439     if (StringUtils.isNotBlank(getTitleSlideBackground())) {
440       metadata.addField(ThemeIndexSchema.TITLE_SLIDE_BACKGROUND, getTitleSlideBackground(), false);
441     }
442 
443     metadata.addField(ThemeIndexSchema.LICENSE_SLIDE_ACTIVE, isLicenseSlideActive(), false);
444 
445     if (StringUtils.isNotBlank(getLicenseSlideDescription())) {
446       metadata.addField(ThemeIndexSchema.LICENSE_SLIDE_DESCRIPTION, getLicenseSlideDescription(), false);
447     }
448 
449     if (StringUtils.isNotBlank(getLicenseSlideBackground())) {
450       metadata.addField(ThemeIndexSchema.LICENSE_SLIDE_BACKGROUND, getLicenseSlideBackground(), false);
451     }
452 
453     metadata.addField(ThemeIndexSchema.WATERMARK_ACTIVE, isWatermarkActive(), false);
454 
455     if (StringUtils.isNotBlank(getWatermarkFile())) {
456       metadata.addField(ThemeIndexSchema.WATERMARK_FILE, getWatermarkFile(), false);
457     }
458 
459     if (StringUtils.isNotBlank(getWatermarkPosition())) {
460       metadata.addField(ThemeIndexSchema.WATERMARK_POSITION, getWatermarkPosition(), false);
461     }
462     return metadata;
463   }
464 }