package com.pugh.sockso.gui.action;
import com.pugh.sockso.Utils;
import com.pugh.sockso.db.Database;
import com.pugh.sockso.gui.AppFrame;
import com.pugh.sockso.gui.PlaylistFileFilter;
import com.pugh.sockso.resources.Resources;
import com.pugh.sockso.resources.Locale;
import com.pugh.sockso.music.Track;
import com.pugh.sockso.music.CollectionManager;
import com.pugh.sockso.music.playlist.PlaylistFile;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import java.io.File;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import com.google.inject.Inject;
/**
* an action to import a playlist
*
*/
public class ImportPlaylist implements ActionListener {
private static final Logger log = Logger.getLogger( ImportPlaylist.class );
private final JFrame parent;
private final Database db;
private final CollectionManager cm;
private final Resources r;
private final Locale locale;
@Inject
public ImportPlaylist( final AppFrame parent, final Database db, final CollectionManager cm,
final Resources r, final Locale locale ) {
this.parent = parent;
this.db = db;
this.cm = cm;
this.r = r;
this.locale = locale;
}
public void actionPerformed( ActionEvent evt ) {
String error = "";
final JFileChooser fc = new JFileChooser();
fc.addChoosableFileFilter( new PlaylistFileFilter(locale) );
if ( fc.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION ) {
try {
final File file = fc.getSelectedFile();
final String playlistName = getPlaylistName( file );
final int playlistId = importPlaylist( file, playlistName );
if ( playlistId == -1 ) {
error = locale.getString("gui.message.playlistImportFailed");
}
else {
JOptionPane.showMessageDialog(
parent, locale.getString("gui.message.playlistImported"),
"Sockso", JOptionPane.INFORMATION_MESSAGE
);
return;
}
}
catch ( final Exception e ) {
e.printStackTrace();
log.error( e );
error = e.getMessage();
}
JOptionPane.showMessageDialog(
parent, error, "Sockso",
JOptionPane.ERROR_MESSAGE
);
}
}
/**
* Import a playlist from the specified file with the specified name
*
* @param file
* @param playlistName
*
* @return
*
* @throws SQLException
* @throws Exception
* @throws IOException
*
*/
protected int importPlaylist(final File file, final String playlistName) throws SQLException, Exception, IOException {
final PlaylistFile playlistFile = PlaylistFile.getPlaylistFile( file.getAbsoluteFile() );
if ( playlistFile == null ) {
throw new Exception( "Unsupported playlist type" );
}
final Track[] tracks = getTracksFromPlaylist( playlistFile );
final int playlistId = cm.savePlaylist( playlistName, tracks );
return playlistId;
}
/**
* Looks through the tracks in the playlist and tries to find them in the
* collection.
*
* @param playlistFile
*
* @return
*
* @throws SQLException
*
*/
protected Track[] getTracksFromPlaylist( final PlaylistFile playlistFile ) throws SQLException {
final ArrayList<Track> tracks = new ArrayList<Track>();
ResultSet rs = null;
PreparedStatement st = null;
try {
for ( final String path : playlistFile.getPaths() ) {
final String sql = Track.getSelectFromSql() +
" where t.path = ? ";
st = db.prepare( sql );
st.setString( 1, path );
rs = st.executeQuery();
if ( rs.next() ) {
tracks.add( Track.createFromResultSet(rs) );
}
}
}
finally {
Utils.close( rs );
Utils.close( st );
}
return tracks.toArray( new Track[]{} );
}
/**
* returns a newName to use for the playlist. this will be the filename
* without the extension, and a number added on to the end if there
* are duplicates in the database already (eg. "playlist (2)")
*
* @param file
*
* @return
*
*/
protected String getPlaylistName( final File file ) throws SQLException {
ResultSet rs = null;
PreparedStatement st = null;
try {
String newName = file.getName();
// remove extension
newName = newName.substring( 0, newName.indexOf(".") );
final String sql = " select p.name " +
" from playlists p ";
st = db.prepare( sql );
rs = st.executeQuery();
int clashes = 0;
while ( rs.next() ) {
final String name = rs.getString( "name" );
if ( name.equals(newName) || name.matches("^" +newName+ " \\(\\d+\\)") )
clashes++;
}
if ( clashes > 0 )
newName += " (" +clashes+ ")";
return newName;
}
finally {
Utils.close( rs );
Utils.close( st );
}
}
}