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