/* * 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.util.compare; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.logging.Logger; import de.dal33t.powerfolder.Member; import de.dal33t.powerfolder.light.AccountInfo; import de.dal33t.powerfolder.message.TransferStatus; import de.dal33t.powerfolder.util.Reject; /** * Comparator for members * * @author <a href="mailto:totmacher@powerfolder.com">Christian Sprajc </a> * @version $Revision: 1.12 $ */ public class MemberComparator implements Comparator<Member> { private static final Logger LOG = Logger.getLogger(MemberComparator.class .getName()); /** In gui used member sorting */ public static final MemberComparator IN_GUI = new MemberComparator(0); /** Sorts members by last (direct) connection date, latest first */ public static final MemberComparator BY_LAST_CONNECT_DATE = new MemberComparator( 1); /** * Member get compared by their connection to us (localnet, inet), localnets * first */ public static final MemberComparator BY_CONNECTION_TYPE = new MemberComparator( 2); /** Sorts nodes by last connection time to the network */ public static final MemberComparator BY_RECONNECTION_PRIORITY = new MemberComparator( 3); /** Sorts nodes by last connection time to the network */ public static final MemberComparator BY_UPLOAD_AVAILIBILITY = new MemberComparator( 4); /** Sorts nodes by nickname */ public static final MemberComparator NICK = new MemberComparator(5); /** Sorts nodes by hostname */ public static final MemberComparator HOSTNAME = new MemberComparator(6); /** Sorts nodes by IP */ public static final MemberComparator IP = new MemberComparator(7); /** Sorts nodes by account username */ public static final MemberComparator DISPLAY_NAME = new MemberComparator(8); private int type; private MemberComparator(int type) { this.type = type; } public int compare(Member member1, Member member2) { int result = 0; if (type == 0) { // Sort, used in the gui // myself at top if (member1.isMySelf()) { result -= 2000; } if (member2.isMySelf()) { result += 2000; } // friends then if (member1.isFriend()) { result -= 1000; } if (member2.isFriend()) { result += 1000; } // then connected members if (member1.isCompletelyConnected()) { result -= 500; } if (member2.isCompletelyConnected()) { result += 500; } // then connected to networked if (member1.isConnectedToNetwork()) { result -= 100; } if (member2.isConnectedToNetwork()) { result += 100; } // otherwise sort after nick result += member1.getNick().toLowerCase() .compareTo(member2.getNick().toLowerCase()); } else if (type == 1) { // Sort by last connect time result = compareDates(member1.getInfo().getLastConnectTime(), member2.getInfo().getLastConnectTime()); } else if (type == 2) { // Sort by connection type result -= member1.isOnLAN() ? 100 : 0; result += member2.isOnLAN() ? 100 : 0; } else if (type == 3) { // Sort by reconn priority result = compareDates(member1.getLastNetworkConnectTime(), member2.getLastNetworkConnectTime()); if (member1.isFriend()) { result -= 8; } if (member2.isFriend()) { result += 8; } if (member1.isSupernode()) { result -= 4; } if (member2.isSupernode()) { result += 4; } if (member1.isConnectedToNetwork()) { result -= 2; } if (member2.isConnectedToNetwork()) { result += 2; } } else if (type == 4) { // Check lan connection result += member1.isOnLAN() ? 10000 : 0; result -= member2.isOnLAN() ? 10000 : 0; // Compare by upload availibility long tsresult = compareTransferStatus( member1.getLastTransferStatus(), member2.getLastTransferStatus()); result += tsresult; // logWarning("TS Result between " + member1.getNick() + " and " // + member2.getNick() +": " + tsresult); } else if (type == 5) { // nickname return member1.getNick().toLowerCase() .compareTo(member2.getNick().toLowerCase()); } else if (type == 6) { // hostname return member1.getHostName().toLowerCase() .compareTo(member2.getHostName().toLowerCase()); } else if (type == 7) { // ip String ip1 = member1.getIP(); if (ip1 == null) { ip1 = ""; } String ip2 = member2.getIP(); if (ip2 == null) { ip2 = ""; } return compareIPs(ip1, ip2); } else if (type == 8) { AccountInfo a1 = member1.getAccountInfo(); AccountInfo a2 = member2.getAccountInfo(); if (a1 == null) { return a2 == null ? 0 : 1; } if (a2 == null) { return -1; } if (a1.getDisplayName() == null) { return a2.getDisplayName() == null ? 0 : 1; } if (a2.getDisplayName() == null) { return -1; } return a1.getDisplayName().compareTo(a2.getDisplayName()); } else { LOG.severe("Unknow comparing type: " + type); } return result; } /** * Creates a COPY of the input list. * * @param input * the initial collection that should get sorted. * @return a sorted copy of the collection that gets put inside.s */ public List<Member> sortedCopy(Collection<Member> input) { Reject.ifNull(input, "Input is null"); List<Member> l = new ArrayList<Member>(input); Collections.sort(l, this); return l; } /** * Compares two transfer stati * * @param t1 * @param t2 * @return */ private int compareTransferStatus(TransferStatus t1, TransferStatus t2) { if (t1 == null) { return t2 == null ? 0 : -5000; } else if (t2 == null) { return 5000; } int result = 0; // Calculate available upload cps long uploadCPSDiffer = (t1.getAvailbleUploadCPS() - t2 .getAvailbleUploadCPS()); // Chop between -1000 and 1000 result += Math.max(Math.min(uploadCPSDiffer / 10, 1000), -1000); return result; } /** * Compares two dates. They may also be null * * @param d1 * @param d2 * @return */ private int compareDates(Date d1, Date d2) { long time1 = d1 != null ? d1.getTime() : 0; long time2 = d2 != null ? d2.getTime() : 0; if (time1 == time2) { return 0; } return (time1 - time2 > 0 ? -1 : 1); } /** compare two Strings that represent IP addresses */ private static int compareIPs(String ip1, String ip2) { if (ip1.trim().equals("") && ip2.trim().equals("")) { return 0; } if (ip1.trim().equals("")) { return -1; } if (ip2.trim().equals("")) { return 1; } String[] ip1Array = ip1.split("\\."); String[] ip2Array = ip2.split("\\."); for (int i = 0; i <= 3; i++) { int part1 = Integer.parseInt(ip1Array[i]); int part2 = Integer.parseInt(ip2Array[i]); if (part1 == part2) { continue; } if (part1 < part2) { return -1; } if (part1 > part2) { return 1; } } return 0; } }