001package org.eclipse.aether.impl;
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;
023
024import org.eclipse.aether.RepositoryException;
025import org.eclipse.aether.repository.RemoteRepository;
026
027/**
028 * A request to check if an update of an artifact/metadata from a remote repository is needed.
029 * 
030 * @param <T>
031 * @param <E>
032 * @see UpdateCheckManager
033 * @provisional This type is provisional and can be changed, moved or removed without prior notice.
034 */
035public final class UpdateCheck<T, E extends RepositoryException>
036{
037
038    private long localLastUpdated;
039
040    private T item;
041
042    private File file;
043
044    private boolean fileValid = true;
045
046    private String policy;
047
048    private RemoteRepository repository;
049
050    private RemoteRepository authoritativeRepository;
051
052    private boolean required;
053
054    private E exception;
055
056    /**
057     * Creates an uninitialized update check request.
058     */
059    public UpdateCheck()
060    {
061    }
062
063    /**
064     * Gets the last-modified timestamp of the corresponding item produced by a local installation. If non-zero, a
065     * remote update will be surpressed if the local item is up-to-date, even if the remote item has not been cached
066     * locally.
067     * 
068     * @return The last-modified timestamp of the corresponding item produced by a local installation or {@code 0} to
069     *         ignore any local item.
070     */
071    public long getLocalLastUpdated()
072    {
073        return localLastUpdated;
074    }
075
076    /**
077     * Sets the last-modified timestamp of the corresponding item produced by a local installation. If non-zero, a
078     * remote update will be surpressed if the local item is up-to-date, even if the remote item has not been cached
079     * locally.
080     * 
081     * @param localLastUpdated The last-modified timestamp of the corresponding item produced by a local installation or
082     *            {@code 0} to ignore any local item.
083     * @return This object for chaining.
084     */
085    public UpdateCheck<T, E> setLocalLastUpdated( long localLastUpdated )
086    {
087        this.localLastUpdated = localLastUpdated;
088        return this;
089    }
090
091    /**
092     * Gets the item of the check.
093     * 
094     * @return The item of the check, never {@code null}.
095     */
096    public T getItem()
097    {
098        return item;
099    }
100
101    /**
102     * Sets the item of the check.
103     * 
104     * @param item The item of the check, must not be {@code null}.
105     * @return This object for chaining.
106     */
107    public UpdateCheck<T, E> setItem( T item )
108    {
109        this.item = item;
110        return this;
111    }
112
113    /**
114     * Returns the local file of the item.
115     * 
116     * @return The local file of the item.
117     */
118    public File getFile()
119    {
120        return file;
121    }
122
123    /**
124     * Sets the local file of the item.
125     * 
126     * @param file The file of the item, never {@code null} .
127     * @return This object for chaining.
128     */
129    public UpdateCheck<T, E> setFile( File file )
130    {
131        this.file = file;
132        return this;
133    }
134
135    /**
136     * Indicates whether the local file given by {@link #getFile()}, if existent, should be considered valid or not. An
137     * invalid file is equivalent to a physically missing file.
138     * 
139     * @return {@code true} if the file should be considered valid if existent, {@code false} if the file should be
140     *         treated as if it was missing.
141     */
142    public boolean isFileValid()
143    {
144        return fileValid;
145    }
146
147    /**
148     * Controls whether the local file given by {@link #getFile()}, if existent, should be considered valid or not. An
149     * invalid file is equivalent to a physically missing file.
150     * 
151     * @param fileValid {@code true} if the file should be considered valid if existent, {@code false} if the file
152     *            should be treated as if it was missing.
153     * @return This object for chaining.
154     */
155    public UpdateCheck<T, E> setFileValid( boolean fileValid )
156    {
157        this.fileValid = fileValid;
158        return this;
159    }
160
161    /**
162     * Gets the policy to use for the check.
163     * 
164     * @return The policy to use for the check.
165     * @see org.eclipse.aether.repository.RepositoryPolicy
166     */
167    public String getPolicy()
168    {
169        return policy;
170    }
171
172    /**
173     * Sets the policy to use for the check.
174     * 
175     * @param policy The policy to use for the check, may be {@code null}.
176     * @return This object for chaining.
177     * @see org.eclipse.aether.repository.RepositoryPolicy
178     */
179    public UpdateCheck<T, E> setPolicy( String policy )
180    {
181        this.policy = policy;
182        return this;
183    }
184
185    /**
186     * Gets the repository from which a potential update/download will performed.
187     * 
188     * @return The repository to use for the check.
189     */
190    public RemoteRepository getRepository()
191    {
192        return repository;
193    }
194
195    /**
196     * Sets the repository from which a potential update/download will performed.
197     * 
198     * @param repository The repository to use for the check, must not be {@code null}.
199     * @return This object for chaining.
200     */
201    public UpdateCheck<T, E> setRepository( RemoteRepository repository )
202    {
203        this.repository = repository;
204        return this;
205    }
206
207    /**
208     * Gets the repository which ultimately hosts the metadata to update. This will be different from the repository
209     * given by {@link #getRepository()} in case the latter denotes a repository manager.
210     * 
211     * @return The actual repository hosting the authoritative copy of the metadata to update, never {@code null} for a
212     *         metadata update check.
213     */
214    public RemoteRepository getAuthoritativeRepository()
215    {
216        return authoritativeRepository != null ? authoritativeRepository : repository;
217    }
218
219    /**
220     * Sets the repository which ultimately hosts the metadata to update. This will be different from the repository
221     * given by {@link #getRepository()} in case the latter denotes a repository manager.
222     * 
223     * @param authoritativeRepository The actual repository hosting the authoritative copy of the metadata to update,
224     *            must not be {@code null} for a metadata update check.
225     * @return This object for chaining.
226     */
227    public UpdateCheck<T, E> setAuthoritativeRepository( RemoteRepository authoritativeRepository )
228    {
229        this.authoritativeRepository = authoritativeRepository;
230        return this;
231    }
232
233    /**
234     * Gets the result of a check, denoting whether the remote repository should be checked for updates.
235     * 
236     * @return The result of a check.
237     */
238    public boolean isRequired()
239    {
240        return required;
241    }
242
243    /**
244     * Sets the result of an update check.
245     * 
246     * @param required The result of an update check. In case of {@code false} and the local file given by
247     *            {@link #getFile()} does actually not exist, {@link #setException(RepositoryException)} should be used
248     *            to provide the previous/cached failure that explains the absence of the file.
249     * @return This object for chaining.
250     */
251    public UpdateCheck<T, E> setRequired( boolean required )
252    {
253        this.required = required;
254        return this;
255    }
256
257    /**
258     * Gets the exception that occurred during the update check.
259     * 
260     * @return The occurred exception or {@code null} if the update check was successful.
261     */
262    public E getException()
263    {
264        return exception;
265    }
266
267    /**
268     * Sets the exception for this update check.
269     * 
270     * @param exception The exception for this update check, may be {@code null} if the check was successful.
271     * @return This object for chaining.
272     */
273    public UpdateCheck<T, E> setException( E exception )
274    {
275        this.exception = exception;
276        return this;
277    }
278
279    @Override
280    public String toString()
281    {
282        return getPolicy() + ": " + getFile() + " < " + getRepository();
283    }
284
285}