package com.limegroup.gnutella.downloader;
import com.limegroup.gnutella.tigertree.HashTree;
/**
* Simple class that enumerates values for the status of
* requesting a file.
*
* Possible options are:
* <ul>
* <li>NoFile (the server is not giving us the file)</li>
* <li>Queued (the server queued us)</li>
* <li>Connected (we are connected and should download)</li>
* <li>NoData (we have no data to request)</li>
* <li>PartialData (the server has other data to use)</li>
* <li>ThexResponse (the server just gave us a HashTree)</li>
* </ul>
*/
public class ConnectionStatus {
enum StatusType {
NO_FILE,
QUEUED,
CONNECTED,
NO_DATA,
PARTIAL_DATA,
THEX_RESPONSE;
}
/** The status of this connection. */
private final StatusType STATUS;
/** The queue position. Only valid if queued. */
private final int QUEUE_POSITION;
/** The queue poll time. Only valid if queued. */
private final int QUEUE_POLL_TIME;
/** The hash tree. Only valid if thex response. */
private final HashTree HASH_TREE;
/** The code that caused this status, -1 if unknown. */
private final int CODE;
/** The sole NO_FILE instance. */
private static final ConnectionStatus NO_FILE = new ConnectionStatus(StatusType.NO_FILE);
/** The sole CONNECTED instance. */
private static final ConnectionStatus CONNECTED = new ConnectionStatus(StatusType.CONNECTED);
/** The sole NO_DATA instance. */
private static final ConnectionStatus NO_DATA = new ConnectionStatus(StatusType.NO_DATA);
/** The sole PARTIAL_DATA instance. */
private static final ConnectionStatus PARTIAL_DATA = new ConnectionStatus(StatusType.PARTIAL_DATA);
/** Constructs a ConnectionStatus of the specified status. */
private ConnectionStatus(StatusType status) {
if(status == StatusType.QUEUED || status == StatusType.THEX_RESPONSE)
throw new IllegalArgumentException();
STATUS = status;
QUEUE_POSITION = -1;
QUEUE_POLL_TIME = -1;
CODE = -1;
HASH_TREE = null;
}
/** Constructs a ConnectionStatus for being queued. */
private ConnectionStatus(StatusType status, int queuePos, int queuePoll) {
if(status != StatusType.QUEUED)
throw new IllegalArgumentException();
STATUS = status;
QUEUE_POSITION = queuePos;
QUEUE_POLL_TIME = queuePoll;
CODE = -1;
HASH_TREE = null;
}
private ConnectionStatus(StatusType status, HashTree tree) {
if(status != StatusType.THEX_RESPONSE)
throw new IllegalArgumentException();
if(tree == null)
throw new NullPointerException("null tree");
STATUS = status;
HASH_TREE = tree;
CODE = -1;
QUEUE_POSITION = -1;
QUEUE_POLL_TIME = -1;
}
/**
* Returns a ConnectionStatus for the server not having the file.
*/
static ConnectionStatus getNoFile() {
return NO_FILE;
}
/**
* Returns a ConnectionStatus for being connected.
*/
static ConnectionStatus getConnected() {
return CONNECTED;
}
/**
* Returns a ConnectionStatus for us not having data.
*/
static ConnectionStatus getNoData() {
return NO_DATA;
}
/**
* Returns a ConnectionStatus for the server having other partial data.
*/
static ConnectionStatus getPartialData() {
return PARTIAL_DATA;
}
/**
* Returns a ConnectionStatus for being queued with the specified position
* and poll time (in seconds).
*/
static ConnectionStatus getQueued(int pos, int poll) {
// convert to milliseconds & add an extra second.
poll *= 1000;
poll += 1000;
return new ConnectionStatus(StatusType.QUEUED, pos, poll);
}
/**
* Returns a ConnectionStatus for having a THEX tree.
*/
static ConnectionStatus getThexResponse(HashTree tree) {
return new ConnectionStatus(StatusType.THEX_RESPONSE, tree);
}
/**
* Returns the type of this ConnectionStatus.
*/
StatusType getType() {
return STATUS;
}
/**
* Determines if this is a NoFile ConnectionStatus.
*/
boolean isNoFile() {
return STATUS == StatusType.NO_FILE;
}
/**
* Determines if this is a Connected ConnectionStatus.
*/
public boolean isConnected() {
return STATUS == StatusType.CONNECTED;
}
/**
* Determines if this is a NoData ConnectionStatus.
*/
boolean isNoData() {
return STATUS == StatusType.NO_DATA;
}
/**
* Determines if this is a PartialData ConnectionStatus.
*/
boolean isPartialData() {
return STATUS == StatusType.PARTIAL_DATA;
}
/**
* Determines if this is a Queued ConnectionStatus.
*/
boolean isQueued() {
return STATUS == StatusType.QUEUED;
}
/**
* Determines if this is a ThexResponse ConnectionStatus.
*/
public boolean isThexResponse() {
return STATUS == StatusType.THEX_RESPONSE;
}
/**
* Determines the queue position. Throws IllegalStateException if called
* when the status is not queued.
*/
int getQueuePosition() {
if(!isQueued())
throw new IllegalStateException();
return QUEUE_POSITION;
}
/**
* Determines the queue poll time (in milliseconds).
* Throws IllegalStateException if called when the status is not queued.
*/
int getQueuePollTime() {
if(!isQueued())
throw new IllegalStateException();
return QUEUE_POLL_TIME;
}
/**
* Returns the HashTree.
* Throws IllegalStateException if called when the status is not ThexResponse.
*/
public HashTree getHashTree() {
if(!isThexResponse())
throw new IllegalStateException();
return HASH_TREE;
}
/** Returns the HTTP response code that caused this status, or -1 if unknown. */
public int getCode() {
return CODE;
}
@Override
public String toString() {
return STATUS.toString();
}
}