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.spi.connector;
020
021import java.io.File;
022import java.nio.file.Path;
023import java.util.Collection;
024import java.util.Collections;
025import java.util.List;
026
027import org.eclipse.aether.RequestTrace;
028import org.eclipse.aether.artifact.Artifact;
029import org.eclipse.aether.repository.RemoteRepository;
030import org.eclipse.aether.transfer.ArtifactTransferException;
031import org.eclipse.aether.transfer.TransferListener;
032
033/**
034 * A download of an artifact from a remote repository. A repository connector processing this download has to use
035 * {@link #setException(ArtifactTransferException)} and {@link #setSupportedContexts(Collection)} (if applicable) to
036 * report the results of the transfer.
037 */
038public final class ArtifactDownload extends ArtifactTransfer {
039
040    private boolean existenceCheck;
041
042    private String checksumPolicy = "";
043
044    private String context = "";
045
046    private Collection<String> contexts;
047
048    private List<RemoteRepository> repositories = Collections.emptyList();
049
050    /**
051     * Creates a new uninitialized download.
052     */
053    public ArtifactDownload() {
054        // enables default constructor
055    }
056
057    /**
058     * Creates a new download with the specified properties.
059     *
060     * @param artifact The artifact to download, may be {@code null}.
061     * @param context The context in which this download is performed, may be {@code null}.
062     * @param file The local file to download the artifact to, may be {@code null}.
063     * @param checksumPolicy The checksum policy, may be {@code null}.
064     * @deprecated Use {@link #ArtifactDownload(Artifact, String, Path, String)} instead.
065     */
066    @Deprecated
067    public ArtifactDownload(Artifact artifact, String context, File file, String checksumPolicy) {
068        setArtifact(artifact);
069        setRequestContext(context);
070        setFile(file);
071        setChecksumPolicy(checksumPolicy);
072    }
073
074    /**
075     * Creates a new download with the specified properties.
076     *
077     * @param artifact The artifact to download, may be {@code null}.
078     * @param context The context in which this download is performed, may be {@code null}.
079     * @param path The local file to download the artifact to, may be {@code null}.
080     * @param checksumPolicy The checksum policy, may be {@code null}.
081     * @since 2.0.0
082     */
083    public ArtifactDownload(Artifact artifact, String context, Path path, String checksumPolicy) {
084        setArtifact(artifact);
085        setRequestContext(context);
086        setPath(path);
087        setChecksumPolicy(checksumPolicy);
088    }
089
090    @Override
091    public ArtifactDownload setArtifact(Artifact artifact) {
092        super.setArtifact(artifact);
093        return this;
094    }
095
096    @Deprecated
097    @Override
098    public ArtifactDownload setFile(File file) {
099        super.setFile(file);
100        return this;
101    }
102
103    @Override
104    public ArtifactDownload setPath(Path path) {
105        super.setPath(path);
106        return this;
107    }
108
109    /**
110     * Indicates whether this transfer shall only verify the existence of the artifact in the remote repository rather
111     * than actually downloading the file. Just like with an actual transfer, a connector is expected to signal the
112     * non-existence of the artifact by associating an {@link org.eclipse.aether.transfer.ArtifactNotFoundException
113     * ArtifactNotFoundException} with this download. <em>Note:</em> If an existence check is requested,
114     * {@link #getFile()} may be {@code null}, i.e. the connector must not try to access the local file.
115     *
116     * @return {@code true} if only the artifact existence shall be verified, {@code false} to actually download the
117     *         artifact.
118     */
119    public boolean isExistenceCheck() {
120        return existenceCheck;
121    }
122
123    /**
124     * Controls whether this transfer shall only verify the existence of the artifact in the remote repository rather
125     * than actually downloading the file.
126     *
127     * @param existenceCheck {@code true} if only the artifact existence shall be verified, {@code false} to actually
128     *            download the artifact.
129     * @return This transfer for chaining, never {@code null}.
130     */
131    public ArtifactDownload setExistenceCheck(boolean existenceCheck) {
132        this.existenceCheck = existenceCheck;
133        return this;
134    }
135
136    /**
137     * Gets the checksum policy for this transfer.
138     *
139     * @return The checksum policy, never {@code null}.
140     */
141    public String getChecksumPolicy() {
142        return checksumPolicy;
143    }
144
145    /**
146     * Sets the checksum policy for this transfer.
147     *
148     * @param checksumPolicy The checksum policy, may be {@code null}.
149     * @return This transfer for chaining, never {@code null}.
150     */
151    public ArtifactDownload setChecksumPolicy(String checksumPolicy) {
152        this.checksumPolicy = (checksumPolicy != null) ? checksumPolicy : "";
153        return this;
154    }
155
156    /**
157     * Gets the context of this transfer.
158     *
159     * @return The context id, never {@code null}.
160     */
161    public String getRequestContext() {
162        return context;
163    }
164
165    /**
166     * Sets the context of this transfer.
167     *
168     * @param context The context id, may be {@code null}.
169     * @return This transfer for chaining, never {@code null}.
170     */
171    public ArtifactDownload setRequestContext(String context) {
172        this.context = (context != null) ? context.intern() : "";
173        return this;
174    }
175
176    /**
177     * Gets the set of request contexts in which the artifact is generally available. Repository managers can indicate
178     * that an artifact is available in more than the requested context to avoid future remote trips for the same
179     * artifact in a different context.
180     *
181     * @return The set of requests context in which the artifact is available, never {@code null}.
182     */
183    public Collection<String> getSupportedContexts() {
184        return (contexts != null) ? contexts : Collections.singleton(context);
185    }
186
187    /**
188     * Sets the set of request contexts in which the artifact is generally available. Repository managers can indicate
189     * that an artifact is available in more than the requested context to avoid future remote trips for the same
190     * artifact in a different context. The set of supported contexts defaults to the original request context if not
191     * overridden by the repository connector.
192     *
193     * @param contexts The set of requests context in which the artifact is available, may be {@code null}.
194     * @return This transfer for chaining, never {@code null}.
195     */
196    public ArtifactDownload setSupportedContexts(Collection<String> contexts) {
197        if (contexts == null || contexts.isEmpty()) {
198            this.contexts = Collections.singleton(context);
199        } else {
200            this.contexts = contexts;
201        }
202        return this;
203    }
204
205    /**
206     * Gets the remote repositories that are being aggregated by the physically contacted remote repository (i.e. a
207     * repository manager).
208     *
209     * @return The remote repositories being aggregated, never {@code null}.
210     */
211    public List<RemoteRepository> getRepositories() {
212        return repositories;
213    }
214
215    /**
216     * Sets the remote repositories that are being aggregated by the physically contacted remote repository (i.e. a
217     * repository manager).
218     *
219     * @param repositories The remote repositories being aggregated, may be {@code null}.
220     * @return This transfer for chaining, never {@code null}.
221     */
222    public ArtifactDownload setRepositories(List<RemoteRepository> repositories) {
223        if (repositories == null) {
224            this.repositories = Collections.emptyList();
225        } else {
226            this.repositories = repositories;
227        }
228        return this;
229    }
230
231    @Override
232    public ArtifactDownload setException(ArtifactTransferException exception) {
233        super.setException(exception);
234        return this;
235    }
236
237    @Override
238    public ArtifactDownload setListener(TransferListener listener) {
239        super.setListener(listener);
240        return this;
241    }
242
243    @Override
244    public ArtifactDownload setTrace(RequestTrace trace) {
245        super.setTrace(trace);
246        return this;
247    }
248
249    @Override
250    public String toString() {
251        return getArtifact() + " - " + (isExistenceCheck() ? "?" : "") + getPath();
252    }
253}