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.resolution;
020
021import org.eclipse.aether.RepositoryException;
022
023/**
024 * Thrown in case of an unreadable or unresolvable artifact descriptor.
025 */
026public class ArtifactDescriptorException extends RepositoryException {
027
028    private final transient ArtifactDescriptorResult result;
029
030    /**
031     * Creates a new exception with the specified result.
032     * Cause will be first selected exception from result, if applicable. All exceptions are added as suppressed as well.
033     *
034     * @param result The descriptor result at the point the exception occurred, may be {@code null}.
035     */
036    public ArtifactDescriptorException(ArtifactDescriptorResult result) {
037        super(
038                "Failed to read artifact descriptor"
039                        + (result != null ? " for " + result.getRequest().getArtifact() : ""),
040                getFirstCause(result));
041        if (result != null) {
042            result.getExceptions().forEach(this::addSuppressed);
043        }
044        this.result = result;
045    }
046
047    /**
048     * Creates a new exception with the specified result and detail message.
049     * Cause will be first selected exception from result, if applicable. All exceptions are added as suppressed as well.
050     *
051     * @param result The descriptor result at the point the exception occurred, may be {@code null}.
052     * @param message The detail message, may be {@code null}.
053     */
054    public ArtifactDescriptorException(ArtifactDescriptorResult result, String message) {
055        super(message, getFirstCause(result));
056        if (result != null) {
057            result.getExceptions().forEach(this::addSuppressed);
058        }
059        this.result = result;
060    }
061
062    /**
063     * Creates a new exception with the specified result, detail message and cause.
064     * All exceptions are added as suppressed as well.
065     *
066     * @param result The descriptor result at the point the exception occurred, may be {@code null}.
067     * @param message The detail message, may be {@code null}.
068     * @param cause The exception that caused this one, may be {@code null}.
069     */
070    public ArtifactDescriptorException(ArtifactDescriptorResult result, String message, Throwable cause) {
071        super(message, cause);
072        if (result != null) {
073            result.getExceptions().forEach(this::addSuppressed);
074        }
075        this.result = result;
076    }
077
078    /**
079     * Gets the descriptor result at the point the exception occurred. Despite being incomplete, callers might want to
080     * use this result to fail gracefully and continue their operation with whatever interim data has been gathered.
081     *
082     * @return The descriptor result or {@code null} if unknown.
083     */
084    public ArtifactDescriptorResult getResult() {
085        return result;
086    }
087
088    private static Throwable getFirstCause(ArtifactDescriptorResult result) {
089        Throwable cause = null;
090        if (result != null && !result.getExceptions().isEmpty()) {
091            cause = result.getExceptions().get(0);
092        }
093        return cause;
094    }
095}