001package org.eclipse.aether.spi.connector;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 * 
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 * 
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
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
039    extends ArtifactTransfer
040{
041
042    private boolean existenceCheck;
043
044    private String checksumPolicy = "";
045
046    private String context = "";
047
048    private Collection<String> contexts;
049
050    private List<RemoteRepository> repositories = Collections.emptyList();
051
052    /**
053     * Creates a new uninitialized download.
054     */
055    public ArtifactDownload()
056    {
057        // enables default constructor
058    }
059
060    /**
061     * Creates a new download with the specified properties.
062     * 
063     * @param artifact The artifact to download, may be {@code null}.
064     * @param context The context in which this download is performed, may be {@code null}.
065     * @param file The local file to download the artifact to, may be {@code null}.
066     * @param checksumPolicy The checksum policy, may be {@code null}.
067     */
068    public ArtifactDownload( Artifact artifact, String context, File file, String checksumPolicy )
069    {
070        setArtifact( artifact );
071        setRequestContext( context );
072        setFile( file );
073        setChecksumPolicy( checksumPolicy );
074    }
075
076    @Override
077    public ArtifactDownload setArtifact( Artifact artifact )
078    {
079        super.setArtifact( artifact );
080        return this;
081    }
082
083    /**
084     * {@inheritDoc} <em>Note:</em> In case of {@link #isExistenceCheck()}, this method may return {@code null}.
085     */
086    @Override
087    public File getFile()
088    {
089        return super.getFile();
090    }
091
092    @Override
093    public ArtifactDownload setFile( File file )
094    {
095        super.setFile( file );
096        return this;
097    }
098
099    /**
100     * Indicates whether this transfer shall only verify the existence of the artifact in the remote repository rather
101     * than actually downloading the file. Just like with an actual transfer, a connector is expected to signal the
102     * non-existence of the artifact by associating an {@link org.eclipse.aether.transfer.ArtifactNotFoundException
103     * ArtifactNotFoundException} with this download. <em>Note:</em> If an existence check is requested,
104     * {@link #getFile()} may be {@code null}, i.e. the connector must not try to access the local file.
105     * 
106     * @return {@code true} if only the artifact existence shall be verified, {@code false} to actually download the
107     *         artifact.
108     */
109    public boolean isExistenceCheck()
110    {
111        return existenceCheck;
112    }
113
114    /**
115     * Controls whether this transfer shall only verify the existence of the artifact in the remote repository rather
116     * than actually downloading the file.
117     * 
118     * @param existenceCheck {@code true} if only the artifact existence shall be verified, {@code false} to actually
119     *            download the artifact.
120     * @return This transfer for chaining, never {@code null}.
121     */
122    public ArtifactDownload setExistenceCheck( boolean existenceCheck )
123    {
124        this.existenceCheck = existenceCheck;
125        return this;
126    }
127
128    /**
129     * Gets the checksum policy for this transfer.
130     * 
131     * @return The checksum policy, never {@code null}.
132     */
133    public String getChecksumPolicy()
134    {
135        return checksumPolicy;
136    }
137
138    /**
139     * Sets the checksum policy for this transfer.
140     * 
141     * @param checksumPolicy The checksum policy, may be {@code null}.
142     * @return This transfer for chaining, never {@code null}.
143     */
144    public ArtifactDownload setChecksumPolicy( String checksumPolicy )
145    {
146        this.checksumPolicy = ( checksumPolicy != null ) ? checksumPolicy : "";
147        return this;
148    }
149
150    /**
151     * Gets the context of this transfer.
152     * 
153     * @return The context id, never {@code null}.
154     */
155    public String getRequestContext()
156    {
157        return context;
158    }
159
160    /**
161     * Sets the context of this transfer.
162     * 
163     * @param context The context id, may be {@code null}.
164     * @return This transfer for chaining, never {@code null}.
165     */
166    public ArtifactDownload setRequestContext( String context )
167    {
168        this.context = ( context != null ) ? context : "";
169        return this;
170    }
171
172    /**
173     * Gets the set of request contexts in which the artifact is generally available. Repository managers can indicate
174     * that an artifact is available in more than the requested context to avoid future remote trips for the same
175     * artifact in a different context.
176     * 
177     * @return The set of requests context in which the artifact is available, never {@code null}.
178     */
179    public Collection<String> getSupportedContexts()
180    {
181        return ( contexts != null ) ? contexts : Collections.singleton( context );
182    }
183
184    /**
185     * Sets the set of request contexts in which the artifact is generally available. Repository managers can indicate
186     * that an artifact is available in more than the requested context to avoid future remote trips for the same
187     * artifact in a different context. The set of supported contexts defaults to the original request context if not
188     * overridden by the repository connector.
189     * 
190     * @param contexts The set of requests context in which the artifact is available, may be {@code null}.
191     * @return This transfer for chaining, never {@code null}.
192     */
193    public ArtifactDownload setSupportedContexts( Collection<String> contexts )
194    {
195        if ( contexts == null || contexts.isEmpty() )
196        {
197            this.contexts = Collections.singleton( context );
198        }
199        else
200        {
201            this.contexts = contexts;
202        }
203        return this;
204    }
205
206    /**
207     * Gets the remote repositories that are being aggregated by the physically contacted remote repository (i.e. a
208     * repository manager).
209     * 
210     * @return The remote repositories being aggregated, never {@code null}.
211     */
212    public List<RemoteRepository> getRepositories()
213    {
214        return repositories;
215    }
216
217    /**
218     * Sets the remote repositories that are being aggregated by the physically contacted remote repository (i.e. a
219     * repository manager).
220     * 
221     * @param repositories The remote repositories being aggregated, may be {@code null}.
222     * @return This transfer for chaining, never {@code null}.
223     */
224    public ArtifactDownload setRepositories( List<RemoteRepository> repositories )
225    {
226        if ( repositories == null )
227        {
228            this.repositories = Collections.emptyList();
229        }
230        else
231        {
232            this.repositories = repositories;
233        }
234        return this;
235    }
236
237    @Override
238    public ArtifactDownload setException( ArtifactTransferException exception )
239    {
240        super.setException( exception );
241        return this;
242    }
243
244    @Override
245    public ArtifactDownload setListener( TransferListener listener )
246    {
247        super.setListener( listener );
248        return this;
249    }
250
251    @Override
252    public ArtifactDownload setTrace( RequestTrace trace )
253    {
254        super.setTrace( trace );
255        return this;
256    }
257
258    @Override
259    public String toString()
260    {
261        return getArtifact() + " - " + ( isExistenceCheck() ? "?" : "" ) + getFile();
262    }
263
264}