View Javadoc

1   package org.varienaja.util.coverart;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.net.URLConnection;
6   import java.util.ArrayList;
7   import java.util.Collection;
8   import java.util.Set;
9   import java.util.TreeSet;
10  
11  import org.apache.log4j.Logger;
12  
13  /**
14   * Class which provides functionality to search for Covers of Playlists, and to
15   * get an InputStream of images found.
16   * @author Varienaja
17   */
18  public class CoverArtProcessor implements ICoverArtFinder {
19  	
20  	/**
21  	 * Inner class providing threaded searching over Coverart.
22  	 * This means that multiple CoverArt-sources can be searched in
23  	 * parallel.
24  	 * @author Varienaja
25  	 */
26  	static class ThreadedCoverFinder extends Thread {
27  		private ICoverArtFinder _finder;
28  		private String _band;
29  		private String _album;
30  		private Collection<CoverArtSearchResult> _results;
31  		
32  		/**
33  		 * Construct this class with a ICoverArtFinder-interface, a band and an album
34  		 * to search for.
35  		 * @param finder The ICoverArtFinder to use.
36  		 * @param band The name of the Band
37  		 * @param album The name of the Album
38  		 */
39  		public ThreadedCoverFinder(ICoverArtFinder finder, String band, String album) {
40  			super();
41  			
42  			_finder = finder;
43  			_band = band;
44  			_album = album;
45  			_results = new ArrayList<CoverArtSearchResult>();
46  		}
47  		
48  		/**
49  		 * Gets called by the JVM to perform the task. Do not call this method
50  		 * by yourself. Start the thread by calling start().
51  		 */
52  		public void run() {
53  			_results = _finder.findCoverURLs(_band,_album);
54  		}
55  		
56  		/**
57  		 * When the Thread is finished, you can get the results with this method.
58  		 * @return A non-null List of CoverArtSearchResult-objects
59  		 */
60  		public Collection<CoverArtSearchResult> getResults() {
61  			return _results;
62  		}
63  		
64  	}
65  	
66  	private static final Logger log = Logger.getLogger(CoverArtProcessor.class);
67  
68  	public Collection<CoverArtSearchResult> findCoverURLs(String band, String album) {
69  		Set<CoverArtSearchResult> results = new TreeSet<CoverArtSearchResult>();
70  		
71  		//Search in all sources in parallel, nifty use of Threads eh?
72  		ThreadedCoverFinder[] threads = new ThreadedCoverFinder[3];
73  		threads[0] = new ThreadedCoverFinder(new GoogleCoverArtFinder(),band,album);
74  		threads[1] = new ThreadedCoverFinder(new AmazonCoverArtFinder(),band,album);
75  		threads[2] = new ThreadedCoverFinder(new YahooCoverArtFinder(),band,album);
76  		
77  		try {
78  			log.debug("Starting coversearch-threads");
79  			for (int i=0;i<threads.length;i++) {
80  				threads[i].start();
81  			}
82  			
83  			//Wait for threads to finish, and get collect their output
84  			for (int i=0;i<threads.length;i++) {
85  				threads[i].join();
86  				results.addAll(threads[i].getResults());
87  			}
88  		} catch (InterruptedException e) {
89  			log.error("Error while searching coverart: "+e);
90  		}
91  		
92  		return results;
93  	}
94  	
95  	public InputStream getCover(CoverArtSearchResult casr,long id) throws IOException {
96  		try {
97  			log.debug("Getting coverart "+casr.getURI());
98  			URLConnection urlc = casr.getURI().toURL().openConnection();
99  			urlc.setRequestProperty("user-agent","Mozilla/5.0"); //Google wants a user-agent.
100 			return urlc.getInputStream();
101 		} catch (IOException e) {
102 			log.error("Error saving coverart: "+e);
103 			throw e;
104 		}
105 	}
106 	
107 }