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