Return unmodifiable view of packs
[xudocci.git] / src / main / java / net / pterodactylus / xdcc / data / Network.java
1 /*
2  * XdccDownloader - Network.java - Copyright © 2013 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.xdcc.data;
19
20 import static com.google.common.base.Preconditions.checkNotNull;
21
22 import java.util.Collection;
23
24 import com.google.common.collect.Sets;
25
26 /**
27  * Defines a network.
28  *
29  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
30  */
31 public class Network {
32
33         /** The name of the network. */
34         private final String name;
35
36         /** The servers of this network. */
37         private final Collection<Server> servers = Sets.newHashSet();
38
39         /**
40          * Creates a new network with the given name.
41          *
42          * @param name
43          *              The name of the network
44          * @throws NullPointerException
45          *              if {@code name} is {@code null}
46          */
47         private Network(String name) throws NullPointerException {
48                 this.name = checkNotNull(name, "name must not be null");
49         }
50
51         //
52         // ACCESSORS
53         //
54
55         /**
56          * Returns the name of this network.
57          *
58          * @return The name of this network
59          */
60         public String name() {
61                 return name;
62         }
63
64         /**
65          * Returns the servers of this network.
66          *
67          * @return The servers of this network
68          */
69         public Collection<Server> servers() {
70                 return servers;
71         }
72
73         //
74         // MUTATORS
75         //
76
77         private void addServer(Server server) {
78                 servers.add(server);
79         }
80
81         //
82         // OBJECT METHODS
83         //
84
85         @Override
86         public boolean equals(Object object) {
87                 if (!(object instanceof Network)) {
88                         return false;
89                 }
90                 Network network = (Network) object;
91                 return name().equals(network.name());
92         }
93
94         @Override
95         public int hashCode() {
96                 return name().hashCode();
97         }
98
99         @Override
100         public String toString() {
101                 return String.format("%s(%d servers)", name(), servers().size());
102         }
103
104         //
105         // STATIC METHODS
106         //
107
108         /**
109          * Returns a network builder.
110          *
111          * @param name
112          *              The name of the network to build
113          * @return A network builder
114          */
115         public static NetworkBuilder builder(String name) {
116                 return new NetworkBuilder(name);
117         }
118
119         /** {@link Network} builder. */
120         public static class NetworkBuilder {
121
122                 /** The network being built. */
123                 private final Network network;
124
125                 /**
126                  * Creates a new network builder.
127                  *
128                  * @param name
129                  *              The name of the network being built
130                  */
131                 private NetworkBuilder(String name) {
132                         network = new Network(name);
133                 }
134
135                 /**
136                  * Returns a server builder that will add the created server to this network.
137                  *
138                  * @return A server builder
139                  */
140                 public ServerBuilder addServer() {
141                         return new ServerBuilder(this);
142                 }
143
144                 /**
145                  * Adds the given server to this builder.
146                  *
147                  * @param server
148                  *              The server to add
149                  * @return This network builder
150                  */
151                 private NetworkBuilder addServer(Server server) {
152                         network.addServer(server);
153                         return this;
154                 }
155
156                 /**
157                  * Returns the built network.
158                  *
159                  * @return The built network
160                  */
161                 public Network build() {
162                         return network;
163                 }
164
165         }
166
167         /** {@link Server} builder. */
168         public static class ServerBuilder {
169
170                 /** The parent network builder. */
171                 private final NetworkBuilder networkBuilder;
172
173                 /** The hostname of the server. */
174                 private String hostname;
175
176                 /** The unencrypted port numbers. */
177                 private final Collection<Integer> unencryptedPorts = Sets.newHashSet();
178
179                 /** The encrypted port numbers. */
180                 private final Collection<Integer> encryptedPorts = Sets.newHashSet();
181
182                 /**
183                  * Creates a new server builder.
184                  *
185                  * @param networkBuilder
186                  *              The parent network builder
187                  */
188                 private ServerBuilder(NetworkBuilder networkBuilder) {
189                         this.networkBuilder = networkBuilder;
190                 }
191
192                 /**
193                  * Sets the hostname of the server to build.
194                  *
195                  * @param hostname
196                  *              The hostname of the server
197                  * @return This server builder
198                  */
199                 public ServerBuilder at(String hostname) {
200                         this.hostname = hostname;
201                         return this;
202                 }
203
204                 /**
205                  * Adds the given port number to the list of unencrypted port numbers.
206                  *
207                  * @param port
208                  *              The port number to add
209                  * @return This server builder
210                  */
211                 public ServerBuilder port(int port) {
212                         unencryptedPorts.add(port);
213                         return this;
214                 }
215
216                 /**
217                  * Adds the given port numbers to the list of unencrypted port numbers.
218                  *
219                  * @param ports
220                  *              The port numbers to add
221                  * @return This server builder
222                  */
223                 public ServerBuilder ports(int... ports) {
224                         for (int port : ports) {
225                                 unencryptedPorts.add(port);
226                         }
227                         return this;
228                 }
229
230                 /**
231                  * Adds the given port number to the list of encrypted port numbers.
232                  *
233                  * @param sslPort
234                  *              The port number to add
235                  * @return This server builder
236                  */
237                 public ServerBuilder sslPort(int sslPort) {
238                         encryptedPorts.add(sslPort);
239                         return this;
240                 }
241
242                 /**
243                  * Adds the given port numbers to the list of encrypted port numbers.
244                  *
245                  * @param sslPorts
246                  *              The port numbers to add
247                  * @return This server builder
248                  */
249                 public ServerBuilder sslPorts(int... sslPorts) {
250                         for (int sslPort : sslPorts) {
251                                 encryptedPorts.add(sslPort);
252                         }
253                         return this;
254                 }
255
256                 /**
257                  * Builds the server, adds it to the parent network builder and returns the
258                  * network builder.
259                  *
260                  * @return The network builder with the configured server added
261                  */
262                 public NetworkBuilder endServer() {
263                         return networkBuilder.addServer(build());
264                 }
265
266                 /**
267                  * Builds the server.
268                  *
269                  * @return The built server
270                  */
271                 private Server build() {
272                         return new Server(networkBuilder.network, hostname, unencryptedPorts, encryptedPorts);
273                 }
274
275         }
276
277 }