package us.jyg.freshet.util;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.farng.mp3.MP3File;
import org.farng.mp3.AbstractMP3Tag;
import org.farng.mp3.TagException;
import org.farng.mp3.id3.AbstractID3v2;
/**
* A SongData is a collection of information about an audio file. Most
* visibly it holds the title, album, artist and musical genre of
* the audio. Currently it is specific for MP3s.
* @author Jason Gabler
* @version 0.1
* @version 0.1
*/
public class SongData{
Log log = LogFactory.getLog(SongData.class);
private String title;
private String album;
private String artist;
private String genre;
private String path;
private int length;
private int track;
/**
* Construst a SongData from an MP3 at the given absolute path
* @param path the absolute path of the MP3
*/
public SongData( String path ) throws SongDataException {
this.path = tagPrep(path);
AbstractMP3Tag tag = null;
try {
MP3File mp3file = new MP3File(path);
if (mp3file.hasID3v2Tag()) {
tag = mp3file.getID3v2Tag();
} else if (mp3file.hasID3v1Tag()) {
tag = mp3file.getID3v1Tag();
} else {
throw new SongDataException( "No MP3 ID tag found for \""+path+"\"" );
}
} catch (TagException tE) {
throw new SongDataException( "(TagException) Broken MP3 ID tag found for \""+path+"\"" );
} catch (IOException ioE) {
log.warn("", ioE);
throw new SongDataException( "IOE for \""+path+"\"" );
}
try { //unfortunately jd3lib isn't perfect...grr...
title = tagPrep(tag.getSongTitle());
album = tagPrep(tag.getAlbumTitle());
artist = tagPrep(tag.getLeadArtist());
genre = tagPrep(tag.getSongGenre());
if (genre.length() > 1) { // ensure that genres do not have mutiples because of case
char firstChar = genre.toUpperCase().charAt(0);
genre = firstChar+genre.substring(1);
}
track = Integer.parseInt(tag.getTrackNumberOnAlbum());
} catch (NullPointerException npE) {
throw new SongDataException( "(NPE) Broken MP3 ID tag found for \""+path+"\"" );
} catch (NumberFormatException nfE) {
log.warn("No track number for " + title);
track = -1;
}
}
private String tagPrep(String tag) {
String prepd;
if (tag == null || "".equals(tag))
prepd = "<unspecified>";
else
prepd = tag;
// remove trailing spaces, ugh
prepd = prepd.replaceAll(" *$", "");
// remove genre id numbers, ugh (followed by a space or nothing)
prepd = prepd.replaceAll("^\\([0-9]+\\)( |) *", "");
// make sure its in the native encoding, or it'll lokos screwy on the web
Charset cs = Charset.defaultCharset();
prepd = new String(cs.encode(prepd).array());
// take out all non-printable characters, make the 'chooser' fail miserables.
// prepd = prepd.replaceAll("[^\\p{Print}]", "");
try {
prepd = new String(prepd.getBytes(), "UTF-8");
} catch (UnsupportedEncodingException ueE) {
log.error("UnsupportedEncodingException UTF-8");
}
prepd = prepd.replaceAll("\\x00","");
return prepd;
}
/**
* Construst a SongData from an MP3 at the given absolute path
*/
public SongData(File file ) throws SongDataException {
this(file.getAbsolutePath());
}
/**
* Construst a SongData from given information about an MP3 file
* @param path the absolute path of an MP3 file
* @param genre the genre of the music
* @param artist the artist of the music
* @param album the album from which the music comes
* @param title the title of the music
*/
public SongData(String path, String genre, String artist, String album, String title) {
this.path = tagPrep(path);
this.title = tagPrep(title);
this.album = tagPrep(album);
this.artist = tagPrep(artist);
this.genre = tagPrep(genre);
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getName() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getTrack() {
return track;
}
public void setTrack(int track) {
this.track = track;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public Log getLog() {
return log;
}
public void setLog(Log log) {
this.log = log;
}
public String getTitle() {
return title;
}
}