1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.transfer;
21
22 import java.io.File;
23
24 import javax.swing.Icon;
25
26 import org.apache.log4j.Logger;
27 import org.xnap.event.StateListener;
28 import org.xnap.event.StateSupport;
29
30 public abstract class AbstractTransfer implements Transfer {
31
32
33
34 public static final int RECALC_INTERVAL = 5000;
35
36 /***
37 * Wait 50 milli seconds before calculating rate for the first time.
38 * Otherwise we will get fantastically high ones.
39 */
40 public static final int MIN_RECALC_INTERVAL = 50;
41
42 /***
43 * The recommended default socket timeout.
44 */
45 public static final int SOCKET_TIMEOUT = 30 * 1000;
46
47
48
49 protected static Logger logger = Logger.getLogger("xnap.net.transfer");
50
51 /***
52 *
53 */
54 private long lastBytesTransferred = 0;
55 private long lastElapsedTime = 0;
56 private long lastRate = 0;
57
58 private long transferStartTime = -1;
59 private long totalRate = -1;
60
61 private StateSupport listeners = new StateSupport(this);
62
63
64
65 public AbstractTransfer()
66 {
67 }
68
69
70
71 public void addStateListener(StateListener listener)
72 {
73 listeners.addStateListener(listener);
74 }
75
76 /***
77 * Does nothing.
78 */
79 public void cleared()
80 {
81 }
82
83 /***
84 * Returns the average transfer rate.
85 */
86 public long getAverageRate()
87 {
88 if (totalRate != -1) {
89 return totalRate;
90 }
91 else if (transferStartTime == -1) {
92 return -1;
93 }
94
95 long elapsedTime = getElapsedTime();
96 if (elapsedTime > 0) {
97 return (getBytesTransferred() * 1000) / elapsedTime;
98 }
99 else {
100 return getBytesTransferred();
101 }
102 }
103
104 /***
105 * Returns how many bytes have been transferred since the transfer
106 * was started.
107 *
108 * @return number of transferred bytes
109 * @see #getCurrentRate()
110 */
111 protected abstract long getBytesTransferred();
112
113 /***
114 * Returns the current download rate. Take at least a
115 * RECALC_INTERVAL into account to avoid jumping values all the
116 * time.
117 *
118 * @return byte / s
119 */
120 public long getCurrentRate()
121 {
122 if (transferStartTime == -1) {
123 return -1;
124 }
125
126 long deltaTime = System.currentTimeMillis() - lastElapsedTime;
127 if (deltaTime > MIN_RECALC_INTERVAL) {
128 long deltaBytes = getBytesTransferred() - lastBytesTransferred;
129 if (getElapsedTime() < RECALC_INTERVAL) {
130 lastRate = (deltaBytes * 1000) / deltaTime;
131 }
132 else {
133 lastBytesTransferred += deltaBytes;
134 lastElapsedTime += deltaTime;
135
136 long t = RECALC_INTERVAL - deltaTime;
137 if (t > 0) {
138
139
140 deltaBytes += (t * lastRate) / 1000;
141 deltaTime = RECALC_INTERVAL;
142 }
143 lastRate = (deltaBytes * 1000) / deltaTime;
144 }
145 }
146
147 return lastRate;
148 }
149
150 /***
151 * Returns null.
152 */
153 public String getDescription()
154 {
155 return null;
156 }
157
158 /***
159 * Returns the number of milli seconds that have passed since the
160 * transfer has been started.
161 */
162 public long getElapsedTime()
163 {
164 return System.currentTimeMillis() - transferStartTime;
165 }
166
167 public String getFilename()
168 {
169 File f = getFile();
170 return (f != null) ? f.getName() : "";
171 }
172
173 public long getFilesize()
174 {
175 File f = getFile();
176 return (f != null) ? f.length() : 0;
177 }
178
179 /***
180 * Returns null.
181 */
182 public Icon getIcon()
183 {
184 return null;
185 }
186
187 /***
188 * Returns -1.
189 */
190 public int getQueuePosition()
191 {
192 return -1;
193 }
194
195 public int getRemainingTime()
196 {
197 long rate = getAverageRate();
198 return (rate <= 0) ? -1 :
199 (int)((getFilesize() - getBytesTransferred()) / rate);
200 }
201
202 public void removeStateListener(StateListener listener)
203 {
204 listeners.removeStateListener(listener);
205 }
206
207 /***
208 * Notifies all StateListeners that the state has changed.
209 */
210 protected void stateChanged()
211 {
212 listeners.fireStateChanged();
213 }
214
215 public String toString()
216 {
217 return getFilename() + ", " + getFilesize();
218 }
219
220 public Segment[] getSegments()
221 {
222 return null;
223 }
224
225 /***
226 * Sub classes should invoke this method when the transfer has started.
227 */
228 protected void transferStarted()
229 {
230 transferStartTime = System.currentTimeMillis();
231 lastElapsedTime = System.currentTimeMillis();
232 totalRate = -1;
233 }
234
235 /***
236 * Sub classes should invoke this method when the transfer has stopped.
237 */
238 protected void transferStopped()
239 {
240 if (getBytesTransferred() > 0) {
241 long rate = getAverageRate();
242 totalRate = (rate != -1) ? rate : getBytesTransferred();
243 }
244 transferStartTime = -1;
245 }
246
247 }