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 }