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