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 }