1 /*** 2 * Ambient - A music player for the Android platform 3 Copyright (C) 2007 Martin Vysny 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 package sk.baka.ambient.stream.shoutcast; 20 21 import java.io.IOException; 22 import java.net.MalformedURLException; 23 import java.net.URL; 24 import java.text.ParseException; 25 import java.util.Collections; 26 import java.util.List; 27 28 import org.xml.sax.Attributes; 29 30 import sk.baka.ambient.collection.TrackMetadataBean; 31 import sk.baka.ambient.commons.NullArgumentException; 32 33 /*** 34 * A SHOUTcast radio station. 35 * 36 * @author Martin Vysny 37 */ 38 public final class Radio { 39 /*** 40 * The displayable radio station name. 41 */ 42 public final String name; 43 /*** 44 * the radio ID 45 */ 46 public final String id; 47 /*** 48 * The radio genre. 49 */ 50 public final String genre; 51 /*** 52 * currently played track, <code>null</code> if not known. 53 */ 54 public final String currentTrack; 55 56 /*** 57 * Creates new radio 58 * 59 * @param name 60 * The displayable radio station name. 61 * @param id 62 * the radio ID 63 * @param genre 64 * The radio genre. 65 * @param currentTrack 66 * currently played track, <code>null</code> if not known. 67 */ 68 public Radio(final String name, final String id, final String genre, 69 final String currentTrack) { 70 this.currentTrack = currentTrack; 71 if (name == null) 72 throw new NullArgumentException("name"); 73 if (id == null) 74 throw new NullArgumentException("id"); 75 this.genre = genre; 76 this.name = name; 77 this.id = id; 78 } 79 80 @Override 81 public String toString() { 82 return "SHOUTcast radio: " + name + " [" + id + "]"; 83 } 84 85 /*** 86 * Retrieves the radio playlist URL. 87 * 88 * @return the URL 89 * @throws MalformedURLException 90 */ 91 public URL getPlaylistURL() throws MalformedURLException { 92 final String url = "http://www.shoutcast.com/sbin/tunein-station.pls?id=" 93 + id; 94 return new URL(url); 95 } 96 97 /*** 98 * Cached URLs - radio sources. 99 */ 100 private List<TrackMetadataBean> radioURLs = null; 101 102 /*** 103 * Returns a list of URLs - radio sources. Blocks until the list is 104 * retrieved. 105 * 106 * @return non-<code>null</code> list of radio sources, read-only. 107 * @throws IOException 108 * if i/o error occurs. 109 * @throws ParseException 110 * if the playlist is not well formed. 111 */ 112 public synchronized List<TrackMetadataBean> getRadioURLs() 113 throws IOException, ParseException { 114 if (radioURLs == null) { 115 radioURLs = ShoutcastUtils.parsePlaylist(getPlaylistURL() 116 .openStream()); 117 radioURLs = Collections.unmodifiableList(radioURLs); 118 } 119 return radioURLs; 120 } 121 122 /*** 123 * Parse the radio from given XML attributes. 124 * 125 * @param attrs 126 * the attributes to parse 127 * @return radio instance, never <code>null</code>. 128 */ 129 public static Radio fromXML(final Attributes attrs) { 130 final String name = ShoutcastUtils.removeAsciiGraphics(attrs 131 .getValue("name")); 132 final String genre = ShoutcastUtils.removeAsciiGraphics(attrs 133 .getValue("genre")); 134 final String ct = ShoutcastUtils.removeAsciiGraphics(attrs 135 .getValue("ct")); 136 final String id = attrs.getValue("id"); 137 return new Radio(name, id, genre, ct); 138 } 139 }