/*
* Copyright 2004 - 2008 Christian Sprajc. All rights reserved.
*
* This file is part of PowerFolder.
*
* PowerFolder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* PowerFolder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PowerFolder. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
package de.dal33t.powerfolder.message;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import de.dal33t.powerfolder.Member;
import de.dal33t.powerfolder.clientserver.ServerClient;
import de.dal33t.powerfolder.light.MemberInfo;
import de.dal33t.powerfolder.util.Reject;
/**
* A request to send the nodelist. Expected answer is a <code>KnownNodes</code>
* message.
* <p>
* TODO Add filter criteria for folders.
*
* @see de.dal33t.powerfolder.message.KnownNodes
* @see de.dal33t.powerfolder.message.SearchNodeRequest
* @author <a href="mailto:totmacher@powerfolder.com">Christian Sprajc </a>
* @version $Revision: 1.1 $
*/
public class RequestNodeList extends Message {
private static final long serialVersionUID = 101L;
/**
* The criteria for getting the supernodes infos.
*/
public static enum NodesCriteria {
ALL, ONLINE, NONE
}
/**
* What supernodes information should be returned.
*/
private NodesCriteria supernodesCriteria;
/**
* What other nodes information should be returned, additionally match
* through nodeId list.
*/
private NodesCriteria nodesCriteria;
/**
* The list of node ids for which we want to request fresh connection
* information. May be null. Usually the ids of the friends.
*/
private Collection<String> nodeIds;
/**
* Constructs a new request.
*/
private RequestNodeList(Collection<String> mIds,
NodesCriteria supernodesCrit, NodesCriteria normalNodesCrit)
{
Reject.ifNull(normalNodesCrit, "Nodes criteria is null");
Reject.ifNull(supernodesCrit, "Supernodes criteria is null");
supernodesCriteria = supernodesCrit;
nodesCriteria = normalNodesCrit;
nodeIds = mIds;
}
// Creation methods *******************************************************
/**
* Creates a request nodes message, which requests all node infomations.
*
* @return the request message
*/
public static RequestNodeList createRequestAllNodes() {
return new RequestNodeList(null, NodesCriteria.ALL, NodesCriteria.ALL);
}
/**
* Creates a request nodes message, which requests nodes information of the
* given nodes. Can additionally obtain information about supernodes.
*
* @param nodes
* the nodes to request new information for
* @param supernodesCriteria
* the supernodes criteria.
* @param normalNodesCriteria
* the criteria for normal nodes in not in id list.
* @return the message to sent
*/
public static RequestNodeList createRequest(Collection<Member> nodes,
NodesCriteria supernodesCriteria, NodesCriteria normalNodesCriteria)
{
Reject.ifNull(nodes, "Nodes is null");
Collection<String> mIds = new HashSet<String>(nodes.size());
for (Member node : nodes) {
mIds.add(node.getId());
}
return new RequestNodeList(mIds, supernodesCriteria,
normalNodesCriteria);
}
// API ********************************************************************
/**
* Filter the collection of nodes with the criterias of this request.
*
* @param source
* the list of nodes
* @return the filtered list of node infos. never contains temporary sever
* nodes.
*/
public List<MemberInfo> filter(Collection<Member> source) {
List<MemberInfo> nodes = null;
// reduce abnormal container growth
if (NodesCriteria.ALL.equals(nodesCriteria)) {
nodes = new ArrayList<MemberInfo>(source.size());
} else {
nodes = new ArrayList<MemberInfo>();
}
for (Member node : source) {
if (matches(node)) {
nodes.add(node.getInfo());
}
}
return nodes;
}
// Helper *****************************************************************
private boolean matches(Member node) {
if (ServerClient.isTempServerNode(node.getInfo())) {
return false;
}
// "general" nodes criteria match
if (NodesCriteria.ALL.equals(nodesCriteria)) {
return true;
}
if (NodesCriteria.ONLINE.equals(nodesCriteria)
&& node.isConnectedToNetwork())
{
return true;
}
// Supernode match
if (NodesCriteria.ALL.equals(supernodesCriteria) && node.isSupernode())
{
return true;
}
if (NodesCriteria.ONLINE.equals(supernodesCriteria)
&& node.isSupernode() && node.isConnectedToNetwork())
{
return true;
}
// Node id list match
if (nodeIds != null && nodeIds.contains(node.getId())) {
return true;
}
return false;
}
// General ****************************************************************
public String toString() {
return "Request for NodeList (supernodes: " + supernodesCriteria
+ ", normal-nodes: " + nodesCriteria + ", "
+ (nodeIds == null ? "all" : Integer.valueOf(nodeIds.size()))
+ " nodes)";
}
}