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;
020
021import java.io.File;
022import java.nio.file.Path;
023import java.util.Collections;
024import java.util.List;
025
026import org.eclipse.aether.artifact.Artifact;
027import org.eclipse.aether.metadata.Metadata;
028import org.eclipse.aether.repository.ArtifactRepository;
029
030import static java.util.Objects.requireNonNull;
031
032/**
033 * An event describing an action performed by the repository system. Note that events which indicate the end of an
034 * action like {@link EventType#ARTIFACT_RESOLVED} are generally fired in both the success and the failure case. Use
035 * {@link #getException()} to check whether an event denotes success or failure.
036 *
037 * @see RepositoryListener
038 * @see RepositoryEvent.Builder
039 */
040public final class RepositoryEvent {
041
042    /**
043     * The type of the repository event.
044     */
045    public enum EventType {
046
047        /**
048         * The artifact descriptor is syntactically or semantically invalid.
049         *
050         * @see RepositoryListener#artifactDescriptorInvalid(RepositoryEvent)
051         */
052        ARTIFACT_DESCRIPTOR_INVALID,
053
054        /**
055         * The artifact descriptor is missing.
056         *
057         * @see RepositoryListener#artifactDescriptorMissing(RepositoryEvent)
058         */
059        ARTIFACT_DESCRIPTOR_MISSING,
060
061        /**
062         * The metadata is syntactically or semantically invalid.
063         *
064         * @see RepositoryListener#metadataInvalid(RepositoryEvent)
065         */
066        METADATA_INVALID,
067
068        /**
069         * An artifact is about to be resolved.
070         *
071         * @see RepositoryListener#artifactResolving(RepositoryEvent)
072         */
073        ARTIFACT_RESOLVING,
074
075        /**
076         * An artifact has been resolved, either successfully or not.
077         *
078         * @see RepositoryListener#artifactResolved(RepositoryEvent)
079         */
080        ARTIFACT_RESOLVED,
081
082        /**
083         * Some metadata is about to be resolved.
084         *
085         * @see RepositoryListener#metadataResolving(RepositoryEvent)
086         */
087        METADATA_RESOLVING,
088
089        /**
090         * Some metadata has been resolved, either successfully or not.
091         *
092         * @see RepositoryListener#metadataResolved(RepositoryEvent)
093         */
094        METADATA_RESOLVED,
095
096        /**
097         * An artifact is about to be downloaded from a remote repository.
098         *
099         * @see RepositoryListener#artifactDownloading(RepositoryEvent)
100         */
101        ARTIFACT_DOWNLOADING,
102
103        /**
104         * An artifact has been downloaded from a remote repository, either successfully or not.
105         *
106         * @see RepositoryListener#artifactDownloaded(RepositoryEvent)
107         */
108        ARTIFACT_DOWNLOADED,
109
110        /**
111         * Some metadata is about to be downloaded from a remote repository.
112         *
113         * @see RepositoryListener#metadataDownloading(RepositoryEvent)
114         */
115        METADATA_DOWNLOADING,
116
117        /**
118         * Some metadata has been downloaded from a remote repository, either successfully or not.
119         *
120         * @see RepositoryListener#metadataDownloaded(RepositoryEvent)
121         */
122        METADATA_DOWNLOADED,
123
124        /**
125         * An artifact is about to be installed to the local repository.
126         *
127         * @see RepositoryListener#artifactInstalling(RepositoryEvent)
128         */
129        ARTIFACT_INSTALLING,
130
131        /**
132         * An artifact has been installed to the local repository, either successfully or not.
133         *
134         * @see RepositoryListener#artifactInstalled(RepositoryEvent)
135         */
136        ARTIFACT_INSTALLED,
137
138        /**
139         * Some metadata is about to be installed to the local repository.
140         *
141         * @see RepositoryListener#metadataInstalling(RepositoryEvent)
142         */
143        METADATA_INSTALLING,
144
145        /**
146         * Some metadata has been installed to the local repository, either successfully or not.
147         *
148         * @see RepositoryListener#metadataInstalled(RepositoryEvent)
149         */
150        METADATA_INSTALLED,
151
152        /**
153         * An artifact is about to be uploaded to a remote repository.
154         *
155         * @see RepositoryListener#artifactDeploying(RepositoryEvent)
156         */
157        ARTIFACT_DEPLOYING,
158
159        /**
160         * An artifact has been uploaded to a remote repository, either successfully or not.
161         *
162         * @see RepositoryListener#artifactDeployed(RepositoryEvent)
163         */
164        ARTIFACT_DEPLOYED,
165
166        /**
167         * Some metadata is about to be uploaded to a remote repository.
168         *
169         * @see RepositoryListener#metadataDeploying(RepositoryEvent)
170         */
171        METADATA_DEPLOYING,
172
173        /**
174         * Some metadata has been uploaded to a remote repository, either successfully or not.
175         *
176         * @see RepositoryListener#metadataDeployed(RepositoryEvent)
177         */
178        METADATA_DEPLOYED
179    }
180
181    private final EventType type;
182
183    private final RepositorySystemSession session;
184
185    private final Artifact artifact;
186
187    private final Metadata metadata;
188
189    private final ArtifactRepository repository;
190
191    private final Path path;
192
193    private final List<Exception> exceptions;
194
195    private final RequestTrace trace;
196
197    RepositoryEvent(Builder builder) {
198        type = builder.type;
199        session = builder.session;
200        artifact = builder.artifact;
201        metadata = builder.metadata;
202        repository = builder.repository;
203        path = builder.path;
204        exceptions = builder.exceptions;
205        trace = builder.trace;
206    }
207
208    /**
209     * Gets the type of the event.
210     *
211     * @return The type of the event, never {@code null}.
212     */
213    public EventType getType() {
214        return type;
215    }
216
217    /**
218     * Gets the repository system session during which the event occurred.
219     *
220     * @return The repository system session during which the event occurred, never {@code null}.
221     */
222    public RepositorySystemSession getSession() {
223        return session;
224    }
225
226    /**
227     * Gets the artifact involved in the event (if any).
228     *
229     * @return The involved artifact or {@code null} if none.
230     */
231    public Artifact getArtifact() {
232        return artifact;
233    }
234
235    /**
236     * Gets the metadata involved in the event (if any).
237     *
238     * @return The involved metadata or {@code null} if none.
239     */
240    public Metadata getMetadata() {
241        return metadata;
242    }
243
244    /**
245     * Gets the file involved in the event (if any).
246     *
247     * @return The involved file or {@code null} if none.
248     * @deprecated Use {@link #getPath()} instead.
249     */
250    @Deprecated
251    public File getFile() {
252        return path != null ? path.toFile() : null;
253    }
254
255    /**
256     * Gets the file involved in the event (if any).
257     *
258     * @return The involved file or {@code null} if none.
259     * @since 2.0.0
260     */
261    public Path getPath() {
262        return path;
263    }
264
265    /**
266     * Gets the repository involved in the event (if any).
267     *
268     * @return The involved repository or {@code null} if none.
269     */
270    public ArtifactRepository getRepository() {
271        return repository;
272    }
273
274    /**
275     * Gets the exception that caused the event (if any). As a rule of thumb, an event accompanied by an exception
276     * indicates a failure of the corresponding action. If multiple exceptions occurred, this method returns the first
277     * exception.
278     *
279     * @return The exception or {@code null} if none.
280     */
281    public Exception getException() {
282        return exceptions.isEmpty() ? null : exceptions.get(0);
283    }
284
285    /**
286     * Gets the exceptions that caused the event (if any). As a rule of thumb, an event accompanied by exceptions
287     * indicates a failure of the corresponding action.
288     *
289     * @return The exceptions, never {@code null}.
290     */
291    public List<Exception> getExceptions() {
292        return exceptions;
293    }
294
295    /**
296     * Gets the trace information about the request during which the event occurred.
297     *
298     * @return The trace information or {@code null} if none.
299     */
300    public RequestTrace getTrace() {
301        return trace;
302    }
303
304    @Override
305    public String toString() {
306        StringBuilder buffer = new StringBuilder(256);
307        buffer.append(getType());
308        if (getArtifact() != null) {
309            buffer.append(" ").append(getArtifact());
310        }
311        if (getMetadata() != null) {
312            buffer.append(" ").append(getMetadata());
313        }
314        if (getPath() != null) {
315            buffer.append(" (").append(getPath()).append(")");
316        }
317        if (getRepository() != null) {
318            buffer.append(" @ ").append(getRepository());
319        }
320        return buffer.toString();
321    }
322
323    /**
324     * A builder to create events.
325     */
326    public static final class Builder {
327
328        final EventType type;
329
330        final RepositorySystemSession session;
331
332        Artifact artifact;
333
334        Metadata metadata;
335
336        ArtifactRepository repository;
337
338        Path path;
339
340        List<Exception> exceptions = Collections.emptyList();
341
342        RequestTrace trace;
343
344        /**
345         * Creates a new event builder for the specified session and event type.
346         *
347         * @param session The repository system session, must not be {@code null}.
348         * @param type The type of the event, must not be {@code null}.
349         */
350        public Builder(RepositorySystemSession session, EventType type) {
351            this.session = requireNonNull(session, "session cannot be null");
352            this.type = requireNonNull(type, "event type cannot be null");
353        }
354
355        /**
356         * Sets the artifact involved in the event.
357         *
358         * @param artifact The involved artifact, may be {@code null}.
359         * @return This event builder for chaining, never {@code null}.
360         */
361        public Builder setArtifact(Artifact artifact) {
362            this.artifact = artifact;
363            return this;
364        }
365
366        /**
367         * Sets the metadata involved in the event.
368         *
369         * @param metadata The involved metadata, may be {@code null}.
370         * @return This event builder for chaining, never {@code null}.
371         */
372        public Builder setMetadata(Metadata metadata) {
373            this.metadata = metadata;
374            return this;
375        }
376
377        /**
378         * Sets the repository involved in the event.
379         *
380         * @param repository The involved repository, may be {@code null}.
381         * @return This event builder for chaining, never {@code null}.
382         */
383        public Builder setRepository(ArtifactRepository repository) {
384            this.repository = repository;
385            return this;
386        }
387
388        /**
389         * Sets the file involved in the event.
390         *
391         * @param file The involved file, may be {@code null}.
392         * @return This event builder for chaining, never {@code null}.
393         * @deprecated Use {@link #setPath(Path)} instead.
394         */
395        @Deprecated
396        public Builder setFile(File file) {
397            return setPath(file != null ? file.toPath() : null);
398        }
399
400        /**
401         * Sets the file involved in the event.
402         *
403         * @param path The involved file, may be {@code null}.
404         * @return This event builder for chaining, never {@code null}.
405         * @since 2.0.0
406         */
407        public Builder setPath(Path path) {
408            this.path = path;
409            return this;
410        }
411
412        /**
413         * Sets the exception causing the event.
414         *
415         * @param exception The exception causing the event, may be {@code null}.
416         * @return This event builder for chaining, never {@code null}.
417         */
418        public Builder setException(Exception exception) {
419            if (exception != null) {
420                this.exceptions = Collections.singletonList(exception);
421            } else {
422                this.exceptions = Collections.emptyList();
423            }
424            return this;
425        }
426
427        /**
428         * Sets the exceptions causing the event.
429         *
430         * @param exceptions The exceptions causing the event, may be {@code null}.
431         * @return This event builder for chaining, never {@code null}.
432         */
433        public Builder setExceptions(List<Exception> exceptions) {
434            if (exceptions != null) {
435                this.exceptions = exceptions;
436            } else {
437                this.exceptions = Collections.emptyList();
438            }
439            return this;
440        }
441
442        /**
443         * Sets the trace information about the request during which the event occurred.
444         *
445         * @param trace The trace information, may be {@code null}.
446         * @return This event builder for chaining, never {@code null}.
447         */
448        public Builder setTrace(RequestTrace trace) {
449            this.trace = trace;
450            return this;
451        }
452
453        /**
454         * Builds a new event from the current values of this builder. The state of the builder itself remains
455         * unchanged.
456         *
457         * @return The event, never {@code null}.
458         */
459        public RepositoryEvent build() {
460            return new RepositoryEvent(this);
461        }
462    }
463}