2 * Copyright (c) 2015-2019. Developed by Hedgecode.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.hedgecode.xml.xspf;
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;
28 import javax.xml.bind.JAXBException;
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;
37 import static org.hedgecode.xml.xspf.XSPFConstants.Format;
38 import static org.hedgecode.xml.xspf.XSPFConstants.Version;
43 * @author Dmitry Samoshin aka gotty
45 public final class XSPFPlaylist implements Playlist {
47 protected XSPFPlaylist(Format format) {
51 protected XSPFPlaylist(Version version) {
52 this.format = Format.RELAX_NG;
55 private Format format;
58 * Human-readable title for the playlist.
63 * Human-readable name of the entity (author, authors, group, company, etc)
64 * that authored the playlist.
66 private String creator;
69 * Human-readable comment on the playlist.
70 * This is character data, not HTML, and it may not contain markup.
72 private String annotation;
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.
82 * Source URI for this playlist.
84 @Validate(validatorType = ValidatorType.URI)
85 private String location;
88 * Canonical ID for this playlist.
89 * Likely to be a hash or other location-independent name.
90 * Must be a legal URI.
92 private String identifier;
95 * URI of an image to display in the absence of
96 * a playlist->trackList->image element.
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).
109 * URI of a resource that describes the license
110 * under which this playlist was released.
112 private String license;
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.
123 private Attribution attribution;
126 * The link element allows XSPF to be extended
127 * without the use of XML namespaces.
129 private List<Link> links = new ArrayList<>();
132 * The meta element allows metadata fields to be added to XSPF.
134 private List<Meta> metas = new ArrayList<>();
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.
140 private List<Extension> extensions = new ArrayList<>();
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.
148 private List<Track> trackList = new ArrayList<>();
152 public String getTitle() {
157 public void setTitle(String title) {
162 public String getCreator() {
167 public void setCreator(String creator) {
168 this.creator = creator;
172 public String getAnnotation() {
177 public void setAnnotation(String annotation) {
178 this.annotation = annotation;
182 public String getInfo() {
187 public void setInfo(String info) {
192 public String getLocation() {
197 public void setLocation(String location) {
198 this.location = location;
202 public String getIdentifier() {
207 public void setIdentifier(String identifier) {
208 this.identifier = identifier;
212 public String getImage() {
217 public void setImage(String image) {
222 public Date getDate() {
227 public void setDate(Date date) {
232 public String getLicense() {
237 public void setLicense(String license) {
238 this.license = license;
242 public Attribution getAttribution() {
247 public void setAttribution(Attribution attribution) {
248 this.attribution = attribution;
252 public List<Link> getLinks() {
257 public void addLink(Link link) {
262 public List<Meta> getMetas() {
267 public void addMeta(Meta meta) {
272 public List<Extension> getExtensions() {
277 public void addExtension(Extension extension) {
278 extensions.add(extension);
282 public List<Track> getTracks() {
287 public void addTrack(Track track) {
288 trackList.add(track);
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);
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();
330 public void read(File inputFile) throws JAXBException {
331 XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
332 bindPlaylist.read(inputFile);
333 unbind(bindPlaylist);
337 public void write(File outputFile) throws JAXBException {
338 XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
340 bindPlaylist.write(outputFile);
344 public OutputStream getAsStream() throws JAXBException {
345 XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
347 return bindPlaylist.getAsStream();
351 public String getAsString()
352 throws JAXBException, UnsupportedEncodingException
354 XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format);
356 return bindPlaylist.getAsString();
361 public void validate() throws ValidateException {
362 for (Field field : getClass().getFields()) {
363 if (field.isAnnotationPresent(Validate.class)) {
366 validator = field.getAnnotation(Validate.class).validatorType().getValidator();
370 } catch (ReflectiveOperationException e) {
371 throw new ValidateException(101, e.getMessage());