1 /* 2 * aTunes 3 * Copyright (C) Alex Aranda, Sylvain Gaudard and contributors 4 * 5 * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors 6 * 7 * http://www.atunes.org 8 * http://sourceforge.net/projects/atunes 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 2 13 * of the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21 package net.sourceforge.atunes.kernel.modules.favorites; 22 23 import java.util.ArrayList; 24 import java.util.Collection; 25 import java.util.HashSet; 26 import java.util.List; 27 import java.util.Set; 28 29 import org.apache.commons.collections.list.SetUniqueList; 30 31 import net.sourceforge.atunes.kernel.modules.webservices.AddLovedSongBackgroundWorker; 32 import net.sourceforge.atunes.kernel.modules.webservices.RemoveLovedSongBackgroundWorker; 33 import net.sourceforge.atunes.model.IAudioObject; 34 import net.sourceforge.atunes.model.IBeanFactory; 35 import net.sourceforge.atunes.model.IFavorites; 36 import net.sourceforge.atunes.model.ILocalAudioObject; 37 import net.sourceforge.atunes.model.IRepositoryHandler; 38 import net.sourceforge.atunes.model.IStateContext; 39 import net.sourceforge.atunes.model.IUnknownObjectChecker; 40 import net.sourceforge.atunes.utils.CollectionUtils; 41 42 /** 43 * Manages favorite songs 44 * 45 * @author alex 46 * 47 */ 48 public class FavoritesSongsManager { 49 50 private IStateContext stateContext; 51 52 private IBeanFactory beanFactory; 53 54 private IRepositoryHandler repositoryHandler; 55 56 private IUnknownObjectChecker unknownObjectChecker; 57 58 /** 59 * @param unknownObjectChecker 60 */ setUnknownObjectChecker( final IUnknownObjectChecker unknownObjectChecker)61 public void setUnknownObjectChecker( 62 final IUnknownObjectChecker unknownObjectChecker) { 63 this.unknownObjectChecker = unknownObjectChecker; 64 } 65 66 /** 67 * @param repositoryHandler 68 */ setRepositoryHandler(final IRepositoryHandler repositoryHandler)69 public void setRepositoryHandler(final IRepositoryHandler repositoryHandler) { 70 this.repositoryHandler = repositoryHandler; 71 } 72 73 /** 74 * @param beanFactory 75 */ setBeanFactory(final IBeanFactory beanFactory)76 public void setBeanFactory(final IBeanFactory beanFactory) { 77 this.beanFactory = beanFactory; 78 } 79 80 /** 81 * @param stateContext 82 */ setStateContext(final IStateContext stateContext)83 public void setStateContext(final IStateContext stateContext) { 84 this.stateContext = stateContext; 85 } 86 87 /** 88 * Adds favorite songs 89 * 90 * @param favorites 91 * @param songs 92 * @param updateWebServices 93 * @return true if favorites have changed 94 */ addSongs(final IFavorites favorites, final Collection<ILocalAudioObject> songs, final boolean updateWebServices)95 public boolean addSongs(final IFavorites favorites, 96 final Collection<ILocalAudioObject> songs, 97 final boolean updateWebServices) { 98 if (CollectionUtils.isEmpty(songs)) { 99 return false; 100 } 101 102 for (ILocalAudioObject song : songs) { 103 favorites.addSong(song); 104 } 105 106 if (updateWebServices && this.stateContext.isLastFmEnabled() 107 && this.stateContext.isAutoLoveFavoriteSong()) { 108 this.beanFactory.getBean(AddLovedSongBackgroundWorker.class).add( 109 new ArrayList<IAudioObject>(songs)); 110 } 111 112 return true; 113 } 114 115 /** 116 * Remove favorite songs 117 * 118 * @param favorites 119 * @param songs 120 * @param updateWebServices 121 * @return true if favorites have changed 122 */ removeSongs(final IFavorites favorites, final Collection<ILocalAudioObject> songs, final boolean updateWebServices)123 public boolean removeSongs(final IFavorites favorites, 124 final Collection<ILocalAudioObject> songs, 125 final boolean updateWebServices) { 126 if (CollectionUtils.isEmpty(songs)) { 127 return false; 128 } 129 130 for (ILocalAudioObject file : songs) { 131 favorites.removeSong(file); 132 } 133 134 if (updateWebServices && this.stateContext.isLastFmEnabled() 135 && this.stateContext.isAutoLoveFavoriteSong()) { 136 this.beanFactory.getBean(RemoveLovedSongBackgroundWorker.class) 137 .remove(new ArrayList<IAudioObject>(songs)); 138 } 139 140 return true; 141 } 142 143 /** 144 * Takes songs from a list of audio objects and add or remove songs from 145 * favorites 146 * 147 * @param favorites 148 * @param songs 149 * @return if favorites have changed 150 */ toggleFavoriteSongs(final IFavorites favorites, final List<ILocalAudioObject> songs)151 public boolean toggleFavoriteSongs(final IFavorites favorites, 152 final List<ILocalAudioObject> songs) { 153 if (CollectionUtils.isEmpty(songs)) { 154 return false; 155 } 156 157 @SuppressWarnings("unchecked") 158 Set<ILocalAudioObject> set = SetUniqueList.decorate(songs).asSet(); 159 160 Set<ILocalAudioObject> toAdd = new HashSet<ILocalAudioObject>(); 161 Set<ILocalAudioObject> toRemove = new HashSet<ILocalAudioObject>(); 162 for (ILocalAudioObject song : set) { 163 // Toggle favorite songs 164 if (favorites.containsSong(song)) { 165 toRemove.add(song); 166 } else { 167 toAdd.add(song); 168 } 169 } 170 171 addSongs(favorites, toAdd, true); 172 removeSongs(favorites, toRemove, true); 173 174 return !toAdd.isEmpty() || !toRemove.isEmpty(); 175 } 176 177 /** 178 * Checks all songs to see if exists in repository, removing if does not 179 * exist 180 * 181 * @param favorites 182 * @return true if favorites changed 183 */ checkFavoriteSongs(final IFavorites favorites)184 public boolean checkFavoriteSongs(final IFavorites favorites) { 185 List<ILocalAudioObject> toRemove = new ArrayList<ILocalAudioObject>(); 186 for (ILocalAudioObject favorite : favorites.getFavoriteSongs()) { 187 if (!this.repositoryHandler.existsFile(favorite)) { 188 toRemove.add(favorite); 189 } 190 } 191 return removeSongs(favorites, toRemove, false); 192 } 193 194 /** 195 * @param favorites 196 * @param artist 197 * @param title 198 * @return true if a song with given artist and title is favorite 199 */ isSongFavorite(final IFavorites favorites, final String artist, final String title)200 public boolean isSongFavorite(final IFavorites favorites, 201 final String artist, final String title) { 202 // TODO: This method checks all favorite songs to find one matching 203 // With favorites stored by metadata this would not be necessary 204 for (ILocalAudioObject ao : favorites.getFavoriteSongs()) { 205 if (ao.getArtist(this.unknownObjectChecker) 206 .equalsIgnoreCase(artist) 207 && title.equalsIgnoreCase(ao.getTitle())) { 208 return true; 209 } 210 } 211 return false; 212 } 213 } 214