2 * XdccDownloader - Download.java - Copyright © 2013 David Roden
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.
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.
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/>.
18 package net.pterodactylus.xdcc.data;
20 import static com.google.common.base.Preconditions.checkNotNull;
22 import java.io.OutputStream;
23 import java.net.InetAddress;
24 import java.util.Comparator;
25 import java.util.concurrent.atomic.AtomicLong;
26 import java.util.concurrent.atomic.AtomicReference;
28 import net.pterodactylus.irc.DccReceiver;
30 import com.google.common.base.Function;
31 import com.google.common.base.Optional;
32 import com.google.common.base.Predicate;
35 * Information about an ongoing download.
37 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
39 public class Download {
41 /** Predicate that identifies downloads that have started. */
42 public static final Predicate<Download> FILTER_RUNNING = new Predicate<Download>() {
45 public boolean apply(Download download) {
46 return download.dccReceiver() != null;
50 /** {@link Comparator} that sorts downloads by their name. */
51 public static final Comparator<Download> BY_NAME = new Comparator<Download>() {
54 public int compare(Download leftDownload, Download rightDownload) {
55 return leftDownload.pack().name().compareToIgnoreCase(rightDownload.pack().name());
59 /** {@link Comparator} that sorts running downloads first. */
60 public static final Comparator<Download> BY_RUNNING = new Comparator<Download>() {
63 public int compare(Download leftDownload, Download rightDownload) {
64 return (leftDownload.dccReceiver() != null) ? -1 : (rightDownload.dccReceiver() != null) ? 1 : 0;
69 * Converts a download into the number of seconds left in the transfer at the
72 public static final Function<Download, Optional<Long>> SECONDS_LEFT = new Function<Download, Optional<Long>>() {
74 public Optional<Long> apply(Download download) {
75 DccReceiver dccReceiver = download.dccReceiver();
76 if ((dccReceiver == null) || (dccReceiver.size() == -1) || (dccReceiver.currentRate() == 0)) {
77 return Optional.absent();
79 long secondsLeft = (dccReceiver.size() - dccReceiver.progress()) / dccReceiver.currentRate();
80 return Optional.of(secondsLeft);
84 /** The bot that is being downloaded from. */
85 private final Bot bot;
87 /** The pack that is being downloaded. */
88 private final Pack pack;
90 /** The name of the file being downloaded. */
91 private final AtomicReference<String> filename = new AtomicReference<String>();
93 /** The size of the file being downloaded. */
94 private final AtomicLong filesize = new AtomicLong();
96 /** The remote address. */
97 private final AtomicReference<InetAddress> remoteAddress = new AtomicReference<InetAddress>();
99 /** The output stream. */
100 private final AtomicReference<OutputStream> outputStream = new AtomicReference<OutputStream>();
102 /** The DCC receiver. */
103 private final AtomicReference<DccReceiver> dccReceiver = new AtomicReference<DccReceiver>();
106 * Creates a new download.
109 * The bot offering the download
111 * The pack being downloaded
113 public Download(Bot bot, Pack pack) {
114 this.bot = checkNotNull(bot, "bot must not be null");
115 this.pack = checkNotNull(pack, "pack must not be null");
123 * Returns the bot offering the download.
125 * @return The bot offering the download
132 * The pack that is being downloaded.
134 * @return The pack being downloaded
141 * The full name of the file being written.
143 * @return The full name of the file
145 public String filename() {
146 return filename.get();
150 * Returns the size of the file.
152 * @return The size of the file
154 public long filesize() {
155 return filesize.get();
159 * Returns the remote address to download from.
161 * @return The remote address to download from
163 public InetAddress remoteAddress() {
164 return remoteAddress.get();
168 * The output stream that writes to the file.
170 * @return The output stream
172 public OutputStream outputStream() {
173 return outputStream.get();
177 * The DCC receiver that is downloading the file
179 * @return The DCC receiver
181 public DccReceiver dccReceiver() {
182 return dccReceiver.get();
190 * Sets the full name of the file being downloaded.
193 * The full name of the file
194 * @return This download
196 public Download filename(String filename) {
197 this.filename.set(filename);
202 * Sets the size of the download.
205 * The size of the download
206 * @return This download
208 public Download filesize(long filesize) {
209 this.filesize.set(filesize);
214 * Sets the remote address of the download.
216 * @param remoteAddress
217 * The remote address of the download
218 * @return This download
220 public Download remoteAddress(InetAddress remoteAddress) {
221 this.remoteAddress.set(remoteAddress);
226 * Sets the output stream the download is being written to
228 * @param outputStream
230 * @return This download
232 public Download outputStream(OutputStream outputStream) {
233 this.outputStream.set(outputStream);
238 * Sets the DCC receiver that downloads the file.
242 * @return This download
244 public Download dccReceiver(DccReceiver dccReceiver) {
245 this.dccReceiver.set(dccReceiver);
254 public boolean equals(Object object) {
255 if (!(object instanceof Download)) {
258 Download download = (Download) object;
259 return bot().equals(download.bot()) && pack().equals(download.pack());
263 public int hashCode() {
264 return bot().hashCode() ^ pack().hashCode();