X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.repo%2Fsrc%2Forg%2Feclipse%2Faether%2Ftransfer%2FTransferEvent.java;fp=org.argeo.slc.repo%2Fsrc%2Forg%2Feclipse%2Faether%2Ftransfer%2FTransferEvent.java;h=9be298fbe88b9e869cceb3671a122b86c599ec2f;hb=825d60c5348dbe3f5be25b0bccf7bdebfe694219;hp=0000000000000000000000000000000000000000;hpb=5e991fff5cba01858dcc5747a27e637325bc5c8e;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.slc.repo/src/org/eclipse/aether/transfer/TransferEvent.java b/org.argeo.slc.repo/src/org/eclipse/aether/transfer/TransferEvent.java new file mode 100644 index 0000000..9be298f --- /dev/null +++ b/org.argeo.slc.repo/src/org/eclipse/aether/transfer/TransferEvent.java @@ -0,0 +1,423 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.transfer; + +import java.nio.ByteBuffer; + +import org.eclipse.aether.RepositorySystemSession; + +/** + * An event fired to a transfer listener during an artifact/metadata transfer. + * + * @see TransferListener + * @see TransferEvent.Builder + */ +public final class TransferEvent +{ + + /** + * The type of the event. + */ + public enum EventType + { + + /** + * @see TransferListener#transferInitiated(TransferEvent) + */ + INITIATED, + + /** + * @see TransferListener#transferStarted(TransferEvent) + */ + STARTED, + + /** + * @see TransferListener#transferProgressed(TransferEvent) + */ + PROGRESSED, + + /** + * @see TransferListener#transferCorrupted(TransferEvent) + */ + CORRUPTED, + + /** + * @see TransferListener#transferSucceeded(TransferEvent) + */ + SUCCEEDED, + + /** + * @see TransferListener#transferFailed(TransferEvent) + */ + FAILED + + } + + /** + * The type of the request/transfer being performed. + */ + public enum RequestType + { + + /** + * Download artifact/metadata. + */ + GET, + + /** + * Check artifact/metadata existence only. + */ + GET_EXISTENCE, + + /** + * Upload artifact/metadata. + */ + PUT, + + } + + private final EventType type; + + private final RequestType requestType; + + private final RepositorySystemSession session; + + private final TransferResource resource; + + private final ByteBuffer dataBuffer; + + private final long transferredBytes; + + private final Exception exception; + + TransferEvent( Builder builder ) + { + type = builder.type; + requestType = builder.requestType; + session = builder.session; + resource = builder.resource; + dataBuffer = builder.dataBuffer; + transferredBytes = builder.transferredBytes; + exception = builder.exception; + } + + /** + * Gets the type of the event. + * + * @return The type of the event, never {@code null}. + */ + public EventType getType() + { + return type; + } + + /** + * Gets the type of the request/transfer. + * + * @return The type of the request/transfer, never {@code null}. + */ + public RequestType getRequestType() + { + return requestType; + } + + /** + * Gets the repository system session during which the event occurred. + * + * @return The repository system session during which the event occurred, never {@code null}. + */ + public RepositorySystemSession getSession() + { + return session; + } + + /** + * Gets the resource that is being transferred. + * + * @return The resource being transferred, never {@code null}. + */ + public TransferResource getResource() + { + return resource; + } + + /** + * Gets the total number of bytes that have been transferred since the download/upload of the resource was started. + * If a download has been resumed, the returned count includes the bytes that were already downloaded during the + * previous attempt. In other words, the ratio of transferred bytes to the content length of the resource indicates + * the percentage of transfer completion. + * + * @return The total number of bytes that have been transferred since the transfer started, never negative. + * @see #getDataLength() + * @see TransferResource#getResumeOffset() + */ + public long getTransferredBytes() + { + return transferredBytes; + } + + /** + * Gets the byte buffer holding the transferred bytes since the last event. A listener must assume this buffer to be + * owned by the event source and must not change any byte in this buffer. Also, the buffer is only valid for the + * duration of the event callback, i.e. the next event might reuse the same buffer (with updated contents). + * Therefore, if the actual event processing is deferred, the byte buffer would have to be cloned to create an + * immutable snapshot of its contents. + * + * @return The (read-only) byte buffer or {@code null} if not applicable to the event, i.e. if the event type is not + * {@link EventType#PROGRESSED}. + */ + public ByteBuffer getDataBuffer() + { + return ( dataBuffer != null ) ? dataBuffer.asReadOnlyBuffer() : null; + } + + /** + * Gets the number of bytes that have been transferred since the last event. + * + * @return The number of bytes that have been transferred since the last event, possibly zero but never negative. + * @see #getTransferredBytes() + */ + public int getDataLength() + { + return ( dataBuffer != null ) ? dataBuffer.remaining() : 0; + } + + /** + * Gets the error that occurred during the transfer. + * + * @return The error that occurred or {@code null} if none. + */ + public Exception getException() + { + return exception; + } + + @Override + public String toString() + { + return getRequestType() + " " + getType() + " " + getResource(); + } + + /** + * A builder to create transfer events. + */ + public static final class Builder + { + + EventType type; + + RequestType requestType; + + RepositorySystemSession session; + + TransferResource resource; + + ByteBuffer dataBuffer; + + long transferredBytes; + + Exception exception; + + /** + * Creates a new transfer event builder for the specified session and the given resource. + * + * @param session The repository system session, must not be {@code null}. + * @param resource The resource being transferred, must not be {@code null}. + */ + public Builder( RepositorySystemSession session, TransferResource resource ) + { + if ( session == null ) + { + throw new IllegalArgumentException( "session not specified" ); + } + if ( resource == null ) + { + throw new IllegalArgumentException( "transfer resource not specified" ); + } + this.session = session; + this.resource = resource; + type = EventType.INITIATED; + requestType = RequestType.GET; + } + + private Builder( Builder prototype ) + { + session = prototype.session; + resource = prototype.resource; + type = prototype.type; + requestType = prototype.requestType; + dataBuffer = prototype.dataBuffer; + transferredBytes = prototype.transferredBytes; + exception = prototype.exception; + } + + /** + * Creates a new transfer event builder from the current values of this builder. The state of this builder + * remains unchanged. + * + * @return The new event builder, never {@code null}. + */ + public Builder copy() + { + return new Builder( this ); + } + + /** + * Sets the type of the event and resets event-specific fields. In more detail, the data buffer and the + * exception fields are set to {@code null}. Furthermore, the total number of transferred bytes is set to + * {@code 0} if the event type is {@link EventType#STARTED}. + * + * @param type The type of the event, must not be {@code null}. + * @return This event builder for chaining, never {@code null}. + */ + public Builder resetType( EventType type ) + { + if ( type == null ) + { + throw new IllegalArgumentException( "event type not specified" ); + } + this.type = type; + dataBuffer = null; + exception = null; + switch ( type ) + { + case INITIATED: + case STARTED: + transferredBytes = 0; + default: + } + return this; + } + + /** + * Sets the type of the event. When re-using the same builder to generate a sequence of events for one transfer, + * {@link #resetType(TransferEvent.EventType)} might be more handy. + * + * @param type The type of the event, must not be {@code null}. + * @return This event builder for chaining, never {@code null}. + */ + public Builder setType( EventType type ) + { + if ( type == null ) + { + throw new IllegalArgumentException( "event type not specified" ); + } + this.type = type; + return this; + } + + /** + * Sets the type of the request/transfer. + * + * @param requestType The request/transfer type, must not be {@code null}. + * @return This event builder for chaining, never {@code null}. + */ + public Builder setRequestType( RequestType requestType ) + { + if ( requestType == null ) + { + throw new IllegalArgumentException( "request type not specified" ); + } + this.requestType = requestType; + return this; + } + + /** + * Sets the total number of bytes that have been transferred so far during the download/upload of the resource. + * If a download is being resumed, the count must include the bytes that were already downloaded in the previous + * attempt and from which the current transfer started. In this case, the event type {@link EventType#STARTED} + * should indicate from what byte the download resumes. + * + * @param transferredBytes The total number of bytes that have been transferred so far during the + * download/upload of the resource, must not be negative. + * @return This event builder for chaining, never {@code null}. + * @see TransferResource#setResumeOffset(long) + */ + public Builder setTransferredBytes( long transferredBytes ) + { + if ( transferredBytes < 0 ) + { + throw new IllegalArgumentException( "number of transferred bytes cannot be negative" ); + } + this.transferredBytes = transferredBytes; + return this; + } + + /** + * Increments the total number of bytes that have been transferred so far during the download/upload. + * + * @param transferredBytes The number of bytes that have been transferred since the last event, must not be + * negative. + * @return This event builder for chaining, never {@code null}. + */ + public Builder addTransferredBytes( long transferredBytes ) + { + if ( transferredBytes < 0 ) + { + throw new IllegalArgumentException( "number of transferred bytes cannot be negative" ); + } + this.transferredBytes += transferredBytes; + return this; + } + + /** + * Sets the byte buffer holding the transferred bytes since the last event. + * + * @param buffer The byte buffer holding the transferred bytes since the last event, may be {@code null} if not + * applicable to the event. + * @param offset The starting point of valid bytes in the array. + * @param length The number of valid bytes, must not be negative. + * @return This event builder for chaining, never {@code null}. + */ + public Builder setDataBuffer( byte[] buffer, int offset, int length ) + { + return setDataBuffer( ( buffer != null ) ? ByteBuffer.wrap( buffer, offset, length ) : null ); + } + + /** + * Sets the byte buffer holding the transferred bytes since the last event. + * + * @param dataBuffer The byte buffer holding the transferred bytes since the last event, may be {@code null} if + * not applicable to the event. + * @return This event builder for chaining, never {@code null}. + */ + public Builder setDataBuffer( ByteBuffer dataBuffer ) + { + this.dataBuffer = dataBuffer; + return this; + } + + /** + * Sets the error that occurred during the transfer. + * + * @param exception The error that occurred during the transfer, may be {@code null} if none. + * @return This event builder for chaining, never {@code null}. + */ + public Builder setException( Exception exception ) + { + this.exception = exception; + return this; + } + + /** + * Builds a new transfer event from the current values of this builder. The state of the builder itself remains + * unchanged. + * + * @return The transfer event, never {@code null}. + */ + public TransferEvent build() + { + return new TransferEvent( this ); + } + + } + +}