/*
* Jajuk
* Copyright (C) The Jajuk Team
* http://jajuk.info
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package org.jajuk.services.lyrics;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.jajuk.base.File;
import org.jajuk.services.lyrics.persisters.ILyricsPersister;
import org.jajuk.services.lyrics.providers.ILyricsProvider;
import org.jajuk.services.lyrics.providers.JajukLyricsProvider;
import org.jajuk.ui.widgets.InformationJPanel;
import org.jajuk.ui.widgets.InformationJPanel.MessageType;
import org.jajuk.util.Messages;
import org.jajuk.util.error.LyricsPersistenceException;
import org.jajuk.util.log.Log;
/**
* Lyrics retrieval service. This service will retrieves lyrics from various
* providers, querying all of them until one returns some valid input.
*
* TODO: user-selectable multi-input-sources. edit the LyricsService so that it will
* notify about various valid sources, so we could propose various inputs to the
* user. For now the lyrics providers list is static and stored directly in this class.
*/
public final class LyricsService {
private static List<ILyricsProvider> providers = null;
private static ILyricsProvider current = null;
private static List<ILyricsPersister> persisters = null;
/** Providers list. */
private static String[] providersClasses = new String[] {
"org.jajuk.services.lyrics.providers.TagLyricsProvider",
"org.jajuk.services.lyrics.providers.TxtLyricsProvider",
"org.jajuk.services.lyrics.providers.AzLyricsWebLyricsProvider",
"org.jajuk.services.lyrics.providers.LyricsManiaWebLyricsProvider",
"org.jajuk.services.lyrics.providers.LyricsWikiaWebLyricsProvider", };
/** Persisters list. */
private static String[] persisterClasses = new String[] {
"org.jajuk.services.lyrics.persisters.TagPersister",
"org.jajuk.services.lyrics.persisters.TxtPersister" };
/**
* Empty private constructor to avoid instantiating utility class.
*/
private LyricsService() {
}
/**
* Loads the appropriate providers from the properties file. For now,
* providers order is static and the providersClasses array reflect jajuk
* artists service preferred ordering
*
* @TODO this behavior could eventually be switched to a shuffle provider list
* for performance or better resources usage reasons
*/
@SuppressWarnings("unchecked")
public static void loadProviders() {
providers = new ArrayList<ILyricsProvider>(2);
try {
for (String providerClass : providersClasses) {
if (!StringUtils.isBlank(providerClass)) {
Class<ILyricsProvider> clazz = (Class<ILyricsProvider>) Class.forName(providerClass);
ILyricsProvider provider = clazz.newInstance();
providers.add(provider);
Log.debug("Added Lyrics provider " + providerClass);
}
}
} catch (Exception e) {
Log.error(e);
}
}
/**
* Load persisters.
*
*/
@SuppressWarnings("unchecked")
public static void loadPersisters() {
persisters = new ArrayList<ILyricsPersister>(2);
try {
for (String persisterClass : persisterClasses) {
if (!StringUtils.isBlank(persisterClass)) {
Class<ILyricsPersister> clazz = (Class<ILyricsPersister>) Class.forName(persisterClass);
ILyricsPersister persister = clazz.newInstance();
persisters.add(persister);
Log.debug("Added Lyrics persister " + persisterClass);
}
}
} catch (Exception e) {
Log.error(e);
}
}
/**
* Cycles through lyrics providers to return the best matching lyrics.
*
* @param audioFile
*
* @return the song's lyrics
*/
public static String getLyrics(final File audioFile) {
String lyrics = null;
current = null;
Log.debug("Retrieving lyrics for file {{" + audioFile + "}}");
for (final ILyricsProvider provider : getProviders()) {
provider.setAudioFile(audioFile);
lyrics = provider.getLyrics();
current = provider;
if (lyrics != null) {
break;
}
}
// None provider found lyrics so reset current
if (lyrics == null) {
current = null;
}
return lyrics;
}
/**
* Commit lyrics for a jajuk lyrics provider (jajuk GUI).
*
* @param provider the JajukLyricsProvider
*
* @throws LyricsPersistenceException if lyrics cannot be written
*/
public static void commitLyrics(JajukLyricsProvider provider) throws LyricsPersistenceException {
boolean commitOK = false;
String destinationPath = null;
Log.debug("Commiting lyrics for file {{" + provider.getFile().getAbsolutePath() + "}}");
// Try each persister until we actually persist lyrics
for (final ILyricsPersister persister : getPersisters()) {
persister.setAudioFile(provider.getFile());
destinationPath = persister.getDestinationFile().getAbsolutePath();
commitOK = persister.commitLyrics(provider.getArtist(), provider.getTitle(),
provider.getLyrics());
if (commitOK) {
break;
}
}
if (commitOK) {
Log.info("Lyrics successfully commited to : " + destinationPath);
InformationJPanel.getInstance().setMessage(
Messages.getString("Success") + " [" + destinationPath + "]", MessageType.INFORMATIVE);
} else {
throw new LyricsPersistenceException("Lyrics could not be commited to "
+ provider.getFile().getAbsolutePath());
}
}
/**
* Delete lyrics from any persister support.
*
* @param provider
*
* @throws LyricsPersistenceException if the lyrics cannot be removed
*/
public static void deleteLyrics(JajukLyricsProvider provider) throws LyricsPersistenceException {
boolean deleteOK = false;
String destinationPath = null;
Log.debug("deleting lyrics for file {{" + provider.getFile().getAbsolutePath() + "}}");
for (final ILyricsPersister persister : getPersisters()) {
persister.setAudioFile(provider.getFile());
destinationPath = persister.getDestinationFile().getAbsolutePath();
deleteOK = persister.deleteLyrics();
if (deleteOK) {
break;
}
}
if (deleteOK) {
Log.info("Lyrics successfully deleted for file : " + provider.getFile().getAbsolutePath());
InformationJPanel.getInstance().setMessage(
Messages.getString("Success") + " [" + destinationPath + "]", MessageType.INFORMATIVE);
} else {
throw new LyricsPersistenceException("Lyrics could not be deleted from "
+ provider.getFile().getName());
}
}
/**
* Returns the lazy-instantiated providers collection.
*
* @return the map of loaded providers
*/
public static List<ILyricsProvider> getProviders() {
if (providers == null) {
loadProviders();
}
return providers;
}
/**
* Gets the current provider.
*
* @return the current provider
*/
public static ILyricsProvider getCurrentProvider() {
return current;
}
/**
* Gets the persisters.
*
* @return the persisters
*/
public static List<ILyricsPersister> getPersisters() {
if (persisters == null) {
loadPersisters();
}
return persisters;
}
}