/* * Copyright (c) 2015. Developed by Hedgecode. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hedgecode.xml.xspf; import java.io.File; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.xml.bind.JAXBException; import org.hedgecode.xml.xspf.bind.BinderFactory; import org.hedgecode.xml.xspf.bind.PlaylistBinder; import org.hedgecode.xml.xspf.validate.Validate; import org.hedgecode.xml.xspf.validate.ValidateException; import org.hedgecode.xml.xspf.validate.Validator; import org.hedgecode.xml.xspf.validate.ValidatorType; import static org.hedgecode.xml.xspf.XSPFConstants.Format; import static org.hedgecode.xml.xspf.XSPFConstants.Version; /** * * * @author Dmitry Samoshin aka gotty */ public final class XSPFPlaylist implements Playlist { protected XSPFPlaylist(Format format) { this.format = format; } protected XSPFPlaylist(Version version) { this.format = Format.RELAX_NG; } private Format format; /** * Human-readable title for the playlist. */ private String title; /** * Human-readable name of the entity (author, authors, group, company, etc) * that authored the playlist. */ private String creator; /** * Human-readable comment on the playlist. * This is character data, not HTML, and it may not contain markup. */ private String annotation; /** * URI of a web page to find out more about this playlist. * Likely to be homepage of the author, and would be used to find out * more about the author and to find more playlists by the author. */ private String info; /** * Source URI for this playlist. */ @Validate(validatorType = ValidatorType.URI) private String location; /** * Canonical ID for this playlist. * Likely to be a hash or other location-independent name. * Must be a legal URI. */ private String identifier; /** * URI of an image to display in the absence of * a playlist->trackList->image element. */ private String image; /** * Creation date (not last-modified date) of the playlist, * formatted as a XML schema dateTime. * In the absence of a timezone, the element may be assumed * to use Coordinated Universal Time (UTC). */ private Date date; /** * URI of a resource that describes the license * under which this playlist was released. */ private String license; /** * An ordered list of URIs. The purpose is to satisfy licenses * allowing modification but requiring attribution. * If you modify such a playlist, move its playlist->location * or playlist->identifier element to the top of the items * in the playlist->attribution element. * Such a list can grow without limit, so as a practical matter * we suggest deleting ancestors more than ten generations back. */ private Attribution attribution; /** * The link element allows XSPF to be extended * without the use of XML namespaces. */ private List links = new ArrayList<>(); /** * The meta element allows metadata fields to be added to XSPF. */ private List metas = new ArrayList<>(); /** * The extension element allows non-XSPF XML to be included in XSPF documents. * The purpose is to allow nested XML, which the meta and link elements do not. */ private List extensions = new ArrayList<>(); /** * Ordered list of track elements to be rendered. * The sequence is a hint, not a requirement; * renderers are advised to play tracks from top to bottom * unless there is an indication otherwise. */ private List trackList = new ArrayList<>(); @Override public String getTitle() { return title; } @Override public void setTitle(String title) { this.title = title; } @Override public String getCreator() { return creator; } @Override public void setCreator(String creator) { this.creator = creator; } @Override public String getAnnotation() { return annotation; } @Override public void setAnnotation(String annotation) { this.annotation = annotation; } @Override public String getInfo() { return info; } @Override public void setInfo(String info) { this.info = info; } @Override public String getLocation() { return location; } @Override public void setLocation(String location) { this.location = location; } @Override public String getIdentifier() { return identifier; } @Override public void setIdentifier(String identifier) { this.identifier = identifier; } @Override public String getImage() { return image; } @Override public void setImage(String image) { this.image = image; } @Override public Date getDate() { return date; } @Override public void setDate(Date date) { this.date = date; } @Override public String getLicense() { return license; } @Override public void setLicense(String license) { this.license = license; } @Override public Attribution getAttribution() { return attribution; } @Override public void setAttribution(Attribution attribution) { this.attribution = attribution; } @Override public List getLinks() { return links; } @Override public void addLink(Link link) { links.add(link); } @Override public List getMetas() { return metas; } @Override public void addMeta(Meta meta) { metas.add(meta); } @Override public List getExtensions() { return extensions; } @Override public void addExtension(Extension extension) { extensions.add(extension); } @Override public List getTracks() { return trackList; } @Override public void addTrack(Track track) { trackList.add(track); } private void bind(XMLBindPlaylist bindPlaylist) { bindPlaylist.setTitle(title); bindPlaylist.setCreator(creator); bindPlaylist.setAnnotation(annotation); bindPlaylist.setInfo(info); bindPlaylist.setLocation(location); bindPlaylist.setIdentifier(identifier); bindPlaylist.setImage(image); bindPlaylist.setDate(date); bindPlaylist.setLicense(license); bindPlaylist.setAttribution(attribution); for (Link link : links) bindPlaylist.addLink(link); for (Meta meta :metas) bindPlaylist.addMeta(meta); for (Extension extension : extensions) bindPlaylist.addExtension(extension); for (Track track : trackList) bindPlaylist.addTrack(track); } private void unbind(XMLBindPlaylist bindPlaylist) { title = bindPlaylist.getTitle(); creator = bindPlaylist.getCreator(); annotation = bindPlaylist.getAnnotation(); info = bindPlaylist.getInfo(); location = bindPlaylist.getLocation(); identifier = bindPlaylist.getIdentifier(); image = bindPlaylist.getImage(); date = bindPlaylist.getDate(); license = bindPlaylist.getLicense(); attribution = bindPlaylist.getAttribution(); links = bindPlaylist.getLinks(); metas = bindPlaylist.getMetas(); extensions = bindPlaylist.getExtensions(); trackList = bindPlaylist.getTracks(); } @Override public void read(File inputFile) throws JAXBException { XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format); bindPlaylist.read(inputFile); unbind(bindPlaylist); } @Override public void write(File outputFile) throws JAXBException { XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format); bind(bindPlaylist); bindPlaylist.write(outputFile); } @Override public OutputStream getAsStream() throws JAXBException { XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format); bind(bindPlaylist); return bindPlaylist.getAsStream(); } @Override public String getAsString() throws JAXBException, UnsupportedEncodingException { XMLBindPlaylist bindPlaylist = new XMLBindPlaylist(format); bind(bindPlaylist); return bindPlaylist.getAsString(); } @Override public void validate() throws ValidateException { for (Field field : getClass().getFields()) { if (field.isAnnotationPresent(Validate.class)) { Validator validator; try { validator = field.getAnnotation(Validate.class).validatorType().getValidator(); validator.validate( field.get(this) ); } catch (ReflectiveOperationException e) { throw new ValidateException(101, e.getMessage()); } } } } }