001package org.eclipse.aether.transfer;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 * 
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 * 
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023
024import org.eclipse.aether.RequestTrace;
025
026/**
027 * Describes a resource being uploaded or downloaded by the repository system.
028 */
029public final class TransferResource
030{
031
032    private final String repositoryId;
033
034    private final String repositoryUrl;
035
036    private final String resourceName;
037
038    private final File file;
039
040    private final long startTime;
041
042    private final RequestTrace trace;
043
044    private long contentLength = -1L;
045
046    private long resumeOffset;
047
048    /**
049     * Creates a new transfer resource with the specified properties.
050     *
051     * @param repositoryUrl The base URL of the repository, may be {@code null} or empty if unknown. If not empty, a
052     * trailing slash will automatically be added if missing.
053     * @param resourceName The relative path to the resource within the repository, may be {@code null}. A leading slash
054     * (if any) will be automatically removed.
055     * @param file The source/target file involved in the transfer, may be {@code null}.
056     * @param trace The trace information, may be {@code null}.
057     *
058     * @deprecated As of 1.1.0, replaced by {@link #TransferResource(java.lang.String, java.lang.String,
059     * java.lang.String, java.io.File, org.eclipse.aether.RequestTrace)}
060     */
061    @Deprecated
062    public TransferResource( String repositoryUrl, String resourceName, File file, RequestTrace trace )
063    {
064        this( null, repositoryUrl, resourceName, file, trace );
065    }
066
067    /**
068     * Creates a new transfer resource with the specified properties.
069     *
070     * @param repositoryId The ID of the repository used to transfer the resource, may be {@code null} or empty if unknown.
071     * @param repositoryUrl The base URL of the repository, may be {@code null} or empty if unknown. If not empty, a
072     *            trailing slash will automatically be added if missing.
073     * @param resourceName The relative path to the resource within the repository, may be {@code null}. A leading slash
074     *            (if any) will be automatically removed.
075     * @param file The source/target file involved in the transfer, may be {@code null}.
076     * @param trace The trace information, may be {@code null}.
077     *
078     * @since 1.1.0
079     */
080    public TransferResource( String repositoryId, String repositoryUrl, String resourceName,
081        File file, RequestTrace trace )
082    {
083        if ( repositoryId == null || repositoryId.length() <= 0 )
084        {
085            this.repositoryId = "";
086        }
087        else
088        {
089            this.repositoryId = repositoryId;
090        }
091
092        if ( repositoryUrl == null || repositoryUrl.length() <= 0 )
093        {
094            this.repositoryUrl = "";
095        }
096        else if ( repositoryUrl.endsWith( "/" ) )
097        {
098            this.repositoryUrl = repositoryUrl;
099        }
100        else
101        {
102            this.repositoryUrl = repositoryUrl + '/';
103        }
104
105        if ( resourceName == null || resourceName.length() <= 0 )
106        {
107            this.resourceName = "";
108        }
109        else if ( resourceName.startsWith( "/" ) )
110        {
111            this.resourceName = resourceName.substring( 1 );
112        }
113        else
114        {
115            this.resourceName = resourceName;
116        }
117
118        this.file = file;
119
120        this.trace = trace;
121
122        startTime = System.currentTimeMillis();
123    }
124
125    /**
126     * The ID of the repository, e.g., "central".
127     *
128     * @return The ID of the repository or an empty string if unknown, never {@code null}.
129     *
130     * @since 1.1.0
131     */
132    public String getRepositoryId()
133    {
134        return repositoryId;
135    }
136
137    /**
138     * The base URL of the repository, e.g. "http://repo1.maven.org/maven2/". Unless the URL is unknown, it will be
139     * terminated by a trailing slash.
140     *
141     * @return The base URL of the repository or an empty string if unknown, never {@code null}.
142     */
143    public String getRepositoryUrl()
144    {
145        return repositoryUrl;
146    }
147
148    /**
149     * The path of the resource relative to the repository's base URL, e.g. "org/apache/maven/maven/3.0/maven-3.0.pom".
150     *
151     * @return The path of the resource, never {@code null}.
152     */
153    public String getResourceName()
154    {
155        return resourceName;
156    }
157
158    /**
159     * Gets the local file being uploaded or downloaded. When the repository system merely checks for the existence of a
160     * remote resource, no local file will be involved in the transfer.
161     *
162     * @return The source/target file involved in the transfer or {@code null} if none.
163     */
164    public File getFile()
165    {
166        return file;
167    }
168
169    /**
170     * The size of the resource in bytes. Note that the size of a resource during downloads might be unknown to the
171     * client which is usually the case when transfers employ compression like gzip. In general, the content length is
172     * not known until the transfer has {@link TransferListener#transferStarted(TransferEvent) started}.
173     *
174     * @return The size of the resource in bytes or a negative value if unknown.
175     */
176    public long getContentLength()
177    {
178        return contentLength;
179    }
180
181    /**
182     * Sets the size of the resource in bytes.
183     *
184     * @param contentLength The size of the resource in bytes or a negative value if unknown.
185     * @return This resource for chaining, never {@code null}.
186     */
187    public TransferResource setContentLength( long contentLength )
188    {
189        this.contentLength = contentLength;
190        return this;
191    }
192
193    /**
194     * Gets the byte offset within the resource from which the download starts. A positive offset indicates a previous
195     * download attempt is being resumed, {@code 0} means the transfer starts at the first byte.
196     *
197     * @return The zero-based index of the first byte being transferred, never negative.
198     */
199    public long getResumeOffset()
200    {
201        return resumeOffset;
202    }
203
204    /**
205     * Sets the byte offset within the resource at which the download starts.
206     *
207     * @param resumeOffset The zero-based index of the first byte being transferred, must not be negative.
208     * @return This resource for chaining, never {@code null}.
209     */
210    public TransferResource setResumeOffset( long resumeOffset )
211    {
212        if ( resumeOffset < 0L )
213        {
214            throw new IllegalArgumentException( "resume offset cannot be negative" );
215        }
216        this.resumeOffset = resumeOffset;
217        return this;
218    }
219
220    /**
221     * Gets the timestamp when the transfer of this resource was started.
222     *
223     * @return The timestamp when the transfer of this resource was started.
224     */
225    public long getTransferStartTime()
226    {
227        return startTime;
228    }
229
230    /**
231     * Gets the trace information that describes the higher level request/operation during which this resource is
232     * transferred.
233     *
234     * @return The trace information about the higher level operation or {@code null} if none.
235     */
236    public RequestTrace getTrace()
237    {
238        return trace;
239    }
240
241    @Override
242    public String toString()
243    {
244        return getRepositoryUrl() + getResourceName() + " <> " + getFile();
245    }
246
247}