/*
Copyright (c) 2005, Dimitrios Kourtesis
This file is part of MusicURI.
MusicURI 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
(at your option) any later version.
MusicURI 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 MPEG7AudioEnc; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
*/
package it.univpm.deit.semedia.musicuri.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.thoughtworks.xstream.XStream;
/**
* @author Dimitrios Kourtesis
*/
public class MusicURIDatabase implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* A HashMap object containing pairs of an MD5 String as key and a MusicURIReference object as value
*/
private HashMap table;
/**
* The path to where the serialized HashMap database is located
*/
private String databasePath;
/**
* The database file name
*/
private String databaseFileName;
/**
* Constructs a MusicURIDatabase object by deserializing the HashMap specified by the path
* @param databasePath the path to the directory containing the db
* @param databaseFileName the filename of the serialized hashmap
*/
public MusicURIDatabase(String databasePath, String databaseFileName)
{
table = new HashMap();
this.databasePath = databasePath;
this.databaseFileName = databaseFileName;
try
{
table = (HashMap) deserialize(databasePath + databaseFileName);
//System.out.println(table.size() + " references loaded from " + databaseFileName);
}
catch (ClassNotFoundException e)
{
e.toString();
//System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
}
catch (InvalidClassException e)
{
e.toString();
//System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
}
catch (IOException e)
{
e.toString();
//System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
}
catch (Exception e)
{
e.toString();
//System.out.println("Can't load database file (" + databasePath + databaseFileName + ")");
}
}
/**
* Creates and adds to the DB a MusicURIReference object for every audio file contained in the directory specified
* @param directoryPath the path to the directory containing the audio files to be added to the DB
*/
public void indexAudioFilesInDirectory(String directoryPath)
{
File path = new File(directoryPath);
File[] list = path.listFiles();
if (list.length == 0)
{
return;
}
else
{
for (int i = 0; i < list.length; i++)
{
File file = list[i];
try
{
if (Toolset.isSupportedAudioFile(file))
addMusicURIReference(new MusicURIReference(file));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
/**
* Adds the given MusicURIReference object to the DB, and also serializes it to xml
* @param newReference the MusicURIReference object to add to the DB
*/
public boolean addMusicURIReference(MusicURIReference newReference)
{
String md5 = newReference.getOriginalAudioFileMD5(); // MD5 used askey
String filename = md5 + ".xml";
File serializedObject = new File(databasePath + filename);
// check if MD5 is already in use, and if the object serialized to xml exists on disk
if (table.containsKey(md5))
{
//System.out.println("This MD5 is already in use");
//if (serializedObject.exists()) System.out.println("XML file exists");
//else System.out.println("XML file does not exist in DB directory");
return false;
}
else
{
//although not required, also serialize to xml for easy debugging
serializeToXmlFile(newReference, databasePath + filename);
//add newReference to list with MD5 String as key, MusicURIReference object as value
table.put(md5, newReference);
saveDb();
return true;
}
}
/**
* Serializes the HashMap table containing all references, saving its state
*/
public void saveDb()
{
serialize(table, databasePath + databaseFileName);
//System.out.println(table.keySet().size() + " references saved in " + databaseFileName);
}
/**
* Removes a MusicURIReference object from the DB
* @param md5 the MD5 key of the MusicURIReference object to remove
*/
public boolean removeMusicURIReference (String md5)
{
if (!table.containsKey(md5)) // check if MD5 key exists in db
{
//System.out.println ("This MD5 key is not registered in the DB");
return false;
}
else
{
//remove MD5 and associated MusicURIReference from db
table.remove(md5);
saveDb();
return true;
}
}
/**
* Fetches a MusicURIReference object from the DB
* @param md5 the MD5 key of the MusicURIReference object to fetch
* @return the MusicURIReference that was fetched, if it exists, null otherwise
*/
public MusicURIReference getMusicURIReference(String md5)
{
if (!table.containsKey(md5)) // check if MD5 key exists in db
{
//System.out.println ("This MD5 key is not registered in the DB");
return null;
}
else
{
// get associated MusicURIReference
return (MusicURIReference)table.get(md5);
}
}
/**
* Fetches the HashMap object that comprises the DB as a set view (object removals supported)
* @return a set view of the keys contained in the HashMap
*/
public Set getSetOfMusicURIReferences()
{
try
{
//HashMap tableClone = (HashMap) Cloner.cloneObject(table);
//return tableClone.keySet();
return table.keySet();
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
/**
* Returns a String containing a formatted list of all the audio files that have
* been indexed as references in the DB (lists their titles and URIs).
*/
public String textFormattedSetOfMusicURIReferences()
{
String text = "\nReference audio files indexed in the DB, and their assigned URIs:\n\n";
Set set = table.entrySet();
Iterator it = set.iterator();
int index = 1;
while (it.hasNext())
{
Map.Entry e = (Map.Entry)it.next();
text = text.concat("["+ index + "]" + "\tTitle : " + ((MusicURIReference)e.getValue()).getLabel() + "\n");
text = text.concat("\tURI : " + ((MusicURIReference)e.getValue()).getMusicUri() + "\n\n");
index ++;
}
return text;
}
/**
* Gets the number of entries in the HashMap object that comprises the DB
* @return the size of the DB
*/
public int getDbSize()
{
return table.size();
}
/**
* Serializes any object to the filename specified
* @param object the object to be serialized
* @param fileName the filename of the serialized object
*/
public void serialize(Object object,String fileName)
{
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
out.writeObject(object);
out.flush();
}
catch (IOException e)
{
System.err.println("Unable to serialize object: " + e.toString());
}
}
/**
* Deserializes any object from the filename specified
* @param filePath the filename of the serialized object
* @return the object that was deserialized
*/
public Object deserialize(String filePath) throws IOException, ClassNotFoundException
{
Object object = new Object();
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath));
object = in.readObject();
return object;
}
/**
* Deserializes a HashMap object from the filename specified
* @param filePath the filename of the serialized HashMap
* @return the HashMap object that was deserialized
*/
public HashMap deserializeHashMap(String filePath) throws IOException, ClassNotFoundException
{
HashMap object = new HashMap();
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath));
object = (HashMap) in.readObject();
return object;
}
/**
* Serializes any object to an XML file with the filename specified
* @param object the object to be serialized
* @param filename the XML filename of the serialized object
*/
public void serializeToXmlFile(Object object, String filename)
{
XStream xstream = new XStream();
String xml = xstream.toXML(object);
try
{
FileWriter fw = new FileWriter(filename);
fw.write(xml);
fw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
// /**
// * Adds an Mp7ACT object to the DB
// * @param act the Mp7ACT object to be added
// * Experimental use only
// */
// private void ACT2ReferenceConverter(Mp7ACT act) throws NoSuchAlgorithmException, IOException, URISyntaxException
// {
// String label = act.getLabel();
// File mp3File = new File(label);
// byte[] md5bytes = Toolset.createMD5Hash(mp3File);
// String md5 = Toolset.toHexString(md5bytes);
// ArrayList keywords = Toolset.ExtractKeywords(mp3File);
// ArrayList metaphones = Toolset.GenerateMetaphones(keywords);
// URI musicUri = new URI ("file", label, null);
//
// MusicURIReference newref = new MusicURIReference(act, md5, keywords, metaphones, musicUri, label);
// addMusicURIReference(newref);
// }
}