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