1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.eclipse.aether.transfer;
20
21 import java.io.File;
22 import java.nio.file.Path;
23
24 import org.eclipse.aether.RequestTrace;
25
26 /**
27 * Describes a resource being uploaded or downloaded by the repository system.
28 */
29 public final class TransferResource {
30
31 private final String repositoryId;
32
33 private final String repositoryUrl;
34
35 private final String resourceName;
36
37 private final Object resource;
38
39 private final Path path;
40
41 private final long startTime;
42
43 private final RequestTrace trace;
44
45 private long contentLength = -1L;
46
47 private long resumeOffset;
48
49 /**
50 * Creates a new transfer resource with the specified properties.
51 *
52 * @param repositoryId The ID of the repository used to transfer the resource, may be {@code null} or
53 * empty if unknown.
54 * @param repositoryUrl The base URL of the repository, may be {@code null} or empty if unknown. If not empty, a
55 * trailing slash will automatically be added if missing.
56 * @param resourceName The relative path to the resource within the repository, may be {@code null}. A leading slash
57 * (if any) will be automatically removed.
58 * @param file The source/target file involved in the transfer, may be {@code null}.
59 * @param trace The trace information, may be {@code null}.
60 *
61 * @since 1.1.0
62 * @deprecated Use {@link TransferResource(String, String, String, Path, Object, RequestTrace)} instead.
63 */
64 @Deprecated
65 public TransferResource(
66 String repositoryId, String repositoryUrl, String resourceName, File file, RequestTrace trace) {
67 this(repositoryId, repositoryUrl, resourceName, file != null ? file.toPath() : null, null, trace);
68 }
69
70 /**
71 * Creates a new transfer resource with the specified properties.
72 *
73 * @param repositoryId The ID of the repository used to transfer the resource, may be {@code null} or
74 * empty if unknown.
75 * @param repositoryUrl The base URL of the repository, may be {@code null} or empty if unknown. If not empty, a
76 * trailing slash will automatically be added if missing.
77 * @param resourceName The relative path to the resource within the repository, may be {@code null}. A leading slash
78 * (if any) will be automatically removed.
79 * @param path The source/target file involved in the transfer, may be {@code null}.
80 * @param resource The representation of this resource, may be {@code null}.
81 * @param trace The trace information, may be {@code null}.
82 *
83 * @since 2.0.0
84 */
85 public TransferResource(
86 String repositoryId,
87 String repositoryUrl,
88 String resourceName,
89 Path path,
90 Object resource,
91 RequestTrace trace) {
92 if (repositoryId == null || repositoryId.isEmpty()) {
93 this.repositoryId = "";
94 } else {
95 this.repositoryId = repositoryId;
96 }
97
98 if (repositoryUrl == null || repositoryUrl.isEmpty()) {
99 this.repositoryUrl = "";
100 } else if (repositoryUrl.endsWith("/")) {
101 this.repositoryUrl = repositoryUrl;
102 } else {
103 this.repositoryUrl = repositoryUrl + '/';
104 }
105
106 if (resourceName == null || resourceName.isEmpty()) {
107 this.resourceName = "";
108 } else if (resourceName.startsWith("/")) {
109 this.resourceName = resourceName.substring(1);
110 } else {
111 this.resourceName = resourceName;
112 }
113
114 this.path = path;
115 this.resource = resource;
116 this.trace = trace;
117 this.startTime = System.currentTimeMillis();
118 }
119
120 /**
121 * The ID of the repository, e.g., "central".
122 *
123 * @return The ID of the repository or an empty string if unknown, never {@code null}.
124 *
125 * @since 1.1.0
126 */
127 public String getRepositoryId() {
128 return repositoryId;
129 }
130
131 /**
132 * The base URL of the repository, e.g. "https://repo1.maven.org/maven2/". Unless the URL is unknown, it will be
133 * terminated by a trailing slash.
134 *
135 * @return The base URL of the repository or an empty string if unknown, never {@code null}.
136 */
137 public String getRepositoryUrl() {
138 return repositoryUrl;
139 }
140
141 /**
142 * The path of the resource relative to the repository's base URL, e.g. "org/apache/maven/maven/3.0/maven-3.0.pom".
143 *
144 * @return The path of the resource, never {@code null}.
145 */
146 public String getResourceName() {
147 return resourceName;
148 }
149
150 /**
151 * The representation of "resource", if any. The content of this field may be
152 * {@link org.eclipse.aether.artifact.Artifact} or {@link org.eclipse.aether.metadata.Metadata} or {@code null}
153 * in case of some legacy flow. Preferred way to handle returned value is with {@code instanceof}.
154 *
155 * @return The representation of this resource, may be {@code null}.
156 * @since 2.0.0
157 */
158 public Object getResource() {
159 return resource;
160 }
161
162 /**
163 * Gets the local file being uploaded or downloaded. When the repository system merely checks for the existence of a
164 * remote resource, no local file will be involved in the transfer.
165 *
166 * @return The source/target file involved in the transfer or {@code null} if none.
167 * @deprecated Use {@link #getPath()} instead.
168 */
169 @Deprecated
170 public File getFile() {
171 return path != null ? path.toFile() : null;
172 }
173
174 /**
175 * Gets the local file being uploaded or downloaded. When the repository system merely checks for the existence of a
176 * remote resource, no local file will be involved in the transfer.
177 *
178 * @return The source/target file involved in the transfer or {@code null} if none.
179 * @since 2.0.0
180 */
181 public Path getPath() {
182 return path;
183 }
184
185 /**
186 * The size of the resource in bytes. Note that the size of a resource during downloads might be unknown to the
187 * client which is usually the case when transfers employ compression like gzip. In general, the content length is
188 * not known until the transfer has {@link TransferListener#transferStarted(TransferEvent) started}.
189 *
190 * @return The size of the resource in bytes or a negative value if unknown.
191 */
192 public long getContentLength() {
193 return contentLength;
194 }
195
196 /**
197 * Sets the size of the resource in bytes.
198 *
199 * @param contentLength The size of the resource in bytes or a negative value if unknown.
200 * @return This resource for chaining, never {@code null}.
201 */
202 public TransferResource setContentLength(long contentLength) {
203 this.contentLength = contentLength;
204 return this;
205 }
206
207 /**
208 * Gets the byte offset within the resource from which the download starts. A positive offset indicates a previous
209 * download attempt is being resumed, {@code 0} means the transfer starts at the first byte.
210 *
211 * @return The zero-based index of the first byte being transferred, never negative.
212 */
213 public long getResumeOffset() {
214 return resumeOffset;
215 }
216
217 /**
218 * Sets the byte offset within the resource at which the download starts.
219 *
220 * @param resumeOffset The zero-based index of the first byte being transferred, must not be negative.
221 * @return This resource for chaining, never {@code null}.
222 */
223 public TransferResource setResumeOffset(long resumeOffset) {
224 if (resumeOffset < 0L) {
225 throw new IllegalArgumentException("resume offset cannot be negative");
226 }
227 this.resumeOffset = resumeOffset;
228 return this;
229 }
230
231 /**
232 * Gets the timestamp when the transfer of this resource was started.
233 *
234 * @return The timestamp when the transfer of this resource was started.
235 */
236 public long getTransferStartTime() {
237 return startTime;
238 }
239
240 /**
241 * Gets the trace information that describes the higher level request/operation during which this resource is
242 * transferred.
243 *
244 * @return The trace information about the higher level operation or {@code null} if none.
245 */
246 public RequestTrace getTrace() {
247 return trace;
248 }
249
250 @Override
251 public String toString() {
252 return getRepositoryUrl() + getResourceName() + " <> " + getPath();
253 }
254 }