Return unmodifiable view of packs
[xudocci.git] / src / main / java / net / pterodactylus / xdcc / data / Bot.java
index 33bec20..c9e2a9b 100644 (file)
 
 package net.pterodactylus.xdcc.data;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.Map;
 
-import com.beust.jcommander.internal.Maps;
+import com.google.common.collect.Maps;
 
 /**
  * A bot is a client in a {@link Network} that carries {@link Pack}s which are
@@ -28,25 +32,23 @@ import com.beust.jcommander.internal.Maps;
  *
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
  */
-public class Bot {
+public class Bot implements Iterable<Pack> {
 
        /** The network this bot is on. */
        private final Network network;
+       private final String channel;
 
        /** The packs this bot carries. */
        private final Map<String, Pack> packs = Maps.newHashMap();
+       private final Map<String, Pack> packsByName = Maps.newHashMap();
 
        /** The current name of the bot. */
        private String name;
 
-       /**
-        * Creates a new bot.
-        *
-        * @param network
-        *              The network the bot is on
-        */
-       public Bot(Network network) {
-               this.network = network;
+       public Bot(Network network, String channel, String name) {
+               this.network = checkNotNull(network, "network must not be null");
+               this.channel = checkNotNull(channel, "channel must not be null");
+               this.name = checkNotNull(name, "name must not be null");
        }
 
        //
@@ -62,6 +64,10 @@ public class Bot {
                return network;
        }
 
+       public String channel() {
+               return channel;
+       }
+
        /**
         * Returns the current name of this bot.
         *
@@ -77,7 +83,9 @@ public class Bot {
         * @return The packs this bot carries
         */
        public Collection<Pack> packs() {
-               return packs.values();
+               synchronized (packs) {
+                       return Collections.unmodifiableCollection(packs.values());
+               }
        }
 
        //
@@ -92,7 +100,7 @@ public class Bot {
         * @return This bot
         */
        public Bot name(String name) {
-               this.name = name;
+               this.name = checkNotNull(name, "name must not be null");
                return this;
        }
 
@@ -107,7 +115,23 @@ public class Bot {
         *              The pack to add
         */
        public void addPack(Pack pack) {
-               packs.put(pack.id(), pack);
+               synchronized (this) {
+                       if (packsByName.containsKey(pack.name())) {
+                               Pack oldPack = packsByName.remove(pack.name());
+                               packs.remove(oldPack.id());
+                       }
+                       packs.put(pack.id(), pack);
+                       packsByName.put(pack.name(), pack);
+               }
+       }
+
+       //
+       // ITERABLE METHODS
+       //
+
+       @Override
+       public Iterator<Pack> iterator() {
+               return packs().iterator();
        }
 
        //
@@ -115,6 +139,20 @@ public class Bot {
        //
 
        @Override
+       public boolean equals(Object object) {
+               if (!(object instanceof Bot)) {
+                       return false;
+               }
+               Bot bot = (Bot) object;
+               return network().equals(bot.network()) && name().equals(bot.name());
+       }
+
+       @Override
+       public int hashCode() {
+               return network().hashCode() ^ name().hashCode();
+       }
+
+       @Override
        public String toString() {
                return String.format("%s/%s", name(), network().name());
        }