com.limegroup.gnutella.messages
Class QueryReply

java.lang.Object
  extended bycom.limegroup.gnutella.messages.Message
      extended bycom.limegroup.gnutella.messages.QueryReply
All Implemented Interfaces:
java.lang.Comparable, java.io.Serializable

public class QueryReply
extends Message
implements java.io.Serializable

A query reply. Contains information about the responding host in addition to an array of responses. These responses are not parsed until the getResponses method is called. For efficiency reasons, bad query reply packets may not be discovered until the getResponses methods are called.

This class has partial support for BearShare-style query reply trailers. You can extract the vendor code, push flag, and busy flag. These methods may throw BadPacketException if the metadata cannot be extracted. Note that BadPacketException does not mean that other data (namely responses) cannot be read; MissingDataException might have been a better name. This class also encapsulates xml metadata. See the description of the QHD below for more details.

See Also:
Serialized Form

Nested Class Summary
static class QueryReply.IPPortCombo
          Another utility class the encapsulates some complexity.
static class QueryReply.PushProxyContainer
          A simple utility class for doling out PushProxy information.
 
Field Summary
static int COMMON_PAYLOAD_LEN
          2 bytes for public area, 2 bytes for xml length.
static boolean debugOn
           
static int XML_MAX_SIZE
           
 
Fields inherited from class com.limegroup.gnutella.messages.Message
F_PING, F_PING_REPLY, F_PUSH, F_QUERY, F_QUERY_REPLY, F_ROUTE_TABLE_UPDATE, F_VENDOR_MESSAGE, F_VENDOR_MESSAGE_STABLE, N_MULTICAST, N_TCP, N_UDP, N_UNKNOWN, RECORD_STATS, SOFT_MAX
 
Constructor Summary
QueryReply(byte[] guid, byte ttl, byte hops, byte[] payload)
          Creates a new query reply with data read from the network.
QueryReply(byte[] guid, byte ttl, int port, byte[] ip, long speed, Response[] responses, byte[] clientGUID, boolean isMulticastReply)
          Creates a new query reply.
QueryReply(byte[] guid, byte ttl, int port, byte[] ip, long speed, Response[] responses, byte[] clientGUID, boolean needsPush, boolean isBusy, boolean finishedUpload, boolean measuredSpeed, boolean supportsChat, boolean isMulticastReply)
          Creates a new QueryReply with a BearShare 2.2.0-style QHD.
QueryReply(byte[] guid, byte ttl, int port, byte[] ip, long speed, Response[] responses, byte[] clientGUID, byte[] xmlBytes, boolean needsPush, boolean isBusy, boolean finishedUpload, boolean measuredSpeed, boolean supportsChat, boolean isMulticastReply)
          Creates a new QueryReply with a BearShare 2.2.0-style QHD.
QueryReply(byte[] guid, byte ttl, int port, byte[] ip, long speed, Response[] responses, byte[] clientGUID, byte[] xmlBytes, boolean needsPush, boolean isBusy, boolean finishedUpload, boolean measuredSpeed, boolean supportsChat, boolean isMulticastReply, java.util.Set proxies)
          Creates a new QueryReply with a BearShare 2.2.0-style QHD.
QueryReply(byte[] guid, QueryReply reply)
          Copy constructor.
 
Method Summary
 int calculateQualityOfService(boolean iFirewalled)
          This method calculates the quality of service for a given host.
static void debug(java.lang.Exception e)
           
static void debug(java.lang.String out)
           
 byte[] getClientGUID()
          Returns the 16 byte client ID (i.e., the "footer") of the responding host.
 boolean getHadSuccessfulUpload()
          Returns true if this has successfully uploaded a complete file (bit set).
 HostData getHostData()
          Returns the HostData object describing information about this QueryReply.
 java.lang.String getIP()
          Returns the IP address of the responding host in standard dotted-decimal format, e.g., "192.168.0.1"
 byte[] getIPBytes()
          Accessor the IP address in byte array form.
 boolean getIsBusy()
          Returns true if this has no more download slots.
 boolean getIsMeasuredSpeed()
          Returns true if the speed in this QueryReply was measured (bit set).
 boolean getNeedsPush()
          Returns true if this's push flag is set, i.e., a push download is needed.
 int getPort()
           
 java.util.Set getPushProxies()
           
 short getResultCount()
          Return the number of results N in this query.
 java.util.Iterator getResults()
          Returns an iterator that will yield the results, each as an instance of the Response class.
 java.util.List getResultsAsList()
          Returns a List that will yield the results, each as an instance of the Response class.
 long getSpeed()
           
 boolean getSupportsBrowseHost()
          Returns true iff the client supports browse host feature.
 boolean getSupportsChat()
          Returns true iff the client supports chat.
 java.lang.String getVendor()
          Returns the name of this' vendor, all capitalized.
 byte[] getXMLBytes()
          Return the associated xml metadata string if the queryreply contained one.
static boolean isFirewalledQuality(int quality)
          Utility method for determining whether or not the given "quality" score for a QueryReply denotes that the host is firewalled or not.
 boolean isReplyToMulticastQuery()
          Returns true iff the reply was sent in response to a multicast query.
 void recordDrop()
          Records the dropping of this message in statistics.
 void setGUID(GUID guid)
          Sets the guid for this message.
 Message stripExtendedPayload()
          Returns this, because it's always safe to send big replies.
 java.lang.String toString()
           
 void writePayload(java.io.OutputStream out)
           
 
Methods inherited from class com.limegroup.gnutella.messages.Message
compareTo, getCreationTime, getFunc, getGUID, getHops, getLength, getNetwork, getPriority, getTotalLength, getTTL, hop, isMulticast, isTCP, isUDP, isUnknownNetwork, makeGuid, read, read, read, read, read, readNullTerminatedBytes, repOk, setHops, setPriority, setTTL, updateLength, write, writeGemExtension, writeGemExtension, writeGemExtensions
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

XML_MAX_SIZE

public static final int XML_MAX_SIZE
See Also:
Constant Field Values

COMMON_PAYLOAD_LEN

public static final int COMMON_PAYLOAD_LEN
2 bytes for public area, 2 bytes for xml length.

See Also:
Constant Field Values

debugOn

public static final boolean debugOn
See Also:
Constant Field Values
Constructor Detail

QueryReply

public QueryReply(byte[] guid,
                  byte ttl,
                  int port,
                  byte[] ip,
                  long speed,
                  Response[] responses,
                  byte[] clientGUID,
                  boolean isMulticastReply)
Creates a new query reply. The number of responses is responses.length The Browse Host GGEP extension is ON by default.


QueryReply

public QueryReply(byte[] guid,
                  byte ttl,
                  int port,
                  byte[] ip,
                  long speed,
                  Response[] responses,
                  byte[] clientGUID,
                  boolean needsPush,
                  boolean isBusy,
                  boolean finishedUpload,
                  boolean measuredSpeed,
                  boolean supportsChat,
                  boolean isMulticastReply)
Creates a new QueryReply with a BearShare 2.2.0-style QHD. The QHD with the LIME vendor code and the given busy and push flags. Note that this constructor has no support for undefined push or busy bits. The Browse Host GGEP extension is ON by default.

Parameters:
needsPush - true iff this is firewalled and the downloader should attempt a push without trying a normal download.
isBusy - true iff this server is busy, i.e., has no more upload slots.
finishedUpload - true iff this server has successfully finished an upload
measuredSpeed - true iff speed is measured, not as reported by the user
supportsChat - true iff the host currently allows chatting.

QueryReply

public QueryReply(byte[] guid,
                  byte ttl,
                  int port,
                  byte[] ip,
                  long speed,
                  Response[] responses,
                  byte[] clientGUID,
                  byte[] xmlBytes,
                  boolean needsPush,
                  boolean isBusy,
                  boolean finishedUpload,
                  boolean measuredSpeed,
                  boolean supportsChat,
                  boolean isMulticastReply)
           throws java.lang.IllegalArgumentException
Creates a new QueryReply with a BearShare 2.2.0-style QHD. The QHD with the LIME vendor code and the given busy and push flags. Note that this constructor has no support for undefined push or busy bits. The Browse Host GGEP extension is ON by default.

Parameters:
needsPush - true iff this is firewalled and the downloader should attempt a push without trying a normal download.
isBusy - true iff this server is busy, i.e., has no more upload slots.
finishedUpload - true iff this server has successfully finished an upload
measuredSpeed - true iff speed is measured, not as reported by the user
xmlBytes - The (non-null) byte[] containing aggregated and indexed information regarding file metadata. In terms of byte-size, this should not be bigger than 65535 bytes. Anything larger will result in an Exception being throw. This String is assumed to consist of compressed data.
supportsChat - true iff the host currently allows chatting.
Throws:
java.lang.IllegalArgumentException - Thrown if xmlBytes.length > XML_MAX_SIZE

QueryReply

public QueryReply(byte[] guid,
                  byte ttl,
                  int port,
                  byte[] ip,
                  long speed,
                  Response[] responses,
                  byte[] clientGUID,
                  byte[] xmlBytes,
                  boolean needsPush,
                  boolean isBusy,
                  boolean finishedUpload,
                  boolean measuredSpeed,
                  boolean supportsChat,
                  boolean isMulticastReply,
                  java.util.Set proxies)
           throws java.lang.IllegalArgumentException
Creates a new QueryReply with a BearShare 2.2.0-style QHD. The QHD with the LIME vendor code and the given busy and push flags. Note that this constructor has no support for undefined push or busy bits. The Browse Host GGEP extension is ON by default.

Parameters:
needsPush - true iff this is firewalled and the downloader should attempt a push without trying a normal download.
isBusy - true iff this server is busy, i.e., has no more upload slots.
finishedUpload - true iff this server has successfully finished an upload
measuredSpeed - true iff speed is measured, not as reported by the user
xmlBytes - The (non-null) byte[] containing aggregated and indexed information regarding file metadata. In terms of byte-size, this should not be bigger than 65535 bytes. Anything larger will result in an Exception being throw. This String is assumed to consist of compressed data.
supportsChat - true iff the host currently allows chatting.
proxies - an array of PushProxy interfaces. will be included in the replies GGEP extension.
Throws:
java.lang.IllegalArgumentException - Thrown if xmlBytes.length > XML_MAX_SIZE

QueryReply

public QueryReply(byte[] guid,
                  byte ttl,
                  byte hops,
                  byte[] payload)
           throws BadPacketException
Creates a new query reply with data read from the network.


QueryReply

public QueryReply(byte[] guid,
                  QueryReply reply)
Copy constructor. Creates a new query reply from the passed query Reply. The new one is same as the passed one, but with different specified GUID.

Note: The payload is not really copied, but the reference in the newly constructed query reply, points to the one in the passed reply. But since the payload cannot be mutated, it shouldn't make difference if different query replies maintain reference to same payload

Parameters:
guid - The new GUID for the reply
reply - The query reply from where to copy the fields into the new constructed query reply
Method Detail

setGUID

public void setGUID(GUID guid)
Sets the guid for this message. Is needed, when we want to cache query replies or sfor some other reason want to change the GUID as per the guid of query request

Overrides:
setGUID in class Message
Parameters:
guid - The guid to be set

writePayload

public void writePayload(java.io.OutputStream out)
                  throws java.io.IOException
Specified by:
writePayload in class Message
Throws:
java.io.IOException

getXMLBytes

public byte[] getXMLBytes()
Return the associated xml metadata string if the queryreply contained one.


getResultCount

public short getResultCount()
Return the number of results N in this query.


getPort

public int getPort()

getIP

public java.lang.String getIP()
Returns the IP address of the responding host in standard dotted-decimal format, e.g., "192.168.0.1"


getIPBytes

public byte[] getIPBytes()
Accessor the IP address in byte array form.

Returns:
the IP address for this query hit as an array of bytes

getSpeed

public long getSpeed()

getResults

public java.util.Iterator getResults()
                              throws BadPacketException
Returns an iterator that will yield the results, each as an instance of the Response class. Throws BadPacketException if this data couldn't be extracted.

Throws:
BadPacketException

getResultsAsList

public java.util.List getResultsAsList()
                                throws BadPacketException
Returns a List that will yield the results, each as an instance of the Response class. Throws BadPacketException if this data couldn't be extracted.

Throws:
BadPacketException

getVendor

public java.lang.String getVendor()
                           throws BadPacketException
Returns the name of this' vendor, all capitalized. Throws BadPacketException if the data couldn't be extracted, either because it is missing or corrupted.

Throws:
BadPacketException

getNeedsPush

public boolean getNeedsPush()
                     throws BadPacketException
Returns true if this's push flag is set, i.e., a push download is needed. Returns false if the flag is present but not set. Throws BadPacketException if the flag couldn't be extracted, either because it is missing or corrupted.

Throws:
BadPacketException

getIsBusy

public boolean getIsBusy()
                  throws BadPacketException
Returns true if this has no more download slots. Returns false if the busy bit is present but not set. Throws BadPacketException if the flag couldn't be extracted, either because it is missing or corrupted.

Throws:
BadPacketException

getHadSuccessfulUpload

public boolean getHadSuccessfulUpload()
                               throws BadPacketException
Returns true if this has successfully uploaded a complete file (bit set). Returns false if the bit is not set. Throws BadPacketException if the flag couldn't be extracted, either because it is missing or corrupted.

Throws:
BadPacketException

getIsMeasuredSpeed

public boolean getIsMeasuredSpeed()
                           throws BadPacketException
Returns true if the speed in this QueryReply was measured (bit set). Returns false if it was set by the user (bit unset). Throws BadPacketException if the flag couldn't be extracted, either because it is missing or corrupted.

Throws:
BadPacketException

getSupportsChat

public boolean getSupportsChat()
                        throws BadPacketException
Returns true iff the client supports chat. Throws BadPacketException if the flag couldn't be extracted, either because it is missing or corrupted. Typically this exception is treated the same way as returning false.

Throws:
BadPacketException

getSupportsBrowseHost

public boolean getSupportsBrowseHost()
                              throws BadPacketException
Returns true iff the client supports browse host feature.

Returns:
true, if the client supports browse host feature, false otherwise
Throws:
Throws - BadPacketException if the flag couldn't be extracted, either because it is missing or corrupted. Typically this exception is treated the same way as returning false.
BadPacketException

isReplyToMulticastQuery

public boolean isReplyToMulticastQuery()
                                throws BadPacketException
Returns true iff the reply was sent in response to a multicast query.

Returns:
true, iff the reply was sent in response to a multicast query, false otherwise
Throws:
Throws - BadPacketException if the flag couldn't be extracted, either because it is missing or corrupted. Typically this exception is treated the same way as returning false.
BadPacketException

getPushProxies

public java.util.Set getPushProxies()
Returns:
null or a non-zero lenght array of PushProxy hosts.

getHostData

public HostData getHostData()
                     throws BadPacketException
Returns the HostData object describing information about this QueryReply.

Throws:
BadPacketException

getClientGUID

public byte[] getClientGUID()
Returns the 16 byte client ID (i.e., the "footer") of the responding host.


stripExtendedPayload

public Message stripExtendedPayload()
Returns this, because it's always safe to send big replies.

Specified by:
stripExtendedPayload in class Message
Returns:
an instance of this without any dangerous extended payload

toString

public java.lang.String toString()
Overrides:
toString in class Message

calculateQualityOfService

public int calculateQualityOfService(boolean iFirewalled)
This method calculates the quality of service for a given host. The calculation is some function of whether or not the host is busy, whether or not the host has ever received an incoming connection, etc. Moved this code from SearchView to here permanently, so we avoid duplication. It makes sense from a data point of view, but this method isn't really essential an essential method.

Parameters:
iFirewalled - switch to indicate if the client is firewalled or not. See RouterService.acceptingIncomingConnection or Acceptor for details.
Returns:
a int from -1 to 3, with -1 for "never work" and 3 for "always work". Typically a return value of N means N+1 stars will be displayed in the GUI.

isFirewalledQuality

public static boolean isFirewalledQuality(int quality)
Utility method for determining whether or not the given "quality" score for a QueryReply denotes that the host is firewalled or not.

Parameters:
quality - the quality, or score, in question
Returns:
true if the quality denotes that the host is firewalled, otherwise false

recordDrop

public void recordDrop()
Description copied from class: Message
Records the dropping of this message in statistics.

Specified by:
recordDrop in class Message

debug

public static void debug(java.lang.String out)

debug

public static void debug(java.lang.Exception e)