package com.limegroup.gnutella.gui.download;
import java.io.File;
import java.util.Iterator;
import javax.swing.Icon;
import com.limegroup.gnutella.Assert;
import com.limegroup.gnutella.Downloader;
import com.limegroup.gnutella.Endpoint;
import com.limegroup.gnutella.InsufficientDataException;
import com.limegroup.gnutella.downloader.VerifyingFile;
import com.limegroup.gnutella.gui.GUIMediator;
import com.limegroup.gnutella.gui.GUIUtils;
import com.limegroup.gnutella.gui.IconManager;
import com.limegroup.gnutella.gui.tables.AbstractDataLine;
import com.limegroup.gnutella.gui.tables.CenteredHolder;
import com.limegroup.gnutella.gui.tables.ChatHolder;
import com.limegroup.gnutella.gui.tables.FileTransfer;
import com.limegroup.gnutella.gui.tables.IconAndNameHolder;
import com.limegroup.gnutella.gui.tables.IconAndNameHolderImpl;
import com.limegroup.gnutella.gui.tables.LazyFileTransfer;
import com.limegroup.gnutella.gui.tables.LimeTableColumn;
import com.limegroup.gnutella.gui.tables.ProgressBarHolder;
import com.limegroup.gnutella.gui.tables.SizeHolder;
import com.limegroup.gnutella.gui.tables.SpeedRenderer;
import com.limegroup.gnutella.gui.tables.TimeRemainingHolder;
import com.limegroup.gnutella.util.CommonUtils;
/**
* This class handles all of the data for a single download, representing
* one "line" in the download window. It continually updates the
* displayed data for the download from the contained <tt>Downloader</tt>
* instance.
*/
public final class DownloadDataLine extends AbstractDataLine
implements LazyFileTransfer {
/**
* Constant for the <tt>Downloader</tt> instance for this download.
*/
private Downloader DOWNLOADER;
/**
* Constant for the "queued" download state.
*/
private static final String QUEUED_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_QUEUED");
/**
* Constant for the "connecting" download state.
*/
private static final String CONNECTING_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_CONNECTING");
/**
* Constant for the "waiting" download state.
*/
private static final String WAITING_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_WAITING");
/**
* Constant for the "complete" download state.
*/
private static final String COMPLETE_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_COMPLETE");
/**
* Constant for the "aborted" download state.
*/
private static final String ABORTED_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_ABORTED");
/**
* Constant for the "failed" download state.
*/
private static final String FAILED_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_FAILED");
/**
* Constant for the "downloading" download state.
*/
private static final String DOWNLOADING_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_DOWNLOADING");
/**
* Constant for the "Could Not Move to Library" download state.
* TODO: change this to a more generic disk problem message
*/
private static final String LIBRARY_MOVE_FAILED_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_LIBRARY_MOVE_FAILED");
/**
* Constant for the "Corrupt File" download state.
*/
private static final String CORRUPT_FILE_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_CORRUPT_FILE");
/**
* Constant for the "Waiting for Results" download state.
*/
private static final String REQUERY_WAITING_STATE_START =
GUIMediator.getStringResource("DOWNLOAD_STATUS_WAITING_FOR_REQUERY_START");
/**
* Constant for the "Waiting for Results" download state.
*/
private static final String REQUERY_WAITING_STATE_END =
GUIMediator.getStringResource("DOWNLOAD_STATUS_WAITING_FOR_REQUERY_END");
/**
* Constant for the "Waiting for Results" download state.
*/
private static final String REQUERY_WAITING_FOR_USER =
GUIMediator.getStringResource("DOWNLOAD_STATUS_WAITING_FOR_USER");
/**
* Constant for the "Waiting for Connections" download state.
*/
private static final String WAITING_FOR_CONNECTIONS_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_WAITING_FOR_CONN");
/**
* Constant for the "Remote Queued" download state
*/
private static final String REMOTE_QUEUED_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_REMOTE_QUEUED");
/**
* Constant for the "Hashing" download state
*/
private static final String HASHING_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_HASHING");
/**
* Constant for the "Saving" download state
*/
private static final String SAVING_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_SAVING");
/**
* Constant for the "Identifying Corruption" download state
*/
private static final String IDENTIFY_CORRUPTION_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_IDENTIFY_CORRUPTION");
/**
* Constant for the "Pausing" download state.
*/
private static final String PAUSING_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_PAUSING");
/**
* Constant for the "Paused" download state.
*/
private static final String PAUSED_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_PAUSED");
/** Constant for 'Invalid' download state. */
private static final String INVALID_STATE =
GUIMediator.getStringResource("DOWNLOAD_STATUS_INVALID");
/**
* Constant for "average bandwidth" tip
*/
private static final String AVERAGE_BANDWIDTH =
GUIMediator.getStringResource("GENERAL_AVERAGE_BANDWIDTH");
/**
* Constant for the "alternate locations" tip
*/
private static final String ALTERNATE_LOCATIONS =
GUIMediator.getStringResource("GENERAL_ALTERNATE_LOCATIONS");
/**
* Constant for the "invalid alternate locations" tip
*/
private static final String INVALID_ALTERNATE_LOCATIONS =
GUIMediator.getStringResource("GENERAL_INVALID_ALTERNATE_LOCATIONS");
/**
* Constant for "Started on" tip
*/
private static final String STARTED_ON =
GUIMediator.getStringResource("GENERAL_STARTED_ON");
/**
* Constant for "Finished on" tip
*/
private static final String FINISHED_ON =
GUIMediator.getStringResource("GENERAL_FINISHED_ON");
/**
* Constant for "Time Spent" tip
*/
private static final String TIME_SPENT =
GUIMediator.getStringResource("GENERAL_TIME_SPENT");
/**
* Constant for "Chunks" tip
*/
private static final String CHUNKS =
GUIMediator.getStringResource("DOWNLOAD_CHUNKS");
/**
* Constant for "Lost By Corruption" tip
*/
private static final String LOST =
GUIMediator.getStringResource("DOWNLOAD_LOST");
/**
* Constant for "KB" tip word
*/
private static final String KB =
GUIMediator.getStringResource("GENERAL_UNIT_KILOBYTES");
/**
* Constant for the " hosts" message.
*/
private static final String HOSTS_LABEL =
GUIMediator.getStringResource("DOWNLOAD_HOSTS_LABEL");
private static final String HOST_LABEL =
GUIMediator.getStringResource("DOWNLOAD_HOST_LABEL");
/**
* Constant for the 'gave up' tooltip message.
*/
private static final String[] GAVE_UP_MESSAGE =
{ GUIMediator.getStringResource("DOWNLOAD_AWAITING_SOURCES") };
/** Constant for the 'invalid' tooltip msg. */
private static final String[] INVALID_MESSAGE =
{ GUIMediator.getStringResource("DOWNLOAD_INVALID_EXPLAIN") };
/**
* Constant for the number of possible hosts this downloader has
*/
private static final String POSSIBLE_HOSTS =
GUIMediator.getStringResource("DOWNLOAD_POSSIBLE_HOSTS");
private static final String BUSY_HOSTS =
GUIMediator.getStringResource("DOWNLOAD_BUSY_HOSTS");
private static final String QUEUED_HOSTS =
GUIMediator.getStringResource("DOWNLOAD_QUEUED_HOSTS");
private static final String DOWNLOAD_SEARCHING =
GUIMediator.getStringResource("DOWNLOAD_SEARCHING");
private static final String SEEDING =
GUIMediator.getStringResource("DOWNLOAD_STATUS_SEEDING");
private static final String WAITING_FOR_TRACKER =
GUIMediator.getStringResource("DOWNLOAD_STATUS_WAITING_FOR_TRACKER");
/**
* Variable for the name of the file being downloaded.
*/
private String _fileName;
/**
* Variable for the status of the download.
*/
private String _status;
/**
* Variable for the amount of the file that has been read.
*/
private long _amountRead = 0;
/**
* Variable for the progress made in the progressbar.
*/
private int _progress;
/**
* Variable for whether or not chat is enabled.
*/
private boolean _chatEnabled;
/**
* Variable for whether or not browse is enabled.
*/
private boolean _browseEnabled;
/**
* Variable for the size of the download.
*/
private long _size = -1;
/**
* Variable for the speed of the download.
*/
private double _speed;
/**
* Variable for how much time is left.
*/
private int _timeLeft;
/**
* Variable for the time this download started
*/
private long _startTime;
/**
* Variable for the time this download ended.
*/
private long _endTime;
/**
* The current vendor we are downloading from.
*/
private String _vendor;
/**
* Stores the current state of this download, as of the last update.
* This is the state the everything should work off of to avoid the
* <tt>Downloader</tt> instance being in a different state than
* this data line.
*/
private int _state;
/**
* Whether or not we've cleaned up this line.
*/
private boolean _cleaned = false;
/**
* Column index for priority.
*/
static final int PRIORITY_INDEX = 0;
private static final LimeTableColumn PRIORITY_COLUMN =
new LimeTableColumn(PRIORITY_INDEX, "DOWNLOAD_PRIORITY_COLUMN",
40, false, CenteredHolder.class);
/**
* Column index for the file name.
*/
static final int FILE_INDEX = 1;
private static final LimeTableColumn FILE_COLUMN =
new LimeTableColumn(FILE_INDEX, "DOWNLOAD_NAME_COLUMN",
201, true, IconAndNameHolder.class);
/**
* Column index for the file size.
*/
static final int SIZE_INDEX = 2;
private static final LimeTableColumn SIZE_COLUMN =
new LimeTableColumn(SIZE_INDEX, "DOWNLOAD_SIZE_COLUMN",
65, true, SizeHolder.class);
/**
* Column index for the file download status.
*/
static final int STATUS_INDEX = 3;
private static final LimeTableColumn STATUS_COLUMN =
new LimeTableColumn(STATUS_INDEX, "DOWNLOAD_STATUS_COLUMN",
152, true, String.class);
/**
* Column index for whether or not the uploader is chat-enabled.
*/
static final int CHAT_INDEX = 4;
private static final LimeTableColumn CHAT_COLUMN =
new LimeTableColumn(CHAT_INDEX, "DOWNLOAD_CHAT_COLUMN",
10, false, ChatHolder.class);
/**
* Column index for the progress of the download.
*/
static final int PROGRESS_INDEX = 5;
private static final LimeTableColumn PROGRESS_COLUMN =
new LimeTableColumn(PROGRESS_INDEX, "DOWNLOAD_PROGRESS_COLUMN",
71, true, ProgressBarHolder.class);
/**
* Column index for the download speed.
*/
static final int SPEED_INDEX = 6;
private static final LimeTableColumn SPEED_COLUMN =
new LimeTableColumn(SPEED_INDEX, "DOWNLOAD_SPEED_COLUMN",
58, true, SpeedRenderer.class);
/**
* Column index for the download time remaining.
*/
static final int TIME_INDEX = 7;
private static final LimeTableColumn TIME_COLUMN =
new LimeTableColumn(TIME_INDEX, "DOWNLOAD_TIME_REMAINING_COLUMN",
49, true, TimeRemainingHolder.class);
/**
* Column index for the vendor of the downloader.
*/
static final int VENDOR_INDEX = 8;
private static final LimeTableColumn VENDOR_COLUMN =
new LimeTableColumn(VENDOR_INDEX, "DOWNLOAD_SERVER_COLUMN",
20, false, String.class);
/**
* Number of columns to display
*/
static final int NUMBER_OF_COLUMNS = 9;
// Implements DataLine interface
public int getColumnCount() { return NUMBER_OF_COLUMNS; }
/**
* Must initialize data.
*
* @param downloader the <tt>Downloader</tt>
* that provides access to
* information about the download
*/
public void initialize(Object downloader) {
super.initialize(downloader);
DOWNLOADER = (Downloader)downloader;
_startTime = System.currentTimeMillis();
_endTime = -1;
_size = DOWNLOADER.getContentLength();
// don't cache filename anymore, since we allow renames henceforth
_fileName = DOWNLOADER.getSaveFile().getName();
if (_fileName==null) //TODO: does this ever happen with an downloader?
_fileName="";
_status = "";
_chatEnabled = false;
_browseEnabled = false;
update();
}
/**
* Tell the downloader to close its sockets.
*/
public void cleanup() {
GUIMediator.instance().schedule(new Runnable() {
public void run() {
DOWNLOADER.stop();
}
});
_cleaned = true;
}
/**
* Determines if this was cleaned up.
*/
public boolean isCleaned() {
return _cleaned;
}
/**
* Gets the file if the download was completed.
*/
public File getFile() {
if(!CommonUtils.isWindows())
return DOWNLOADER.getFile();
else {
if(DOWNLOADER.isCompleted())
return DOWNLOADER.getFile();
else
return null;
}
}
/**
* Lazily gets the file -- constructs it only if necessary.
*/
public FileTransfer getLazyFile() {
return new FileTransfer() {
public File getFile() {
return DOWNLOADER.getDownloadFragment();
}
};
}
/**
* Returns the <tt>Object</tt> stored at the specified column in this
* line of data.
*
* @param index the index of the column to retrieve data from
* @return the <tt>Object</tt> stored at that index
* @implements DataLine interface
*/
public Object getValueAt(int index) {
switch(index) {
case PRIORITY_INDEX:
if(DOWNLOADER.isPaused())
return PriorityHolder.PAUSED_P;
if(DOWNLOADER.isInactive())
return new PriorityHolder(DOWNLOADER.getInactivePriority());
else if(DOWNLOADER.isCompleted())
return PriorityHolder.COMPLETE_P;
else
return PriorityHolder.ACTIVE_P;
case FILE_INDEX:
Icon icon = IconManager.instance().getIconForFile(DOWNLOADER.getFile());
return new IconAndNameHolderImpl(icon, _fileName);
case SIZE_INDEX:
return new SizeHolder(_size);
case STATUS_INDEX:
return _status;
case CHAT_INDEX:
return _chatEnabled ? Boolean.TRUE : Boolean.FALSE;
case PROGRESS_INDEX:
return new Integer(_progress);
case SPEED_INDEX:
return new Double(_speed);
case TIME_INDEX:
return new TimeRemainingHolder(_timeLeft);
case VENDOR_INDEX:
return _vendor;
}
return null;
}
/**
* @implements DataLine interface
*/
public LimeTableColumn getColumn(int idx) {
switch(idx) {
case PRIORITY_INDEX: return PRIORITY_COLUMN;
case FILE_INDEX: return FILE_COLUMN;
case SIZE_INDEX: return SIZE_COLUMN;
case STATUS_INDEX: return STATUS_COLUMN;
case CHAT_INDEX: return CHAT_COLUMN;
case PROGRESS_INDEX: return PROGRESS_COLUMN;
case SPEED_INDEX: return SPEED_COLUMN;
case TIME_INDEX: return TIME_COLUMN;
case VENDOR_INDEX: return VENDOR_COLUMN;
}
return null;
}
public boolean isClippable(int idx) {
switch(idx) {
case CHAT_INDEX:
case PROGRESS_INDEX:
return false;
default:
return true;
}
}
public int getTypeAheadColumn() {
return FILE_INDEX;
}
public boolean isTooltipRequired(int col) {
return _state == Downloader.INVALID;
}
public String[] getToolTipArray(int col) {
// give a new message if we gave up
if( _state == Downloader.GAVE_UP )
return GAVE_UP_MESSAGE;
if(_state == Downloader.INVALID )
return INVALID_MESSAGE;
String[] info = new String[11];
String bandwidth = AVERAGE_BANDWIDTH + ": " + GUIUtils.rate2speed(
DOWNLOADER.getAverageBandwidth()
);
String numHosts = POSSIBLE_HOSTS + ": " +
DOWNLOADER.getPossibleHostCount();
String busyHosts = BUSY_HOSTS + ": " +DOWNLOADER.getBusyHostCount();
String queuedHosts=QUEUED_HOSTS + ": "+DOWNLOADER.getQueuedHostCount();
String numLocs = ALTERNATE_LOCATIONS + ": " +
DOWNLOADER.getNumberOfAlternateLocations();
String numInvalidLocs = INVALID_ALTERNATE_LOCATIONS + ": " +
DOWNLOADER.getNumberOfInvalidAlternateLocations();
int chunkSize = DOWNLOADER.getChunkSize();
String numChunks,lost;
int totalPending = VerifyingFile.getNumPendingItems();
synchronized(DOWNLOADER) {
numChunks = CHUNKS + ": "+DOWNLOADER.getAmountVerified() / chunkSize +"/"+
DOWNLOADER.getAmountRead() / chunkSize+ "["+
DOWNLOADER.getAmountPending()+"|"+totalPending+"]"+
"/"+
(DOWNLOADER.getContentLength() + chunkSize -1) / chunkSize +
", "+chunkSize/1024+KB;
lost = LOST+": "+DOWNLOADER.getAmountLost()/1024+KB;
}
info[0] = STARTED_ON + " " + GUIUtils.msec2DateTime( _startTime );
if( _endTime != -1 ) {
info[1] = FINISHED_ON + " " + GUIUtils.msec2DateTime( _endTime );
info[2] = TIME_SPENT + ": " + CommonUtils.seconds2time(
(int)((_endTime - _startTime) / 1000 ) );
info[3] = "";
info[4] = bandwidth;
info[5] = numHosts;
info[6] = busyHosts;
info[7] = queuedHosts;
info[8] = numLocs;
info[9] = numInvalidLocs;
info[10] = lost;
} else {
info[1] = TIME_SPENT + ": " + CommonUtils.seconds2time(
(int) ((System.currentTimeMillis() - _startTime) / 1000 ) );
info[2] = "";
info[3] = bandwidth;
info[4] = numHosts;
info[5] = busyHosts;
info[6] = queuedHosts;
info[7] = numLocs;
info[8] = numInvalidLocs;
info[9] = numChunks;
info[10] = lost;}
return info;
}
public boolean isDynamic(int idx) {
switch(idx) {
case PRIORITY_INDEX:
case STATUS_INDEX:
case PROGRESS_INDEX:
case SPEED_INDEX:
case TIME_INDEX:
case VENDOR_INDEX:
return true;
}
return false;
}
/**
* Returns the total size in bytes of the file being downloaded.
*
* @return the total size in bytes of the file being downloaded
*/
long getLength() {
return _size;
}
/**
* Returns name of the file being downloaded.
* @return name of the downloaded file.
*/
public String getFileName() {
return _fileName;
}
/**
* Returns whether or not the <tt>Downloader</tt> for this download
* is equal to the one passed in.
*
* @return <tt>true</tt> if the passed-in downloader is equal to the
* <tt>Downloader</tt> for this download, <tt>false</tt> otherwise
*/
boolean containsDownloader(Downloader downloader) {
return DOWNLOADER.equals(downloader);
}
/**
* Returns the <tt>Downloader</tt> associated with this download.
*
* @return the <tt>Downloader</tt> associated with this download
*/
Downloader getDownloader() {
return DOWNLOADER;
}
/**
* Return the state of the Downloader
*
* @return the state of the downloader
*/
int getState() {
return _state;
}
/**
* Returns whether or not the download has completed.
*
* @return <tt>true</tt> if the download is complete, <tt>false</tt> otherwise
*/
boolean isCompleted() {
return _state == Downloader.COMPLETE;
}
/**
* Returns whether or not chat is enabled for this download.
*
* @return <tt>true</tt> if the host we're downloading from is chattable,
* <tt>false</tt> otherwise
*/
boolean getChatEnabled() {
return _chatEnabled;
}
/**
* Returns whether or not browse is enabled for this download.
*
* @return <tt>true</tt> if the host we're downloading from is browsable,
* <tt>false</tt> otherwise
*/
boolean getBrowseEnabled() {
return _browseEnabled;
}
/**
* Updates all of the data for this download, obtaining fresh information
* from the contained <tt>Downloader</tt> instance.
*
* @implements DataLine interface
*/
public void update() {
synchronized(DOWNLOADER) {
// always get new file name it might have changed
_fileName = DOWNLOADER.getSaveFile().getName();
_speed = -1;
if ( _size == -1 )
_size = DOWNLOADER.getContentLength();
_amountRead = DOWNLOADER.getAmountRead();
_chatEnabled = DOWNLOADER.hasChatEnabledHost();
_browseEnabled = DOWNLOADER.hasBrowseEnabledHost();
_timeLeft = 0;
//note: we *always* want to update progress
// specifically for when the user has downloaded stuff,
// closed the app, and then re-opened the app.
//previously, because progress was only set while downloading
//or corrupted, the GUI would display 0 progress, even
//though it actually had progress.
double d = (double)_amountRead/(double)_size;
_progress = (int)(d*100);
this.updateStatus();
// downloads can go from inactive to active through resuming.
if ( !this.isInactive() ) _endTime = -1;
}
}
/**
* Updates the status of the download based on the state stored in the
* <tt>Downloader</tt> instance for this <tt>DownloadDataLine</tt>.
*/
private void updateStatus() {
final String lastVendor = _vendor;
_vendor = "";
_state = DOWNLOADER.getState();
boolean paused = DOWNLOADER.isPaused();
if(paused && _state != Downloader.PAUSED && !DOWNLOADER.isCompleted()) {
_status = PAUSING_STATE;
return;
}
switch (_state) {
case Downloader.QUEUED:
_status = QUEUED_STATE;
break;
case Downloader.CONNECTING:
_status = CONNECTING_STATE;
break;
case Downloader.BUSY:
_status = WAITING_STATE;
break;
case Downloader.HASHING:
_status = HASHING_STATE;
break;
case Downloader.SAVING:
_status = SAVING_STATE;
break;
case Downloader.COMPLETE:
_status = COMPLETE_STATE;
_progress = 100;
break;
case Downloader.ABORTED:
_status = ABORTED_STATE;
break;
case Downloader.GAVE_UP:
_status = FAILED_STATE;
break;
case Downloader.IDENTIFY_CORRUPTION:
_status = IDENTIFY_CORRUPTION_STATE;
break;
case Downloader.RECOVERY_FAILED:
_status = "Recovery Failed";
break;
case Downloader.DOWNLOADING:
_vendor = lastVendor;
updateHostCount(DOWNLOADER);
try {
_speed = (double)DOWNLOADER.getMeasuredBandwidth();
} catch(InsufficientDataException ide) {
_speed = 0;
}
// If we have a valid rate (can't compute if rate is 0),
// then determine how much time (in seconds) is remaining.
if ( _speed > 0) {
double kbLeft = (((double)_size/1024.0) -
((double)_amountRead/1024.0));
_timeLeft = (int)(kbLeft / _speed);
}
break;
case Downloader.DISK_PROBLEM:
_status = LIBRARY_MOVE_FAILED_STATE;
_progress = 100;
break;
case Downloader.CORRUPT_FILE:
_status = CORRUPT_FILE_STATE;
break;
case Downloader.WAITING_FOR_RESULTS:
int stateTime=DOWNLOADER.getRemainingStateTime();
_status = (REQUERY_WAITING_STATE_START+" "+stateTime
+REQUERY_WAITING_STATE_END);
break;
case Downloader.ITERATIVE_GUESSING:
_status = DOWNLOAD_SEARCHING;
break;
case Downloader.WAITING_FOR_USER:
_status = REQUERY_WAITING_FOR_USER;
break;
case Downloader.WAITING_FOR_CONNECTIONS:
_status = WAITING_FOR_CONNECTIONS_STATE;
break;
case Downloader.REMOTE_QUEUED:
_status = REMOTE_QUEUED_STATE+" "+DOWNLOADER.getQueuePosition();
_vendor = DOWNLOADER.getVendor();
break;
case Downloader.PAUSED:
_status = PAUSED_STATE;
break;
case Downloader.INVALID:
_status = INVALID_STATE;
break;
case Downloader.SEEDING:
_status = SEEDING;
break;
case Downloader.WAITING_FOR_TRACKER:
_status = WAITING_FOR_TRACKER;
break;
default:
Assert.that(false,
"Unknown status "+DOWNLOADER.getState()+" of downloader");
}
}
/**
* Returns a human-readable description of the address(es) from
* which d is downloading.
*/
private void updateHostCount(Downloader d) {
int count = d.getNumHosts();
// we are in between chunks with this host,
// use the previous count so-as not to confuse
// the user.
if (count == 0) {
// don't change anything.
return;
}
if (count==1) {
_status = DOWNLOADING_STATE + " " + count + " "+ HOST_LABEL;
_vendor = d.getVendor();
} else {
_status = DOWNLOADING_STATE + " " + count + " " + HOSTS_LABEL;
_vendor = d.getVendor();
}
}
/**
* Returns whether or not this download is in what
* is considered an "inactive"
* state, such as completeed, aborted, failed, etc.
*
* @return <tt>true</tt> if this download is in an inactive state,
* <tt>false</tt> otherwise
*/
boolean isInactive() {
return (_state == Downloader.COMPLETE ||
_state == Downloader.ABORTED ||
_state == Downloader.GAVE_UP ||
_state == Downloader.DISK_PROBLEM ||
_state == Downloader.CORRUPT_FILE);
}
/**
* Determines if the downloader is in what it considers an inactive state.
*/
boolean isDownloaderInactive() {
return DOWNLOADER.isInactive();
}
/**
* Returns whether or not the
* download for this line is currently downloading
*
* @return <tt>true</tt> if this download is currently downloading,
* <tt>false</tt> otherwise
*/
boolean isDownloading() {
return _state == Downloader.DOWNLOADING;
}
/**
* Sets the time this download ended.
*/
void setEndTime(long time) {
_endTime = time;
}
}