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 repositoryUrl;
033
034    private final String resourceName;
035
036    private final File file;
037
038    private final long startTime;
039
040    private final RequestTrace trace;
041
042    private long contentLength = -1;
043
044    private long resumeOffset;
045
046    /**
047     * Creates a new transfer resource with the specified properties.
048     * 
049     * @param repositoryUrl The base URL of the repository, may be {@code null} or empty if unknown. If not empty, a
050     *            trailing slash will automatically be added if missing.
051     * @param resourceName The relative path to the resource within the repository, may be {@code null}. A leading slash
052     *            (if any) will be automatically removed.
053     * @param file The source/target file involved in the transfer, may be {@code null}.
054     * @param trace The trace information, may be {@code null}.
055     */
056    public TransferResource( String repositoryUrl, String resourceName, File file, RequestTrace trace )
057    {
058        if ( repositoryUrl == null || repositoryUrl.length() <= 0 )
059        {
060            this.repositoryUrl = "";
061        }
062        else if ( repositoryUrl.endsWith( "/" ) )
063        {
064            this.repositoryUrl = repositoryUrl;
065        }
066        else
067        {
068            this.repositoryUrl = repositoryUrl + '/';
069        }
070
071        if ( resourceName == null || resourceName.length() <= 0 )
072        {
073            this.resourceName = "";
074        }
075        else if ( resourceName.startsWith( "/" ) )
076        {
077            this.resourceName = resourceName.substring( 1 );
078        }
079        else
080        {
081            this.resourceName = resourceName;
082        }
083
084        this.file = file;
085
086        this.trace = trace;
087
088        startTime = System.currentTimeMillis();
089    }
090
091    /**
092     * The base URL of the repository, e.g. "http://repo1.maven.org/maven2/". Unless the URL is unknown, it will be
093     * terminated by a trailing slash.
094     * 
095     * @return The base URL of the repository or an empty string if unknown, never {@code null}.
096     */
097    public String getRepositoryUrl()
098    {
099        return repositoryUrl;
100    }
101
102    /**
103     * The path of the resource relative to the repository's base URL, e.g. "org/apache/maven/maven/3.0/maven-3.0.pom".
104     * 
105     * @return The path of the resource, never {@code null}.
106     */
107    public String getResourceName()
108    {
109        return resourceName;
110    }
111
112    /**
113     * Gets the local file being uploaded or downloaded. When the repository system merely checks for the existence of a
114     * remote resource, no local file will be involved in the transfer.
115     * 
116     * @return The source/target file involved in the transfer or {@code null} if none.
117     */
118    public File getFile()
119    {
120        return file;
121    }
122
123    /**
124     * The size of the resource in bytes. Note that the size of a resource during downloads might be unknown to the
125     * client which is usually the case when transfers employ compression like gzip. In general, the content length is
126     * not known until the transfer has {@link TransferListener#transferStarted(TransferEvent) started}.
127     * 
128     * @return The size of the resource in bytes or a negative value if unknown.
129     */
130    public long getContentLength()
131    {
132        return contentLength;
133    }
134
135    /**
136     * Sets the size of the resource in bytes.
137     * 
138     * @param contentLength The size of the resource in bytes or a negative value if unknown.
139     * @return This resource for chaining, never {@code null}.
140     */
141    public TransferResource setContentLength( long contentLength )
142    {
143        this.contentLength = contentLength;
144        return this;
145    }
146
147    /**
148     * Gets the byte offset within the resource from which the download starts. A positive offset indicates a previous
149     * download attempt is being resumed, {@code 0} means the transfer starts at the first byte.
150     * 
151     * @return The zero-based index of the first byte being transferred, never negative.
152     */
153    public long getResumeOffset()
154    {
155        return resumeOffset;
156    }
157
158    /**
159     * Sets the byte offset within the resource at which the download starts.
160     * 
161     * @param resumeOffset The zero-based index of the first byte being transferred, must not be negative.
162     * @return This resource for chaining, never {@code null}.
163     */
164    public TransferResource setResumeOffset( long resumeOffset )
165    {
166        if ( resumeOffset < 0 )
167        {
168            throw new IllegalArgumentException( "resume offset cannot be negative" );
169        }
170        this.resumeOffset = resumeOffset;
171        return this;
172    }
173
174    /**
175     * Gets the timestamp when the transfer of this resource was started.
176     * 
177     * @return The timestamp when the transfer of this resource was started.
178     */
179    public long getTransferStartTime()
180    {
181        return startTime;
182    }
183
184    /**
185     * Gets the trace information that describes the higher level request/operation during which this resource is
186     * transferred.
187     * 
188     * @return The trace information about the higher level operation or {@code null} if none.
189     */
190    public RequestTrace getTrace()
191    {
192        return trace;
193    }
194
195    @Override
196    public String toString()
197    {
198        return getRepositoryUrl() + getResourceName() + " <> " + getFile();
199    }
200
201}