161e4f51960637324ad14c1601f665af1d48673b
[hespiff.git] / src / main / java / org / hedgecode / xml / xspf / XMLBindPlaylist.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.ByteArrayOutputStream;
20 import java.io.File;
21 import java.io.OutputStream;
22 import java.io.UnsupportedEncodingException;
23 import java.nio.charset.Charset;
24 import java.util.Date;
25 import java.util.List;
26
27 import javax.xml.bind.JAXBContext;
28 import javax.xml.bind.JAXBElement;
29 import javax.xml.bind.JAXBException;
30 import javax.xml.bind.Marshaller;
31 import javax.xml.bind.Unmarshaller;
32 import javax.xml.bind.annotation.XmlRootElement;
33
34 import org.hedgecode.xml.xspf.bind.Binder;
35 import org.hedgecode.xml.xspf.bind.BinderFactory;
36 import org.hedgecode.xml.xspf.bind.PlaylistBinder;
37 import org.hedgecode.xml.xspf.validate.ValidateException;
38
39 import static org.hedgecode.xml.xspf.XSPFConstants.Format;
40
41 /**
42  *
43  *
44  * @author Dmitry Samoshin aka gotty
45  */
46 public class XMLBindPlaylist extends AbstractXMLBindElement implements Playlist {
47
48     private PlaylistBinder binder;
49
50     protected XMLBindPlaylist(PlaylistBinder binder) {
51         if (binder == null)
52             this.binder = BinderFactory.createPlaylistBinder();
53         else
54             this.binder = binder;
55         setDefaults();
56     }
57
58     protected XMLBindPlaylist(Format format) {
59         this.binder = BinderFactory.createPlaylistBinder(format);
60         setDefaults();
61     }
62
63     private void setDefaults() {
64         binder.setVersion(XSPFConstants.XSPF_VERSION);
65     }
66
67     @Override
68     protected Binder getBinder() {
69         return binder;
70     }
71
72     @Override
73     public String getLocation() {
74         return binder.getLocation();
75     }
76
77     @Override
78     public void setLocation(String location) {
79         binder.setLocation(location);
80     }
81
82     @Override
83     public String getIdentifier() {
84         return binder.getIdentifier();
85     }
86
87     @Override
88     public void setIdentifier(String identifier) {
89         binder.setIdentifier(identifier);
90     }
91
92     @Override
93     public Date getDate() {
94         return binder.getDate();
95     }
96
97     @Override
98     public void setDate(Date date) {
99         binder.setDate(date);
100     }
101
102     @Override
103     public String getLicense() {
104         return binder.getLicense();
105     }
106
107     @Override
108     public void setLicense(String license) {
109         binder.setLicense(license);
110     }
111
112     @Override
113     public Attribution getAttribution() {
114         return binder.getAttribution();
115     }
116
117     @Override
118     public void setAttribution(Attribution attribution) {
119         binder.setAttribution(attribution);
120     }
121
122     @Override
123     public List<Track> getTracks() {
124         return binder.getTracks();
125     }
126
127     @Override
128     public void addTrack(Track track) {
129         binder.addTrack(track);
130     }
131
132     public void read(File inputFile) throws JAXBException {
133         binder.setPlaylist(
134                 extractRootObject(
135                         binder.getPlaylistClass(),
136                         createUnmarshaller(
137                                 binder.getPlaylistClass()
138                         ).unmarshal(inputFile)
139                 )
140         );
141     }
142
143     @Override
144     public void write(File outputFile) throws JAXBException {
145         createMarshaller(
146                 binder.getPlaylistClass()
147         ).marshal(
148                 wrapPlaylist(binder),
149                 outputFile
150         );
151     }
152
153     @Override
154     public OutputStream getAsStream() throws JAXBException {
155         ByteArrayOutputStream baos = new ByteArrayOutputStream();
156         createMarshaller(
157                 binder.getPlaylistClass()
158         ).marshal(
159                 wrapPlaylist(binder),
160                 baos
161         );
162         return baos;
163     }
164
165     @Override
166     public String getAsString()
167             throws JAXBException, UnsupportedEncodingException
168     {
169         Charset charset = (Charset) Properties.getProperty(
170                 Properties.CHARSET, Charset.class
171         );
172         ByteArrayOutputStream os = (ByteArrayOutputStream) getAsStream();
173         return os.toString(
174                 charset.name()
175         );
176     }
177
178     private Marshaller createMarshaller(Class xmlRootClass) throws JAXBException {
179         JAXBContext jaxbContext = JAXBContext.newInstance(xmlRootClass);
180         Marshaller marshaller = jaxbContext.createMarshaller();
181         Charset charset = (Charset) Properties.getProperty(Properties.CHARSET, Charset.class);
182         marshaller.setProperty(
183                 Marshaller.JAXB_ENCODING,
184                 charset.name()
185         );
186         marshaller.setProperty(
187                 Marshaller.JAXB_FORMATTED_OUTPUT,
188                 Properties.getProperty(Properties.FORMATTED, Boolean.class)
189         );
190         Object standalone = Properties.getProperty(Properties.STANDALONE, Boolean.class);
191         if (Boolean.FALSE.equals(standalone)) {
192             marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
193             marshaller.setProperty(
194                     XSPFConstants.XML_HEADER_NAME,
195                     XSPFConstants.XML_HEADER_VALUE.replace("%CHARSET%", charset.name())
196             );
197         }
198         return marshaller;
199     }
200
201     private Unmarshaller createUnmarshaller(Class xmlRootClass) throws JAXBException {
202         JAXBContext jaxbContext = JAXBContext.newInstance(xmlRootClass);
203         return jaxbContext.createUnmarshaller();
204     }
205
206     private Object extractRootObject(Class xmlRootClass, Object unmarshallingObject) {
207         if (xmlRootClass.getAnnotation(XmlRootElement.class) != null)
208             return unmarshallingObject;
209         return unmarshallingObject instanceof JAXBElement
210                 ? ((JAXBElement) unmarshallingObject).getValue()
211                 : null;
212
213     }
214
215     private Object wrapPlaylist(PlaylistBinder binder) {
216         if (binder.getPlaylistClass().getAnnotation(XmlRootElement.class) != null)
217             return binder.getPlaylist();
218         return binder.wrapPlaylist();
219     }
220
221     @Override
222     public void validate() throws ValidateException {
223
224     }
225
226 }