View Javadoc
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 Path path;
38  
39      private final long startTime;
40  
41      private final RequestTrace trace;
42  
43      private long contentLength = -1L;
44  
45      private long resumeOffset;
46  
47      /**
48       * Creates a new transfer resource with the specified properties.
49       *
50       * @param repositoryId The ID of the repository used to transfer the resource, may be {@code null} or
51       *                     empty if unknown.
52       * @param repositoryUrl The base URL of the repository, may be {@code null} or empty if unknown. If not empty, a
53       *            trailing slash will automatically be added if missing.
54       * @param resourceName The relative path to the resource within the repository, may be {@code null}. A leading slash
55       *            (if any) will be automatically removed.
56       * @param file The source/target file involved in the transfer, may be {@code null}.
57       * @param trace The trace information, may be {@code null}.
58       *
59       * @since 1.1.0
60       * @deprecated Use {@link TransferResource(String, String, String, Path, RequestTrace)} instead.
61       */
62      @Deprecated
63      public TransferResource(
64              String repositoryId, String repositoryUrl, String resourceName, File file, RequestTrace trace) {
65          this(repositoryId, repositoryUrl, resourceName, file != null ? file.toPath() : null, trace);
66      }
67  
68      /**
69       * Creates a new transfer resource with the specified properties.
70       *
71       * @param repositoryId The ID of the repository used to transfer the resource, may be {@code null} or
72       *                     empty if unknown.
73       * @param repositoryUrl The base URL of the repository, may be {@code null} or empty if unknown. If not empty, a
74       *            trailing slash will automatically be added if missing.
75       * @param resourceName The relative path to the resource within the repository, may be {@code null}. A leading slash
76       *            (if any) will be automatically removed.
77       * @param path The source/target file involved in the transfer, may be {@code null}.
78       * @param trace The trace information, may be {@code null}.
79       *
80       * @since 2.0.0
81       */
82      public TransferResource(
83              String repositoryId, String repositoryUrl, String resourceName, Path path, RequestTrace trace) {
84          if (repositoryId == null || repositoryId.isEmpty()) {
85              this.repositoryId = "";
86          } else {
87              this.repositoryId = repositoryId;
88          }
89  
90          if (repositoryUrl == null || repositoryUrl.isEmpty()) {
91              this.repositoryUrl = "";
92          } else if (repositoryUrl.endsWith("/")) {
93              this.repositoryUrl = repositoryUrl;
94          } else {
95              this.repositoryUrl = repositoryUrl + '/';
96          }
97  
98          if (resourceName == null || resourceName.isEmpty()) {
99              this.resourceName = "";
100         } else if (resourceName.startsWith("/")) {
101             this.resourceName = resourceName.substring(1);
102         } else {
103             this.resourceName = resourceName;
104         }
105 
106         this.path = path;
107 
108         this.trace = trace;
109 
110         startTime = System.currentTimeMillis();
111     }
112 
113     /**
114      * The ID of the repository, e.g., "central".
115      *
116      * @return The ID of the repository or an empty string if unknown, never {@code null}.
117      *
118      * @since 1.1.0
119      */
120     public String getRepositoryId() {
121         return repositoryId;
122     }
123 
124     /**
125      * The base URL of the repository, e.g. "https://repo1.maven.org/maven2/". Unless the URL is unknown, it will be
126      * terminated by a trailing slash.
127      *
128      * @return The base URL of the repository or an empty string if unknown, never {@code null}.
129      */
130     public String getRepositoryUrl() {
131         return repositoryUrl;
132     }
133 
134     /**
135      * The path of the resource relative to the repository's base URL, e.g. "org/apache/maven/maven/3.0/maven-3.0.pom".
136      *
137      * @return The path of the resource, never {@code null}.
138      */
139     public String getResourceName() {
140         return resourceName;
141     }
142 
143     /**
144      * Gets the local file being uploaded or downloaded. When the repository system merely checks for the existence of a
145      * remote resource, no local file will be involved in the transfer.
146      *
147      * @return The source/target file involved in the transfer or {@code null} if none.
148      * @deprecated Use {@link #getPath()} instead.
149      */
150     @Deprecated
151     public File getFile() {
152         return path != null ? path.toFile() : null;
153     }
154 
155     /**
156      * Gets the local file being uploaded or downloaded. When the repository system merely checks for the existence of a
157      * remote resource, no local file will be involved in the transfer.
158      *
159      * @return The source/target file involved in the transfer or {@code null} if none.
160      * @since 2.0.0
161      */
162     public Path getPath() {
163         return path;
164     }
165 
166     /**
167      * The size of the resource in bytes. Note that the size of a resource during downloads might be unknown to the
168      * client which is usually the case when transfers employ compression like gzip. In general, the content length is
169      * not known until the transfer has {@link TransferListener#transferStarted(TransferEvent) started}.
170      *
171      * @return The size of the resource in bytes or a negative value if unknown.
172      */
173     public long getContentLength() {
174         return contentLength;
175     }
176 
177     /**
178      * Sets the size of the resource in bytes.
179      *
180      * @param contentLength The size of the resource in bytes or a negative value if unknown.
181      * @return This resource for chaining, never {@code null}.
182      */
183     public TransferResource setContentLength(long contentLength) {
184         this.contentLength = contentLength;
185         return this;
186     }
187 
188     /**
189      * Gets the byte offset within the resource from which the download starts. A positive offset indicates a previous
190      * download attempt is being resumed, {@code 0} means the transfer starts at the first byte.
191      *
192      * @return The zero-based index of the first byte being transferred, never negative.
193      */
194     public long getResumeOffset() {
195         return resumeOffset;
196     }
197 
198     /**
199      * Sets the byte offset within the resource at which the download starts.
200      *
201      * @param resumeOffset The zero-based index of the first byte being transferred, must not be negative.
202      * @return This resource for chaining, never {@code null}.
203      */
204     public TransferResource setResumeOffset(long resumeOffset) {
205         if (resumeOffset < 0L) {
206             throw new IllegalArgumentException("resume offset cannot be negative");
207         }
208         this.resumeOffset = resumeOffset;
209         return this;
210     }
211 
212     /**
213      * Gets the timestamp when the transfer of this resource was started.
214      *
215      * @return The timestamp when the transfer of this resource was started.
216      */
217     public long getTransferStartTime() {
218         return startTime;
219     }
220 
221     /**
222      * Gets the trace information that describes the higher level request/operation during which this resource is
223      * transferred.
224      *
225      * @return The trace information about the higher level operation or {@code null} if none.
226      */
227     public RequestTrace getTrace() {
228         return trace;
229     }
230 
231     @Override
232     public String toString() {
233         return getRepositoryUrl() + getResourceName() + " <> " + getPath();
234     }
235 }