/**
*
*/
package edu.washington.cs.oneswarm.f2f.xml;
import java.beans.ExceptionListener;
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.concurrent.Semaphore;
import java.util.logging.Logger;
import org.gudy.azureus2.core3.util.Debug;
import edu.washington.cs.oneswarm.f2f.friends.FriendManager;
public class OSF2FXMLBeanReader<T> implements Runnable {
public static interface OSF2FXMLBeanReaderCallback<T> {
public void readObject(T object);
public void completed();
}
private final static Logger logger = Logger.getLogger(OSF2FXMLBeanReader.class.getName());
private final Semaphore lock;
private final OSF2FXMLBeanReaderCallback<T> cb;
private final ClassLoader cl;
private final Class<T> c;
private final String filename;
public OSF2FXMLBeanReader(ClassLoader classloader, Class<T> c, String filename, Semaphore lock,
OSF2FXMLBeanReaderCallback<T> callback) {
this.lock = lock;
this.cb = callback;
this.cl = classloader;
this.c = c;
this.filename = filename;
}
@Override
public void run() {
try {
boolean classesLoaded = false;
while (!classesLoaded) {
try {
logger.fine("trying to load objects from disk: " + filename);
cl.loadClass(c.getCanonicalName());
classesLoaded = true;
} catch (ClassNotFoundException e) {
Debug.out("cannot load class: " + c.getCanonicalName() + ", trying to sleep...");
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
logger.finer("reading objects from disk");
File friendsFile = new File(FriendManager.OSF2F_DIR, filename);
if (friendsFile.isFile()) {
logger.finer("reading from file '" + friendsFile + "'");
T[] objects = readFriendsFromFile(friendsFile);
for (T o : objects) {
cb.readObject(o);
}
logger.fine("read " + objects.length + " objects");
} else {
logger.warning("File not found: " + friendsFile.getPath());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
} finally {
logger.fine("releasing lock");
lock.release();
cb.completed();
}
}
@SuppressWarnings("unchecked")
private T[] readFriendsFromFile(File friendsFile) throws FileNotFoundException {
XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(
new FileInputStream(friendsFile)), this, new ExceptionListener() {
@Override
public void exceptionThrown(Exception e) {
e.printStackTrace();
}
}, cl);
T[] o = (T[]) new Object[0];
try {
o = (T[]) decoder.readObject();
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
logger.severe("Error parsing friends file (corrupt?): " + e.toString());
}
decoder.close();
return o;
}
}