[LIB-4] Add hespiff source files
[hespiff.git] / src / main / java / org / hedgecode / xml / xspf / XSPFPlaylist.java
1 /*
2  * Copyright (c) 2015. Developed by Hedgecode.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.hedgecode.xml.xspf;
18
19 import java.io.File;
20 import java.io.OutputStream;
21 import java.io.UnsupportedEncodingException;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.Method;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.List;
27
28 import javax.xml.bind.JAXBException;
29
30 import org.hedgecode.xml.xspf.bind.BinderFactory;
31 import org.hedgecode.xml.xspf.bind.PlaylistBinder;
32 import org.hedgecode.xml.xspf.validate.Validate;
33 import org.hedgecode.xml.xspf.validate.ValidateException;
34 import org.hedgecode.xml.xspf.validate.Validator;
35 import org.hedgecode.xml.xspf.validate.ValidatorType;
36
37 import static org.hedgecode.xml.xspf.XSPFConstants.Format;
38 import static org.hedgecode.xml.xspf.XSPFConstants.Version;
39
40 /**
41  *
42  *
43  * @author Dmitry Samoshin aka gotty
44  */
45 public final class XSPFPlaylist implements Playlist {
46
47     protected XSPFPlaylist(Format format) {
48         this.format = format;
49     }
50
51     protected XSPFPlaylist(Version version) {
52         this.format = Format.RELAX_NG;
53     }
54
55     private Format format;
56
57     /**
58      * Human-readable title for the playlist.
59      */
60     private String title;
61
62     /**
63      * Human-readable name of the entity (author, authors, group, company, etc)
64      * that authored the playlist.
65      */
66     private String creator;
67
68     /**
69      * Human-readable comment on the playlist.
70      * This is character data, not HTML, and it may not contain markup.
71      */
72     private String annotation;
73
74     /**
75      * URI of a web page to find out more about this playlist.
76      * Likely to be homepage of the author, and would be used to find out
77      * more about the author and to find more playlists by the author.
78      */
79     private String info;
80
81     /**
82      * Source URI for this playlist.
83      */
84     @Validate(validatorType = ValidatorType.URI)
85     private String location;
86
87     /**
88      * Canonical ID for this playlist.
89      * Likely to be a hash or other location-independent name.
90      * Must be a legal URI.
91      */
92     private String identifier;
93
94     /**
95      * URI of an image to display in the absence of
96      * a playlist->trackList->image element.
97      */
98     private String image;
99
100     /**
101      * Creation date (not last-modified date) of the playlist,
102      * formatted as a XML schema dateTime.
103      * In the absence of a timezone, the element may be assumed
104      * to use Coordinated Universal Time (UTC).
105      */
106     private Date date;
107
108     /**
109      * URI of a resource that describes the license
110      * under which this playlist was released.
111      */
112     private String license;
113
114     /**
115      * An ordered list of URIs. The purpose is to satisfy licenses
116      * allowing modification but requiring attribution.
117      * If you modify such a playlist, move its playlist->location
118      * or playlist->identifier element to the top of the items
119      * in the playlist->attribution element.
120      * Such a list can grow without limit, so as a practical matter
121      * we suggest deleting ancestors more than ten generations back.
122      */
123     private Attribution attribution;
124
125     /**
126      * The link element allows XSPF to be extended
127      * without the use of XML namespaces.
128      */
129     private List<Link> links = new ArrayList<>();
130
131     /**
132      * The meta element allows metadata fields to be added to XSPF.
133      */
134     private List<Meta> metas = new ArrayList<>();
135
136     /**
137      * The extension element allows non-XSPF XML to be included in XSPF documents.
138      * The purpose is to allow nested XML, which the meta and link elements do not.
139      */
140     private List<Extension> extensions = new ArrayList<>();
141
142     /**
143      * Ordered list of track elements to be rendered.
144      * The sequence is a hint, not a requirement;
145      * renderers are advised to play tracks from top to bottom
146      * unless there is an indication otherwise.
147      */
148     private List<Track> trackList = new ArrayList<>();
149
150
151     @Override
152     public String getTitle() {
153         return title;
154     }
155
156     @Override
157     public void setTitle(String title) {
158         this.title = title;
159     }
160
161     @Override
162     public String getCreator() {
163         return creator;
164     }
165
166     @Override
167     public void setCreator(String creator) {
168         this.creator = creator;
169     }
170
171     @Override
172     public String getAnnotation() {
173         return annotation;
174     }
175
176     @Override
177     public void setAnnotation(String annotation) {
178         this.annotation = annotation;
179     }
180
181     @Override
182     public String getInfo() {
183         return info;
184     }
185
186     @Override
187     public void setInfo(String info) {
188         this.info = info;
189     }
190
191     @Override
192     public String getLocation() {
193         return location;
194     }
195
196     @Override
197     public void setLocation(String location) {
198         this.location = location;
199     }
200
201     @Override
202     public String getIdentifier() {
203         return identifier;
204     }
205
206     @Override
207     public void setIdentifier(String identifier) {
208         this.identifier = identifier;
209     }
210
211     @Override
212     public String getImage() {
213         return image;
214     }
215
216     @Override
217     public void setImage(String image) {
218         this.image = image;
219     }
220
221     @Override
222     public Date getDate() {
223         return date;
224     }
225
226     @Override
227     public void setDate(Date date) {
228         this.date = date;
229     }
230
231     @Override
232     public String getLicense() {
233         return license;
234     }
235
236     @Override
237     public void setLicense(String license) {
238         this.license = license;
239     }
240
241     @Override
242     public Attribution getAttribution() {
243         return attribution;
244     }
245
246     @Override
247     public void setAttribution(Attribution attribution) {
248         this.attribution = attribution;
249     }
250
251     @Override
252     public List<Link> getLinks() {
253         return links;
254     }
255
256     @Override
257     public void addLink(Link link) {
258         links.add(link);
259     }
260
261     @Override
262     public List<Meta> getMetas() {
263         return metas;
264     }
265
266     @Override
267     public void addMeta(Meta meta) {
268         metas.add(meta);
269     }
270
271     @Override
272     public List<Extension> getExtensions() {
273         return extensions;
274     }
275
276     @Override
277     public void addExtension(Extension extension) {
278         extensions.add(extension);
279     }
280
281     @Override
282     public List<Track> getTracks() {
283         return trackList;
284     }
285
286     @Override
287     public void addTrack(Track track) {
288         trackList.add(track);
289     }
290
291     private void bind(XMLBindPlaylist bindPlaylist) {
292         bindPlaylist.setTitle(title);
293         bindPlaylist.setCreator(creator);
294         bindPlaylist.setAnnotation(annotation);
295         bindPlaylist.setInfo(info);
296         bindPlaylist.setLocation(location);
297         bindPlaylist.setIdentifier(identifier);
298         bindPlaylist.setImage(image);
299         bindPlaylist.setDate(date);
300         bindPlaylist.setLicense(license);
301         bindPlaylist.setAttribution(attribution);
302         for (Link link : links)
303             bindPlaylist.addLink(link);
304         for (Meta meta :metas)
305             bindPlaylist.addMeta(meta);
306         for (Extension extension : extensions)
307             bindPlaylist.addExtension(extension);
308         for (Track track : trackList)
309             bindPlaylist.addTrack(track);
310     }
311
312     private void unbind(XMLBindPlaylist bindPlaylist) {
313         title = bindPlaylist.getTitle();
314         creator = bindPlaylist.getCreator();
315         annotation = bindPlaylist.getAnnotation();
316         info = bindPlaylist.getInfo();
317         location = bindPlaylist.getLocation();
318         identifier = bindPlaylist.getIdentifier();
319         image = bindPlaylist.getImage();
320         date = bindPlaylist.getDate();
321         license = bindPlaylist.getLicense();
322         attribution = bindPlaylist.getAttribution();
323         links = bindPlaylist.getLinks();
324         metas = bindPlaylist.getMetas();
325         extensions = bindPlaylist.getExtensions();
326         trackList = bindPlaylist.getTracks();
327     }
328
329     @Override
330     public void read(File inputFile) throws JAXBException {
331         XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
332         bindPlaylist.read(inputFile);
333         unbind(bindPlaylist);
334     }
335
336     @Override
337     public void write(File outputFile) throws JAXBException {
338         XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
339         bind(bindPlaylist);
340         bindPlaylist.write(outputFile);
341     }
342
343     @Override
344     public OutputStream getAsStream() throws JAXBException {
345         XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
346         bind(bindPlaylist);
347         return bindPlaylist.getAsStream();
348     }
349
350     @Override
351     public String getAsString()
352             throws JAXBException, UnsupportedEncodingException
353     {
354         XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
355         bind(bindPlaylist);
356         return bindPlaylist.getAsString();
357     }
358
359
360     @Override
361     public void validate() throws ValidateException {
362         for (Field field : getClass().getFields()) {
363             if (field.isAnnotationPresent(Validate.class)) {
364                 Validator validator;
365                 try {
366                     validator = field.getAnnotation(Validate.class).validatorType().getValidator();
367                     validator.validate(
368                             field.get(this)
369                     );
370                 } catch (ReflectiveOperationException e) {
371                     throw new ValidateException(101, e.getMessage());
372                 }
373             }
374         }
375     }
376 }