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 package sk.baka.ambient.playlist; 19 20 import java.util.ArrayList; 21 import java.util.Collections; 22 import java.util.Comparator; 23 import java.util.HashMap; 24 import java.util.List; 25 import java.util.Map; 26 import java.util.Random; 27 28 import sk.baka.ambient.collection.CollectionUtils; 29 import sk.baka.ambient.collection.TrackMetadataBean; 30 import sk.baka.ambient.commons.MiscUtils; 31 32 /*** 33 * Utility methods. 34 * 35 * @author Martin Vysny 36 */ 37 public final class Utils { 38 /*** 39 * Prevent instantiation 40 */ 41 private Utils() { 42 super(); 43 } 44 45 /*** 46 * Orders the tracks by albums, track number and finally by filenames. 47 */ 48 public static final Comparator<PlaylistItem> PLAYLIST_ALBUM_ORDER_COMPARATOR = new Comparator<PlaylistItem>() { 49 public int compare(PlaylistItem object1, PlaylistItem object2) { 50 return CollectionUtils.ALBUM_ORDER_COMPARATOR.compare(object1 51 .getTrack(), object2.getTrack()); 52 } 53 }; 54 55 /*** 56 * Sorts the tracks by albums, track number and finally by filenames. 57 * 58 * @param playlist 59 * the playlist to sort. 60 */ 61 public static void sortPlaylistByAlbumOrder( 62 final List<PlaylistItem> playlist) { 63 Collections.sort(playlist, PLAYLIST_ALBUM_ORDER_COMPARATOR); 64 } 65 66 /*** 67 * Retrieves a map of album names to a list of tracks in that particular 68 * album. 69 * 70 * @param playlist 71 * retrieve the map from this playlist. 72 * @return map from album name to its tracks. The track ordering is the same 73 * as in the playlist. Same tracks may appear multiple times in the 74 * album if they appeared multiple times in the original playlist. 75 */ 76 public static Map<String, List<PlaylistItem>> getAlbumsFromPlaylist( 77 final List<PlaylistItem> playlist) { 78 final Map<String, List<PlaylistItem>> result = new HashMap<String, List<PlaylistItem>>(); 79 for (final PlaylistItem item : playlist) { 80 List<PlaylistItem> albumTracklist = result.get(item.getTrack() 81 .getAlbum()); 82 if (albumTracklist == null) { 83 albumTracklist = new ArrayList<PlaylistItem>(); 84 result.put(item.getTrack().getAlbum(), albumTracklist); 85 } 86 albumTracklist.add(item); 87 } 88 return result; 89 } 90 91 /*** 92 * Adds given track to the album map structure. 93 * 94 * @param albumMap 95 * the map to modify, must not be <code>null</code> 96 * @param item 97 * the track to add, must not be <code>null</code> 98 */ 99 public static void addToAlbumMap( 100 final Map<String, List<TrackMetadataBean>> albumMap, 101 final TrackMetadataBean item) { 102 List<TrackMetadataBean> albumTracklist = albumMap.get(item.getAlbum()); 103 if (albumTracklist == null) { 104 albumTracklist = new ArrayList<TrackMetadataBean>(); 105 albumMap.put(item.getAlbum(), albumTracklist); 106 } 107 albumTracklist.add(item); 108 } 109 110 /*** 111 * Removes given track from the album map structure. 112 * 113 * @param albumMap 114 * the map to modify, must not be <code>null</code> 115 * @param item 116 * the track to remove, must not be <code>null</code> 117 */ 118 public static void removeFromAlbumMap( 119 final Map<String, List<TrackMetadataBean>> albumMap, 120 final TrackMetadataBean item) { 121 List<TrackMetadataBean> albumTracklist = albumMap.get(item.getAlbum()); 122 if (albumTracklist == null) { 123 return; 124 } 125 albumTracklist.remove(item); 126 if (albumTracklist.isEmpty()) { 127 albumMap.remove(item.getAlbum()); 128 } 129 } 130 131 /*** 132 * Retrieves a map of album names to a list of tracks in that particular 133 * album. 134 * 135 * @param playlist 136 * retrieve the map from this playlist. 137 * @param sort 138 * if <code>true</code> then all albums tracks will be sorted. 139 * @return map from album name to its tracks. The track ordering is the same 140 * as in the playlist unless sort is required. Same tracks may 141 * appear multiple times in the album if they appeared multiple 142 * times in the original playlist. 143 */ 144 public static Map<String, List<TrackMetadataBean>> getAlbumsFromBeans( 145 final List<TrackMetadataBean> playlist, boolean sort) { 146 final Map<String, List<TrackMetadataBean>> result = new HashMap<String, List<TrackMetadataBean>>(); 147 for (final TrackMetadataBean item : playlist) { 148 addToAlbumMap(result, item); 149 } 150 if (sort) { 151 for (List<TrackMetadataBean> album : result.values()) { 152 CollectionUtils.sortByAlbumOrder(album); 153 } 154 } 155 return result; 156 } 157 158 /*** 159 * Returns {@link List#subList(int, int)} from given list with all items 160 * having given album. 161 * 162 * @param playlist 163 * the playlist 164 * @param album 165 * the album to search for 166 * @return first continuous sublist from given list with given album name. 167 * Returns empty list from the end of the playlist if no album 168 * match. 169 */ 170 public static List<PlaylistItem> getAlbumSublist( 171 final List<PlaylistItem> playlist, final String album) { 172 int from; 173 for (from = 0; from < playlist.size(); from++) { 174 if (MiscUtils.nullCompare(playlist.get(from).getTrack().getAlbum(), 175 album, true) == 0) 176 break; 177 } 178 int to; 179 for (to = from; to < playlist.size(); to++) { 180 if (MiscUtils.nullCompare(playlist.get(to).getTrack().getAlbum(), 181 album, true) != 0) 182 break; 183 } 184 return playlist.subList(from, to); 185 } 186 187 /*** 188 * Creates new list, having all items with given album. 189 * 190 * @param playlist 191 * the playlist 192 * @param album 193 * the album to search for 194 * @return all items from given playlist in the playlist ordering. Never 195 * <code>null</code>, may be empty. 196 */ 197 public static List<PlaylistItem> filterOnAlbum( 198 final List<PlaylistItem> playlist, final String album) { 199 final List<PlaylistItem> result = new ArrayList<PlaylistItem>(); 200 for (final PlaylistItem item : playlist) { 201 if (MiscUtils.nullEquals(album, item.track.getAlbum())) { 202 result.add(item); 203 } 204 } 205 return result; 206 } 207 208 /*** 209 * The random number generator. 210 */ 211 public final static Random RANDOM = new Random(); 212 213 /*** 214 * Modifies the playlist by changing all {@link PlaylistItem} locations. 215 * 216 * @param locationMap 217 * maps old locations to new locations. 218 * @param playlist 219 * the playlist 220 */ 221 public static void replaceLocations(final List<PlaylistItem> playlist, 222 final Map<String, String> locationMap) { 223 for (final PlaylistItem item: playlist) { 224 final String newLocation = locationMap.get(item.getTrack() 225 .getLocation()); 226 if (newLocation == null) { 227 continue; 228 } 229 final TrackMetadataBean track = new TrackMetadataBean.Builder() 230 .getData(item.getTrack()).setLocation(newLocation).build( 231 item.getTrack().getTrackId()); 232 item.track = track; 233 } 234 } 235 }