+/*
+ * 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.ByteArrayOutputStream;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.hedgecode.xml.xspf.bind.Binder;
+import org.hedgecode.xml.xspf.bind.BinderFactory;
+import org.hedgecode.xml.xspf.bind.PlaylistBinder;
+import org.hedgecode.xml.xspf.validate.ValidateException;
+
+import static org.hedgecode.xml.xspf.XSPFConstants.Format;
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class XMLBindPlaylist extends AbstractXMLBindElement implements Playlist {
+
+ private PlaylistBinder binder;
+
+ protected XMLBindPlaylist(PlaylistBinder binder) {
+ if (binder == null)
+ this.binder = BinderFactory.createPlaylistBinder();
+ else
+ this.binder = binder;
+ setDefaults();
+ }
+
+ protected XMLBindPlaylist(Format format) {
+ this.binder = BinderFactory.createPlaylistBinder(format);
+ setDefaults();
+ }
+
+ private void setDefaults() {
+ binder.setVersion(XSPFConstants.XSPF_VERSION);
+ }
+
+ @Override
+ protected Binder getBinder() {
+ return binder;
+ }
+
+ @Override
+ public String getLocation() {
+ return binder.getLocation();
+ }
+
+ @Override
+ public void setLocation(String location) {
+ binder.setLocation(location);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return binder.getIdentifier();
+ }
+
+ @Override
+ public void setIdentifier(String identifier) {
+ binder.setIdentifier(identifier);
+ }
+
+ @Override
+ public Date getDate() {
+ return binder.getDate();
+ }
+
+ @Override
+ public void setDate(Date date) {
+ binder.setDate(date);
+ }
+
+ @Override
+ public String getLicense() {
+ return binder.getLicense();
+ }
+
+ @Override
+ public void setLicense(String license) {
+ binder.setLicense(license);
+ }
+
+ @Override
+ public Attribution getAttribution() {
+ return binder.getAttribution();
+ }
+
+ @Override
+ public void setAttribution(Attribution attribution) {
+ binder.setAttribution(attribution);
+ }
+
+ @Override
+ public List<Track> getTracks() {
+ return binder.getTracks();
+ }
+
+ @Override
+ public void addTrack(Track track) {
+ binder.addTrack(track);
+ }
+
+ public void read(File inputFile) throws JAXBException {
+ binder.setPlaylist(
+ extractRootObject(
+ binder.getPlaylistClass(),
+ createUnmarshaller(
+ binder.getPlaylistClass()
+ ).unmarshal(inputFile)
+ )
+ );
+ }
+
+ @Override
+ public void write(File outputFile) throws JAXBException {
+ createMarshaller(
+ binder.getPlaylistClass()
+ ).marshal(
+ wrapPlaylist(binder),
+ outputFile
+ );
+ }
+
+ @Override
+ public OutputStream getAsStream() throws JAXBException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ createMarshaller(
+ binder.getPlaylistClass()
+ ).marshal(
+ wrapPlaylist(binder),
+ baos
+ );
+ return baos;
+ }
+
+ @Override
+ public String getAsString()
+ throws JAXBException, UnsupportedEncodingException
+ {
+ Charset charset = (Charset) Properties.getProperty(
+ Properties.CHARSET, Charset.class
+ );
+ ByteArrayOutputStream os = (ByteArrayOutputStream) getAsStream();
+ return os.toString(
+ charset.name()
+ );
+ }
+
+ private Marshaller createMarshaller(Class xmlRootClass) throws JAXBException {
+ JAXBContext jaxbContext = JAXBContext.newInstance(xmlRootClass);
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ Charset charset = (Charset) Properties.getProperty(Properties.CHARSET, Charset.class);
+ marshaller.setProperty(
+ Marshaller.JAXB_ENCODING,
+ charset.name()
+ );
+ marshaller.setProperty(
+ Marshaller.JAXB_FORMATTED_OUTPUT,
+ Properties.getProperty(Properties.FORMATTED, Boolean.class)
+ );
+ Object standalone = Properties.getProperty(Properties.STANDALONE, Boolean.class);
+ if (Boolean.FALSE.equals(standalone)) {
+ marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
+ marshaller.setProperty(
+ XSPFConstants.XML_HEADER_NAME,
+ XSPFConstants.XML_HEADER_VALUE.replace("%CHARSET%", charset.name())
+ );
+ }
+ return marshaller;
+ }
+
+ private Unmarshaller createUnmarshaller(Class xmlRootClass) throws JAXBException {
+ JAXBContext jaxbContext = JAXBContext.newInstance(xmlRootClass);
+ return jaxbContext.createUnmarshaller();
+ }
+
+ private Object extractRootObject(Class xmlRootClass, Object unmarshallingObject) {
+ if (xmlRootClass.getAnnotation(XmlRootElement.class) != null)
+ return unmarshallingObject;
+ return unmarshallingObject instanceof JAXBElement
+ ? ((JAXBElement) unmarshallingObject).getValue()
+ : null;
+
+ }
+
+ private Object wrapPlaylist(PlaylistBinder binder) {
+ if (binder.getPlaylistClass().getAnnotation(XmlRootElement.class) != null)
+ return binder.getPlaylist();
+ return binder.wrapPlaylist();
+ }
+
+ @Override
+ public void validate() throws ValidateException {
+
+ }
+
+}