View Javadoc

1   /*
2    * Copyright (C) 2005  Michael Wever ( mick@wever.org )
3   
4    *   This program is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU General Public License
6    *   as published by the Free Software Foundation; either version 2
7    *   of the License, or (at your option) any later version.
8    *
9    *   This program is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   *   GNU General Public License for more details.
13   *
14   *   You should have received a copy of the GNU General Public License
15   *   along with this program; if not, write to the Free Software
16   *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17   *
18   *   Document   : SongCollection.java
19   *   Created on : 23. juni 2005, 22:05
20   *   Author     : mick
21   *   Version    : $Id$
22   *   Description:
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      // Bean Patterns //
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     // Helper accessors //
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     // Displays //
215     
216     /***
217      * 
218      * @throws javax.xml.parsers.ParserConfigurationException 
219      * @return 
220      */
221     public Document toXMLDocument() throws ParserConfigurationException {
222         // Document
223         final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
224         final Document doc = builder.newDocument();
225         // category elements
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         // category structure
231         doc.appendChild(musicCollectionE);
232         musicCollectionE.appendChild(artistsE);
233         musicCollectionE.appendChild(albumsE);
234         musicCollectionE.appendChild(genresE);
235         // category to element mapping
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         // loop through the categories
242         for(Category category : categories){
243             // loop through each category 
244             for( String key : category.getMap().keySet() ){
245                 // create element
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                 // add element to category element
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 }