/**
*
*/
package controller;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import model.Track;
/**
* holt Tracks aus TrackToDBQueue und schreibt sie in die datenbank
*
* @author Artur Dawtjan
*
*/
public class TracktoDBwriter implements Runnable, ActionListener{
TrackToDBQueue queue;
JProgressBar progressBar;
JDialog progressDialog;
boolean abrot = false;
JLabel progressLabel;
/*
* für die db-performance: beim durchsuchen bereits gefundene artists/albums
* werden hier als id abgelegt.
*/
//Map<String, Integer> foundArtists = new HashMap<String, Integer>();
// artistID, string[]albumnames
//Map<Integer, ArrayList<String>> foundAlbums = new HashMap<Integer, ArrayList<String>>();
// Map<String, Integer> albums = new HashMap<String, Integer>();//
private PreparedStatement addArtist;
private PreparedStatement addAlbum;
private PreparedStatement findArtist;
private PreparedStatement findAlbum;
private PreparedStatement addTrack;
public TracktoDBwriter(TrackToDBQueue q) {
progressDialog = new JDialog(PhoenixCore.INSTANCE.getCurrentGUI());
progressDialog.setTitle("Importieren läuft...");
progressDialog.getContentPane().setLayout(new BorderLayout());
progressLabel = new JLabel("Importieren wird initialisiert...");
progressBar = new JProgressBar();
progressBar.setSize(700, 40);
progressBar.setMinimum(0);
progressDialog.getContentPane().add(progressBar, BorderLayout.NORTH);
JButton abrotBtn = new JButton("Abbrechen!");
abrotBtn.addActionListener(this);
progressDialog.getContentPane().add(progressLabel, BorderLayout.CENTER);
progressDialog.getContentPane().add(abrotBtn, BorderLayout.SOUTH);
progressDialog.setMinimumSize(new Dimension(300, 100));
Rectangle r = progressDialog.getOwner().getBounds();
int x = r.x + (r.width - progressDialog.getSize().width)/2;
int y = r.y + (r.height - progressDialog.getSize().height)/2;
progressDialog.setLocation(x, y);
progressDialog.setResizable(false);
queue = q;
try {
addAlbum = PhoenixCore.DBCON.prepareOnLib("insert into albums (name, id, artist) values (?, NULL, ?)");
addArtist = PhoenixCore.DBCON.prepareOnLib("insert into artists (name, id) values (?, NULL)");
addTrack = PhoenixCore.DBCON.prepareOnLib("insert into tracks (id, name, album, track, genre, path, checked, length)" +
" values (NULL, ?, ?, ?, ?, ?, 1,?)");
findAlbum = PhoenixCore.DBCON.prepareOnLib("SELECT id from albums where name=? and artist=?");
findArtist = PhoenixCore.DBCON.prepareOnLib("SELECT id from artists where name=?");
} catch (SQLException e) {
e.printStackTrace();
}
}
public void run() {
Track t;
int trackCount=0;
try {
// timer, da erst gepollt wird und producer nicht
// so schnell eins insertet.
progressBar.setIndeterminate(true);
progressDialog.setVisible(true);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.setIndeterminate(false);
abrot = false;
while (!abrot && (queue.hasFinnished() ? (queue.size()>0 ? true : false):true)) { // solange die queue abarbeiten
progressBar.setMaximum(trackCount+queue.size());
progressLabel.setText(trackCount+" von "+(trackCount+queue.size())+" Tracks geschrieben");
progressBar.setValue(trackCount);
t = queue.poll();
if (t == null){ // bis ein null ankommt
try {
Thread.sleep(2000); //dem folderImporter zeit lassen, falls er mit dem nachbefuellen der queue nicht hinterherkommt
} catch (InterruptedException e) {
e.printStackTrace();
}
continue;
}
// ######-Abarbeitung-#######
int artistID = insertArtist(t.getArtistName());
int albumID = insertAlbum(t.getAlbumName(), artistID);
try {
insertTrack(artistID, albumID, t);
trackCount++;
} catch (SQLException e) {
e.printStackTrace();
}
}
progressDialog.setVisible(false);
progressLabel.setText("Importieren wird initialisiert...");
JOptionPane.showMessageDialog(null, "Es wurden "+trackCount+" Titel in die Datenbank hinzugefügt.");
PhoenixCore.INSTANCE.refreshLibrary();
// foundAlbums = null; // zum Abschuss
// foundArtists = null;// freigeben und
Runtime.getRuntime().gc(); // entsorgen
}
/**
* fuegt einen track zur DB hinzu.
* @param artistID
* @param albumID
* @param t
* @throws SQLException
*/
private void insertTrack(int artistID, int albumID, Track t) throws SQLException{
addTrack.setString(1, t.getTitle());
addTrack.setInt(2, albumID);
addTrack.setString(3, t.getTrack());
addTrack.setString(4, t.getGenre());
addTrack.setString(5, t.getPath().toFile().getAbsolutePath());
addTrack.setInt(6, t.getLength());
addTrack.executeUpdate();
}
/**
* fuegt den kuenstler zur db hinzu, falls dieser nicht schon drin ist.
*
* @return ID des kuenstlers
*/
private int insertArtist(String artName) {
// if (foundArtists.containsKey(artName)
// &&(artName!=null&&!artName.equals("")&&!artName.equals("NULL"))) { // vllt schon in map?(null könnte alles sein!!)
// return foundArtists.get(artName);
// }
int id = 0; // schade, dann eben so:
try {
findArtist.setString(1, artName);
ResultSet rs = findArtist.executeQuery();// in db vorhanden?
if (rs.next()) {
id = rs.getInt("id"); // super, also zurückgeben.
// foundArtists.put(artName, id);
} else {
rs.close();
addArtist.setString(1, artName);// nicht in der DB, also einfügen
addArtist.executeUpdate();
ResultSet tmp = addArtist.getGeneratedKeys();// und erzeugte id zurückgeben.
tmp.next();
id=tmp.getInt(1);
tmp.close();
// foundArtists.put(artName, id);
}
// foundAlbums.put(id, new ArrayList<String>());
} catch (SQLException e) {
e.printStackTrace();
}
return id;
}
/**
* fuegt album zur DB hinzu, falls nicht schon vorhanden.
*
* @param album
* @param artistID
* @return id des Albums
*/
private int insertAlbum(String album, int artistID) {
// if (albums.containsKey(album) &&
// foundAlbums.get(artistID).contains(album)) { // vllt schon in map?
// return albums.get(album);
// }else foundAlbums.get(artistID).add(album);
int id = 0; // schade, dann eben so:
try {
findAlbum.setString(1, album);
findAlbum.setInt(2, artistID);
ResultSet rs = findAlbum.executeQuery(); // in db vorhanden?
if (rs.next()) {
id = rs.getInt("id"); // super, also zurückgeben.
// albums.put(album, id);
} else {
rs.close();
addAlbum.setString(1, album);
addAlbum.setInt(2, artistID);
addAlbum.executeUpdate();// nicht in der DB, also einfügen
ResultSet tmp = addArtist.getGeneratedKeys();// und erzeugte id zurückgeben.
tmp.next();
id=tmp.getInt(1);
tmp.close();
// albums.put(album, id);
}
} catch (SQLException e) {
e.printStackTrace();
}
return id;
}
/**
* abbruch des imports
*/
@Override
public void actionPerformed(ActionEvent e) {
this.abrot = true;
}
}