package org.limewire.libtorrent;
import java.io.File;
import java.util.List;
import org.limewire.bittorrent.Torrent;
import org.limewire.bittorrent.TorrentFileEntry;
import org.limewire.bittorrent.TorrentManager;
import org.limewire.bittorrent.TorrentManagerSettings;
import org.limewire.bittorrent.TorrentPeer;
import org.limewire.inject.EagerSingleton;
import org.limewire.inspection.Inspectable;
import org.limewire.inspection.InspectionPoint;
import org.limewire.lifecycle.Service;
import org.limewire.lifecycle.ServiceRegistry;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* Lazy TorrentManager wraps the TorrentManagerImpl and allows holding off
* initializing against the native libraries until the first time and methods
* are called on the torrent manager.
*
* It registers itself as a service to still enabled proper shutdown of the
* Torrent code, but cleanup only needs to be done is the underlying
* implementation was initialized.
*
*/
@EagerSingleton
public class LazyTorrentManager implements TorrentManager, Service {
private final Provider<TorrentManagerImpl> torrentManager;
private volatile boolean initialized = false;
@SuppressWarnings("unused")
@InspectionPoint("torrent manager status")
private final Inspectable torrentManagerStatus = new TorrentManagerStatus();
@Inject
public LazyTorrentManager(Provider<TorrentManagerImpl> torrentManager) {
this.torrentManager = torrentManager;
}
@Inject
public void register(ServiceRegistry serviceRegistry) {
serviceRegistry.register(this);
}
private void setupTorrentManager() {
if (!initialized) {
synchronized (this) {
if (!initialized) {
try {
this.torrentManager.get().initialize();
if (torrentManager.get().isValid()) {
this.torrentManager.get().start();
}
} finally {
initialized = true;
}
}
}
}
}
@Override
public String getServiceName() {
return "TorrentManager";
}
@Override
public TorrentManagerSettings getTorrentManagerSettings() {
// not calling setup because we don't want to initialize the library
// here.
// settings can be gotten without initialization.
return torrentManager.get().getTorrentManagerSettings();
}
@Override
public void initialize() {
// handled in setup method.
}
@Override
public boolean isDownloadingTorrent(File torrentFile) {
if(!initialized) {
return false;
}
setupTorrentManager();
return torrentManager.get().isDownloadingTorrent(torrentFile);
}
@Override
public boolean isManagedTorrent(File torrentFile) {
if (!initialized) {
return false;
}
setupTorrentManager();
return torrentManager.get().isManagedTorrent(torrentFile);
}
@Override
public boolean isManagedTorrent(String sha1) {
if (!initialized) {
return false;
}
setupTorrentManager();
return torrentManager.get().isManagedTorrent(sha1);
}
@Override
public boolean isValid() {
setupTorrentManager();
return torrentManager.get().isValid();
}
@Override
public void moveTorrent(Torrent torrent, File directory) {
setupTorrentManager();
torrentManager.get().moveTorrent(torrent, directory);
}
@Override
public void pauseTorrent(Torrent torrent) {
setupTorrentManager();
torrentManager.get().pauseTorrent(torrent);
}
@Override
public void recoverTorrent(Torrent torrent) {
setupTorrentManager();
torrentManager.get().recoverTorrent(torrent);
}
@Override
public void registerTorrent(Torrent torrent) {
setupTorrentManager();
torrentManager.get().registerTorrent(torrent);
}
@Override
public void removeTorrent(Torrent torrent) {
setupTorrentManager();
torrentManager.get().removeTorrent(torrent);
}
@Override
public void resumeTorrent(Torrent torrent) {
setupTorrentManager();
torrentManager.get().resumeTorrent(torrent);
}
@Override
public void start() {
// handled in setup method.
}
@Override
public void stop() {
synchronized (this) {
try {
if (initialized && torrentManager.get().isValid()) {
torrentManager.get().stop();
}
} finally {
initialized = true;
}
}
}
@Override
public void setTorrentManagerSettings(TorrentManagerSettings settings) {
setupTorrentManager();
torrentManager.get().setTorrentManagerSettings(settings);
}
@Override
public float getTotalDownloadRate() {
if (!initialized) {
return 0;
}
setupTorrentManager();
return torrentManager.get().getTotalDownloadRate();
}
@Override
public float getTotalUploadRate() {
if (!initialized) {
return 0;
}
setupTorrentManager();
return torrentManager.get().getTotalUploadRate();
}
@Override
public List<TorrentFileEntry> getTorrentFileEntries(Torrent torrent) {
setupTorrentManager();
return torrentManager.get().getTorrentFileEntries(torrent);
}
@Override
public List<TorrentPeer> getTorrentPeers(Torrent torrent) {
setupTorrentManager();
return torrentManager.get().getTorrentPeers(torrent);
}
@Override
public void setAutoManaged(Torrent torrent, boolean autoManaged) {
setupTorrentManager();
torrentManager.get().setAutoManaged(torrent, autoManaged);
}
private enum Status{NOT_INITIALIZED, LOADED, FAILED}
private class TorrentManagerStatus implements Inspectable {
@Override
public Object inspect() {
synchronized (LazyTorrentManager.this) {
return initialized ? (torrentManager.get().isValid() ? Status.LOADED.toString() : Status.FAILED.toString()) : Status.NOT_INITIALIZED.toString();
}
}
}
@Override
public void setTorrenFileEntryPriority(Torrent torrent, TorrentFileEntry torrentFileEntry,
int priority) {
setupTorrentManager();
torrentManager.get().setTorrenFileEntryPriority(torrent, torrentFileEntry, priority);
}
@Override
public boolean isInitialized() {
return initialized;
}
}