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 unparseable or unresolvable version range.
025 */
026public class VersionRangeResolutionException extends RepositoryException {
027
028    private final transient VersionRangeResult 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 version range result at the point the exception occurred, may be {@code null}.
035     */
036    public VersionRangeResolutionException(VersionRangeResult result) {
037        super(getMessage(result), getFirstCause(result));
038        if (result != null) {
039            result.getExceptions().forEach(this::addSuppressed);
040        }
041        this.result = result;
042    }
043
044    private static String getMessage(VersionRangeResult result) {
045        StringBuilder buffer = new StringBuilder(256);
046        buffer.append("Failed to resolve version range");
047        if (result != null) {
048            buffer.append(" for ").append(result.getRequest().getArtifact());
049            if (!result.getExceptions().isEmpty()) {
050                buffer.append(": ")
051                        .append(result.getExceptions().iterator().next().getMessage());
052            }
053        }
054        return buffer.toString();
055    }
056
057    private static Throwable getFirstCause(VersionRangeResult result) {
058        Throwable cause = null;
059        if (result != null && !result.getExceptions().isEmpty()) {
060            cause = result.getExceptions().get(0);
061        }
062        return cause;
063    }
064
065    /**
066     * Creates a new exception with the specified result and detail message.
067     * All exceptions are added as suppressed as well.
068     *
069     * @param result The version range result at the point the exception occurred, may be {@code null}.
070     * @param message The detail message, may be {@code null}.
071     */
072    public VersionRangeResolutionException(VersionRangeResult result, String message) {
073        super(message);
074        if (result != null) {
075            result.getExceptions().forEach(this::addSuppressed);
076        }
077        this.result = result;
078    }
079
080    /**
081     * Creates a new exception with the specified result, detail message and cause.
082     * All exceptions are added as suppressed as well.
083     *
084     * @param result The version range result at the point the exception occurred, may be {@code null}.
085     * @param message The detail message, may be {@code null}.
086     * @param cause The exception that caused this one, may be {@code null}.
087     */
088    public VersionRangeResolutionException(VersionRangeResult result, String message, Throwable cause) {
089        super(message, cause);
090        if (result != null) {
091            result.getExceptions().forEach(this::addSuppressed);
092        }
093        this.result = result;
094    }
095
096    /**
097     * Gets the version range result at the point the exception occurred. Despite being incomplete, callers might want
098     * to use this result to fail gracefully and continue their operation with whatever interim data has been gathered.
099     *
100     * @return The version range result or {@code null} if unknown.
101     */
102    public VersionRangeResult getResult() {
103        return result;
104    }
105}