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