1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.wever.jradiodj.beans;
26 import java.io.File;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.SortedMap;
32 import java.util.SortedSet;
33 import java.util.TreeMap;
34 import java.util.TreeSet;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37 import javax.xml.parsers.DocumentBuilder;
38 import javax.xml.parsers.DocumentBuilderFactory;
39 import javax.xml.parsers.ParserConfigurationException;
40
41 import org.w3c.dom.Document;
42 import org.w3c.dom.Element;
43
44
45 /***
46 *
47 * @author mick
48 * @version $Id$
49 */
50 public final class SongCollection extends AbstractBean {
51
52 private final SortedMap < String, SortedSet < File > >
53 artists = new TreeMap< String, SortedSet < File > > (),
54 albums = new TreeMap< String, SortedSet < File > > (),
55 genres = new TreeMap< String, SortedSet < File > > ();
56
57 private final Category[] categories = new Category[] {
58 new Category("artists", artists),
59 new Category("albums", albums),
60 new Category("genres", genres)
61 };
62
63 private final SortedMap < String, File > titles = new TreeMap< String, File > ();
64 private final SortedSet < File > songs = new TreeSet< File > ();
65
66 private static final Logger LOG = Logger.getLogger(SongCollection.class.getName());
67 private static volatile long filesLoaded = 0, filesProcessed = 0;
68
69 static {
70 LOG.setLevel(Level.FINEST);
71 }
72
73 /*** Creates a new instance of SongCollection. */
74 public SongCollection() {
75 }
76
77
78
79 /***
80 *
81 * @return
82 */
83 public Set < String > getArtists() {
84 return Collections.unmodifiableSet( artists.keySet() );
85 }
86
87 /***
88 *
89 * @return
90 */
91 public Set < String > getAlbums() {
92 return Collections.unmodifiableSet( albums.keySet() );
93 }
94
95 /***
96 *
97 * @return
98 */
99 public Set < String > getGenres() {
100 return Collections.unmodifiableSet( genres.keySet() );
101 }
102
103 /***
104 *
105 * @return
106 */
107 public Set < String > getTitles() {
108 return Collections.unmodifiableSet( titles.keySet() );
109 }
110
111
112
113 /***
114 *
115 * @return
116 */
117 public SortedSet < File > getFiles() {
118 return Collections.unmodifiableSortedSet( songs );
119 }
120
121 /***
122 *
123 * @param artist
124 * @return
125 */
126 public SortedSet < File > getFilesForArtist(final String artist) {
127 return Collections.unmodifiableSortedSet( artists.get( artist ) );
128 }
129
130 /***
131 *
132 * @param album
133 * @return
134 */
135 public SortedSet < File > getFilesForAlbum(final String album) {
136 return Collections.unmodifiableSortedSet( albums.get( album ) );
137 }
138
139 /***
140 *
141 * @param genre
142 * @return
143 */
144 public SortedSet < File > getFilesForGenre(final String genre) {
145 return Collections.unmodifiableSortedSet( genres.get( genre ) );
146 }
147
148 /***
149 *
150 * @param artist
151 * @param song
152 */
153 public void addArtist(final String artist, final File song) {
154 if( artist != null ){
155 SortedSet < File > _songs = artists.get(artist);
156 if( _songs == null ) {
157 _songs = new TreeSet < File > ();
158 artists.put(artist, _songs);
159 }
160 _songs.add( song );
161 LOG.log(Level.FINEST, "Added " + song.getName() + " to " + artist);
162 }else{
163 LOG.warning( "Missing artist tag in " + song.getName() );
164 }
165 }
166
167 /***
168 *
169 * @param album
170 * @param song
171 */
172 public void addAlbum(final String album, final File song) {
173 if( album != null ){
174 SortedSet < File > _songs = albums.get(album);
175 if( _songs == null ) {
176 _songs = new TreeSet < File > ();
177 albums.put(album, _songs);
178 }
179 _songs.add( song );
180 LOG.log(Level.FINEST, "Added " + song.getName() + " to " + album);
181 }else{
182 LOG.warning( "Missing album tag in " + song.getName() );
183 }
184 }
185
186 /***
187 *
188 * @param title
189 * @param song
190 */
191 public void addTitle(final String title, final File song) {
192 if( title != null ){
193 titles.put(title, song);
194 LOG.log(Level.FINEST, "Added " + song.getName() + " to " + title);
195 }else{
196 LOG.warning( "Missing title tag in " + song.getName() );
197 }
198 }
199
200 private void addGenre(final String genre, final File song){
201 if( genre != null ){
202 SortedSet < File > _songs = genres.get(genre);
203 if( _songs == null ) {
204 _songs = new TreeSet < File > ();
205 genres.put(genre, _songs);
206 }
207 _songs.add( song );
208 LOG.log(Level.FINEST, "Added " + song.getName() + " to " + genre);
209 }else{
210 LOG.warning( "Missing genre tag in " + song.getName() );
211 }
212 }
213
214
215
216 /***
217 *
218 * @throws javax.xml.parsers.ParserConfigurationException
219 * @return
220 */
221 public Document toXMLDocument() throws ParserConfigurationException {
222
223 final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
224 final Document doc = builder.newDocument();
225
226 final Element musicCollectionE = doc.createElement("musicCollection");
227 final Element artistsE = doc.createElement("artists");
228 final Element albumsE = doc.createElement("albums");
229 final Element genresE = doc.createElement("genres");
230
231 doc.appendChild(musicCollectionE);
232 musicCollectionE.appendChild(artistsE);
233 musicCollectionE.appendChild(albumsE);
234 musicCollectionE.appendChild(genresE);
235
236 final Map < SortedMap < String,SortedSet < File > > , Element > categoriesToElements
237 = new HashMap < SortedMap < String, SortedSet < File > > ,Element > ();
238 categoriesToElements.put(artists, artistsE);
239 categoriesToElements.put(albums, albumsE);
240 categoriesToElements.put(genres, genresE);
241
242 for(Category category : categories){
243
244 for( String key : category.getMap().keySet() ){
245
246 final Element element = doc.createElement(category.getName());
247 element.setAttribute("name", key);
248 final StringBuilder fileList = new StringBuilder();
249 for( File file : category.getMap().get(key)){
250 if( fileList.length() > 0 ){ fileList.append(','); }
251 fileList.append(file.getAbsolutePath());
252 }
253 element.setNodeValue(fileList.toString());
254
255 categoriesToElements.get(category.getMap().get(key)).appendChild(element);
256 }
257 }
258
259 return doc;
260 }
261
262 /*** A category is a reference to one of the maps of artists, albums, or genres.
263 ***/
264 private static final class Category {
265 private final String name;
266 private final SortedMap < String, SortedSet < File > > map;
267
268 public Category(final String name, final SortedMap < String, SortedSet < File > > category) {
269 this.name = name;
270 this.map = category;
271 }
272
273 public String getName() {
274 return name;
275 }
276
277 public SortedMap < String, SortedSet < File > > getMap() {
278 return map;
279 }
280 }
281 }