/* $Id$ */
package org.noreply.fancydress.directory;
import org.noreply.fancydress.misc.Util;
import org.noreply.fancydress.status.*;
import org.noreply.fancydress.crypto.*;
import java.util.*;
/**
* This class represents a server, pooling one or more server descriptors into one class.
*
* @see ServerDescriptor
*/
public class Server {
/**
* Nickname of the server.
*
* Note that all nickname comparisons need to be done in a case insensitive way.
*/
String nickname;
/**
* The asn1 representation of the server's identity key.
*/
byte[] identity;
/**
* The hash of identity
, which is the node's keyid
*/
byte[] keyid;
/**
* A list of one of more server descriptors.
*/
ArrayList descriptors;
/**
* whether or not this node is recommended.
*/
boolean recommended;
/**
* Construct a Server from a given ServerDescriptor.
*
* @param descriptor a ServerDescriptor.
*/
public Server(ServerDescriptor descriptor) {
nickname = descriptor.getNickname();
identity = descriptor.getIdentity();
keyid = CryptoPrimitives.hash(identity);
descriptors = new ArrayList();
descriptors.add(descriptor);
recommended = false;
}
/**
* Set this node recommended.
*
* This is done by the Directory according to the recommended-servers list.
*
* @see Directory
*/
public void setRecommended() {
recommended = true;
}
/**
* Get whether or not this node recommended.
*
* @return whether or not this node is recommended
*/
public boolean isRecommended() {
return recommended;
}
/**
* Get whether or not this node is useable.
*
* A server is useable if it understands PacketVersions that we speak,
* has a serverdescriptor that is useable right now, and this SD has
* an Incoming/MMTP section.
*
* @return whether or not this node is useable
*/
public boolean isUseable() {
ServerDescriptor sd;
try {
sd = getDescriptor();
} catch (Mix3NoServerDescriptorException e) {
return false;
}
String[] pv = sd.getPacketVersions(); /* getPacketVersions only returns packet versions that we understand */
if (pv.length == 0)
return false;
if (sd.getIncomingMMTPSection() == null)
return false;
return true;
}
/**
* Add a ServerDescriptor to this Server.
*
* @param descriptor a ServerDescriptor to add.
* @throws Mix3BadServerFormatException if the nickname or the identity key do not match this server's nickname or identity key.
*/
public void addDescriptor(ServerDescriptor descriptor) throws Mix3BadServerFormatException {
if (!nickname.equalsIgnoreCase(descriptor.getNickname()))
/* This indicates an error in whoever called us */
throw new Error("Nickname does not match.");
if (!Util.equal(identity, descriptor.getIdentity()))
/* While this might happen. In this case this ServerDesc should be ignored */
throw new Mix3BadServerFormatException("Identity does not match.");
descriptors.add(descriptor);
}
/**
* Get the keyid (hash of the identity key) of this Server.
*
* @return keyid
*/
public byte[] getKeyID() {
return keyid;
}
/**
* Get the nickname of this server.
*
* @return nickname
*/
public String getNickname() {
return nickname;
}
/**
* get the the currently valid server descriptor.
*
* @return current server descriptor
* @throws Mix3NoServerDescriptorException if there is no valid server descriptor
*/
public ServerDescriptor getDescriptor() throws Mix3NoServerDescriptorException {
ServerDescriptor result = null;
Date now = new Date();
for (int i=0; i