From 6310cd885e1db660feb7dc222c2e86cccb5c1fce Mon Sep 17 00:00:00 2001 From: gotty Date: Fri, 1 Jul 2016 22:31:57 +0000 Subject: [PATCH] [LIB-4] Add hespiff source files git-svn-id: https://svn.hedgecode.org/xml/hespiff/trunk@69 fb0bcced-7025-49ed-a12f-f98bce993226 --- pom.xml | 214 ++++++++++++ .../hedgecode/xml/xspf/AbstractXMLBindElement.java | 112 ++++++ .../java/org/hedgecode/xml/xspf/Attribution.java | 32 ++ src/main/java/org/hedgecode/xml/xspf/Element.java | 60 ++++ .../java/org/hedgecode/xml/xspf/Extension.java | 34 ++ src/main/java/org/hedgecode/xml/xspf/Link.java | 32 ++ src/main/java/org/hedgecode/xml/xspf/Meta.java | 32 ++ src/main/java/org/hedgecode/xml/xspf/Playlist.java | 70 ++++ .../org/hedgecode/xml/xspf/PlaylistFactory.java | 78 +++++ .../java/org/hedgecode/xml/xspf/Properties.java | 63 ++++ src/main/java/org/hedgecode/xml/xspf/Track.java | 48 +++ .../org/hedgecode/xml/xspf/XMLBindPlaylist.java | 226 +++++++++++++ .../java/org/hedgecode/xml/xspf/XMLBindTrack.java | 102 ++++++ src/main/java/org/hedgecode/xml/xspf/XSPF.java | 139 ++++++++ .../org/hedgecode/xml/xspf/XSPFAttribution.java | 50 +++ .../java/org/hedgecode/xml/xspf/XSPFConstants.java | 107 ++++++ .../java/org/hedgecode/xml/xspf/XSPFException.java | 41 +++ .../java/org/hedgecode/xml/xspf/XSPFExtension.java | 54 +++ src/main/java/org/hedgecode/xml/xspf/XSPFLink.java | 52 +++ src/main/java/org/hedgecode/xml/xspf/XSPFMeta.java | 52 +++ .../java/org/hedgecode/xml/xspf/XSPFPlaylist.java | 376 +++++++++++++++++++++ .../java/org/hedgecode/xml/xspf/XSPFTrack.java | 264 +++++++++++++++ .../hedgecode/xml/xspf/bind/AbstractRNGBinder.java | 210 ++++++++++++ .../hedgecode/xml/xspf/bind/AbstractXSDBinder.java | 30 ++ .../java/org/hedgecode/xml/xspf/bind/Binder.java | 64 ++++ .../org/hedgecode/xml/xspf/bind/BinderFactory.java | 77 +++++ .../hedgecode/xml/xspf/bind/PlaylistBinder.java | 75 ++++ .../hedgecode/xml/xspf/bind/RNGPlaylistBinder.java | 282 ++++++++++++++++ .../hedgecode/xml/xspf/bind/RNGTrackBinder.java | 175 ++++++++++ .../org/hedgecode/xml/xspf/bind/TrackBinder.java | 48 +++ .../hedgecode/xml/xspf/bind/XSDPlaylistBinder.java | 350 +++++++++++++++++++ .../hedgecode/xml/xspf/bind/XSDTrackBinder.java | 243 +++++++++++++ .../xml/xspf/validate/EmptyValidator.java | 37 ++ .../hedgecode/xml/xspf/validate/URIValidator.java | 37 ++ .../org/hedgecode/xml/xspf/validate/Validate.java | 38 +++ .../xml/xspf/validate/ValidateException.java | 37 ++ .../org/hedgecode/xml/xspf/validate/Validator.java | 28 ++ .../hedgecode/xml/xspf/validate/ValidatorType.java | 39 +++ src/main/rng/xspf-1_0.7.rng | 333 ++++++++++++++++++ src/main/xsd/xspf-1_0.2.xsd | 126 +++++++ src/test/java/org/hedgecode/xml/xspf/XSPFTest.java | 69 ++++ src/test/resources/playlist.xspf | 40 +++ src/test/resources/torrent-tv.ru.xspf | 1 + 43 files changed, 4577 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/org/hedgecode/xml/xspf/AbstractXMLBindElement.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Attribution.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Element.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Extension.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Link.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Meta.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Playlist.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/PlaylistFactory.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Properties.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/Track.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XMLBindPlaylist.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XMLBindTrack.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPF.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFAttribution.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFConstants.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFException.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFExtension.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFLink.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFMeta.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFPlaylist.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/XSPFTrack.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/AbstractRNGBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/AbstractXSDBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/Binder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/BinderFactory.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/PlaylistBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/RNGPlaylistBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/RNGTrackBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/TrackBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/XSDPlaylistBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/bind/XSDTrackBinder.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/validate/EmptyValidator.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/validate/URIValidator.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/validate/Validate.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/validate/ValidateException.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/validate/Validator.java create mode 100644 src/main/java/org/hedgecode/xml/xspf/validate/ValidatorType.java create mode 100644 src/main/rng/xspf-1_0.7.rng create mode 100644 src/main/xsd/xspf-1_0.2.xsd create mode 100644 src/test/java/org/hedgecode/xml/xspf/XSPFTest.java create mode 100644 src/test/resources/playlist.xspf create mode 100644 src/test/resources/torrent-tv.ru.xspf diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c648b54 --- /dev/null +++ b/pom.xml @@ -0,0 +1,214 @@ + + + + + + 4.0.0 + + + + org.hedgecode.xml + hespiff + 0.1-SNAPSHOT + jar + + Hedgecode XSPF API + + Hedgecode XSPF API. + + 2015 + + http://hedgecode.org/xml/${project.artifactId}/ + + + scm:svn:http://svn.hedgecode.org/xml/${project.artifactId}/trunk/ + scm:svn:http://svn.hedgecode.org/xml/${project.artifactId}/trunk/ + http://svn.hedgecode.org/xml/${project.artifactId}/trunk/ + + + + 7 + 1.${javaVersion} + 1.${javaVersion} + UTF-8 + UTF-8 + 4.8.2 + + ${project.groupId}.xspf + ${project.basedir}/src/main/xsd + xspf-1_0.2 + ${project.basedir}/src/main/rng + xspf-1_0.7 + ${project.build.directory}/generated-xsd + ${project.build.directory}/generated-sources + ${project.build.outputDirectory}/META-INF + + + + LIB-4 + + + + + junit + junit + ${junitVersion} + test + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.7 + + + copy-xsd + validate + + copy-resources + + + ${generated.meta.directory} + + + ${xsd.directory} + + + ${relaxng.directory} + + + + + + + + us.bryon + relaxng-maven-plugin + 1.1 + + + generate-sources + + trang + + + + + ${relaxng.directory}/${relaxng.filename}.rng + ${generated.xsd.directory}/${relaxng.filename}.xsd + + + + + + + + org.codehaus.mojo + jaxb2-maven-plugin + 2.2 + + + generate-sources + + xjc + + + ${generated.sources.directory}/xsd + ${project.package}.xsd + + -episode + ${generated.meta.directory}/xsd-jaxb.episode + + + + + + + org.jvnet.jaxb2.maven2 + maven-jaxb2-plugin + 0.13.1 + + + generate-sources + + generate + + + ${generated.xsd.directory} + ${generated.sources.directory}/rng + ${project.package}.rng + ${generated.meta.directory}/rng-jaxb.episode + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.9.1 + + + generate-sources + + add-source + + + + ${generated.sources.directory}/xsd + ${generated.sources.directory}/rng + + + + + + + + + diff --git a/src/main/java/org/hedgecode/xml/xspf/AbstractXMLBindElement.java b/src/main/java/org/hedgecode/xml/xspf/AbstractXMLBindElement.java new file mode 100644 index 0000000..059f25a --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/AbstractXMLBindElement.java @@ -0,0 +1,112 @@ +/* + * 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.util.List; + +import org.hedgecode.xml.xspf.bind.Binder; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public abstract class AbstractXMLBindElement implements Element { + + protected abstract Binder getBinder(); + + @Override + public String getTitle() { + return getBinder().getTitle(); + } + + @Override + public void setTitle(String title) { + getBinder().setTitle(title); + } + + @Override + public String getCreator() { + return getBinder().getCreator(); + } + + @Override + public void setCreator(String creator) { + getBinder().setCreator(creator); + } + + @Override + public String getAnnotation() { + return getBinder().getAnnotation(); + } + + @Override + public void setAnnotation(String annotation) { + getBinder().setAnnotation(annotation); + } + + @Override + public String getInfo() { + return getBinder().getInfo(); + } + + @Override + public void setInfo(String info) { + getBinder().setInfo(info); + } + + @Override + public String getImage() { + return getBinder().getImage(); + } + + @Override + public void setImage(String image) { + getBinder().setImage(image); + } + + @Override + public List getLinks() { + return getBinder().getLinks(); + } + + @Override + public void addLink(Link link) { + getBinder().addLink(link); + } + + @Override + public List getMetas() { + return getBinder().getMetas(); + } + + @Override + public void addMeta(Meta meta) { + getBinder().addMeta(meta); + } + + @Override + public List getExtensions() { + return getBinder().getExtensions(); + } + + @Override + public void addExtension(Extension extension) { + getBinder().addExtension(extension); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Attribution.java b/src/main/java/org/hedgecode/xml/xspf/Attribution.java new file mode 100644 index 0000000..0c679de --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Attribution.java @@ -0,0 +1,32 @@ +/* + * 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.util.Map; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Attribution { + + Map get(); + + void add(String identifier, String location); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Element.java b/src/main/java/org/hedgecode/xml/xspf/Element.java new file mode 100644 index 0000000..cd6f557 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Element.java @@ -0,0 +1,60 @@ +/* + * 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.util.List; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Element { + + String getTitle(); + + void setTitle(String title); + + String getCreator(); + + void setCreator(String creator); + + String getAnnotation(); + + void setAnnotation(String annotation); + + String getInfo(); + + void setInfo(String info); + + String getImage(); + + void setImage(String image); + + List getLinks(); + + void addLink(Link link); + + List getMetas(); + + void addMeta(Meta meta); + + List getExtensions(); + + void addExtension(Extension extension); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Extension.java b/src/main/java/org/hedgecode/xml/xspf/Extension.java new file mode 100644 index 0000000..ebcd9de --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Extension.java @@ -0,0 +1,34 @@ +/* + * 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.util.List; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Extension { + + String getApplication(); + + List getContent(); + + void set(String application, List content); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Link.java b/src/main/java/org/hedgecode/xml/xspf/Link.java new file mode 100644 index 0000000..8b3d3c4 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Link.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Link { + + String getRel(); + + String getContent(); + + void set(String rel, String content); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Meta.java b/src/main/java/org/hedgecode/xml/xspf/Meta.java new file mode 100644 index 0000000..4784fb4 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Meta.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Meta { + + String getRel(); + + String getContent(); + + void set(String rel, String content); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Playlist.java b/src/main/java/org/hedgecode/xml/xspf/Playlist.java new file mode 100644 index 0000000..b9728e8 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Playlist.java @@ -0,0 +1,70 @@ +/* + * 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.util.Date; +import java.util.List; + +import javax.xml.bind.JAXBException; + +import org.hedgecode.xml.xspf.validate.ValidateException; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Playlist extends Element { + + String getLocation(); + + void setLocation(String location); + + String getIdentifier(); + + void setIdentifier(String identifier); + + Date getDate(); + + void setDate(Date date); + + String getLicense(); + + void setLicense(String license); + + Attribution getAttribution(); + + void setAttribution(Attribution attribution); + + List getTracks(); + + void addTrack(Track track); + + void read(File inputFile) throws JAXBException; + + void write(File outputFile) throws JAXBException; + + public OutputStream getAsStream() throws JAXBException; + + public String getAsString() throws JAXBException, UnsupportedEncodingException; + + void validate() throws ValidateException; + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/PlaylistFactory.java b/src/main/java/org/hedgecode/xml/xspf/PlaylistFactory.java new file mode 100644 index 0000000..1e74eb2 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/PlaylistFactory.java @@ -0,0 +1,78 @@ +/* + * 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.util.List; + +import org.hedgecode.xml.xspf.bind.TrackBinder; + +import static org.hedgecode.xml.xspf.XSPFConstants.Format; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public final class PlaylistFactory { + + public static Playlist createPlaylist(Format format) { + return new XSPFPlaylist(format); + } + + public static Track createTrack() { + return new XSPFTrack(); + } + + public static Track createTrack(TrackBinder trackBinder) { + XSPFTrack track = new XSPFTrack(); + track.unbind( + new XMLBindTrack(trackBinder) + ); + return track; + } + + public static void bindTrack(Track track, TrackBinder trackBinder) { + if (track instanceof XSPFTrack) + ((XSPFTrack)track).bind( + new XMLBindTrack(trackBinder) + ); + } + + public static Attribution createAttribution() { + Attribution attribution = new XSPFAttribution(); + return attribution; + } + + public static Attribution createAttribution(String identifier, String location) { + Attribution attribution = new XSPFAttribution(); + attribution.add(identifier, location); + return attribution; + } + + public static Link createLink(String rel, String content) { + return new XSPFLink(rel, content); + } + + public static Meta createMeta(String rel, String content) { + return new XSPFMeta(rel, content); + } + + public static Extension createExtension(String application, List content) { + return new XSPFExtension(application, content); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Properties.java b/src/main/java/org/hedgecode/xml/xspf/Properties.java new file mode 100644 index 0000000..b8d0584 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Properties.java @@ -0,0 +1,63 @@ +/* + * 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.util.HashMap; +import java.util.Map; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public final class Properties { + + public static final String CHARSET = "xspf.charset"; + public static final String FORMATTED = "xspf.formatted"; + public static final String STANDALONE = "xspf.standalone"; + + private static final Map props = new HashMap() { + { + put(CHARSET, XSPFConstants.DEF_CHARSET); + put(FORMATTED, Boolean.TRUE); + put(STANDALONE, Boolean.FALSE); + } + }; + + public static void setProperty(String name, Object value) { + if (props.containsKey(name)) { + if (props.get(name).getClass().equals(value.getClass())) + props.put(name, value); + } + } + + public static Object getProperty(String name, Class clazz) { + if (clazz != null && props.containsKey(name)) { + Object property = props.get(name); + if (clazz.isAssignableFrom(property.getClass())) + return property; + } + return null; + } + + private Properties() { + throw new AssertionError( + "I am so paranoid!" + ); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/Track.java b/src/main/java/org/hedgecode/xml/xspf/Track.java new file mode 100644 index 0000000..a591a6c --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/Track.java @@ -0,0 +1,48 @@ +/* + * 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.util.List; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Track extends Element { + + List getLocations(); + + void addLocation(String location); + + List getIdentifiers(); + + void addIdentifier(String identifier); + + String getAlbum(); + + void setAlbum(String album); + + Integer getTrackNum(); + + void setTrackNum(Integer trackNum); + + Integer getDuration(); + + void setDuration(Integer duration); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XMLBindPlaylist.java b/src/main/java/org/hedgecode/xml/xspf/XMLBindPlaylist.java new file mode 100644 index 0000000..161e4f5 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XMLBindPlaylist.java @@ -0,0 +1,226 @@ +/* + * 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 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 { + + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XMLBindTrack.java b/src/main/java/org/hedgecode/xml/xspf/XMLBindTrack.java new file mode 100644 index 0000000..5ba70a5 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XMLBindTrack.java @@ -0,0 +1,102 @@ +/* + * 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.util.List; + +import org.hedgecode.xml.xspf.bind.Binder; +import org.hedgecode.xml.xspf.bind.BinderFactory; +import org.hedgecode.xml.xspf.bind.TrackBinder; + +import static org.hedgecode.xml.xspf.XSPFConstants.Format; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class XMLBindTrack extends AbstractXMLBindElement implements Track { + + private TrackBinder binder; + + protected XMLBindTrack(TrackBinder binder) { + if (binder == null) + this.binder = BinderFactory.createTrackBinder(); + else + this.binder = binder; + } + + protected XMLBindTrack(Format format) { + this.binder = BinderFactory.createTrackBinder(format); + } + + @Override + protected Binder getBinder() { + return binder; + } + + @Override + public List getLocations() { + return binder.getLocations(); + } + + @Override + public void addLocation(String location) { + binder.addLocation(location); + } + + @Override + public List getIdentifiers() { + return binder.getIdentifiers(); + } + + @Override + public void addIdentifier(String identifier) { + binder.addIdentifier(identifier); + } + + @Override + public String getAlbum() { + return binder.getAlbum(); + } + + @Override + public void setAlbum(String album) { + binder.setAlbum(album); + } + + @Override + public Integer getTrackNum() { + return binder.getTrackNum(); + } + + @Override + public void setTrackNum(Integer trackNum) { + binder.setTrackNum(trackNum); + } + + @Override + public Integer getDuration() { + return binder.getDuration(); + } + + @Override + public void setDuration(Integer duration) { + binder.setDuration(duration); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPF.java b/src/main/java/org/hedgecode/xml/xspf/XSPF.java new file mode 100644 index 0000000..845c57f --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPF.java @@ -0,0 +1,139 @@ +/* + * 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.UnsupportedEncodingException; + +import javax.xml.bind.JAXBException; + +import org.hedgecode.xml.xspf.validate.ValidateException; + +import static org.hedgecode.xml.xspf.XSPFConstants.Format; +import static org.hedgecode.xml.xspf.XSPFConstants.Version; + +/** + * XSPF API for external applications. + * + * @author Dmitry Samoshin aka gotty + */ +public final class XSPF { + + public static Playlist create() { + return create(Format.RELAX_NG); + } + + public static Playlist create(Format format) { + return new XSPFPlaylist(format); + } + + public static Playlist create(Version version) { + return new XSPFPlaylist(version); + } + + public static Playlist create(String key) { + Format format = Format.byName(key); + if (format != null) + return create(format); + + Version version = Version.byName(key); + if (version != null) + return create(version); + + return null; + } + + public static void generate(Playlist playlist, File outputFile) throws XSPFException { + if (playlist == null) + throw new XSPFException(XSPFConstants.Errors.NULL_PLAYLIST); + try { + playlist.write(outputFile); + } catch (JAXBException e) { + throw new XSPFException(XSPFConstants.Errors.BINDING_ERROR); + } + } + + public static String generate(Playlist playlist) throws XSPFException { + if (playlist == null) + throw new XSPFException(XSPFConstants.Errors.NULL_PLAYLIST); + String result; + try { + result = playlist.getAsString(); + } catch (JAXBException e) { + throw new XSPFException(XSPFConstants.Errors.BINDING_ERROR); + } catch (UnsupportedEncodingException e) { + throw new XSPFException(XSPFConstants.Errors.ENCODING_ERROR); + } + return result; + } + + public static Playlist create(File inputFile) throws JAXBException { + Playlist playlist = PlaylistFactory.createPlaylist(Format.XSD); + playlist.read(inputFile); + return playlist; + } + + public static Track createTrack(String location, String title) { + Track track = PlaylistFactory.createTrack(); + track.addLocation(location); + track.setTitle(title); + return track; + } + + public static Track addTrack(Playlist playlist, String location, String title) { + Track track = createTrack(location, title); + playlist.addTrack(track); + return track; + } + + public static void addTrack(Playlist playlist, Track track) { + playlist.addTrack(track); + } + + public static void addTracks( + Playlist playlist, Playlist tracksPlaylist) throws XSPFException + { + if (playlist == null) + throw new XSPFException(XSPFConstants.Errors.NULL_PLAYLIST); + if (tracksPlaylist != null) { + for (Track track : tracksPlaylist.getTracks()) { + playlist.addTrack(track); + } + } + } + + public static void setProperty(String name, Object value) { + Properties.setProperty(name, value); + } + + public static int validate(File inputFile) throws JAXBException { + int result = 0; + Playlist playlist = create(inputFile); + if (playlist != null) + try { + playlist.validate(); + } catch (ValidateException e) { + result = e.getCode(); + } + return result; + } + + public static String get(int code) { + return null; // todo + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFAttribution.java b/src/main/java/org/hedgecode/xml/xspf/XSPFAttribution.java new file mode 100644 index 0000000..fbf7302 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFAttribution.java @@ -0,0 +1,50 @@ +/* + * 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.util.HashMap; +import java.util.Map; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public final class XSPFAttribution implements Attribution { + + private Map idLocations; + + public XSPFAttribution() { + idLocations = new HashMap<>(); + } + + public XSPFAttribution(Map idLocations) { + this.idLocations = idLocations; + } + + @Override + public Map get() { + return idLocations; + } + + @Override + public void add(String identifier, String location) { + idLocations.put( + identifier, location + ); + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFConstants.java b/src/main/java/org/hedgecode/xml/xspf/XSPFConstants.java new file mode 100644 index 0000000..158281b --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFConstants.java @@ -0,0 +1,107 @@ +/* + * 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.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import javax.xml.namespace.QName; + +/** + * Store of library constants. + * + * @author Dmitry Samoshin aka gotty + */ +public final class XSPFConstants { + + public static final Charset DEF_CHARSET = StandardCharsets.UTF_8; + + public static final String XSD_FORMAT = "xsd"; + public static final String RNG_FORMAT = "rng"; + + public static enum Format { + + XSD ( XSD_FORMAT ), + RELAX_NG ( RNG_FORMAT ); + + private String formatName; + + Format(String name) { + this.formatName = name; + } + + public String getName() { + return formatName; + } + + public static Format byName(String formatName) { + for (Format format : Format.values()) { + if (format.getName().equals(formatName)) + return format; + } + return null; + } + } + + public static final String VER_1_0_2 = "1_0.2"; + public static final String VER_1_0_7 = "1_0.7"; + + public static enum Version { + + V1_2 ( VER_1_0_2 ), + V1_7 ( VER_1_0_7 ); + + private String versionName; + + Version(String name) { + this.versionName = name; + } + + public String getName() { + return versionName; + } + + public static Version byName(String versionName) { + for (Version version : Version.values()) { + if (version.getName().equals(versionName)) + return version; + } + return null; + } + } + + public static final String XSPF_VERSION = "1"; + + public static final QName PLAYLIST_QNAME = new QName("http://xspf.org/ns/0/", "playlist"); + + public static final String XML_HEADER_NAME = "com.sun.xml.internal.bind.xmlHeaders"; + public static final String XML_HEADER_VALUE = ""; + + + public static interface Errors { + public static final int NULL_PLAYLIST = 101; + public static final int VALIDATE_ERROR = 201; + public static final int BINDING_ERROR = 301; + public static final int ENCODING_ERROR = 401; + } + + private XSPFConstants() { + throw new AssertionError( + "No org.hedgecode.xml.xspf.XSPFConstants instances!" + ); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFException.java b/src/main/java/org/hedgecode/xml/xspf/XSPFException.java new file mode 100644 index 0000000..67cb36c --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFException.java @@ -0,0 +1,41 @@ +/* + * 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.util.HashMap; +import java.util.Map; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class XSPFException extends Exception { + + private static final Map errors = new HashMap() { + { + put(XSPFConstants.Errors.NULL_PLAYLIST, ""); + put(XSPFConstants.Errors.VALIDATE_ERROR, ""); + put(XSPFConstants.Errors.BINDING_ERROR, ""); + put(XSPFConstants.Errors.ENCODING_ERROR, ""); + } + }; + + public XSPFException(int errorCode) { + super(errors.get(errorCode)); + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFExtension.java b/src/main/java/org/hedgecode/xml/xspf/XSPFExtension.java new file mode 100644 index 0000000..81e378a --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFExtension.java @@ -0,0 +1,54 @@ +/* + * 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.util.List; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public final class XSPFExtension implements Extension { + + private String application; + private List content; + + public XSPFExtension() { + } + + public XSPFExtension(String application, List content) { + this.application = application; + this.content = content; + } + + @Override + public String getApplication() { + return application; + } + + @Override + public List getContent() { + return content; + } + + @Override + public void set(String application, List content) { + this.application = application; + this.content = content; + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFLink.java b/src/main/java/org/hedgecode/xml/xspf/XSPFLink.java new file mode 100644 index 0000000..8420461 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFLink.java @@ -0,0 +1,52 @@ +/* + * 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; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public final class XSPFLink implements Link { + + private String rel; + private String content; + + public XSPFLink() { + } + + public XSPFLink(String rel, String content) { + this.rel = rel; + this.content = content; + } + + @Override + public String getRel() { + return rel; + } + + @Override + public String getContent() { + return content; + } + + @Override + public void set(String rel, String content) { + this.rel = rel; + this.content = content; + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFMeta.java b/src/main/java/org/hedgecode/xml/xspf/XSPFMeta.java new file mode 100644 index 0000000..b756864 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFMeta.java @@ -0,0 +1,52 @@ +/* + * 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; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public final class XSPFMeta implements Meta { + + private String rel; + private String content; + + public XSPFMeta() { + } + + public XSPFMeta(String rel, String content) { + this.rel = rel; + this.content = content; + } + + @Override + public String getRel() { + return rel; + } + + @Override + public String getContent() { + return content; + } + + @Override + public void set(String rel, String content) { + this.rel = rel; + this.content = content; + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFPlaylist.java b/src/main/java/org/hedgecode/xml/xspf/XSPFPlaylist.java new file mode 100644 index 0000000..36736ba --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFPlaylist.java @@ -0,0 +1,376 @@ +/* + * 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()); + } + } + } + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/XSPFTrack.java b/src/main/java/org/hedgecode/xml/xspf/XSPFTrack.java new file mode 100644 index 0000000..d844507 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/XSPFTrack.java @@ -0,0 +1,264 @@ +/* + * 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.util.ArrayList; +import java.util.List; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public final class XSPFTrack implements Track { + + protected XSPFTrack() { + } + + /** + * + */ + private List locations = new ArrayList<>(); + + /** + * + */ + private List identifiers = new ArrayList<>(); + + /** + * + */ + private String title; + + /** + * + */ + private String creator; + + /** + * + */ + private String annotation; + + /** + * + */ + private String info; + + /** + * + */ + private String image; + + /** + * + */ + private String album; + + /** + * + */ + private Integer trackNum; + + /** + * + */ + private Integer duration; + + /** + * + */ + private List links = new ArrayList<>(); + + /** + * + */ + private List metas = new ArrayList<>(); + + /** + * + */ + private List extensions = new ArrayList<>(); + + @Override + public List getLocations() { + return locations; + } + + @Override + public void addLocation(String location) { + locations.add(location); + } + + @Override + public List getIdentifiers() { + return identifiers; + } + + @Override + public void addIdentifier(String identifier) { + identifiers.add(identifier); + } + + @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 getImage() { + return image; + } + + @Override + public void setImage(String image) { + this.image = image; + } + + @Override + public String getAlbum() { + return album; + } + + @Override + public void setAlbum(String album) { + this.album = album; + } + + @Override + public Integer getTrackNum() { + return trackNum; + } + + @Override + public void setTrackNum(Integer trackNum) { + this.trackNum = trackNum; + } + + @Override + public Integer getDuration() { + return duration; + } + + @Override + public void setDuration(Integer duration) { + this.duration = duration; + } + + @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); + } + + protected void bind(XMLBindTrack bindTrack) { + for (String location : locations) + bindTrack.addLocation(location); + for (String identifier : identifiers) + bindTrack.addIdentifier(identifier); + bindTrack.setTitle(title); + bindTrack.setCreator(creator); + bindTrack.setAnnotation(annotation); + bindTrack.setInfo(info); + bindTrack.setImage(image); + bindTrack.setAlbum(album); + bindTrack.setTrackNum(trackNum); + bindTrack.setDuration(duration); + for (Link link : links) + bindTrack.addLink(link); + for (Meta meta :metas) + bindTrack.addMeta(meta); + for (Extension extension : extensions) + bindTrack.addExtension(extension); + } + + protected void unbind(XMLBindTrack bindTrack) { + locations = bindTrack.getLocations(); + identifiers = bindTrack.getIdentifiers(); + title = bindTrack.getTitle(); + creator = bindTrack.getCreator(); + annotation = bindTrack.getAnnotation(); + info = bindTrack.getInfo(); + image = bindTrack.getImage(); + album = bindTrack.getAlbum(); + trackNum = bindTrack.getTrackNum(); + duration = bindTrack.getDuration(); + links = bindTrack.getLinks(); + metas = bindTrack.getMetas(); + extensions = bindTrack.getExtensions(); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/AbstractRNGBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/AbstractRNGBinder.java new file mode 100644 index 0000000..3ffa956 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/AbstractRNGBinder.java @@ -0,0 +1,210 @@ +/* + * 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.bind; + +import java.util.ArrayList; +import java.util.List; + +import org.hedgecode.xml.xspf.PlaylistFactory; +import org.hedgecode.xml.xspf.rng.Annotation; +import org.hedgecode.xml.xspf.rng.Creator; +import org.hedgecode.xml.xspf.rng.Extension; +import org.hedgecode.xml.xspf.rng.Image; +import org.hedgecode.xml.xspf.rng.Info; +import org.hedgecode.xml.xspf.rng.Link; +import org.hedgecode.xml.xspf.rng.Meta; +import org.hedgecode.xml.xspf.rng.ObjectFactory; +import org.hedgecode.xml.xspf.rng.Title; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public abstract class AbstractRNGBinder implements Binder { + + protected static final ObjectFactory RNG_FACTORY = new ObjectFactory(); + + protected abstract Object getElement(Class elementClass); + + protected abstract List getElements(Class elementClass); + + protected abstract List getAllElements(); + + @Override + public String getTitle() { + Title titleElement = (Title) getElement(Title.class); + return titleElement != null ? titleElement.getContent() : null; + } + + @Override + public void setTitle(String title) { + Title titleElement = (Title) getElement(Title.class); + if (titleElement != null) + getAllElements().remove(titleElement); + if (title != null) { + titleElement = RNG_FACTORY.createTitle(); + titleElement.setContent(title); + getAllElements().add(titleElement); + } + } + + @Override + public String getCreator() { + Creator creatorElement = (Creator) getElement(Creator.class); + return creatorElement != null ? creatorElement.getContent() : null; + } + + @Override + public void setCreator(String creator) { + Creator creatorElement = (Creator) getElement(Creator.class); + if (creatorElement != null) + getAllElements().remove(creatorElement); + if (creator != null) { + creatorElement = RNG_FACTORY.createCreator(); + creatorElement.setContent(creator); + getAllElements().add(creatorElement); + } + } + + @Override + public String getAnnotation() { + Annotation annotationElement = (Annotation) getElement(Annotation.class); + return annotationElement != null ? annotationElement.getContent() : null; + } + + @Override + public void setAnnotation(String annotation) { + Annotation annotationElement = (Annotation) getElement(Annotation.class); + if (annotationElement != null) + getAllElements().remove(annotationElement); + if (annotation != null) { + annotationElement = RNG_FACTORY.createAnnotation(); + annotationElement.setContent(annotation); + getAllElements().add(annotationElement); + } + } + + @Override + public String getInfo() { + Info infoElement = (Info) getElement(Info.class); + return infoElement != null ? infoElement.getValue() : null; + } + + @Override + public void setInfo(String info) { + Info infoElement = (Info) getElement(Info.class); + if (infoElement != null) + getAllElements().remove(infoElement); + if (info != null) { + infoElement = RNG_FACTORY.createInfo(); + infoElement.setValue(info); + getAllElements().add(infoElement); + } + } + + @Override + public String getImage() { + Image imageElement = (Image) getElement(Image.class); + return imageElement != null ? imageElement.getValue() : null; + } + + @Override + public void setImage(String image) { + Image imageElement = (Image) getElement(Image.class); + if (imageElement != null) + getAllElements().remove(imageElement); + if (image != null) { + imageElement = RNG_FACTORY.createImage(); + imageElement.setValue(image); + getAllElements().add(imageElement); + } + } + + @Override + public List getLinks() { + List links = new ArrayList<>(); + for (Object element : getElements(Link.class)) { + Link linkElement = (Link) element; + links.add( + PlaylistFactory.createLink( + linkElement.getRel(), linkElement.getValue() + ) + ); + } + return links; + } + + @Override + public void addLink(org.hedgecode.xml.xspf.Link link) { + if (link != null) { + Link linkElement = RNG_FACTORY.createLink(); + linkElement.setRel(link.getRel()); + linkElement.setValue(link.getContent()); + getAllElements().add(linkElement); + } + } + + @Override + public List getMetas() { + List metas = new ArrayList<>(); + for (Object element : getElements(Meta.class)) { + Meta metaElement = (Meta) element; + metas.add( + PlaylistFactory.createMeta( + metaElement.getRel(), metaElement.getContent() + ) + ); + } + return metas; + } + + @Override + public void addMeta(org.hedgecode.xml.xspf.Meta meta) { + if (meta != null) { + Meta metaElement = RNG_FACTORY.createMeta(); + metaElement.setRel(meta.getRel()); + metaElement.setContent(meta.getContent()); + getAllElements().add(metaElement); + } + } + + @Override + public List getExtensions() { + List extensions = new ArrayList<>(); + for (Object element : getElements(Extension.class)) { + Extension extensionElement = (Extension) element; + extensions.add( + PlaylistFactory.createExtension( + extensionElement.getApplication(), extensionElement.getContent() + ) + ); + } + return extensions; + } + + @Override + public void addExtension(org.hedgecode.xml.xspf.Extension extension) { + if (extension != null) { + Extension extensionElement = RNG_FACTORY.createExtension(); + extensionElement.setApplication(extension.getApplication()); + extensionElement.getContent().addAll(extension.getContent()); + getAllElements().add(extensionElement); + } + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/AbstractXSDBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/AbstractXSDBinder.java new file mode 100644 index 0000000..1e5fef8 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/AbstractXSDBinder.java @@ -0,0 +1,30 @@ +/* + * 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.bind; + +import org.hedgecode.xml.xspf.xsd.ObjectFactory; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public abstract class AbstractXSDBinder implements Binder { + + protected static final ObjectFactory XSD_FACTORY = new ObjectFactory(); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/Binder.java b/src/main/java/org/hedgecode/xml/xspf/bind/Binder.java new file mode 100644 index 0000000..c60c6fc --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/Binder.java @@ -0,0 +1,64 @@ +/* + * 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.bind; + +import java.util.List; + +import org.hedgecode.xml.xspf.Extension; +import org.hedgecode.xml.xspf.Link; +import org.hedgecode.xml.xspf.Meta; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Binder { + + String getTitle(); + + void setTitle(String title); + + String getCreator(); + + void setCreator(String creator); + + String getAnnotation(); + + void setAnnotation(String annotation); + + String getInfo(); + + void setInfo(String info); + + String getImage(); + + void setImage(String image); + + List getLinks(); + + void addLink(Link link); + + List getMetas(); + + void addMeta(Meta meta); + + List getExtensions(); + + void addExtension(Extension extension); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/BinderFactory.java b/src/main/java/org/hedgecode/xml/xspf/bind/BinderFactory.java new file mode 100644 index 0000000..a4cbe36 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/BinderFactory.java @@ -0,0 +1,77 @@ +/* + * 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.bind; + +import org.hedgecode.xml.xspf.rng.Track; +import org.hedgecode.xml.xspf.xsd.TrackType; + +import static org.hedgecode.xml.xspf.XSPFConstants.Format; + +/** + * Playlist/Track Binder Factory. + * + * @author Dmitry Samoshin aka gotty + */ +public final class BinderFactory { + + public static PlaylistBinder createPlaylistBinder() { + return getDefaultPlaylistBinder(); + } + + public static PlaylistBinder createPlaylistBinder(Format format) { + switch(format) { + case RELAX_NG: + return new RNGPlaylistBinder(); + case XSD: + return new XSDPlaylistBinder(); + default: + return getDefaultPlaylistBinder(); + } + } + + public static TrackBinder createTrackBinder() { + return getDefaultTrackBinder(); + } + + public static TrackBinder createTrackBinder(Format format) { + switch(format) { + case RELAX_NG: + return new RNGTrackBinder(); + case XSD: + return new XSDTrackBinder(); + default: + return getDefaultTrackBinder(); + } + } + + public static TrackBinder createTrackBinder(Track track) { + return new RNGTrackBinder(track); + } + + public static TrackBinder createTrackBinder(TrackType trackType) { + return new XSDTrackBinder(trackType); + } + + private static PlaylistBinder getDefaultPlaylistBinder() { + return new RNGPlaylistBinder(); + } + + private static TrackBinder getDefaultTrackBinder() { + return new RNGTrackBinder(); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/PlaylistBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/PlaylistBinder.java new file mode 100644 index 0000000..ec270c5 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/PlaylistBinder.java @@ -0,0 +1,75 @@ +/* + * 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.bind; + +import java.util.Date; +import java.util.List; + +import javax.xml.bind.JAXBElement; + +import org.hedgecode.xml.xspf.Attribution; +import org.hedgecode.xml.xspf.Extension; +import org.hedgecode.xml.xspf.Link; +import org.hedgecode.xml.xspf.Meta; +import org.hedgecode.xml.xspf.Track; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface PlaylistBinder extends Binder { + + String getPackageName(); + + Class getPlaylistClass(); + + Object getPlaylist(); + + void setPlaylist(Object playlist); + + public JAXBElement wrapPlaylist(); + + String getLocation(); + + void setLocation(String location); + + String getIdentifier(); + + void setIdentifier(String identifier); + + Date getDate(); + + void setDate(Date date); + + String getLicense(); + + void setLicense(String license); + + Attribution getAttribution(); + + void setAttribution(Attribution attribution); + + List getTracks(); + + void addTrack(Track track); + + String getVersion(); + + void setVersion(String version); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/RNGPlaylistBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/RNGPlaylistBinder.java new file mode 100644 index 0000000..338d0eb --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/RNGPlaylistBinder.java @@ -0,0 +1,282 @@ +/* + * 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.bind; + +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Map; + +import javax.xml.bind.JAXBElement; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; + +import org.hedgecode.xml.xspf.PlaylistFactory; +import org.hedgecode.xml.xspf.XSPFConstants; +import org.hedgecode.xml.xspf.rng.Attribution; +import org.hedgecode.xml.xspf.rng.Date; +import org.hedgecode.xml.xspf.rng.Identifier; +import org.hedgecode.xml.xspf.rng.License; +import org.hedgecode.xml.xspf.rng.Location; +import org.hedgecode.xml.xspf.rng.Playlist; +import org.hedgecode.xml.xspf.rng.Track; +import org.hedgecode.xml.xspf.rng.TrackList; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class RNGPlaylistBinder extends AbstractRNGBinder implements PlaylistBinder { + + private Playlist rngPlaylist; + + public RNGPlaylistBinder() { + this.rngPlaylist = RNG_FACTORY.createPlaylist(); + } + + public RNGPlaylistBinder(Playlist rngPlaylist) { + this.rngPlaylist = rngPlaylist; + } + + @Override + protected Object getElement(Class elementClass) { + for (Object element : rngPlaylist.getTitleOrCreatorOrAnnotation()) { + if (element.getClass().equals(elementClass)) + return element; + } + return null; + } + + @Override + protected List getElements(Class elementClass) { + List elements = new ArrayList<>(); + for (Object element : rngPlaylist.getTitleOrCreatorOrAnnotation()) { + if (element.getClass().equals(elementClass)) + elements.add(element); + } + return elements; + } + + @Override + protected List getAllElements() { + return rngPlaylist.getTitleOrCreatorOrAnnotation(); + } + + @Override + public String getPackageName() { + return rngPlaylist.getClass().getPackage().getName(); + } + + @Override + public Class getPlaylistClass() { + return rngPlaylist.getClass(); + } + + @Override + public Object getPlaylist() { + return rngPlaylist; + } + + @Override + public void setPlaylist(Object playlist) { + if (playlist instanceof Playlist) + this.rngPlaylist = (Playlist) playlist; + } + + @Override + public JAXBElement wrapPlaylist() { + return new JAXBElement<>( + XSPFConstants.PLAYLIST_QNAME, + Playlist.class, + rngPlaylist + ); + } + + @Override + public String getLocation() { + Location locationElement = (Location) getElement(Location.class); + return locationElement != null ? locationElement.getValue() : null; + } + + @Override + public void setLocation(String location) { + Location locationElement = (Location) getElement(Location.class); + if (locationElement != null) + getAllElements().remove(locationElement); + if (location != null) { + locationElement = RNG_FACTORY.createLocation(); + locationElement.setValue(location); + getAllElements().add(locationElement); + } + } + + @Override + public String getIdentifier() { + Identifier identifierElement = (Identifier) getElement(Identifier.class); + return identifierElement != null ? identifierElement.getValue() : null; + } + + @Override + public void setIdentifier(String identifier) { + Identifier identifierElement = (Identifier) getElement(Identifier.class); + if (identifierElement != null) + getAllElements().remove(identifierElement); + if (identifier != null) { + identifierElement = RNG_FACTORY.createIdentifier(); + identifierElement.setValue(identifier); + getAllElements().add(identifierElement); + } + } + + @Override + public java.util.Date getDate() { + Date dateElement = (Date) getElement(Date.class); + return dateElement != null && dateElement.getValue() != null + ? dateElement.getValue().toGregorianCalendar().getTime() + : null; + } + + @Override + public void setDate(java.util.Date date) { + Date dateElement = (Date) getElement(Date.class); + if (dateElement != null) + getAllElements().remove(dateElement); + if (date != null) { + dateElement = RNG_FACTORY.createDate(); + GregorianCalendar gCalendar = new GregorianCalendar(); + gCalendar.setTime(date); + XMLGregorianCalendar xmlCalendar = null; + try { + xmlCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gCalendar); + } catch (DatatypeConfigurationException ignored) {} + dateElement.setValue(xmlCalendar); + getAllElements().add(dateElement); + } + } + + @Override + public String getLicense() { + License licenseElement = (License) getElement(License.class); + return licenseElement != null ? licenseElement.getValue() : null; + } + + @Override + public void setLicense(String license) { + License licenseElement = (License) getElement(License.class); + if (licenseElement != null) + getAllElements().remove(licenseElement); + if (license != null) { + licenseElement = RNG_FACTORY.createLicense(); + licenseElement.setValue(license); + getAllElements().add(licenseElement); + } + } + + @Override + public org.hedgecode.xml.xspf.Attribution getAttribution() { + Attribution attributionElement = (Attribution) getElement(Attribution.class); + if (attributionElement != null) { + org.hedgecode.xml.xspf.Attribution attribution = PlaylistFactory.createAttribution(); + String identifier = null, location = null; + for (Object element : attributionElement.getIdentifierOrLocation()) { + + if (element.getClass().equals(Identifier.class)) + identifier = ((Identifier) element).getValue(); + else if (element.getClass().equals(Location.class)) + location = ((Location) element).getValue(); + + if (identifier != null && location != null) { + attribution.add(identifier, location); + identifier = null; + location = null; + } + } + return attribution; + } + return null; + } + + @Override + public void setAttribution(org.hedgecode.xml.xspf.Attribution attribution) { + Attribution attributionElement = (Attribution) getElement(Attribution.class); + if (attributionElement != null) + getAllElements().remove(attributionElement); + if (attribution != null) { + attributionElement = RNG_FACTORY.createAttribution(); + for (Map.Entry element : attribution.get().entrySet()) { + Location location = RNG_FACTORY.createLocation(); + location.setValue(element.getKey()); + Identifier identifier = RNG_FACTORY.createIdentifier(); + identifier.setValue(element.getValue()); + attributionElement.getIdentifierOrLocation().add(location); + attributionElement.getIdentifierOrLocation().add(identifier); + } + getAllElements().add(attributionElement); + } + } + + @Override + public List getTracks() { + List tracks = new ArrayList<>(); + TrackList traclListElement = (TrackList) getElement(TrackList.class); + if (traclListElement != null) { + for (Track track : traclListElement.getTrack()) { + tracks.add( + PlaylistFactory.createTrack( + BinderFactory.createTrackBinder(track) + ) + ); + } + } + return tracks; + } + + @Override + public void addTrack(org.hedgecode.xml.xspf.Track track) { + if (track != null) { + TrackList trackListElement = (TrackList) getElement(TrackList.class); + if (trackListElement == null) { + trackListElement = RNG_FACTORY.createTrackList(); + getAllElements().add(trackListElement); + } + + Track trackElement = RNG_FACTORY.createTrack(); + PlaylistFactory.bindTrack( + track, + BinderFactory.createTrackBinder(trackElement) + ); + + trackListElement.getTrack().add( + trackElement + ); + } + } + + @Override + public String getVersion() { + return rngPlaylist.getVersion(); + } + + @Override + public void setVersion(String version) { + rngPlaylist.setVersion(version); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/RNGTrackBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/RNGTrackBinder.java new file mode 100644 index 0000000..d2dc95a --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/RNGTrackBinder.java @@ -0,0 +1,175 @@ +/* + * 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.bind; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.hedgecode.xml.xspf.rng.Album; +import org.hedgecode.xml.xspf.rng.Duration; +import org.hedgecode.xml.xspf.rng.Identifier; +import org.hedgecode.xml.xspf.rng.Location; +import org.hedgecode.xml.xspf.rng.Track; +import org.hedgecode.xml.xspf.rng.TrackNum; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class RNGTrackBinder extends AbstractRNGBinder implements TrackBinder { + + private Track rngTrack; + + public RNGTrackBinder() { + this.rngTrack = RNG_FACTORY.createTrack(); + } + + public RNGTrackBinder(Track rngTrack) { + this.rngTrack = rngTrack; + } + + @Override + protected Object getElement(Class elementClass) { + for (Object element : rngTrack.getLocationOrIdentifierOrTitle()) { + if (element.getClass().equals(elementClass)) + return element; + } + return null; + } + + @Override + protected List getElements(Class elementClass) { + List elements = new ArrayList<>(); + for (Object element : rngTrack.getLocationOrIdentifierOrTitle()) { + if (element.getClass().equals(elementClass)) + elements.add(element); + } + return elements; + } + + @Override + protected List getAllElements() { + return rngTrack.getLocationOrIdentifierOrTitle(); + } + + @Override + public List getLocations() { + List locations = new ArrayList<>(); + for (Object element : getElements(Location.class)) { + Location locationElement = (Location) element; + locations.add( + locationElement.getValue() + ); + } + return locations; + } + + @Override + public void addLocation(String location) { + if (location != null) { + Location locationElement = RNG_FACTORY.createLocation(); + locationElement.setValue(location); + getAllElements().add(locationElement); + } + } + + @Override + public List getIdentifiers() { + List identifiers = new ArrayList<>(); + for (Object element : getElements(Identifier.class)) { + Identifier identifierElement = (Identifier) element; + identifiers.add( + identifierElement.getValue() + ); + } + return identifiers; + } + + @Override + public void addIdentifier(String identifier) { + if (identifier != null) { + Identifier identifierElement = RNG_FACTORY.createIdentifier(); + identifierElement.setValue(identifier); + getAllElements().add(identifierElement); + } + } + + @Override + public String getAlbum() { + Album albumElement = (Album) getElement(Album.class); + return albumElement != null ? albumElement.getContent() : null; + } + + @Override + public void setAlbum(String album) { + Album albumElement = (Album) getElement(Album.class); + if (albumElement != null) + getAllElements().remove(albumElement); + if (album != null) { + albumElement = RNG_FACTORY.createAlbum(); + albumElement.setContent(album); + getAllElements().add(albumElement); + } + } + + @Override + public Integer getTrackNum() { + TrackNum trackNumElement = (TrackNum) getElement(TrackNum.class); + return trackNumElement != null && trackNumElement.getValue() != null + ? trackNumElement.getValue().intValue() + : null; + } + + @Override + public void setTrackNum(Integer trackNum) { + TrackNum trackNumElement = (TrackNum) getElement(TrackNum.class); + if (trackNumElement != null) + getAllElements().remove(trackNumElement); + if (trackNum != null) { + trackNumElement = RNG_FACTORY.createTrackNum(); + trackNumElement.setValue( + BigInteger.valueOf(trackNum) + ); + getAllElements().add(trackNumElement); + } + } + + @Override + public Integer getDuration() { + Duration durationElement = (Duration) getElement(Duration.class); + return durationElement != null && durationElement.getValue() != null + ? durationElement.getValue().intValue() + : null; + } + + @Override + public void setDuration(Integer duration) { + Duration durationElement = (Duration) getElement(Duration.class); + if (durationElement != null) + getAllElements().remove(durationElement); + if (duration != null) { + durationElement = RNG_FACTORY.createDuration(); + durationElement.setValue( + BigInteger.valueOf(duration) + ); + getAllElements().add(durationElement); + } + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/TrackBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/TrackBinder.java new file mode 100644 index 0000000..55505c0 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/TrackBinder.java @@ -0,0 +1,48 @@ +/* + * 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.bind; + +import java.util.List; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface TrackBinder extends Binder { + + List getLocations(); + + void addLocation(String location); + + List getIdentifiers(); + + void addIdentifier(String identifier); + + String getAlbum(); + + void setAlbum(String album); + + Integer getTrackNum(); + + void setTrackNum(Integer trackNum); + + Integer getDuration(); + + void setDuration(Integer duration); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/XSDPlaylistBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/XSDPlaylistBinder.java new file mode 100644 index 0000000..0a7a346 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/XSDPlaylistBinder.java @@ -0,0 +1,350 @@ +/* + * 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.bind; + +import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Map; + +import javax.xml.bind.JAXBElement; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; + +import org.hedgecode.xml.xspf.Attribution; +import org.hedgecode.xml.xspf.Extension; +import org.hedgecode.xml.xspf.Link; +import org.hedgecode.xml.xspf.Meta; +import org.hedgecode.xml.xspf.PlaylistFactory; +import org.hedgecode.xml.xspf.Track; +import org.hedgecode.xml.xspf.xsd.ExtensionType; +import org.hedgecode.xml.xspf.xsd.LinkType; +import org.hedgecode.xml.xspf.xsd.MetaType; +import org.hedgecode.xml.xspf.xsd.PlaylistType; +import org.hedgecode.xml.xspf.xsd.TrackType; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class XSDPlaylistBinder extends AbstractXSDBinder implements PlaylistBinder { + + private static final String REF_LOCATION_NAME = "location"; + private static final String REF_IDENTIFIER_NAME = "identifier"; + + private PlaylistType xsdPlaylist; + + public XSDPlaylistBinder() { + this.xsdPlaylist = XSD_FACTORY.createPlaylistType(); + } + + public XSDPlaylistBinder(PlaylistType xsdPlaylist) { + this.xsdPlaylist = xsdPlaylist; + } + + @Override + public String getPackageName() { + return xsdPlaylist.getClass().getPackage().getName(); + } + + @Override + public Class getPlaylistClass() { + return xsdPlaylist.getClass(); + } + + @Override + public Object getPlaylist() { + return xsdPlaylist; + } + + @Override + public void setPlaylist(Object playlist) { + if (playlist instanceof PlaylistType) + this.xsdPlaylist = (PlaylistType) playlist; + } + + @Override + public JAXBElement wrapPlaylist() { + return XSD_FACTORY.createPlaylist(xsdPlaylist); + } + + @Override + public String getTitle() { + return xsdPlaylist.getTitle(); + } + + @Override + public void setTitle(String title) { + xsdPlaylist.setTitle(title); + } + + @Override + public String getCreator() { + return xsdPlaylist.getCreator(); + } + + @Override + public void setCreator(String creator) { + xsdPlaylist.setCreator(creator); + } + + @Override + public String getAnnotation() { + return xsdPlaylist.getAnnotation(); + } + + @Override + public void setAnnotation(String annotation) { + xsdPlaylist.setAnnotation(annotation); + } + + @Override + public String getInfo() { + return xsdPlaylist.getInfo(); + } + + @Override + public void setInfo(String info) { + xsdPlaylist.setInfo(info); + } + + @Override + public String getLocation() { + return xsdPlaylist.getLocation(); + } + + @Override + public void setLocation(String location) { + xsdPlaylist.setLocation(location); + } + + @Override + public String getIdentifier() { + return xsdPlaylist.getIdentifier(); + } + + @Override + public void setIdentifier(String identifier) { + xsdPlaylist.setIdentifier(identifier); + } + + @Override + public String getImage() { + return xsdPlaylist.getImage(); + } + + @Override + public void setImage(String image) { + xsdPlaylist.setImage(image); + } + + @Override + public Date getDate() { + XMLGregorianCalendar calendar = xsdPlaylist.getDate(); + if (calendar != null) + return calendar.toGregorianCalendar().getTime(); + return null; + } + + @Override + public void setDate(Date date) { + XMLGregorianCalendar xmlCalendar = null; + if (date != null) { + GregorianCalendar gCalendar = new GregorianCalendar(); + gCalendar.setTime(date); + try { + xmlCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gCalendar); + } catch (DatatypeConfigurationException ignored) {} + } + xsdPlaylist.setDate(xmlCalendar); + } + + @Override + public String getLicense() { + return xsdPlaylist.getLicense(); + } + + @Override + public void setLicense(String license) { + xsdPlaylist.setLicense(license); + } + + @Override + public Attribution getAttribution() { + if (xsdPlaylist.getAttribution() != null) { + List> elements = xsdPlaylist.getAttribution().getIdentifierOrLocation(); + Attribution attribution = PlaylistFactory.createAttribution(); + String identifier = null, location = null; + for (JAXBElement element : elements) { + + if (REF_IDENTIFIER_NAME.equals(element.getName().getLocalPart())) + identifier = element.getValue(); + else if (REF_LOCATION_NAME.equals(element.getName().getLocalPart())) + location = element.getValue(); + + if (identifier != null && location != null) { + attribution.add(identifier, location); + identifier = null; + location = null; + } + } + return attribution; + } + return null; + } + + @Override + public void setAttribution(Attribution attribution) { + if (attribution != null) { + if (xsdPlaylist.getAttribution() == null) { + xsdPlaylist.setAttribution( + XSD_FACTORY.createAttributionType() + ); + } + for (Map.Entry element : attribution.get().entrySet()) { + xsdPlaylist.getAttribution().getIdentifierOrLocation().add( + XSD_FACTORY.createAttributionTypeIdentifier(element.getKey()) + ); + xsdPlaylist.getAttribution().getIdentifierOrLocation().add( + XSD_FACTORY.createAttributionTypeLocation(element.getValue()) + ); + } + } + } + + @Override + public List getLinks() { + List links = new ArrayList<>(); + for (LinkType link : xsdPlaylist.getLink()) { + links.add( + PlaylistFactory.createLink(link.getRel(), link.getValue()) + ); + } + return links; + } + + @Override + public void addLink(Link link) { + if (link != null) { + LinkType linkType = XSD_FACTORY.createLinkType(); + linkType.setRel(link.getRel()); + linkType.setValue(link.getContent()); + xsdPlaylist.getLink().add( + linkType + ); + } + } + + @Override + public List getMetas() { + List metas = new ArrayList<>(); + for (MetaType meta : xsdPlaylist.getMeta()) { + metas.add( + PlaylistFactory.createMeta(meta.getRel(), meta.getValue()) + ); + } + return metas; + } + + @Override + public void addMeta(Meta meta) { + if (meta != null) { + MetaType metaType = XSD_FACTORY.createMetaType(); + metaType.setRel(meta.getRel()); + metaType.setValue(meta.getContent()); + xsdPlaylist.getMeta().add( + metaType + ); + } + } + + @Override + public List getExtensions() { + List extensions = new ArrayList<>(); + for (ExtensionType extension : xsdPlaylist.getExtension()) { + extensions.add( + PlaylistFactory.createExtension( + extension.getApplication(), extension.getContent() + ) + ); + } + return extensions; + } + + @Override + public void addExtension(Extension extension) { + if (extension != null) { + ExtensionType extensionType = XSD_FACTORY.createExtensionType(); + extensionType.setApplication(extension.getApplication()); + extensionType.getContent().addAll(extension.getContent()); + xsdPlaylist.getExtension().add( + extensionType + ); + } + } + + @Override + public List getTracks() { + List tracks = new ArrayList<>(); + if (xsdPlaylist.getTrackList() != null) { + for (TrackType track : xsdPlaylist.getTrackList().getTrack()) { + tracks.add( + PlaylistFactory.createTrack( + BinderFactory.createTrackBinder(track) + ) + ); + } + } + return tracks; + } + + @Override + public void addTrack(Track track) { + if (track != null) { + if (xsdPlaylist.getTrackList() == null) { + xsdPlaylist.setTrackList( + XSD_FACTORY.createTrackListType() + ); + } + TrackType trackType = XSD_FACTORY.createTrackType(); + + PlaylistFactory.bindTrack( + track, + BinderFactory.createTrackBinder(trackType) + ); + + xsdPlaylist.getTrackList().getTrack().add( + trackType + ); + } + } + + @Override + public String getVersion() { + return xsdPlaylist.getVersion(); + } + + @Override + public void setVersion(String version) { + xsdPlaylist.setVersion(version); + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/bind/XSDTrackBinder.java b/src/main/java/org/hedgecode/xml/xspf/bind/XSDTrackBinder.java new file mode 100644 index 0000000..d32008c --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/bind/XSDTrackBinder.java @@ -0,0 +1,243 @@ +/* + * 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.bind; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.hedgecode.xml.xspf.Extension; +import org.hedgecode.xml.xspf.Link; +import org.hedgecode.xml.xspf.Meta; +import org.hedgecode.xml.xspf.PlaylistFactory; +import org.hedgecode.xml.xspf.xsd.ExtensionType; +import org.hedgecode.xml.xspf.xsd.LinkType; +import org.hedgecode.xml.xspf.xsd.MetaType; +import org.hedgecode.xml.xspf.xsd.TrackType; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class XSDTrackBinder extends AbstractXSDBinder implements TrackBinder { + + private TrackType xsdTrack; + + public XSDTrackBinder() { + this.xsdTrack = XSD_FACTORY.createTrackType(); + } + + public XSDTrackBinder(TrackType xsdTrack) { + this.xsdTrack = xsdTrack; + } + + public Object getTrack() { + return xsdTrack; + } + + public void setTrack(Object track) { + if (track != null && track instanceof TrackType) + this.xsdTrack = (TrackType) track; + } + + @Override + public List getLocations() { + return xsdTrack.getLocation(); + } + + @Override + public void addLocation(String location) { + if (location != null) { + xsdTrack.getLocation().add( + location + ); + } + } + + @Override + public List getIdentifiers() { + return xsdTrack.getIdentifier(); + } + + @Override + public void addIdentifier(String identifier) { + if (identifier != null) { + xsdTrack.getIdentifier().add( + identifier + ); + } + } + + @Override + public String getTitle() { + return xsdTrack.getTitle(); + } + + @Override + public void setTitle(String title) { + xsdTrack.setTitle(title); + } + + @Override + public String getCreator() { + return xsdTrack.getCreator(); + } + + @Override + public void setCreator(String creator) { + xsdTrack.setCreator(creator); + } + + @Override + public String getAnnotation() { + return xsdTrack.getAnnotation(); + } + + @Override + public void setAnnotation(String annotation) { + xsdTrack.setAnnotation(annotation); + } + + @Override + public String getInfo() { + return xsdTrack.getInfo(); + } + + @Override + public void setInfo(String info) { + xsdTrack.setInfo(info); + } + + @Override + public String getImage() { + return xsdTrack.getImage(); + } + + @Override + public void setImage(String image) { + xsdTrack.setImage(image); + } + + @Override + public String getAlbum() { + return xsdTrack.getAlbum(); + } + + @Override + public void setAlbum(String album) { + xsdTrack.setAlbum(album); + } + + @Override + public Integer getTrackNum() { + BigInteger trackNum = xsdTrack.getTrackNum(); + return trackNum != null ? trackNum.intValue() : null; + } + + @Override + public void setTrackNum(Integer trackNum) { + xsdTrack.setTrackNum( + trackNum != null ? BigInteger.valueOf(trackNum) : null + ); + } + + @Override + public Integer getDuration() { + BigInteger duration = xsdTrack.getDuration(); + return duration != null ? duration.intValue() : null; + } + + @Override + public void setDuration(Integer duration) { + xsdTrack.setDuration( + duration != null ? BigInteger.valueOf(duration) : null + ); + } + + @Override + public List getLinks() { + List links = new ArrayList<>(); + for (LinkType link : xsdTrack.getLink()) { + links.add( + PlaylistFactory.createLink(link.getRel(), link.getValue()) + ); + } + return links; + } + + @Override + public void addLink(Link link) { + if (link != null) { + LinkType linkType = XSD_FACTORY.createLinkType(); + linkType.setRel(link.getRel()); + linkType.setValue(link.getContent()); + xsdTrack.getLink().add( + linkType + ); + } + } + + @Override + public List getMetas() { + List metas = new ArrayList<>(); + for (MetaType meta : xsdTrack.getMeta()) { + metas.add( + PlaylistFactory.createMeta(meta.getRel(), meta.getValue()) + ); + } + return metas; + } + + @Override + public void addMeta(Meta meta) { + if (meta != null) { + MetaType metaType = XSD_FACTORY.createMetaType(); + metaType.setRel(meta.getRel()); + metaType.setValue(meta.getContent()); + xsdTrack.getMeta().add( + metaType + ); + } + } + + @Override + public List getExtensions() { + List extensions = new ArrayList<>(); + for (ExtensionType extension : xsdTrack.getExtension()) { + extensions.add( + PlaylistFactory.createExtension( + extension.getApplication(), extension.getContent() + ) + ); + } + return extensions; + } + + @Override + public void addExtension(Extension extension) { + if (extension != null) { + ExtensionType extensionType = XSD_FACTORY.createExtensionType(); + extensionType.setApplication(extension.getApplication()); + extensionType.getContent().addAll(extension.getContent()); + xsdTrack.getExtension().add( + extensionType + ); + } + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/validate/EmptyValidator.java b/src/main/java/org/hedgecode/xml/xspf/validate/EmptyValidator.java new file mode 100644 index 0000000..ee95d1f --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/validate/EmptyValidator.java @@ -0,0 +1,37 @@ +/* + * 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.validate; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class EmptyValidator implements Validator { + + private EmptyValidator() { + } + + public static Validator getInstance() { + return new EmptyValidator(); + } + + @Override + public void validate(Object validateObj) { + + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/validate/URIValidator.java b/src/main/java/org/hedgecode/xml/xspf/validate/URIValidator.java new file mode 100644 index 0000000..4c78479 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/validate/URIValidator.java @@ -0,0 +1,37 @@ +/* + * 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.validate; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class URIValidator implements Validator { + + private URIValidator() { + } + + public static Validator getInstance() { + return new URIValidator(); + } + + @Override + public void validate(Object validateObj) { + + } +} diff --git a/src/main/java/org/hedgecode/xml/xspf/validate/Validate.java b/src/main/java/org/hedgecode/xml/xspf/validate/Validate.java new file mode 100644 index 0000000..4303fa2 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/validate/Validate.java @@ -0,0 +1,38 @@ +/* + * 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.validate; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +@Target({TYPE, FIELD, METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Validate { + + ValidatorType validatorType(); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/validate/ValidateException.java b/src/main/java/org/hedgecode/xml/xspf/validate/ValidateException.java new file mode 100644 index 0000000..e02f358 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/validate/ValidateException.java @@ -0,0 +1,37 @@ +/* + * 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.validate; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public class ValidateException extends Exception { + + private int code; + + public ValidateException(int code, String message) { + super(message); + this.code = code; + } + + public int getCode() { + return code; + } + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/validate/Validator.java b/src/main/java/org/hedgecode/xml/xspf/validate/Validator.java new file mode 100644 index 0000000..496de85 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/validate/Validator.java @@ -0,0 +1,28 @@ +/* + * 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.validate; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public interface Validator { + + void validate(Object validateObj); + +} diff --git a/src/main/java/org/hedgecode/xml/xspf/validate/ValidatorType.java b/src/main/java/org/hedgecode/xml/xspf/validate/ValidatorType.java new file mode 100644 index 0000000..40d62b0 --- /dev/null +++ b/src/main/java/org/hedgecode/xml/xspf/validate/ValidatorType.java @@ -0,0 +1,39 @@ +/* + * 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.validate; + +/** + * + * + * @author Dmitry Samoshin aka gotty + */ +public enum ValidatorType { + + EMPTY ( EmptyValidator.getInstance() ), + URI ( URIValidator.getInstance() ); + + private Validator validator; + + private ValidatorType(Validator validator) { + this.validator = validator; + } + + public Validator getValidator() { + return validator; + } + +} diff --git a/src/main/rng/xspf-1_0.7.rng b/src/main/rng/xspf-1_0.7.rng new file mode 100644 index 0000000..0e693d6 --- /dev/null +++ b/src/main/rng/xspf-1_0.7.rng @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/xsd/xspf-1_0.2.xsd b/src/main/xsd/xspf-1_0.2.xsd new file mode 100644 index 0000000..84b0584 --- /dev/null +++ b/src/main/xsd/xspf-1_0.2.xsd @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/org/hedgecode/xml/xspf/XSPFTest.java b/src/test/java/org/hedgecode/xml/xspf/XSPFTest.java new file mode 100644 index 0000000..aedc50b --- /dev/null +++ b/src/test/java/org/hedgecode/xml/xspf/XSPFTest.java @@ -0,0 +1,69 @@ +/* + * 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 org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link XSPF}. + * + * @author Dmitry Samoshin aka gotty + */ +@RunWith(JUnit4.class) +public class XSPFTest extends Assert { + + private static final String XSPF_FILE_DIR = "/"; + private static final String XSPF_PLAYLIST_FILE = "playlist.xspf"; + private static final String XSPF_TORRENT_FILE = "torrent-tv.ru.xspf"; + + @Test + public void testBind() throws Exception { + + File xspfFile = new File( + XSPFTest.class.getResource( + XSPF_FILE_DIR + XSPF_PLAYLIST_FILE + ).toURI() + ); + + + Playlist playlist = XSPF.create(xspfFile); + + playlist.write( + new File("test.xspf") + ); + } + + @Test + public void testCreate() throws Exception { + + Playlist playlist = XSPF.create(XSPFConstants.Format.XSD); + playlist.setTitle("Title"); + playlist.setLocation("Location"); + XSPF.addTrack(playlist, "a.mp3", "First MP3"); + XSPF.addTrack(playlist, "b.mp3", "Second MP3"); + XSPF.addTrack(playlist, "c.mp3", "Third MP3"); + playlist.write( + new File("test2.xspf") + ); + } + +} diff --git a/src/test/resources/playlist.xspf b/src/test/resources/playlist.xspf new file mode 100644 index 0000000..ff0936e --- /dev/null +++ b/src/test/resources/playlist.xspf @@ -0,0 +1,40 @@ + + + My playlist + Jane Doe + My favorite songs + http://example.com/myplaylists + http://example.com/myplaylists/myplaylist + magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C + http://example.com/img/mypicture + 2005-01-08T17:10:47-05:00 + http://creativecommons.org/licenses/by/1.0/ + + http://bar.com/secondderived.xspf + http://foo.com/original.xspf + + http://socialnetwork.example.org/foaf/mary.rdfs + value + + + + + + http://example.com/my.mp3 + magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C + My Way + Frank Sinatra + This is my theme song. + http://franksinatra.com/myway + http://franksinatra.com/img/myway + Frank Sinatra's Greatest Hits + 3 + 19200 + http://socialnetwork.org/foaf/mary.rdfs + value + + + + + + \ No newline at end of file diff --git a/src/test/resources/torrent-tv.ru.xspf b/src/test/resources/torrent-tv.ru.xspf new file mode 100644 index 0000000..abcaeb0 --- /dev/null +++ b/src/test/resources/torrent-tv.ru.xspf @@ -0,0 +1 @@ +Избранные каналы TORRENT-TV.RUhttp://content.torrent-tv.ru/djY5Y2h1MFcrS0FWQUR0dlp1SGp2ZTJudmNlTCs1ajJLVHpDbFhIS3hLWGtId0d0ako2c0RiaFd0K1d5TkpKLzgrWFdLbzVBZVI3ZXo1aEpKNVNOUkE9PQ/cdn/5_reg.aceliveEurosporthttp://content.torrent-tv.ru/ZWcrTkgwY3FXZURPVkdjZkEvU1ErVXFqeWFXRE1Ed1Rzd045TUxnR1JRTG9GbEY1dGwxa013OWRDQ1ovUnFTQlNvSGMxcWtVQlh4OWkrOVZ6QVA4MGc9PQ/cdn/6_reg.aceliveEurospоrt 2http://content.torrent-tv.ru/Q1lWeUt0VnJXYnU1WFliNWhKd2xwWE91MUJsSGRCQVV6YzNyK3VFWTJRajhJUVVpTDY3RjR2eDNxV1ZCbUpDb0w1aUFjcXg1UC85YWt6clZhZTRKd1E9PQ/13250.aceliveEurospоrt 2 North-Easthttp://content.torrent-tv.ru/VVhaVmNyL05vb0pBUS9tUGFTWDh1ZE45Q25yTUpWWVFORlhTYUx2T2lPL2ozUFNISzR5MXkrVXBFZ1VJblMzckVScHpZTXYxWktudGVwSWwwYzgrZmc9PQ/cdn/38_reg.aceliveНТВ+ Спортhttp://content.torrent-tv.ru/U0NYRG16NTR3a0lKWlNkOEdtT3RoT1czVVk4YjdRanpKbmtMbit0UTJuSnhhdzFnOXhqejZxK0QyYy9mSjdzVEdweEpVWnExd3ZPc3gxOVZpZmE2cXc9PQ/cdn/222_reg.aceliveНТВ+ Спорт плюсhttp://content.torrent-tv.ru/K2ZVWDZEeW9GR3FrZHppeCsrQTJZeU9PUGROa2dDeTRxdU5VeDRwY3JMVlFhRk0vaXAxTG50Z28yZmxLV0JHR2xrTG1XM3pjMm5INUJPQ0xEZ0tlN3c9PQ/cdn/172_reg.aceliveEurosport HDhttp://content.torrent-tv.ru/eUh5WHVlbEcyenUyTVJOeGFMNWNZeGlUdHlBU1hwWTJRY2JzTEdXZU81WGR0ME96dUltQ2w5UFNzWElyRnNSZEFJU3FROHA0UDM3My96a3h0SHJhUnc9PQ/11160.aceliveEurospоrt 2 North-East HDhttp://content.torrent-tv.ru/VElRQ2tIRHdyelk4RDloOTlWaXlsZDd5RTlZd1Jlck1DVkVMcVo1RmpTamFROFNQcFVZOW0yU0hDenh6T0EyUVAxdUtsUlliMlpRVmlHSVRuYUUxQ1E9PQ/cdn/625_reg.aceliveНТВ+ Футбол 1 HDhttp://content.torrent-tv.ru/MHdOeXdMQlNPVSt1TDIrcFlyWnFmOTJxbWJ5QlR0YmVsd2JkdlppK1dwbmVDYnE5VzlIWGlOZklHYlR3eHpYUHlmZTNwN3poY05vaTN1bWJqQnNxSFE9PQ/cdn/611_reg.aceliveНТВ+ Футбол 2 HDhttp://content.torrent-tv.ru/N1NVQ1dWdmlkelpqQVlyYVNCbkFoQ2dBM0FoWlpQaHRmdzRpTlRVN1lDbm5ZU2EzTEVPc0tNOU9ONWV6Q0k2TUdyd3dGaHc3OU0zWlVLdFk1RkRQUXc9PQ/cdn/646_reg.aceliveНТВ+ Футбол 3 HDhttp://content.torrent-tv.ru/RzNvVStPUTFNUGFyZGFtRkR5N1dLUExwdzR6NGs0Q0ZIYmNqcVdydVByTnlSTlRVSDcxWGMrTjZNNmxocUJleXozRmxlUkd2YkNqZXpLcS95b0QvdWc9PQ/cdn/473_reg.aceliveСпортhttp://content.torrent-tv.ru/Rm9ZbWZGN1lFbnJtRGtnem5ScSsrQjA4M1FudTh3dlBkcmxKK2dHMXFaUVhZMHYwd29LMFA4aHhqTHBKbkJtaUxWUS9jNCtnMzR1WXhaakZ1SmdHalE9PQ/cdn/526_reg.aceliveСпорт 1 HDhttp://content.torrent-tv.ru/NUhOTlZXa3QxSnI1SzVUdFR2K2VQV3JGWTZVMTN0SHNsTFVKcHZERVFOU29zTDh3bWV0bHZDc2lWU0NqQURqTVpPazlzNlB0RGg0dHhjN0l0T0RXdHc9PQ/cdn/112_reg.aceliveHD Спортhttp://content.torrent-tv.ru/QjVVeFlzWStIWnZrYUpVTkl1eCt1ZXVtWXJIMEhXOUxBYWc5cGYzMUFYWVlRQ3FlV2gxK0dOcmx1OHlCUmtneGQ5dlBiMHJVQ3Q1RFRsZ1AwQ2Mzc3c9PQ/cdn/538_reg.aceliveКХЛ HDhttp://content.torrent-tv.ru/dUlQSjB4L0NZMTN1YjlUcHJQS0VpZ0YyMmtodUI3bVZGTWJiR2xuS3RPZDhyWGF4M2tzbGhvaFhHbmQzWU1Fb1VOeENmbThRUGVDMDNBMVVTU2Izcmc9PQ/cdn/487_all.aceliveParamount Comedyhttp://content.torrent-tv.ru/eDEwazVwZWFXS0tPZXNPeVc0THljdFM5aTZNTlRRSmYwQ3pPcW1iWkY2djZsb2g1RE9PT0YrNzNLNXFVd0RnUitkWnNHcGIvTUMrbWhIUGY1NFVGSlE9PQ/11181.aceliveParamount Comedy HDhttp://content.torrent-tv.ru/U0NrTzNaMFZ1U1F6ODMwbVppQXFEdXNzUkVNM1UrV24wR3FVMmdISzRoM3NLNHdoMFhSajh5aEFVQkNtYzgvSkZHdFhlZ0NtOXBFUG91UG9lVmxjZWc9PQ/cdn/28_reg.aceliveПерецhttp://content.torrent-tv.ru/cWpKZHZjbHRiZnRleGx4YzhudjI2N3lNSVMwREVCS2VralBHbk9mMTZZK3JHM05HU3gzOGtJSzlZMUJ3dy84Yng0ZEI4M2Z1MGRjRHo1YlpJTXdrdEE9PQ/cdn/731_reg.aceliveМультhttp://content.torrent-tv.ru/ZlJ5ZXBkOEd0SG56R1JFdzdyWC8zT2RSNlV0aEN1M1FUTHB4RzVyekJQajMvNXZ3R3Bsc3BkbGQwQytHb3pJdzZhR3FoeEFyVW81OG1kS1kzQXdzN0E9PQ/cdn/69_reg.aceliveTV 1000http://content.torrent-tv.ru/V3ppeE12NkFBbE5rNkk0blM3V2ZrMjc3b09jVWFoMjYzb3BLSTJQS3ZwN2c4M2Vxc0drVTlRQjdrRXlCaTAvdzNBKzNHbHUxOGJydTFLOWRXSFkzTUE9PQ/cdn/118_reg.aceliveTV 1000 Русское киноhttp://content.torrent-tv.ru/dGJobWkvQXpseTk2ZFUwSXFXWkJIT2c4dDlpSGpSZUdhcHFiWTk2Qm0zRVZJbG9jVmdzamdCTjVWVm9wS0dIbFVvNlhzblJ1NXA5djROditncVUrdFE9PQ/cdn/557_reg.aceliveTV1000 Comedy HDhttp://content.torrent-tv.ru/Zkx6VUJPSE04OVJyNEhqOU9pVGx4ZmRFMHRhZWtud1c2S2psRmt4VlJvZlBjczRtU0J2N0RxU0ZCRlFmcWNtVVpQeUpQQzAwT3hLdTFuS0lJSGU3cWc9PQ/cdn/36_reg.aceliveНТВ+ Наше киноhttp://content.torrent-tv.ru/aTBnUEUzbXlNa1BpK0xwSDFPcnNsYmhlbDV0aW9INGpDTG9nZ0Z4ckFXcko1VEJwbVZhVitVQjRBcjVGZlE3UGw1eGtpMUJ1TVZ3SjNXV2t2NlV3ZWc9PQ/cdn/228_reg.aceliveНТВ+ Кино плюсhttp://content.torrent-tv.ru/TzJrNXFUdC9DRUR4bDRaSjVPakE4bDZkbm4xWlJnYmVRWVZYRFZId2hFRnRzUk9vNkxNNmpDUDF3N0hjdk1xYWxWaWwwVUd3RmMvUm83QTNYQi9vcVE9PQ/cdn/77_reg.aceliveНТВ+ Кинохитhttp://content.torrent-tv.ru/bE5GNkFqajdjS2NYRDU4VTNLd3FtWmNIbnJpNzFNTE9kTko4T3RwR0I2NC9Xbm9ZNUw0Qmptd0xEVUM5V3JGWTk0bFJTOURmemMzQ0lrVUNQSnNHSWc9PQ/cdn/37_reg.aceliveНТВ+ Премьераhttp://content.torrent-tv.ru/QnNHQndPYWU2TGNWUnVCOThOMDZxeUVwY0JJYkV5OG1YVDNRYnBLZXZXRUFNODU4OHRDSFFrQzJreGRWZ1lDNWpKS2RNZEJFOWd0Q1dNOFFzclZ0VHc9PQ/cdn/81_reg.aceliveНТВ+ Наше новое киноhttp://content.torrent-tv.ru/cXRrYUFOendTTWpNaCtDNG45MTFMYXIzZ0tJK094Ly9YOEFSb3p2WmhlTlM3dUhndWcrYjJqWG16Y1B3bm9TWnhGK3p4blNBd3FqU0dEZStnZDR3NkE9PQ/cdn/35_reg.aceliveНТВ+ Киноклубhttp://content.torrent-tv.ru/SkVDVDV4dTl1YWUxYitJdHJwTmplL2VkdWRuN282V1RQbmd5ek9QYVdSMGxoR0FvS2JpcE1XMFRKY2twb0JZU240cVd5RnYrclRHUVlKUnNYQ1Iwdnc9PQ/cdn/82_reg.aceliveНТВ+ Кино Союзhttp://content.torrent-tv.ru/SUxaNmU2aVhBbDMrUEkxK25HQ1VITkVYcEdySnJZUzBTMEEzZXdlL0VnWVJtYm1ib3FWSmZPR3lkUHBIZ0RFWUxXSStzRTMyQThvVENqeDV3VWQ2UkE9PQ/cdn/691_reg.aceliveНТВ+ 3D \ No newline at end of file -- 2.10.0