Refactored some code to more sensible locations.

Made IDatabase abstract rather than an interface and self referential for implemented methods.
This commit is contained in:
neviyn 2016-08-25 21:32:52 +01:00
parent 12a9af2ba3
commit 82d393d3b5
23 changed files with 241 additions and 224 deletions

12
pom.xml
View File

@ -134,9 +134,15 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>log4j-core</artifactId>
<version>1.7.21</version> <version>2.6.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.6.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -4,7 +4,7 @@ import musicplayer.model.Song;
public class StartPlayingException extends Exception { public class StartPlayingException extends Exception {
private Song song; private final Song song;
public StartPlayingException(Song song){ public StartPlayingException(Song song){
this.song = song; this.song = song;

View File

@ -1,20 +0,0 @@
package musicplayer.callbacks;
public interface LibraryCallbackInterface {
/**
* Call this after performing library updates so the front-end knows that updating has completed.
* @param message Error message.
*/
void libraryUpdated(String message);
/**
* Call this after performing library updates so the front-end knows that updating has completed.
*/
void libraryUpdated();
/**
* Update the current display with the file/folder currently being parsed.
* @param name Data about the file/folder to be shown to the user.
*/
void currentlyUpdating(String name);
}

View File

@ -2,7 +2,6 @@ package musicplayer.db;
import musicplayer.util.ConfigManager; import musicplayer.util.ConfigManager;
import musicplayer.model.*; import musicplayer.model.*;
import org.hibernate.Criteria;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
@ -20,7 +19,7 @@ import java.util.Properties;
/** /**
* Class for managing connection to Hibernate. * Class for managing connection to Hibernate.
*/ */
public class HibernateDatabase implements IDatabase{ public class HibernateDatabase extends IDatabase{
private SessionFactory sessionFactory; private SessionFactory sessionFactory;

View File

@ -1,16 +1,48 @@
package musicplayer.db; package musicplayer.db;
import musicplayer.library.ILibrary;
import musicplayer.model.*; import musicplayer.model.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
public interface IDatabase { public abstract class IDatabase {
Optional<Album> getOneAlbum(String name); abstract public Optional<Album> getOneAlbum(String name);
Optional<Artist> getOneArtist(String name); abstract public Optional<Artist> getOneArtist(String name);
Optional<Song> getOneSong(ExtractedMetadata metadata); abstract public Optional<Song> getOneSong(ExtractedMetadata metadata);
void batchDeleteNot(Long[] validIds); abstract public void batchDeleteNot(Long[] validIds);
<T extends IDBType> Optional<List<T>> listAllT(Class<T> typeClass); abstract public <T extends IDBType> Optional<List<T>> listAllT(Class<T> typeClass);
Song addSong(ExtractedMetadata metadata); abstract public Song addSong(ExtractedMetadata metadata);
void addSong(Song song); abstract public void addSong(Song song);
private static String musicFileExtensionRegex = "(?iu).*\\.(mp3|mp4|flac|ogg)";
/**
* Add all songs contained with all paths in rootDirectory to the database.
* @param rootDirectory Folder(s) containing music files to index.
*/
public void processSongsWithCallback(ILibrary library, List<Path> rootDirectory){
rootDirectory.forEach(dir -> {
try {
Set<Long> seenIds = new HashSet<>();
Files.walk(dir)
.filter(f -> f.toString().matches(musicFileExtensionRegex)).map(ExtractedMetadata::autoParse)
.forEach(x -> x.ifPresent(i -> {
Song song = addSong(i);
seenIds.add(song.getId());
library.currentlyUpdating(i.toString());
}));
batchDeleteNot(seenIds.toArray(new Long[seenIds.size()]));
} catch (IOException e) {
library.libraryUpdateFailed(e.getMessage());
}
});
library.libraryUpdated();
}
} }

View File

@ -1,73 +1,33 @@
package musicplayer.library; package musicplayer.library;
import musicplayer.callbacks.LibraryCallbackInterface;
import musicplayer.db.IDatabase; import musicplayer.db.IDatabase;
import musicplayer.model.ExtractedMetadata;
import musicplayer.model.HasSongs; import musicplayer.model.HasSongs;
import musicplayer.model.Song;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagException;
import java.io.IOException; public abstract class ILibrary {
import java.nio.file.Files; IDatabase database;
import java.nio.file.Path; abstract public void showSongs();
import java.util.HashSet; abstract public <T extends HasSongs & Comparable<T>> void showGroupedSongs(Class<T> grouping);
import java.util.List; abstract public void updateLibrary();
import java.util.Optional; abstract public void refreshLibrary();
import java.util.Set;
public interface ILibrary { public ILibrary(IDatabase database){
void showSongs(); this.database = database;
<T extends HasSongs & Comparable<T>> void showGroupedSongs(Class<T> grouping);
void updateLibrary();
void refreshLibrary();
String musicFileExtensionRegex = "(?iu).*\\.(mp3|mp4|flac|ogg)";
/**
* Add all songs contained with all paths in rootDirectory to the database.
* @param rootDirectory Folder(s) containing music files to index.
* @param callbackInterface Object to send callback data to, set to null if the application doesn't require update data.
*/
static void processSongsWithCallback(IDatabase database, List<Path> rootDirectory, LibraryCallbackInterface callbackInterface){
boolean callbacksEnabled = callbackInterface != null;
rootDirectory.forEach(dir -> {
try {
Set<Long> seenIds = new HashSet<>();
Files.walk(dir)
.filter(f -> f.toString().matches(musicFileExtensionRegex)).map(ILibrary::autoParse)
.forEach(x -> x.ifPresent(i -> {
Song song = database.addSong(i);
seenIds.add(song.getId());
if (callbacksEnabled)
callbackInterface.currentlyUpdating(i.toString());
}));
database.batchDeleteNot(seenIds.toArray(new Long[seenIds.size()]));
} catch (IOException e) {
if(callbacksEnabled)
callbackInterface.libraryUpdated(e.getMessage());
}
});
if(callbacksEnabled)
callbackInterface.libraryUpdated();
} }
/** /**
* Extract music metadata from the target file. * The library was updated but there was an error (partial update may have occurred).
* * @param message Error message.
* @param targetFile Path to file to extract metadata from.
* @return Metadata contained in targetFile.
*/ */
static Optional<ExtractedMetadata> autoParse(Path targetFile) { abstract public void libraryUpdateFailed(String message);
Tag audioTags = null;
try { /**
audioTags = AudioFileIO.read(targetFile.toFile()).getTag(); * Library updated successfully.
} catch (CannotReadException | IOException | ReadOnlyFileException | TagException | InvalidAudioFrameException ignored) { */
} abstract public void libraryUpdated();
return audioTags == null ? Optional.empty() : Optional.of(new ExtractedMetadata(audioTags, targetFile.toFile()));
} /**
* Show data on the current update item being indexed.
* @param name Data about the file/folder to be shown to the user.
*/
abstract public void currentlyUpdating(String name);
} }

View File

@ -2,7 +2,6 @@ package musicplayer.library;
import com.google.inject.Inject; import com.google.inject.Inject;
import musicplayer.util.ConfigManager; import musicplayer.util.ConfigManager;
import musicplayer.callbacks.LibraryCallbackInterface;
import musicplayer.db.IDatabase; import musicplayer.db.IDatabase;
import musicplayer.model.Album; import musicplayer.model.Album;
import musicplayer.model.Artist; import musicplayer.model.Artist;
@ -31,10 +30,9 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class JTreeLibrary extends JPanel implements ILibrary, LibraryCallbackInterface{ public class JTreeLibrary extends ILibrary{
private IDatabase database; private final IPlaylist playlist;
private IPlaylist playlist;
static final DefaultMutableTreeNode updatingNode = new DefaultMutableTreeNode(); static final DefaultMutableTreeNode updatingNode = new DefaultMutableTreeNode();
private final AtomicBoolean libraryUpdating = new AtomicBoolean(false); private final AtomicBoolean libraryUpdating = new AtomicBoolean(false);
private final JComboBox<String> libraryDisplayType = new JComboBox<>(); private final JComboBox<String> libraryDisplayType = new JComboBox<>();
@ -44,6 +42,8 @@ public class JTreeLibrary extends JPanel implements ILibrary, LibraryCallbackInt
private final static Map<Long, ImageIcon> albumArt = new ConcurrentHashMap<>(); private final static Map<Long, ImageIcon> albumArt = new ConcurrentHashMap<>();
private ExecutorService albumArtCollectorPool; private ExecutorService albumArtCollectorPool;
private final JPanel libraryPanel = new JPanel();
/** /**
* @return Map of display types for the library paired code to populate the library with data in the correct format. * @return Map of display types for the library paired code to populate the library with data in the correct format.
*/ */
@ -57,16 +57,16 @@ public class JTreeLibrary extends JPanel implements ILibrary, LibraryCallbackInt
@Inject @Inject
public JTreeLibrary(IDatabase database, IPlaylist playlist){ public JTreeLibrary(IDatabase database, IPlaylist playlist){
this.database = database; super(database);
this.playlist = playlist; this.playlist = playlist;
this.setLayout(new BorderLayout(0, 0)); libraryPanel.setLayout(new BorderLayout(0, 0));
libraryTree.setRootVisible(false); libraryTree.setRootVisible(false);
libraryTree.setToggleClickCount(1); libraryTree.setToggleClickCount(1);
libraryTree.setCellRenderer(new LibraryTreeCellRenderer()); libraryTree.setCellRenderer(new LibraryTreeCellRenderer());
libraryTree.addMouseListener(new LibraryMouseAdapter()); libraryTree.addMouseListener(new LibraryMouseAdapter());
libraryTree.setScrollsOnExpand(false); libraryTree.setScrollsOnExpand(false);
final JScrollPane libraryPane = new JScrollPane(libraryTree); final JScrollPane libraryPane = new JScrollPane(libraryTree);
this.add(libraryPane, BorderLayout.CENTER); libraryPanel.add(libraryPane, BorderLayout.CENTER);
libraryDisplayVariants.keySet().forEach(libraryDisplayType::addItem); libraryDisplayVariants.keySet().forEach(libraryDisplayType::addItem);
libraryDisplayType.setSelectedIndex(ConfigManager.getLastDisplayTypeIndex()); libraryDisplayType.setSelectedIndex(ConfigManager.getLastDisplayTypeIndex());
@ -83,10 +83,17 @@ public class JTreeLibrary extends JPanel implements ILibrary, LibraryCallbackInt
otherContainer.setLayout(new BoxLayout(otherContainer, BoxLayout.PAGE_AXIS)); otherContainer.setLayout(new BoxLayout(otherContainer, BoxLayout.PAGE_AXIS));
otherContainer.add(libraryDisplayType); otherContainer.add(libraryDisplayType);
otherContainer.add(librarySearchField); otherContainer.add(librarySearchField);
this.add(otherContainer, BorderLayout.NORTH); libraryPanel.add(otherContainer, BorderLayout.NORTH);
getAlbumArt(); getAlbumArt();
} }
/**
* @return JPanel showing this library.
*/
public JPanel getLibraryPanel(){
return libraryPanel;
}
/** /**
* Add an item to libraryView. * Add an item to libraryView.
* *
@ -170,7 +177,7 @@ public class JTreeLibrary extends JPanel implements ILibrary, LibraryCallbackInt
addNodeToTreeModel(model, parentNode, updatingNode); addNodeToTreeModel(model, parentNode, updatingNode);
libraryTree.setModel(model); libraryTree.setModel(model);
List<Path> dirs = ConfigManager.getLibraryDirectories().stream().map(File::toPath).collect(Collectors.toList()); List<Path> dirs = ConfigManager.getLibraryDirectories().stream().map(File::toPath).collect(Collectors.toList());
Thread updaterThread = new Thread(() -> ILibrary.processSongsWithCallback(database, dirs, this), "updater"); Thread updaterThread = new Thread(() -> database.processSongsWithCallback(this, dirs), "updater");
updaterThread.start(); updaterThread.start();
} }
} }
@ -205,8 +212,8 @@ public class JTreeLibrary extends JPanel implements ILibrary, LibraryCallbackInt
* @param message Error message. * @param message Error message.
*/ */
@Override @Override
public void libraryUpdated(String message) { public void libraryUpdateFailed(String message) {
JOptionPane.showMessageDialog(this, message, "Update Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(libraryPanel, message, "Update Error", JOptionPane.ERROR_MESSAGE);
libraryUpdated(); libraryUpdated();
} }

View File

@ -90,6 +90,7 @@ public class Album implements Comparable<Album>, IDBType, HasSongs {
* Get album art for a given album. * Get album art for a given album.
* @return Album art. * @return Album art.
*/ */
@Transient
public Optional<ImageIcon> getAlbumArt(){ public Optional<ImageIcon> getAlbumArt(){
Tag audioTags; Tag audioTags;
File targetFile = songs.iterator().next().getSongFile(); File targetFile = songs.iterator().next().getSongFile();

View File

@ -1,16 +1,24 @@
package musicplayer.model; package musicplayer.model;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.tag.FieldKey; import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag; import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagException;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
/** /**
* Internal class representing metadata extracted from a music file. * Internal class representing metadata extracted from a music file.
*/ */
public class ExtractedMetadata { public class ExtractedMetadata {
private final Tag audioTags; private final Tag audioTags;
private String songFile; private final String songFile;
/** /**
* @param audioTags jaudiotagger tag data. * @param audioTags jaudiotagger tag data.
@ -37,4 +45,19 @@ public class ExtractedMetadata {
@Override @Override
public String toString() { return getTitle()+ " - " + getArtist(); } public String toString() { return getTitle()+ " - " + getArtist(); }
/**
* Extract music metadata from the target file.
*
* @param targetFile Path to file to extract metadata from.
* @return Metadata contained in targetFile.
*/
public static Optional<ExtractedMetadata> autoParse(Path targetFile) {
Tag audioTags = null;
try {
audioTags = AudioFileIO.read(targetFile.toFile()).getTag();
} catch (CannotReadException | IOException | ReadOnlyFileException | TagException | InvalidAudioFrameException ignored) {
}
return audioTags == null ? Optional.empty() : Optional.of(new ExtractedMetadata(audioTags, targetFile.toFile()));
}
} }

View File

@ -150,7 +150,7 @@ public class GStreamerPlayer implements IPlayer{
if (this.thread != null) { if (this.thread != null) {
playBin.stop(); playBin.stop();
internalThread.stop(); internalThread.stop();
thread = null; thread.interrupt();
resetSeek(); resetSeek();
playlist.setStopped(); playlist.setStopped();
} }

View File

@ -18,8 +18,8 @@ import java.util.Optional;
public class VLCPlayer implements IPlayer { public class VLCPlayer implements IPlayer {
private ArrayList<String> libvlcArgs = new ArrayList<>(Collections.singletonList("--vout=dummy")); private final ArrayList<String> libvlcArgs = new ArrayList<>(Collections.singletonList("--vout=dummy"));
private MediaPlayer mediaPlayer; private final MediaPlayer mediaPlayer;
private Song currentSong; private Song currentSong;
private final PlayerCallbackInterface callbackInterface; private final PlayerCallbackInterface callbackInterface;

View File

@ -1,8 +1,8 @@
package musicplayer.playlist; package musicplayer.playlist;
import musicplayer.library.ILibrary;
import musicplayer.model.Album; import musicplayer.model.Album;
import musicplayer.model.Artist; import musicplayer.model.Artist;
import musicplayer.model.ExtractedMetadata;
import musicplayer.model.Song; import musicplayer.model.Song;
import java.io.*; import java.io.*;
@ -38,15 +38,15 @@ public interface IPlaylist {
* @throws IOException * @throws IOException
*/ */
static void writePlaylistToFile(List<Song> playlist, File targetFile) throws IOException { static void writePlaylistToFile(List<Song> playlist, File targetFile) throws IOException {
if(!targetFile.exists()) if(targetFile.exists() || targetFile.createNewFile()) {
targetFile.createNewFile();
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "utf-8"))) { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "utf-8"))) {
writer.write("#EXTM3U\n"); writer.write("#EXTM3U\n");
for(Song song : playlist){ for (Song song : playlist) {
writer.write(song.getM3UFormatString()); writer.write(song.getM3UFormatString());
} }
} }
} }
}
/** /**
* Read songs in from an m3u playlist. * Read songs in from an m3u playlist.
@ -67,7 +67,7 @@ public interface IPlaylist {
songPaths.set(i, Paths.get(targetFile.getParent(), songPaths.get(i).toString())); songPaths.set(i, Paths.get(targetFile.getParent(), songPaths.get(i).toString()));
} }
} }
songPaths.stream().map(ILibrary::autoParse).filter(Optional::isPresent).map(Optional::get) songPaths.stream().map(ExtractedMetadata::autoParse).filter(Optional::isPresent).map(Optional::get)
.forEach(x -> result.add(new Song(x.getTrackNumber(), x.getDiscNumber(), x.getTitle(), new Artist(x.getArtist()), new Album(x.getAlbum()), x.getGenre(), x.getSongFile()))); .forEach(x -> result.add(new Song(x.getTrackNumber(), x.getDiscNumber(), x.getTitle(), new Artist(x.getArtist()), new Album(x.getAlbum()), x.getGenre(), x.getSongFile())));
} }
} catch (IOException ignored) { } } catch (IOException ignored) { }

View File

@ -133,7 +133,7 @@ public class JTablePlaylist extends JScrollPane implements IPlaylist {
private class PlaylistTableModel extends AbstractTableModel { private class PlaylistTableModel extends AbstractTableModel {
private List<Song> songList = new ArrayList<>(); private final List<Song> songList = new ArrayList<>();
private int playingRow = -1; // -1 means no song is currently playing. private int playingRow = -1; // -1 means no song is currently playing.
public PlaylistTableModel(){ } public PlaylistTableModel(){ }

View File

@ -7,8 +7,8 @@ import musicplayer.util.Icons;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
public class ControlBar extends JPanel { class ControlBar extends JPanel {
IPlayer player; private final IPlayer player;
public ControlBar(IPlayer player){ public ControlBar(IPlayer player){
this.player = player; this.player = player;

View File

@ -4,6 +4,7 @@ import com.google.inject.Inject;
import musicplayer.StartPlayingException; import musicplayer.StartPlayingException;
import musicplayer.callbacks.PlayerCallbackInterface; import musicplayer.callbacks.PlayerCallbackInterface;
import musicplayer.library.ILibrary; import musicplayer.library.ILibrary;
import musicplayer.library.JTreeLibrary;
import musicplayer.player.IPlayer; import musicplayer.player.IPlayer;
import musicplayer.playlist.IPlaylist; import musicplayer.playlist.IPlaylist;
import musicplayer.util.ConfigManager; import musicplayer.util.ConfigManager;
@ -115,7 +116,7 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
libraryAndPlaylistPane.setDividerLocation(240); libraryAndPlaylistPane.setDividerLocation(240);
libraryAndPlaylistPane.setRightComponent((JScrollPane) playlist); libraryAndPlaylistPane.setRightComponent((JScrollPane) playlist);
this.add(libraryAndPlaylistPane, BorderLayout.CENTER); this.add(libraryAndPlaylistPane, BorderLayout.CENTER);
libraryAndPlaylistPane.setLeftComponent((JPanel) library); libraryAndPlaylistPane.setLeftComponent(((JTreeLibrary)library).getLibraryPanel());
final JPanel controlPane = new JPanel(); final JPanel controlPane = new JPanel();
controlPane.setLayout(new BorderLayout(0, 0)); controlPane.setLayout(new BorderLayout(0, 0));
this.add(controlPane, BorderLayout.SOUTH); this.add(controlPane, BorderLayout.SOUTH);

View File

@ -1,9 +1,7 @@
package musicplayer.db; package musicplayer.db;
import musicplayer.model.Album; import musicplayer.library.ILibrary;
import musicplayer.model.Artist; import musicplayer.model.*;
import musicplayer.model.ExtractedMetadata;
import musicplayer.model.Song;
import org.jaudiotagger.tag.FieldKey; import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag; import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.id3.ID3v23Tag; import org.jaudiotagger.tag.id3.ID3v23Tag;
@ -11,6 +9,8 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.File; import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -216,4 +216,47 @@ public class HibernateDatabaseTest {
assertTrue(db.contains(song2)); assertTrue(db.contains(song2));
assertFalse(db.contains(song3)); assertFalse(db.contains(song3));
} }
@Test
public void testProcessSongsWithCallback() throws Exception {
Path dir = new File(HibernateDatabaseTest.class.getResource("/sample.mp3").getFile()).getParentFile().toPath();
List<Path> dirList = new ArrayList<>();
dirList.add(dir);
FakeLibrary library = new FakeLibrary(database);
database.processSongsWithCallback(library, dirList);
assertEquals(1, database.listAllT(Song.class).get().size());
assertTrue(library.success);
assertFalse(library.failed);
}
private class FakeLibrary extends ILibrary{
public boolean success = false;
public boolean failed = false;
public FakeLibrary(IDatabase database) {
super(database);
}
@Override
public void showSongs() {}
@Override
public <T extends HasSongs & Comparable<T>> void showGroupedSongs(Class<T> grouping) {}
@Override
public void updateLibrary() {}
@Override
public void refreshLibrary() {}
@Override
public void libraryUpdateFailed(String message) { failed = true;}
@Override
public void libraryUpdated() { success = true;}
@Override
public void currentlyUpdating(String name) {}
}
} }

View File

@ -1,79 +0,0 @@
package musicplayer.library;
import musicplayer.callbacks.LibraryCallbackInterface;
import musicplayer.db.HibernateDatabase;
import musicplayer.db.IDatabase;
import musicplayer.model.ExtractedMetadata;
import musicplayer.model.Song;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag;
import org.junit.Test;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.*;
public class ILibraryTest {
@Test
public void testAutoParse() throws Exception {
File inputFile = new File(ILibraryTest.class.getResource("/sample.mp3").getFile());
Optional<ExtractedMetadata> data = ILibrary.autoParse(inputFile.toPath());
Tag audioTags = AudioFileIO.read(inputFile).getTag();
assertTrue(data.isPresent());
ExtractedMetadata internal = data.get();
assertEquals(audioTags.getFirst(FieldKey.ARTIST), internal.getArtist());
assertEquals(audioTags.getFirst(FieldKey.GENRE), internal.getGenre());
assertEquals(audioTags.getFirst(FieldKey.TITLE), internal.getTitle());
assertEquals(audioTags.getFirst(FieldKey.ALBUM), internal.getAlbum());
assertEquals(audioTags.getFirst(FieldKey.TRACK), internal.getTrackNumber());
assertEquals(audioTags.getFirst(FieldKey.DISC_NO), internal.getDiscNumber());
assertEquals(inputFile.getPath(), internal.getSongFile());
}
@Test
public void testAutoParseInvalidFile() throws Exception {
File inputFile = new File("");
Optional<ExtractedMetadata> data = ILibrary.autoParse(inputFile.toPath());
assertFalse(data.isPresent());
}
@Test
public void testProcessSongsWithCallback() throws Exception {
CallbackInterface callbackInterface = new CallbackInterface();
Path dir = new File(ILibraryTest.class.getResource("/sample.mp3").getFile()).getParentFile().toPath();
List<Path> dirList = new ArrayList<>();
dirList.add(dir);
IDatabase database = new HibernateDatabase(true);
ILibrary.processSongsWithCallback(database, dirList, callbackInterface);
assertEquals(1, database.listAllT(Song.class).get().size());
assertTrue(callbackInterface.status);
assertFalse(callbackInterface.error);
}
private class CallbackInterface implements LibraryCallbackInterface{
public boolean status = false;
public String update = "";
public boolean error = false;
@Override
public void libraryUpdated(String message) {
error = true;
}
@Override
public void libraryUpdated() {
status = true;
}
@Override
public void currentlyUpdating(String name) {
update = name;
}
}
}

View File

@ -4,6 +4,7 @@ import musicplayer.db.HibernateDatabase;
import musicplayer.db.IDatabase; import musicplayer.db.IDatabase;
import musicplayer.model.Album; import musicplayer.model.Album;
import musicplayer.model.Artist; import musicplayer.model.Artist;
import musicplayer.model.ExtractedMetadata;
import musicplayer.model.Song; import musicplayer.model.Song;
import musicplayer.playlist.IPlaylist; import musicplayer.playlist.IPlaylist;
import musicplayer.playlist.JTablePlaylist; import musicplayer.playlist.JTablePlaylist;
@ -12,18 +13,21 @@ import org.junit.Test;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import java.io.File; import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class JTreeLibraryTest { public class JTreeLibraryTest {
JTreeLibrary library; private JTreeLibrary library;
Song sampleSong = new Song(ILibrary.autoParse( private final Song sampleSong = new Song(ExtractedMetadata.autoParse(
new File(JTreeLibraryTest.class.getResource("/sample.mp3").getFile()).toPath()).get()); new File(JTreeLibraryTest.class.getResource("/sample.mp3").getFile()).toPath()).get());
IDatabase database; private IDatabase database;
@Before @Before
public void setUp() throws Exception { public void setUp() {
database = new HibernateDatabase(true); database = new HibernateDatabase(true);
IPlaylist playlist = new JTablePlaylist(); IPlaylist playlist = new JTablePlaylist();
library = new JTreeLibrary(database, playlist); library = new JTreeLibrary(database, playlist);
@ -85,6 +89,6 @@ public class JTreeLibraryTest {
public void testCurrentlyUpdating() throws Exception { public void testCurrentlyUpdating() throws Exception {
String updateText = "Test String"; String updateText = "Test String";
library.currentlyUpdating("Test String"); library.currentlyUpdating("Test String");
assertEquals(updateText, library.updatingNode.getUserObject()); assertEquals(updateText, JTreeLibrary.updatingNode.getUserObject());
} }
} }

View File

@ -0,0 +1,38 @@
package musicplayer.model;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag;
import org.junit.Test;
import java.io.File;
import java.util.Optional;
import static org.junit.Assert.*;
public class ExtractedMetadataTest {
@Test
public void testAutoParse() throws Exception {
File inputFile = new File(ExtractedMetadataTest.class.getResource("/sample.mp3").getFile());
Optional<ExtractedMetadata> data = ExtractedMetadata.autoParse(inputFile.toPath());
Tag audioTags = AudioFileIO.read(inputFile).getTag();
assertTrue(data.isPresent());
ExtractedMetadata internal = data.get();
assertEquals(audioTags.getFirst(FieldKey.ARTIST), internal.getArtist());
assertEquals(audioTags.getFirst(FieldKey.GENRE), internal.getGenre());
assertEquals(audioTags.getFirst(FieldKey.TITLE), internal.getTitle());
assertEquals(audioTags.getFirst(FieldKey.ALBUM), internal.getAlbum());
assertEquals(audioTags.getFirst(FieldKey.TRACK), internal.getTrackNumber());
assertEquals(audioTags.getFirst(FieldKey.DISC_NO), internal.getDiscNumber());
assertEquals(inputFile.getPath(), internal.getSongFile());
}
@Test
public void testAutoParseInvalidFile() throws Exception {
File inputFile = new File("");
Optional<ExtractedMetadata> data = ExtractedMetadata.autoParse(inputFile.toPath());
assertFalse(data.isPresent());
}
}

View File

@ -1,6 +1,7 @@
package musicplayer.player; package musicplayer.player;
import musicplayer.library.ILibrary; import musicplayer.library.ILibrary;
import musicplayer.model.ExtractedMetadata;
import musicplayer.model.Song; import musicplayer.model.Song;
import musicplayer.playlist.IPlaylist; import musicplayer.playlist.IPlaylist;
import musicplayer.playlist.JTablePlaylist; import musicplayer.playlist.JTablePlaylist;
@ -15,13 +16,13 @@ import static org.junit.Assert.*;
public class GStreamerPlayerTest { public class GStreamerPlayerTest {
GStreamerPlayer player; private GStreamerPlayer player;
IPlaylist playlist; private IPlaylist playlist;
Song sampleSong = new Song(ILibrary.autoParse( private final Song sampleSong = new Song(ExtractedMetadata.autoParse(
new File(GStreamerPlayerTest.class.getResource("/sample.mp3").getFile()).toPath()).get()); new File(GStreamerPlayerTest.class.getResource("/sample.mp3").getFile()).toPath()).get());
@Before @Before
public void setUp() throws Exception { public void setUp() {
playlist = new JTablePlaylist(); playlist = new JTablePlaylist();
player = new GStreamerPlayer(null, playlist, true); player = new GStreamerPlayer(null, playlist, true);
} }

View File

@ -1,10 +1,10 @@
package musicplayer.player; package musicplayer.player;
import musicplayer.library.ILibrary; import musicplayer.library.ILibrary;
import musicplayer.model.ExtractedMetadata;
import musicplayer.model.Song; import musicplayer.model.Song;
import musicplayer.playlist.IPlaylist; import musicplayer.playlist.IPlaylist;
import musicplayer.playlist.JTablePlaylist; import musicplayer.playlist.JTablePlaylist;
import musicplayer.util.ConfigManager;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -15,13 +15,13 @@ import static org.junit.Assert.*;
public class VLCPlayerTest { public class VLCPlayerTest {
VLCPlayer player; private VLCPlayer player;
IPlaylist playlist; private IPlaylist playlist;
Song sampleSong = new Song(ILibrary.autoParse( private final Song sampleSong = new Song(ExtractedMetadata.autoParse(
new File(VLCPlayerTest.class.getResource("/sample.mp3").getFile()).toPath()).get()); new File(VLCPlayerTest.class.getResource("/sample.mp3").getFile()).toPath()).get());
@Before @Before
public void setUp() throws Exception { public void setUp() {
playlist = new JTablePlaylist(); playlist = new JTablePlaylist();
player = new VLCPlayer(null, playlist, true); player = new VLCPlayer(null, playlist, true);
} }

View File

@ -1,6 +1,6 @@
package musicplayer.playlist; package musicplayer.playlist;
import musicplayer.library.ILibrary; import musicplayer.model.ExtractedMetadata;
import musicplayer.model.Song; import musicplayer.model.Song;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -19,12 +19,13 @@ public class IPlaylistTest {
@Test @Test
public void testWriteAndReadPlaylist() throws Exception { public void testWriteAndReadPlaylist() throws Exception {
Song sampleSong = new Song(ILibrary.autoParse( Song sampleSong = new Song(ExtractedMetadata.autoParse(
new File(IPlaylistTest.class.getResource("/sample.mp3").getFile()).toPath()).get()); new File(IPlaylistTest.class.getResource("/sample.mp3").getFile()).toPath()).get());
File playlistFile = folder.newFile(); File playlistFile = folder.newFile();
List<Song> playlist = new ArrayList<>(); List<Song> playlist = new ArrayList<>();
playlist.add(sampleSong); playlist.add(sampleSong);
IPlaylist.writePlaylistToFile(playlist, playlistFile); IPlaylist.writePlaylistToFile(playlist, playlistFile);
assertTrue(playlistFile.exists());
List<Song> result = IPlaylist.readPlaylistFromFile(playlistFile); List<Song> result = IPlaylist.readPlaylistFromFile(playlistFile);
assertEquals(sampleSong, result.get(0)); assertEquals(sampleSong, result.get(0));
} }

View File

@ -14,8 +14,8 @@ import static org.junit.Assert.*;
public class JTablePlaylistTest { public class JTablePlaylistTest {
JTablePlaylist playlist; private JTablePlaylist playlist;
JTable innerTable; private JTable innerTable;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {