]> git.argeo.org Git - gpl/argeo-jcr.git/blob - TransferEvent.java
9be298fbe88b9e869cceb3671a122b86c599ec2f
[gpl/argeo-jcr.git] / TransferEvent.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2013 Sonatype, Inc.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Sonatype, Inc. - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.aether.transfer;
12
13 import java.nio.ByteBuffer;
14
15 import org.eclipse.aether.RepositorySystemSession;
16
17 /**
18 * An event fired to a transfer listener during an artifact/metadata transfer.
19 *
20 * @see TransferListener
21 * @see TransferEvent.Builder
22 */
23 public final class TransferEvent
24 {
25
26 /**
27 * The type of the event.
28 */
29 public enum EventType
30 {
31
32 /**
33 * @see TransferListener#transferInitiated(TransferEvent)
34 */
35 INITIATED,
36
37 /**
38 * @see TransferListener#transferStarted(TransferEvent)
39 */
40 STARTED,
41
42 /**
43 * @see TransferListener#transferProgressed(TransferEvent)
44 */
45 PROGRESSED,
46
47 /**
48 * @see TransferListener#transferCorrupted(TransferEvent)
49 */
50 CORRUPTED,
51
52 /**
53 * @see TransferListener#transferSucceeded(TransferEvent)
54 */
55 SUCCEEDED,
56
57 /**
58 * @see TransferListener#transferFailed(TransferEvent)
59 */
60 FAILED
61
62 }
63
64 /**
65 * The type of the request/transfer being performed.
66 */
67 public enum RequestType
68 {
69
70 /**
71 * Download artifact/metadata.
72 */
73 GET,
74
75 /**
76 * Check artifact/metadata existence only.
77 */
78 GET_EXISTENCE,
79
80 /**
81 * Upload artifact/metadata.
82 */
83 PUT,
84
85 }
86
87 private final EventType type;
88
89 private final RequestType requestType;
90
91 private final RepositorySystemSession session;
92
93 private final TransferResource resource;
94
95 private final ByteBuffer dataBuffer;
96
97 private final long transferredBytes;
98
99 private final Exception exception;
100
101 TransferEvent( Builder builder )
102 {
103 type = builder.type;
104 requestType = builder.requestType;
105 session = builder.session;
106 resource = builder.resource;
107 dataBuffer = builder.dataBuffer;
108 transferredBytes = builder.transferredBytes;
109 exception = builder.exception;
110 }
111
112 /**
113 * Gets the type of the event.
114 *
115 * @return The type of the event, never {@code null}.
116 */
117 public EventType getType()
118 {
119 return type;
120 }
121
122 /**
123 * Gets the type of the request/transfer.
124 *
125 * @return The type of the request/transfer, never {@code null}.
126 */
127 public RequestType getRequestType()
128 {
129 return requestType;
130 }
131
132 /**
133 * Gets the repository system session during which the event occurred.
134 *
135 * @return The repository system session during which the event occurred, never {@code null}.
136 */
137 public RepositorySystemSession getSession()
138 {
139 return session;
140 }
141
142 /**
143 * Gets the resource that is being transferred.
144 *
145 * @return The resource being transferred, never {@code null}.
146 */
147 public TransferResource getResource()
148 {
149 return resource;
150 }
151
152 /**
153 * Gets the total number of bytes that have been transferred since the download/upload of the resource was started.
154 * If a download has been resumed, the returned count includes the bytes that were already downloaded during the
155 * previous attempt. In other words, the ratio of transferred bytes to the content length of the resource indicates
156 * the percentage of transfer completion.
157 *
158 * @return The total number of bytes that have been transferred since the transfer started, never negative.
159 * @see #getDataLength()
160 * @see TransferResource#getResumeOffset()
161 */
162 public long getTransferredBytes()
163 {
164 return transferredBytes;
165 }
166
167 /**
168 * Gets the byte buffer holding the transferred bytes since the last event. A listener must assume this buffer to be
169 * owned by the event source and must not change any byte in this buffer. Also, the buffer is only valid for the
170 * duration of the event callback, i.e. the next event might reuse the same buffer (with updated contents).
171 * Therefore, if the actual event processing is deferred, the byte buffer would have to be cloned to create an
172 * immutable snapshot of its contents.
173 *
174 * @return The (read-only) byte buffer or {@code null} if not applicable to the event, i.e. if the event type is not
175 * {@link EventType#PROGRESSED}.
176 */
177 public ByteBuffer getDataBuffer()
178 {
179 return ( dataBuffer != null ) ? dataBuffer.asReadOnlyBuffer() : null;
180 }
181
182 /**
183 * Gets the number of bytes that have been transferred since the last event.
184 *
185 * @return The number of bytes that have been transferred since the last event, possibly zero but never negative.
186 * @see #getTransferredBytes()
187 */
188 public int getDataLength()
189 {
190 return ( dataBuffer != null ) ? dataBuffer.remaining() : 0;
191 }
192
193 /**
194 * Gets the error that occurred during the transfer.
195 *
196 * @return The error that occurred or {@code null} if none.
197 */
198 public Exception getException()
199 {
200 return exception;
201 }
202
203 @Override
204 public String toString()
205 {
206 return getRequestType() + " " + getType() + " " + getResource();
207 }
208
209 /**
210 * A builder to create transfer events.
211 */
212 public static final class Builder
213 {
214
215 EventType type;
216
217 RequestType requestType;
218
219 RepositorySystemSession session;
220
221 TransferResource resource;
222
223 ByteBuffer dataBuffer;
224
225 long transferredBytes;
226
227 Exception exception;
228
229 /**
230 * Creates a new transfer event builder for the specified session and the given resource.
231 *
232 * @param session The repository system session, must not be {@code null}.
233 * @param resource The resource being transferred, must not be {@code null}.
234 */
235 public Builder( RepositorySystemSession session, TransferResource resource )
236 {
237 if ( session == null )
238 {
239 throw new IllegalArgumentException( "session not specified" );
240 }
241 if ( resource == null )
242 {
243 throw new IllegalArgumentException( "transfer resource not specified" );
244 }
245 this.session = session;
246 this.resource = resource;
247 type = EventType.INITIATED;
248 requestType = RequestType.GET;
249 }
250
251 private Builder( Builder prototype )
252 {
253 session = prototype.session;
254 resource = prototype.resource;
255 type = prototype.type;
256 requestType = prototype.requestType;
257 dataBuffer = prototype.dataBuffer;
258 transferredBytes = prototype.transferredBytes;
259 exception = prototype.exception;
260 }
261
262 /**
263 * Creates a new transfer event builder from the current values of this builder. The state of this builder
264 * remains unchanged.
265 *
266 * @return The new event builder, never {@code null}.
267 */
268 public Builder copy()
269 {
270 return new Builder( this );
271 }
272
273 /**
274 * Sets the type of the event and resets event-specific fields. In more detail, the data buffer and the
275 * exception fields are set to {@code null}. Furthermore, the total number of transferred bytes is set to
276 * {@code 0} if the event type is {@link EventType#STARTED}.
277 *
278 * @param type The type of the event, must not be {@code null}.
279 * @return This event builder for chaining, never {@code null}.
280 */
281 public Builder resetType( EventType type )
282 {
283 if ( type == null )
284 {
285 throw new IllegalArgumentException( "event type not specified" );
286 }
287 this.type = type;
288 dataBuffer = null;
289 exception = null;
290 switch ( type )
291 {
292 case INITIATED:
293 case STARTED:
294 transferredBytes = 0;
295 default:
296 }
297 return this;
298 }
299
300 /**
301 * Sets the type of the event. When re-using the same builder to generate a sequence of events for one transfer,
302 * {@link #resetType(TransferEvent.EventType)} might be more handy.
303 *
304 * @param type The type of the event, must not be {@code null}.
305 * @return This event builder for chaining, never {@code null}.
306 */
307 public Builder setType( EventType type )
308 {
309 if ( type == null )
310 {
311 throw new IllegalArgumentException( "event type not specified" );
312 }
313 this.type = type;
314 return this;
315 }
316
317 /**
318 * Sets the type of the request/transfer.
319 *
320 * @param requestType The request/transfer type, must not be {@code null}.
321 * @return This event builder for chaining, never {@code null}.
322 */
323 public Builder setRequestType( RequestType requestType )
324 {
325 if ( requestType == null )
326 {
327 throw new IllegalArgumentException( "request type not specified" );
328 }
329 this.requestType = requestType;
330 return this;
331 }
332
333 /**
334 * Sets the total number of bytes that have been transferred so far during the download/upload of the resource.
335 * If a download is being resumed, the count must include the bytes that were already downloaded in the previous
336 * attempt and from which the current transfer started. In this case, the event type {@link EventType#STARTED}
337 * should indicate from what byte the download resumes.
338 *
339 * @param transferredBytes The total number of bytes that have been transferred so far during the
340 * download/upload of the resource, must not be negative.
341 * @return This event builder for chaining, never {@code null}.
342 * @see TransferResource#setResumeOffset(long)
343 */
344 public Builder setTransferredBytes( long transferredBytes )
345 {
346 if ( transferredBytes < 0 )
347 {
348 throw new IllegalArgumentException( "number of transferred bytes cannot be negative" );
349 }
350 this.transferredBytes = transferredBytes;
351 return this;
352 }
353
354 /**
355 * Increments the total number of bytes that have been transferred so far during the download/upload.
356 *
357 * @param transferredBytes The number of bytes that have been transferred since the last event, must not be
358 * negative.
359 * @return This event builder for chaining, never {@code null}.
360 */
361 public Builder addTransferredBytes( long transferredBytes )
362 {
363 if ( transferredBytes < 0 )
364 {
365 throw new IllegalArgumentException( "number of transferred bytes cannot be negative" );
366 }
367 this.transferredBytes += transferredBytes;
368 return this;
369 }
370
371 /**
372 * Sets the byte buffer holding the transferred bytes since the last event.
373 *
374 * @param buffer The byte buffer holding the transferred bytes since the last event, may be {@code null} if not
375 * applicable to the event.
376 * @param offset The starting point of valid bytes in the array.
377 * @param length The number of valid bytes, must not be negative.
378 * @return This event builder for chaining, never {@code null}.
379 */
380 public Builder setDataBuffer( byte[] buffer, int offset, int length )
381 {
382 return setDataBuffer( ( buffer != null ) ? ByteBuffer.wrap( buffer, offset, length ) : null );
383 }
384
385 /**
386 * Sets the byte buffer holding the transferred bytes since the last event.
387 *
388 * @param dataBuffer The byte buffer holding the transferred bytes since the last event, may be {@code null} if
389 * not applicable to the event.
390 * @return This event builder for chaining, never {@code null}.
391 */
392 public Builder setDataBuffer( ByteBuffer dataBuffer )
393 {
394 this.dataBuffer = dataBuffer;
395 return this;
396 }
397
398 /**
399 * Sets the error that occurred during the transfer.
400 *
401 * @param exception The error that occurred during the transfer, may be {@code null} if none.
402 * @return This event builder for chaining, never {@code null}.
403 */
404 public Builder setException( Exception exception )
405 {
406 this.exception = exception;
407 return this;
408 }
409
410 /**
411 * Builds a new transfer event from the current values of this builder. The state of the builder itself remains
412 * unchanged.
413 *
414 * @return The transfer event, never {@code null}.
415 */
416 public TransferEvent build()
417 {
418 return new TransferEvent( this );
419 }
420
421 }
422
423 }