package org.limewire.ui.swing.mainframe;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import org.limewire.core.api.connection.GnutellaConnectionManager;
import org.limewire.core.api.download.DownloadListManager;
import org.limewire.core.api.upload.UploadListManager;
import com.google.inject.Inject;
/**
* This handles a delayed shutdown of the application after all transfers are
* completed. An application must install an instance of DelayedShutdownHandler
* by calling the <code>install(AppFrame)</code> method.
*/
public class DelayedShutdownHandler {
private final GnutellaConnectionManager gnutellaConnectionManager;
private final DownloadListManager downloadListManager;
private final UploadListManager uploadListManager;
/** Application instance. */
private AppFrame appFrame;
/** Indicates whether a disconnect was performed prior to shutdown. */
private boolean disconnectOnShutdown;
/** Indicates whether a delayed shutdown has been initiated. */
private boolean shutdownInitiated;
/** Indicates whether all file downloads are complete. */
private boolean downloadsCompleted;
/** Indicates whether all file uploads are complete. */
private boolean uploadsCompleted;
/** Listener for downloads completed event. */
private PropertyChangeListener downloadsCompletedListener;
/** Listener for uploads completed event. */
private PropertyChangeListener uploadsCompletedListener;
/**
* Constructs a handler to exit the application after all transfers are
* completed.
*/
@Inject
public DelayedShutdownHandler(
GnutellaConnectionManager gnutellaConnectionManager,
DownloadListManager downloadListManager,
UploadListManager uploadListManager) {
this.gnutellaConnectionManager = gnutellaConnectionManager;
this.downloadListManager = downloadListManager;
this.uploadListManager = uploadListManager;
}
/**
* Installs the handler on the specified application instance. This method
* also adds a listener to the GUI main frame to cancel shutdown when the
* window is restored.
*/
public void install(AppFrame appFrame) {
// Save application instance.
this.appFrame = appFrame;
// Add listener to cancel delayed shutdown whenever UI is restored.
appFrame.getMainFrame().addWindowListener(new WindowAdapter() {
@Override
public void windowDeiconified(WindowEvent e) {
cancelShutdown();
}
});
}
/**
* Exits the application after all transfers are completed. This performs
* the following tasks:
* <ul>
* <li>Disconnects from Gnutella</li>
* <li>Installs a listener for download completion</li>
* <li>Installs a listener for upload completion</li>
* <li>Minimizes the UI to the system tray</li>
* </ul>
*/
public void shutdownAfterTransfers() {
// Skip if shutdown already initiated.
if (shutdownInitiated) {
return;
}
shutdownInitiated = true;
// Disconnect from Gnutella, and save state for possible reconnect.
disconnectOnShutdown = gnutellaConnectionManager.isConnected();
if (disconnectOnShutdown) {
gnutellaConnectionManager.disconnect();
}
// Initialize indicators.
downloadsCompleted = false;
uploadsCompleted = false;
// Install listener for downloads completed event. The event is
// handled by setting an indicator and performing the delayed shutdown.
if (downloadsCompletedListener == null) {
downloadsCompletedListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (DownloadListManager.DOWNLOADS_COMPLETED.equals(evt.getPropertyName())) {
downloadsCompleted = true;
doDelayedShutdown();
}
}
};
downloadListManager.addPropertyChangeListener(downloadsCompletedListener);
}
// Install listener for uploads completed event. The event is
// handled by setting an indicator and performing the delayed shutdown.
if (uploadsCompletedListener == null) {
uploadsCompletedListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (UploadListManager.UPLOADS_COMPLETED.equals(evt.getPropertyName())) {
uploadsCompleted = true;
doDelayedShutdown();
}
}
};
uploadListManager.addPropertyChangeListener(uploadsCompletedListener);
}
// Update state after installing listeners. This generates events for
// transfers that are already done.
downloadListManager.updateDownloadsCompleted();
uploadListManager.updateUploadsCompleted();
// Minimize UI window.
appFrame.minimizeToTray();
}
/**
* Performs delayed shutdown if all downloads and uploads are completed.
*/
private void doDelayedShutdown() {
if (shutdownInitiated && downloadsCompleted && uploadsCompleted) {
// Exit using action to notify ExitListener instances.
appFrame.exit(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "Shutdown"));
}
}
/**
* Cancels delayed shutdown after transfer operation. This performs the
* following tasks:
* <ul>
* <li>Resets indicators</li>
* <li>Uninstalls listeners for download/upload completion</li>
* <li>Reconnects to Gnutella</li>
* </ul>
*/
public void cancelShutdown() {
// Reset indicator.
shutdownInitiated = false;
// Remove download/upload listeners.
if (downloadsCompletedListener != null) {
downloadListManager.removePropertyChangeListener(downloadsCompletedListener);
downloadsCompletedListener = null;
}
if (uploadsCompletedListener != null) {
uploadListManager.removePropertyChangeListener(uploadsCompletedListener);
uploadsCompletedListener = null;
}
// Reset indicators.
downloadsCompleted = false;
uploadsCompleted = false;
// Reconnect to Gnutella.
if (disconnectOnShutdown) {
gnutellaConnectionManager.connect();
disconnectOnShutdown = false;
}
}
}