/src/de/felixbruns/jotify/JotifyPool.java

https://github.com/arildbjerkenes/jotify · Java · 554 lines · 362 code · 180 blank · 12 comment · 27 complexity · 3db43504e2e0bb8d54f86c3c029962d0 MD5 · raw file

  1. package de.felixbruns.jotify;
  2. import java.awt.Image;
  3. import java.io.IOException;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6. import java.util.concurrent.BlockingQueue;
  7. import java.util.concurrent.LinkedBlockingQueue;
  8. import java.util.concurrent.TimeUnit;
  9. import java.util.concurrent.TimeoutException;
  10. import javax.sound.sampled.LineUnavailableException;
  11. import de.felixbruns.jotify.exceptions.AuthenticationException;
  12. import de.felixbruns.jotify.exceptions.ConnectionException;
  13. import de.felixbruns.jotify.media.Album;
  14. import de.felixbruns.jotify.media.Artist;
  15. import de.felixbruns.jotify.media.Playlist;
  16. import de.felixbruns.jotify.media.PlaylistContainer;
  17. import de.felixbruns.jotify.media.Result;
  18. import de.felixbruns.jotify.media.Track;
  19. import de.felixbruns.jotify.media.User;
  20. import de.felixbruns.jotify.player.PlaybackListener;
  21. import de.felixbruns.jotify.player.Player;
  22. public class JotifyPool implements Jotify, Player {
  23. private List<Jotify> connectionList;
  24. private BlockingQueue<Jotify> connectionQueue;
  25. private Jotify playConnection;
  26. private int poolSize;
  27. private String username;
  28. private String password;
  29. private static JotifyPool instance;
  30. static {
  31. instance = new JotifyPool();
  32. }
  33. public static JotifyPool getInstance(){
  34. return instance;
  35. }
  36. public JotifyPool(){
  37. this(2);
  38. }
  39. public JotifyPool(int poolSize){
  40. this.connectionList = new LinkedList<Jotify>();
  41. this.connectionQueue = new LinkedBlockingQueue<Jotify>();
  42. this.playConnection = null;
  43. this.poolSize = poolSize;
  44. this.username = null;
  45. this.password = null;
  46. }
  47. private synchronized Jotify createConnection() throws ConnectionException, AuthenticationException {
  48. /* Check if username and password are set. */
  49. if(this.username == null || this.password == null){
  50. throw new IllegalStateException("Not logged in!");
  51. }
  52. /* Create a new connection. */
  53. Jotify connection = new JotifyConnection();
  54. /* Try to login with given username and password. */
  55. connection.login(this.username, this.password);
  56. /* Start the connections I/O thread. */
  57. new Thread(connection, "JotifyConnection-Thread").start();
  58. /* Add connection to pool. */
  59. this.connectionList.add(connection);
  60. return connection;
  61. }
  62. private void releaseConnection(Jotify connection){
  63. this.connectionQueue.add(connection);
  64. }
  65. private Jotify getConnection(){
  66. Jotify connection;
  67. /* Check if pool size is reached. */
  68. if(this.connectionList.size() >= this.poolSize){
  69. /* Try to get a connection from the queue. */
  70. try{
  71. connection = this.connectionQueue.poll(10, TimeUnit.SECONDS);
  72. if(connection == null){
  73. throw new TimeoutException("Couldn't get connection after 10 seconds.");
  74. }
  75. }
  76. catch(InterruptedException e){
  77. throw new RuntimeException(e);
  78. }
  79. catch(TimeoutException e){
  80. throw new RuntimeException(e);
  81. }
  82. }
  83. else{
  84. /* Create a new connection. */
  85. try{
  86. connection = this.createConnection();
  87. }
  88. catch(ConnectionException e){
  89. throw new RuntimeException(e);
  90. }
  91. catch(AuthenticationException e){
  92. throw new RuntimeException(e);
  93. }
  94. }
  95. return connection;
  96. }
  97. public void login(String username, String password) throws ConnectionException, AuthenticationException {
  98. /* Check if connections are available. */
  99. if(!this.connectionList.isEmpty()){
  100. throw new AuthenticationException("Already logged in!");
  101. }
  102. this.username = username;
  103. this.password = password;
  104. /* Create a new connection and immediately add it to the queue. */
  105. Jotify connection = this.createConnection();
  106. this.releaseConnection(connection);
  107. }
  108. public void close() throws ConnectionException {
  109. this.connectionQueue.clear();
  110. /* Close all connections. */
  111. for(Jotify connection : this.connectionList){
  112. connection.close();
  113. }
  114. this.connectionList.clear();
  115. }
  116. public void run(){
  117. /* Do nothing. */
  118. }
  119. public User user() throws TimeoutException {
  120. Jotify connection = this.getConnection();
  121. User user = connection.user();
  122. this.releaseConnection(connection);
  123. return user;
  124. }
  125. public Result toplist(String type, String region, String username) throws TimeoutException {
  126. Jotify connection = this.getConnection();
  127. Result result = connection.toplist(type, region, username);
  128. this.releaseConnection(connection);
  129. return result;
  130. }
  131. public Result search(String query) throws TimeoutException {
  132. Jotify connection = this.getConnection();
  133. Result result = connection.search(query);
  134. this.releaseConnection(connection);
  135. return result;
  136. }
  137. public Image image(String id) throws TimeoutException {
  138. Jotify connection = this.getConnection();
  139. Image image = connection.image(id);
  140. this.releaseConnection(connection);
  141. return image;
  142. }
  143. public Artist browse(Artist artist) throws TimeoutException {
  144. Jotify connection = this.getConnection();
  145. artist = connection.browse(artist);
  146. this.releaseConnection(connection);
  147. return artist;
  148. }
  149. public Album browse(Album album) throws TimeoutException {
  150. Jotify connection = this.getConnection();
  151. album = connection.browse(album);
  152. this.releaseConnection(connection);
  153. return album;
  154. }
  155. public Track browse(Track track) throws TimeoutException {
  156. Jotify connection = this.getConnection();
  157. Track result = connection.browse(track);
  158. this.releaseConnection(connection);
  159. return result;
  160. }
  161. public List<Track> browse(List<Track> tracks) throws TimeoutException {
  162. Jotify connection = this.getConnection();
  163. List<Track> result = connection.browse(tracks);
  164. this.releaseConnection(connection);
  165. return result;
  166. }
  167. public Album browseAlbum(String id) throws TimeoutException {
  168. Jotify connection = this.getConnection();
  169. Album album = connection.browseAlbum(id);
  170. this.releaseConnection(connection);
  171. return album;
  172. }
  173. public Artist browseArtist(String id) throws TimeoutException {
  174. Jotify connection = this.getConnection();
  175. Artist artist = connection.browseArtist(id);
  176. this.releaseConnection(connection);
  177. return artist;
  178. }
  179. public Track browseTrack(String id) throws TimeoutException {
  180. Jotify connection = this.getConnection();
  181. Track result = connection.browseTrack(id);
  182. this.releaseConnection(connection);
  183. return result;
  184. }
  185. public List<Track> browseTracks(List<String> ids) throws TimeoutException {
  186. Jotify connection = this.getConnection();
  187. List<Track> result = connection.browseTracks(ids);
  188. this.releaseConnection(connection);
  189. return result;
  190. }
  191. public Track replacement(Track track) throws TimeoutException {
  192. Jotify connection = this.getConnection();
  193. Track result = connection.replacement(track);
  194. this.releaseConnection(connection);
  195. return result;
  196. }
  197. public List<Track> replacement(List<Track> tracks) throws TimeoutException {
  198. Jotify connection = this.getConnection();
  199. List<Track> result = connection.replacement(tracks);
  200. this.releaseConnection(connection);
  201. return result;
  202. }
  203. public PlaylistContainer playlistContainer() throws TimeoutException {
  204. Jotify connection = this.getConnection();
  205. PlaylistContainer playlistContainer = connection.playlistContainer();
  206. this.releaseConnection(connection);
  207. return playlistContainer;
  208. }
  209. public boolean playlistContainerAddPlaylist(PlaylistContainer playlistContainer, Playlist playlist) throws TimeoutException {
  210. Jotify connection = this.getConnection();
  211. boolean success = connection.playlistContainerAddPlaylist(playlistContainer, playlist);
  212. this.releaseConnection(connection);
  213. return success;
  214. }
  215. public boolean playlistContainerAddPlaylist(PlaylistContainer playlistContainer, Playlist playlist, int position) throws TimeoutException {
  216. Jotify connection = this.getConnection();
  217. boolean success = connection.playlistContainerAddPlaylist(playlistContainer, playlist, position);
  218. this.releaseConnection(connection);
  219. return success;
  220. }
  221. public boolean playlistContainerAddPlaylists(PlaylistContainer playlistContainer, List<Playlist> playlists, int position) throws TimeoutException {
  222. Jotify connection = this.getConnection();
  223. boolean success = connection.playlistContainerAddPlaylists(playlistContainer, playlists, position);
  224. this.releaseConnection(connection);
  225. return success;
  226. }
  227. public boolean playlistContainerRemovePlaylist(PlaylistContainer playlistContainer, int position) throws TimeoutException {
  228. Jotify connection = this.getConnection();
  229. boolean success = connection.playlistContainerRemovePlaylist(playlistContainer, position);
  230. this.releaseConnection(connection);
  231. return success;
  232. }
  233. public boolean playlistContainerRemovePlaylists(PlaylistContainer playlistContainer, int position, int count) throws TimeoutException {
  234. Jotify connection = this.getConnection();
  235. boolean success = connection.playlistContainerRemovePlaylists(playlistContainer, position, count);
  236. this.releaseConnection(connection);
  237. return success;
  238. }
  239. public Playlist playlist(String id, boolean cached) throws TimeoutException {
  240. Jotify connection = this.getConnection();
  241. Playlist playlist = connection.playlist(id, cached);
  242. this.releaseConnection(connection);
  243. return playlist;
  244. }
  245. public Playlist playlist(String id) throws TimeoutException {
  246. return this.playlist(id, false);
  247. }
  248. public Playlist playlistCreate(String name, boolean collaborative, String description, String picture) throws TimeoutException {
  249. Jotify connection = this.getConnection();
  250. Playlist playlist = connection.playlistCreate(name, collaborative, description, picture);
  251. this.releaseConnection(connection);
  252. return playlist;
  253. }
  254. public Playlist playlistCreate(String name) throws TimeoutException {
  255. Jotify connection = this.getConnection();
  256. Playlist playlist = connection.playlistCreate(name);
  257. this.releaseConnection(connection);
  258. return playlist;
  259. }
  260. public Playlist playlistCreate(Album sourceAlbum) throws TimeoutException {
  261. Jotify connection = this.getConnection();
  262. Playlist playlist = connection.playlistCreate(sourceAlbum);
  263. this.releaseConnection(connection);
  264. return playlist;
  265. }
  266. public boolean playlistDestroy(Playlist playlist) throws TimeoutException {
  267. Jotify connection = this.getConnection();
  268. boolean success = connection.playlistDestroy(playlist);
  269. this.releaseConnection(connection);
  270. return success;
  271. }
  272. public boolean playlistAddTrack(Playlist playlist, Track track) throws TimeoutException {
  273. Jotify connection = this.getConnection();
  274. boolean success = connection.playlistAddTrack(playlist, track);
  275. this.releaseConnection(connection);
  276. return success;
  277. }
  278. public boolean playlistAddTrack(Playlist playlist, Track track, int position) throws TimeoutException {
  279. Jotify connection = this.getConnection();
  280. boolean success = connection.playlistAddTrack(playlist, track, position);
  281. this.releaseConnection(connection);
  282. return success;
  283. }
  284. public boolean playlistAddTracks(Playlist playlist, List<Track> tracks, int position) throws TimeoutException {
  285. Jotify connection = this.getConnection();
  286. boolean success = connection.playlistAddTracks(playlist, tracks, position);
  287. this.releaseConnection(connection);
  288. return success;
  289. }
  290. public boolean playlistRemoveTrack(Playlist playlist, int position) throws TimeoutException {
  291. Jotify connection = this.getConnection();
  292. boolean success = connection.playlistRemoveTrack(playlist, position);
  293. this.releaseConnection(connection);
  294. return success;
  295. }
  296. public boolean playlistRemoveTracks(Playlist playlist, int position, int count) throws TimeoutException {
  297. Jotify connection = this.getConnection();
  298. boolean success = connection.playlistRemoveTracks(playlist, position, count);
  299. this.releaseConnection(connection);
  300. return success;
  301. }
  302. public boolean playlistRename(Playlist playlist, String name) throws TimeoutException {
  303. Jotify connection = this.getConnection();
  304. boolean success = connection.playlistRename(playlist, name);
  305. this.releaseConnection(connection);
  306. return success;
  307. }
  308. public boolean playlistSetCollaborative(Playlist playlist, boolean collaborative) throws TimeoutException {
  309. Jotify connection = this.getConnection();
  310. boolean success = connection.playlistSetCollaborative(playlist, collaborative);
  311. this.releaseConnection(connection);
  312. return success;
  313. }
  314. public boolean playlistSetInformation(Playlist playlist, String description, String picture) throws TimeoutException {
  315. Jotify connection = this.getConnection();
  316. boolean success = connection.playlistSetInformation(playlist, description, picture);
  317. this.releaseConnection(connection);
  318. return success;
  319. }
  320. public void play(Track track, int bitrate, PlaybackListener listener) throws TimeoutException, IOException, LineUnavailableException {
  321. if(this.playConnection != null){
  322. this.playConnection.stop();
  323. this.releaseConnection(this.playConnection);
  324. this.playConnection = null;
  325. }
  326. this.playConnection = this.getConnection();
  327. this.playConnection.play(track, bitrate, listener);
  328. }
  329. public void play(){
  330. if(this.playConnection != null){
  331. this.playConnection.play();
  332. }
  333. }
  334. public void pause(){
  335. if(this.playConnection != null){
  336. this.playConnection.pause();
  337. }
  338. }
  339. public void stop(){
  340. if(this.playConnection != null){
  341. this.playConnection.stop();
  342. this.releaseConnection(this.playConnection);
  343. this.playConnection = null;
  344. }
  345. }
  346. public int length(){
  347. if(this.playConnection != null){
  348. return this.playConnection.length();
  349. }
  350. return -1;
  351. }
  352. public int position(){
  353. if(this.playConnection != null){
  354. return this.playConnection.position();
  355. }
  356. return -1;
  357. }
  358. public void seek(int position) throws IOException {
  359. if(this.playConnection != null){
  360. this.playConnection.seek(position);
  361. }
  362. }
  363. public float volume(){
  364. if(this.playConnection != null){
  365. return this.playConnection.volume();
  366. }
  367. return Float.NaN;
  368. }
  369. public void volume(float volume){
  370. if(this.playConnection != null){
  371. this.playConnection.volume(volume);
  372. }
  373. }
  374. }